feat: add prisma json types (#1583)

This commit is contained in:
David Nguyen
2025-01-15 13:46:45 +11:00
committed by GitHub
parent 901be70f97
commit 5750f2b477
21 changed files with 174 additions and 188 deletions

View File

@ -27,6 +27,6 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"typescript": "^5"
"typescript": "5.6.2"
}
}

View File

@ -16,8 +16,8 @@
"next": "14.2.6"
},
"devDependencies": {
"@types/node": "20.16.5",
"@types/node": "^20",
"@types/react": "18.3.5",
"typescript": "5.5.4"
"typescript": "5.6.2"
}
}

View File

@ -68,11 +68,11 @@
"@simplewebauthn/types": "^9.0.1",
"@types/formidable": "^2.0.6",
"@types/luxon": "^3.3.1",
"@types/node": "20.1.0",
"@types/node": "^20",
"@types/papaparse": "^5.3.14",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/ua-parser-js": "^0.7.39",
"typescript": "5.2.2"
"typescript": "5.6.2"
}
}

171
package-lock.json generated
View File

@ -20,6 +20,7 @@
"mupdf": "^1.0.0",
"next-runtime-env": "^3.2.0",
"react": "^18",
"typescript": "5.6.2",
"zod": "3.24.1"
},
"devDependencies": {
@ -63,7 +64,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"typescript": "^5"
"typescript": "5.6.2"
}
},
"apps/documentation/node_modules/next-plausible": {
@ -88,18 +89,9 @@
"next": "14.2.6"
},
"devDependencies": {
"@types/node": "20.16.5",
"@types/node": "^20",
"@types/react": "18.3.5",
"typescript": "5.5.4"
}
},
"apps/openpage-api/node_modules/@types/node": {
"version": "20.16.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz",
"integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
"dev": true,
"dependencies": {
"undici-types": "~6.19.2"
"typescript": "5.6.2"
}
},
"apps/openpage-api/node_modules/@types/react": {
@ -112,25 +104,6 @@
"csstype": "^3.0.2"
}
},
"apps/openpage-api/node_modules/typescript": {
"version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"apps/openpage-api/node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true
},
"apps/web": {
"name": "@documenso/web",
"version": "1.9.0-rc.8",
@ -190,20 +163,14 @@
"@simplewebauthn/types": "^9.0.1",
"@types/formidable": "^2.0.6",
"@types/luxon": "^3.3.1",
"@types/node": "20.1.0",
"@types/node": "^20",
"@types/papaparse": "^5.3.14",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/ua-parser-js": "^0.7.39",
"typescript": "5.2.2"
"typescript": "5.6.2"
}
},
"apps/web/node_modules/@types/node": {
"version": "20.1.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz",
"integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==",
"dev": true
},
"apps/web/node_modules/next-axiom": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/next-axiom/-/next-axiom-1.5.1.tgz",
@ -221,19 +188,6 @@
"react": ">=18.0.0"
}
},
"apps/web/node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
@ -10205,7 +10159,8 @@
"node_modules/@types/node": {
"version": "20.5.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz",
"integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg=="
"integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==",
"license": "MIT"
},
"node_modules/@types/node-fetch": {
"version": "2.6.11",
@ -32257,9 +32212,10 @@
}
},
"node_modules/typescript": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz",
"integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==",
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -34132,24 +34088,10 @@
"@documenso/prisma": "*",
"@documenso/web": "*",
"@playwright/test": "^1.18.1",
"@types/node": "^20.8.2",
"@types/node": "^20",
"pdf-lib": "^1.17.1"
}
},
"packages/app-tests/node_modules/@types/node": {
"version": "20.8.4",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~5.25.1"
}
},
"packages/app-tests/node_modules/undici-types": {
"version": "5.25.3",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
"dev": true
},
"packages/assets": {
"name": "@documenso/assets",
"version": "0.1.0"
@ -34239,7 +34181,7 @@
"eslint-plugin-package-json": "^0.10.4",
"eslint-plugin-react": "^7.34.0",
"eslint-plugin-unused-imports": "^3.1.0",
"typescript": "5.2.2"
"typescript": "5.6.2"
}
},
"packages/eslint-config/node_modules/@eslint/eslintrc": {
@ -35301,18 +35243,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"packages/eslint-config/node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"packages/eslint-config/node_modules/which-typed-array": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz",
@ -35445,9 +35375,10 @@
"devDependencies": {
"dotenv": "^16.3.1",
"dotenv-cli": "^7.3.0",
"prisma-json-types-generator": "^3.2.2",
"prisma-kysely": "^1.8.0",
"tsx": "^4.11.0",
"typescript": "5.2.2",
"typescript": "5.6.2",
"zod-prisma-types": "3.1.9"
}
},
@ -35468,23 +35399,54 @@
"@prisma/debug": "5.22.0"
}
},
"packages/prisma/node_modules/prisma-json-types-generator": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/prisma-json-types-generator/-/prisma-json-types-generator-3.2.2.tgz",
"integrity": "sha512-kvEbJPIP5gxk65KmLs0nAvY+CxpqVMWb4OsEvXlyXZmp2IGfi5f52BUV7ezTYQNjRPZyR4QlayWJXffoqVVAfA==",
"dev": true,
"dependencies": {
"@prisma/generator-helper": "6.0.0",
"tslib": "2.8.1"
},
"bin": {
"prisma-json-types-generator": "index.js"
},
"engines": {
"node": ">=14.0"
},
"funding": {
"url": "https://github.com/arthurfiorette/prisma-json-types-generator?sponsor=1"
},
"peerDependencies": {
"prisma": "^5 || ^6",
"typescript": "^5.6.2"
}
},
"packages/prisma/node_modules/prisma-json-types-generator/node_modules/@prisma/debug": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.0.0.tgz",
"integrity": "sha512-eUjoNThlDXdyJ1iQ2d7U6aTVwm59EwvODb5zFVNJEokNoSiQmiYWNzZIwZyDmZ+j51j42/0iTaHIJ4/aZPKFRg==",
"dev": true
},
"packages/prisma/node_modules/prisma-json-types-generator/node_modules/@prisma/generator-helper": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-6.0.0.tgz",
"integrity": "sha512-5DkG7hspZo6U4OtqI2W0JcgtY37sr7HgT8Q0W/sjL4VoV4px6ivzK6Eif5bKM7q+S4yFUHtjUt/3s69ErfLn7A==",
"dev": true,
"dependencies": {
"@prisma/debug": "6.0.0"
}
},
"packages/prisma/node_modules/ts-pattern": {
"version": "5.0.6",
"resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.0.6.tgz",
"integrity": "sha512-Y+jOjihlFriWzcBjncPCf2/am+Hgz7LtsWs77pWg5vQQKLQj07oNrJryo/wK2G0ndNaoVn2ownFMeoeAuReu3Q=="
},
"packages/prisma/node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
"packages/prisma/node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true
},
"packages/prisma/node_modules/zod-prisma-types": {
"version": "3.1.9",
@ -35639,7 +35601,7 @@
"@types/react": "^18",
"@types/react-dom": "^18",
"react": "^18",
"typescript": "5.2.2"
"typescript": "5.6.2"
}
},
"packages/ui/node_modules/react-pdf": {
@ -35678,19 +35640,6 @@
"engines": {
"node": ">=6"
}
},
"packages/ui/node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
}
}
}

