Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
"typescript.preferences.importModuleSpecifier": "relative",
"npm.packageManager": "pnpm",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[typescript]": {
Expand Down
43 changes: 43 additions & 0 deletions examples/erp/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

drizzle
9 changes: 4 additions & 5 deletions examples/erp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"format": "prettier --write .",
"format:check": "prettier --check .",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"db:migrate": "drizzle-kit migrate",
"db:generate": "drizzle-kit generate"
},
Expand All @@ -24,17 +23,17 @@
"next-themes": "^0.4.6",
"pg": "^8.14.1",
"postcss": "^8.5.3",
"react": "18.3.1",
"react-dom": "18.3.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"tailwindcss": "^4.0.14",
"zod": "3.24.4"
},
"devDependencies": {
"@internals/project-config": "workspace:^",
"@types/node": "^22.13.10",
"@types/pg": "^8.11.11",
"@types/react": "18.3.18",
"@types/react-dom": "18.3.5",
"@types/react": "19.1.4",
"@types/react-dom": "19.1.5",
"@vitejs/plugin-react": "^4.3.4",
"drizzle-kit": "^0.30.6",
"type-fest": "^4.38.0",
Expand Down
2 changes: 1 addition & 1 deletion examples/erp/src/app/(admin)/_helper/server.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use server'

import { handleServerFunction, ServerFunction } from '@kivotos/next'
import { handleServerFunction, type ServerFunction } from '@kivotos/next'

import { serverConfig } from '~/drizzlify/config'

Expand Down
2 changes: 1 addition & 1 deletion examples/erp/src/components/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { PropsWithChildren } from 'react'
import type { PropsWithChildren } from 'react'

import { ThemeProvider as NextThemesProvider } from 'next-themes'

Expand Down
1 change: 1 addition & 0 deletions internals/project-config/eslint/base.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const config = tseslint.config(
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/consistent-type-imports': 'error',
},
},
{
Expand Down
3 changes: 2 additions & 1 deletion internals/project-config/tsconfig/base.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"preserveWatchOutput": true,
"skipLibCheck": true,
"strict": true,
"resolveJsonModule": true
"resolveJsonModule": true,
"verbatimModuleSyntax": true
},
"exclude": ["node_modules"]
}
9 changes: 5 additions & 4 deletions packages/core/src/auth/context.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { and, AnyTable, asc, Column, desc, eq } from 'drizzle-orm'
import { UndefinedToOptional } from 'type-fest/source/internal'
import type { AnyTable, Column } from 'drizzle-orm'
import { and, asc, desc, eq } from 'drizzle-orm'
import type { UndefinedToOptional } from 'type-fest/source/internal'

import { AnyAccountTable, AnySessionTable, AnyUserTable, AuthConfig } from '.'
import type { AnyAccountTable, AnySessionTable, AnyUserTable, AuthConfig } from '.'
import { AccountProvider } from './constant'
import { getSessionCookie } from './utils'

import { MinimalContext } from '../config'
import type { MinimalContext } from '../config'

type InferTableType<T extends AnyTable<{}>> = UndefinedToOptional<{
[K in keyof T['_']['columns']]: T['_']['columns'][K]['_']['notNull'] extends true
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/auth/handlers/forgot-password.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import z from 'zod'

import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
import { AuthContext } from '../context'
import { type ApiRouteHandler, type ApiRouteSchema, createEndpoint } from '../../endpoint'
import { type AuthContext } from '../context'

interface InternalRouteOptions {
prefix?: string
}

export function forgotPasswordEmail<const TOptions extends InternalRouteOptions>(
options: TOptions

Check warning on line 11 in packages/core/src/auth/handlers/forgot-password.ts

View workflow job for this annotation

GitHub Actions / ci

'options' is defined but never used. Allowed unused args must match /^_/u
) {
const schema = {
method: 'POST',
Expand Down Expand Up @@ -47,7 +47,7 @@
),
})

const resetPasswordLink = `${args.context.authConfig.resetPassword?.resetPasswordUrl ?? '/auth/reset-password'}?token=${token}`

Check warning on line 50 in packages/core/src/auth/handlers/forgot-password.ts

View workflow job for this annotation

GitHub Actions / ci

'resetPasswordLink' is assigned a value but never used. Allowed unused vars must match /^_/u
// Send email