View File

@ -65,6 +65,7 @@
"dependencies": {
"@documenso/pdf-sign": "^0.1.0",
"@documenso/prisma": "^0.0.0",
"typescript": "5.6.2",
"@lingui/core": "^4.11.3",
"inngest-cli": "^0.29.1",
"luxon": "^3.5.0",

View File

@ -1053,12 +1053,12 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, {
.with('TEXT', () => ZTextFieldMeta.safeParse(fieldMeta))
.with('SIGNATURE', 'INITIALS', 'DATE', 'EMAIL', 'NAME', () => ({
success: true,
data: {},
data: undefined,
}))
.with('FREE_SIGNATURE', () => ({
success: false,
error: 'FREE_SIGNATURE is not supported',
data: {},
data: undefined,
}))
.exhaustive();

View File

@ -27,7 +27,7 @@ function createTempPdfFile() {
'%PDF-1.4\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R>>endobj\nxref\n0 4\n0000000000 65535 f\n0000000009 00000 n\n0000000052 00000 n\n0000000101 00000 n\ntrailer<</Size 4/Root 1 0 R>>\nstartxref\n178\n%%EOF',
);
fs.writeFileSync(tempFilePath, pdfContent);
fs.writeFileSync(tempFilePath, new Uint8Array(pdfContent));
return tempFilePath;
}

View File

@ -13,7 +13,7 @@
"author": "",
"devDependencies": {
"@playwright/test": "^1.18.1",
"@types/node": "^20.8.2",
"@types/node": "^20",
"@documenso/lib": "*",
"@documenso/prisma": "*",
"@documenso/web": "*",

View File

@ -15,6 +15,6 @@
"eslint-plugin-package-json": "^0.10.4",
"eslint-plugin-react": "^7.34.0",
"eslint-plugin-unused-imports": "^3.1.0",
"typescript": "5.2.2"
"typescript": "5.6.2"
}
}

View File

@ -33,7 +33,7 @@ export const setupTwoFactorAuthentication = async ({
const accountName = user.email;
const uri = createTOTPKeyURI(ISSUER, accountName, secret);
const encodedSecret = base32.encode(secret);
const encodedSecret = base32.encode(new Uint8Array(secret));
await prisma.user.update({
where: {

View File

@ -65,11 +65,6 @@ export const updateField = async ({
},
});
const newFieldMeta = {
...(oldField.fieldMeta as FieldMeta),
...fieldMeta,
};
const field = prisma.$transaction(async (tx) => {
const updatedField = await tx.field.update({
where: {
@ -83,7 +78,7 @@ export const updateField = async ({
positionY: pageY,
width: pageWidth,
height: pageHeight,
fieldMeta: newFieldMeta,
fieldMeta,
},
include: {
recipient: true,

View File

@ -0,0 +1,8 @@
import { z } from 'zod';
export const ZDocumentFormValuesSchema = z.record(
z.string(),
z.union([z.string(), z.boolean(), z.number()]),
);
export type TDocumentFormValues = z.infer<typeof ZDocumentFormValuesSchema>;

View File

@ -9,36 +9,36 @@ export const ZBaseFieldMeta = z.object({
export type TBaseFieldMeta = z.infer<typeof ZBaseFieldMeta>;
export const ZInitialsFieldMeta = z.object({
type: z.literal('initials').default('initials'),
export const ZInitialsFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('initials'),
fontSize: z.number().min(8).max(96).optional(),
});
export type TInitialsFieldMeta = z.infer<typeof ZInitialsFieldMeta>;
export const ZNameFieldMeta = z.object({
type: z.literal('name').default('name'),
export const ZNameFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('name'),
fontSize: z.number().min(8).max(96).optional(),
});
export type TNameFieldMeta = z.infer<typeof ZNameFieldMeta>;
export const ZEmailFieldMeta = z.object({
type: z.literal('email').default('email'),
export const ZEmailFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('email'),
fontSize: z.number().min(8).max(96).optional(),
});
export type TEmailFieldMeta = z.infer<typeof ZEmailFieldMeta>;
export const ZDateFieldMeta = z.object({
type: z.literal('date').default('date'),
export const ZDateFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('date'),
fontSize: z.number().min(8).max(96).optional(),
});
export type TDateFieldMeta = z.infer<typeof ZDateFieldMeta>;
export const ZTextFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('text').default('text'),
type: z.literal('text'),
text: z.string().optional(),
characterLimit: z.number().optional(),
fontSize: z.number().min(8).max(96).optional(),
@ -47,7 +47,7 @@ export const ZTextFieldMeta = ZBaseFieldMeta.extend({
export type TTextFieldMeta = z.infer<typeof ZTextFieldMeta>;
export const ZNumberFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('number').default('number'),
type: z.literal('number'),
numberFormat: z.string().optional(),
value: z.string().optional(),
minValue: z.number().optional(),
@ -58,7 +58,7 @@ export const ZNumberFieldMeta = ZBaseFieldMeta.extend({
export type TNumberFieldMeta = z.infer<typeof ZNumberFieldMeta>;
export const ZRadioFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('radio').default('radio'),
type: z.literal('radio'),
values: z
.array(
z.object({
@ -73,7 +73,7 @@ export const ZRadioFieldMeta = ZBaseFieldMeta.extend({
export type TRadioFieldMeta = z.infer<typeof ZRadioFieldMeta>;
export const ZCheckboxFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('checkbox').default('checkbox'),
type: z.literal('checkbox'),
values: z
.array(
z.object({
@ -90,30 +90,27 @@ export const ZCheckboxFieldMeta = ZBaseFieldMeta.extend({
export type TCheckboxFieldMeta = z.infer<typeof ZCheckboxFieldMeta>;
export const ZDropdownFieldMeta = ZBaseFieldMeta.extend({
type: z.literal('dropdown').default('dropdown'),
type: z.literal('dropdown'),
values: z.array(z.object({ value: z.string() })).optional(),
defaultValue: z.string().optional(),
});
export type TDropdownFieldMeta = z.infer<typeof ZDropdownFieldMeta>;
/**
* This will parse empty objects to { "type": "initials" }
*
* Todo: Fix.
*/
export const ZFieldMetaSchema = z
.union([
ZBaseFieldMeta.extend(ZInitialsFieldMeta.shape),
ZBaseFieldMeta.extend(ZNameFieldMeta.shape),
ZBaseFieldMeta.extend(ZEmailFieldMeta.shape),
ZBaseFieldMeta.extend(ZDateFieldMeta.shape),
export const ZFieldMetaNotOptionalSchema = z.discriminatedUnion('type', [
ZInitialsFieldMeta,
ZNameFieldMeta,
ZEmailFieldMeta,
ZDateFieldMeta,
ZTextFieldMeta,
ZNumberFieldMeta,
ZRadioFieldMeta,
ZCheckboxFieldMeta,
ZDropdownFieldMeta,
])
.optional();
]);
export type TFieldMetaNotOptionalSchema = z.infer<typeof ZFieldMetaNotOptionalSchema>;
export const ZFieldMetaSchema = ZFieldMetaNotOptionalSchema.optional();
export type TFieldMetaSchema = z.infer<typeof ZFieldMetaSchema>;

View File

@ -1,3 +1,4 @@
/// <reference types="@documenso/prisma/types/types.d.ts" />
import { PrismaClient } from '@prisma/client';
import { Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler } from 'kysely';
import kyselyExtension from 'prisma-extension-kysely';

View File

@ -30,9 +30,10 @@
"devDependencies": {
"dotenv": "^16.3.1",
"dotenv-cli": "^7.3.0",
"prisma-json-types-generator": "^3.2.2",
"prisma-kysely": "^1.8.0",
"tsx": "^4.11.0",
"typescript": "5.2.2",
"typescript": "5.6.2",
"zod-prisma-types": "3.1.9"
}
}

View File

@ -6,6 +6,10 @@ generator client {
provider = "prisma-client-js"
}
generator json {
provider = "prisma-json-types-generator"
}
generator zod {
provider = "zod-prisma-types"
createInputTypes = false
@ -297,14 +301,14 @@ enum DocumentVisibility {
ADMIN
}
/// @zod.import(["import { ZDocumentAuthOptionsSchema } from '@documenso/lib/types/document-auth';"])
/// @zod.import(["import { ZDocumentAuthOptionsSchema } from '@documenso/lib/types/document-auth';", "import { ZDocumentFormValuesSchema } from '@documenso/lib/types/document-form-values';"])
model Document {
id Int @id @default(autoincrement())
externalId String? /// @zod.string.describe("A custom external ID you can use to identify the document.")
userId Int /// @zod.number.describe("The ID of the user that created this document.")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
authOptions Json? /// Todo: zod.custom.use(ZDocumentAuthOptionsSchema.describe("Hello"))
formValues Json?
authOptions Json? /// [DocumentAuthOptions] @zod.custom.use(ZDocumentAuthOptionsSchema)
formValues Json? /// [DocumentFormValues] @zod.custom.use(ZDocumentFormValuesSchema)
visibility DocumentVisibility @default(EVERYONE)
title String
status DocumentStatus @default(DRAFT)
@ -373,6 +377,7 @@ enum DocumentDistributionMethod {
NONE
}
/// @zod.import(["import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';"])
model DocumentMeta {
id String @id @default(cuid())
subject String?
@ -387,7 +392,7 @@ model DocumentMeta {
typedSignatureEnabled Boolean @default(true)
language String @default("en")
distributionMethod DocumentDistributionMethod @default(EMAIL)
emailSettings Json?
emailSettings Json? /// [DocumentEmailSettings] @zod.custom.use(ZDocumentEmailSettingsSchema)
}
enum ReadStatus {
@ -424,7 +429,7 @@ model Recipient {
documentDeletedAt DateTime?
expired DateTime?
signedAt DateTime?
authOptions Json? /// Todo: zod.custom.use(ZRecipientAuthOptionsSchema)
authOptions Json? /// [RecipientAuthOptions] @zod.custom.use(ZRecipientAuthOptionsSchema)
signingOrder Int? /// @zod.number.describe("The order in which the recipient should sign the document. Only works if the document is set to sequential signing.")
rejectionReason String?
role RecipientRole @default(SIGNER)
@ -457,6 +462,7 @@ enum FieldType {
DROPDOWN
}
/// @zod.import(["import { ZFieldMetaNotOptionalSchema } from '@documenso/lib/types/field-meta';"])
model Field {
id Int @id @default(autoincrement())
secondaryId String @unique @default(cuid())
@ -475,7 +481,7 @@ model Field {
template Template? @relation(fields: [templateId], references: [id], onDelete: Cascade)
recipient Recipient @relation(fields: [recipientId], references: [id], onDelete: Cascade)
signature Signature?
fieldMeta Json? // Todo: Fix ZFieldMetaSchema before using it here.
fieldMeta Json? /// [FieldMeta] @zod.custom.use(ZFieldMetaNotOptionalSchema)
@@index([documentId])
@@index([templateId])
@ -640,6 +646,7 @@ enum TemplateType {
PRIVATE
}
/// @zod.import(["import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';"])
model TemplateMeta {
id String @id @default(cuid())
subject String?
@ -655,9 +662,10 @@ model TemplateMeta {
template Template @relation(fields: [templateId], references: [id], onDelete: Cascade)
redirectUrl String?
language String @default("en")
emailSettings Json?
emailSettings Json? /// [DocumentEmailSettings] @zod.custom.use(ZDocumentEmailSettingsSchema)
}
/// @zod.import(["import { ZDocumentAuthOptionsSchema } from '@documenso/lib/types/document-auth';"])
model Template {
id Int @id @default(autoincrement())
externalId String?
@ -666,7 +674,7 @@ model Template {
userId Int
teamId Int?
visibility DocumentVisibility @default(EVERYONE)
authOptions Json?
authOptions Json? /// [DocumentAuthOptions] @zod.custom.use(ZDocumentAuthOptionsSchema)
templateMeta TemplateMeta?
templateDocumentDataId String
createdAt DateTime @default(now())

25
packages/prisma/types/types.d.ts vendored Normal file
View File

@ -0,0 +1,25 @@
/* eslint-disable @typescript-eslint/no-namespace */
import type {
TDocumentAuthOptions,
TRecipientAuthOptions,
} from '@documenso/lib/types/document-auth';
import type { TDocumentEmailSettings } from '@documenso/lib/types/document-email';
import type { TDocumentFormValues } from '@documenso/lib/types/document-form-values';
import type { TFieldMetaNotOptionalSchema } from '@documenso/lib/types/field-meta';
/**
* Global types for Prisma.Json instances.
*/
declare global {
namespace PrismaJson {
type DocumentFormValues = TDocumentFormValues;
type DocumentAuthOptions = TDocumentAuthOptions;
type DocumentEmailSettings = TDocumentEmailSettings;
type RecipientAuthOptions = TRecipientAuthOptions;
type FieldMeta = TFieldMetaNotOptionalSchema;
}
}
export {};

View File

@ -26,9 +26,9 @@ export const updateSigningPlaceholder = ({ pdf }: UpdateSigningPlaceholderOption
const newByteRange = `[${byteRange.join(' ')}]`.padEnd(byteRangeSlice.length, ' ');
const updatedPdf = Buffer.concat([
pdf.subarray(0, byteRangeStart),
Buffer.from(newByteRange),
pdf.subarray(byteRangeEnd + 1),
new Uint8Array(pdf.subarray(0, byteRangeStart)),
new Uint8Array(Buffer.from(newByteRange)),
new Uint8Array(pdf.subarray(byteRangeEnd + 1)),
]);
if (updatedPdf.length !== length) {

View File

@ -23,13 +23,14 @@ export const signWithGoogleCloudHSM = async ({ pdf }: SignWithGoogleCloudHSMOpti
process.env.NEXT_PRIVATE_SIGNING_GCLOUD_APPLICATION_CREDENTIALS_CONTENTS
) {
if (!fs.existsSync(process.env.GOOGLE_APPLICATION_CREDENTIALS)) {
fs.writeFileSync(
process.env.GOOGLE_APPLICATION_CREDENTIALS,
const contents = new Uint8Array(
Buffer.from(
process.env.NEXT_PRIVATE_SIGNING_GCLOUD_APPLICATION_CREDENTIALS_CONTENTS,
'base64',
),
);
fs.writeFileSync(process.env.GOOGLE_APPLICATION_CREDENTIALS, contents);
}
}
@ -38,8 +39,8 @@ export const signWithGoogleCloudHSM = async ({ pdf }: SignWithGoogleCloudHSMOpti
});
const pdfWithoutSignature = Buffer.concat([
pdfWithPlaceholder.subarray(0, byteRange[1]),
pdfWithPlaceholder.subarray(byteRange[2]),
new Uint8Array(pdfWithPlaceholder.subarray(0, byteRange[1])),
new Uint8Array(pdfWithPlaceholder.subarray(byteRange[2])),
]);
const signatureLength = byteRange[2] - byteRange[1];
@ -70,9 +71,9 @@ export const signWithGoogleCloudHSM = async ({ pdf }: SignWithGoogleCloudHSMOpti
const signatureAsHex = signature.toString('hex');
const signedPdf = Buffer.concat([
pdfWithPlaceholder.subarray(0, byteRange[1]),
Buffer.from(`<${signatureAsHex.padEnd(signatureLength - 2, '0')}>`),
pdfWithPlaceholder.subarray(byteRange[2]),
new Uint8Array(pdfWithPlaceholder.subarray(0, byteRange[1])),
new Uint8Array(Buffer.from(`<${signatureAsHex.padEnd(signatureLength - 2, '0')}>`)),
new Uint8Array(pdfWithPlaceholder.subarray(byteRange[2])),
]);
return signedPdf;

View File

@ -15,8 +15,8 @@ export const signWithLocalCert = async ({ pdf }: SignWithLocalCertOptions) => {
});
const pdfWithoutSignature = Buffer.concat([
pdfWithPlaceholder.subarray(0, byteRange[1]),
pdfWithPlaceholder.subarray(byteRange[2]),
new Uint8Array(pdfWithPlaceholder.subarray(0, byteRange[1])),
new Uint8Array(pdfWithPlaceholder.subarray(byteRange[2])),
]);
const signatureLength = byteRange[2] - byteRange[1];
@ -51,9 +51,9 @@ export const signWithLocalCert = async ({ pdf }: SignWithLocalCertOptions) => {
const signatureAsHex = signature.toString('hex');
const signedPdf = Buffer.concat([
pdfWithPlaceholder.subarray(0, byteRange[1]),
Buffer.from(`<${signatureAsHex.padEnd(signatureLength - 2, '0')}>`),
pdfWithPlaceholder.subarray(byteRange[2]),
new Uint8Array(pdfWithPlaceholder.subarray(0, byteRange[1])),
new Uint8Array(Buffer.from(`<${signatureAsHex.padEnd(signatureLength - 2, '0')}>`)),
new Uint8Array(pdfWithPlaceholder.subarray(byteRange[2])),
]);
return signedPdf;

View File

@ -23,7 +23,7 @@
"@types/react": "^18",
"@types/react-dom": "^18",
"react": "^18",
"typescript": "5.2.2"
"typescript": "5.6.2"
},
"dependencies": {
"@documenso/lib": "*",