return {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/auth/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import { signOut } from './sign-out'
import { signUp } from './sign-up'

import { AuthConfig } from '..'
import type { AuthConfig } from '..'

export function createAuthHandlers<TAuthConfig extends AuthConfig>(config: TAuthConfig) {

Check warning on line 10 in packages/core/src/auth/handlers/index.ts

View workflow job for this annotation

GitHub Actions / ci

'config' is defined but never used. Allowed unused args must match /^_/u
const handlers = {
// No authentication required
signUp: signUp({}),
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/auth/handlers/me.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import z from 'zod'

import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
import { AuthContext } from '../context'
import { type ApiRouteHandler, type ApiRouteSchema, createEndpoint } from '../../endpoint'
import { type AuthContext } from '../context'

interface InternalRouteOptions {
prefix?: string
}

export function me<const TOptions extends InternalRouteOptions>(options: TOptions) {

Check warning on line 10 in packages/core/src/auth/handlers/me.ts

View workflow job for this annotation

GitHub Actions / ci

'options' is defined but never used. Allowed unused args must match /^_/u
const schema = {
method: 'GET',
path: '/api/auth/me',
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/auth/handlers/reset-password.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import z from 'zod'

import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
import { AuthContext } from '../context'
import { type ApiRouteHandler, type ApiRouteSchema, createEndpoint } from '../../endpoint'
import { type AuthContext } from '../context'

interface InternalRouteOptions {
prefix?: string
}

export function resetPasswordEmail<const TOptions extends InternalRouteOptions>(options: TOptions) {

Check warning on line 10 in packages/core/src/auth/handlers/reset-password.ts

View workflow job for this annotation

GitHub Actions / ci

'options' is defined but never used. Allowed unused args must match /^_/u
const schema = {
method: 'POST',
path: '/api/auth/reset-password',
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/auth/handlers/sign-in-email.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import z from 'zod'

import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
import { type ApiRouteHandler, type ApiRouteSchema, createEndpoint } from '../../endpoint'
import { AccountProvider } from '../constant'
import { AuthContext } from '../context'
import { type AuthContext } from '../context'
import { setSessionCookie } from '../utils'

interface InternalRouteOptions {
prefix?: string
}

export function signInEmail<const TOptions extends InternalRouteOptions>(options: TOptions) {

Check warning on line 12 in packages/core/src/auth/handlers/sign-in-email.ts

View workflow job for this annotation

GitHub Actions / ci

'options' is defined but never used. Allowed unused args must match /^_/u
const schema = {
method: 'POST',
path: '/api/auth/sign-in-email',
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/auth/handlers/sign-out.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import z from 'zod'

import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
import { AuthContext } from '../context'
import { type ApiRouteHandler, type ApiRouteSchema, createEndpoint } from '../../endpoint'
import { type AuthContext } from '../context'
import { deleteSessionCookie, getSessionCookie } from '../utils'

interface InternalRouteOptions {
prefix?: string
}

export function signOut<const TOptions extends InternalRouteOptions>(options: TOptions) {

Check warning on line 11 in packages/core/src/auth/handlers/sign-out.ts

View workflow job for this annotation

GitHub Actions / ci

'options' is defined but never used. Allowed unused args must match /^_/u
const schema = {
method: 'POST',
path: '/api/auth/sign-out',
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/auth/handlers/sign-up.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import z from 'zod'

import { ApiRouteHandler, ApiRouteSchema, createEndpoint } from '../../endpoint'
import { type ApiRouteHandler, type ApiRouteSchema, createEndpoint } from '../../endpoint'
import { AccountProvider } from '../constant'
import { AuthContext } from '../context'
import { type AuthContext } from '../context'

interface InternalRouteOptions {}

export function signUp<const TOptions extends InternalRouteOptions>(options: TOptions) {

Check warning on line 9 in packages/core/src/auth/handlers/sign-up.ts

View workflow job for this annotation

GitHub Actions / ci

'options' is defined but never used. Allowed unused args must match /^_/u
const schema = {
method: 'POST',
path: '/api/auth/sign-up',
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { AnyColumn, AnyTable } from 'drizzle-orm'
import type { AnyColumn, AnyTable } from 'drizzle-orm'
import * as R from 'remeda'
import { Simplify } from 'type-fest'
import type { Simplify } from 'type-fest'

import { AuthContext, createAuthContext } from './context'
import { type AuthContext, createAuthContext } from './context'
import { createAuthHandlers } from './handlers'

import { MinimalContext } from '../config'
import { ApiRouteHandler } from '../endpoint'
import type { MinimalContext } from '../config'
import type { ApiRouteHandler } from '../endpoint'

export type AnyTypedColumn<T> = AnyColumn & { _: { data: T; dialect: 'pg' } }
export type WithNotNull<T> = T & { _: { notNull: true } }
Expand Down Expand Up @@ -129,7 +129,7 @@ export type Auth<
>
}

export function createAuth<TContext extends MinimalContext = MinimalContext>(
export function createAuth<TContext extends MinimalContext<any> = MinimalContext<any>>(
config: AuthConfig,
context: TContext
): Auth<TContext> {
Expand Down
52 changes: 32 additions & 20 deletions packages/core/src/builder.handler.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { eq, or } from 'drizzle-orm'
import { NodePgDatabase } from 'drizzle-orm/node-postgres'
import type { NodePgDatabase } from 'drizzle-orm/node-postgres'
import { beforeEach, describe, expect, it, vi } from 'vitest'

import * as schema from './__mocks__/test-schema'
Expand Down Expand Up @@ -166,7 +166,7 @@ describe('ApiHandler', () => {
},
])
expect(tx.insert).toHaveBeenCalledTimes(1)
expect(result).toEqual(postData.id)
expect(result).toEqual({ __pk: postData.id, id: postData.id })
})

it('should (R) read successfully', async () => {
Expand Down Expand Up @@ -223,7 +223,7 @@ describe('ApiHandler', () => {
eq(postCollection.fields.idField._.column, postData.id)
)
expect(setMock).toHaveBeenCalledWith([{ nameTs: updatedPostData.name }])
expect(result).toEqual(postData.id)
expect(result).toEqual({ __pk: postData.id, id: postData.id })
})

it('should (D) delete successfully', async () => {
Expand Down Expand Up @@ -251,7 +251,7 @@ describe('ApiHandler', () => {
})
})

describe('with relation', () => {
describe.todo('with relation', () => {
describe('with "create" mode', () => {
describe('with "One" relation', () => {
const postWithAuthorCreateCollection = builder.collection('postWithAuthorTs', {
Expand Down Expand Up @@ -302,7 +302,9 @@ describe('ApiHandler', () => {
data: {
nameField: postData.name,
authorField: {
nameField: authorData.name,
create: {
nameField: authorData.name,
},
},
},
context: { db: mockDb as any },
Expand Down Expand Up @@ -392,7 +394,9 @@ describe('ApiHandler', () => {
data: {
nameField: updatedPostData.name,
authorField: {
nameField: updatedAuthorData.name,
create: {
nameField: updatedAuthorData.name,
},
},
},
})
Expand All @@ -406,7 +410,7 @@ describe('ApiHandler', () => {
expect(whereUpdateMock).toHaveBeenCalledWith(
eq(postWithAuthorCreateCollection.fields.idField._.column, postData.id)
)
expect(result).toEqual(postData.id)
expect(result).toEqual({ __pk: postData.id, id: postData.id })
})

it('should (D) delete successfully', async () => {
Expand Down Expand Up @@ -484,15 +488,17 @@ describe('ApiHandler', () => {
context: { db: mockDb as any },
data: {
nameField: postData.name,
postsField: [
mockPostData[0],
mockPostData[1],
mockPostData[2],
mockPostData[3],
mockPostData[4],
].map((post) => ({
nameField: post.name,
})),
postsField: {
create: [
mockPostData[0],
mockPostData[1],
mockPostData[2],
mockPostData[3],
mockPostData[4],
].map((post) => ({
nameField: post.name,
})),
},
},
})

Expand All @@ -501,7 +507,7 @@ describe('ApiHandler', () => {
expect(valuesInsertMock).toHaveBeenCalledWith([
expect.objectContaining({ nameTs: postData.name }),
])
expect(result).toEqual(authorData.id)
expect(result).toEqual({ __pk: authorData.id, id: authorData.id })
})

it('should (R) read successfully', async () => {
Expand Down Expand Up @@ -671,7 +677,9 @@ describe('ApiHandler', () => {
context: { db: mockDb as any },
data: {
nameField: postData.name,
authorField: authorData.id,
authorField: {
connect: authorData.id,
},
},
})

Expand Down Expand Up @@ -846,7 +854,9 @@ describe('ApiHandler', () => {
context: { db: mockDb as any },
data: {
nameField: authorData.name,
postsField: [mockPostData[0].id, mockPostData[1].id, mockPostData[2].id],
postsField: {
connect: [mockPostData[0].id, mockPostData[1].id, mockPostData[2].id],
},
},
})

Expand Down Expand Up @@ -951,7 +961,9 @@ describe('ApiHandler', () => {
id: updatedAuthorData.id,
data: {
nameField: updatedAuthorDataField.nameField,
postsField: [1, 2, 3],
postsField: {
connect: [1, 2, 3],
},
},
})
// ====== end user part (field) ======
Expand Down
Loading
Loading