@payloadcms/drizzle 3.79.0 → 3.79.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/find/traverseFields.d.ts.map +1 -1
  2. package/dist/find/traverseFields.js +33 -11
  3. package/dist/find/traverseFields.js.map +1 -1
  4. package/dist/postgres/columnToCodeConverter.d.ts.map +1 -1
  5. package/dist/postgres/columnToCodeConverter.js +2 -2
  6. package/dist/postgres/columnToCodeConverter.js.map +1 -1
  7. package/dist/postgres/createJSONQuery/index.d.ts.map +1 -1
  8. package/dist/postgres/createJSONQuery/index.js +2 -1
  9. package/dist/postgres/createJSONQuery/index.js.map +1 -1
  10. package/dist/queries/parseParams.d.ts.map +1 -1
  11. package/dist/queries/parseParams.js +1 -1
  12. package/dist/queries/parseParams.js.map +1 -1
  13. package/dist/queries/sanitizeQueryValue.d.ts.map +1 -1
  14. package/dist/queries/sanitizeQueryValue.js +3 -3
  15. package/dist/queries/sanitizeQueryValue.js.map +1 -1
  16. package/dist/sqlite/columnToCodeConverter.d.ts.map +1 -1
  17. package/dist/sqlite/columnToCodeConverter.js +2 -2
  18. package/dist/sqlite/columnToCodeConverter.js.map +1 -1
  19. package/dist/sqlite/createJSONQuery/convertPathToJSONTraversal.d.ts.map +1 -1
  20. package/dist/sqlite/createJSONQuery/convertPathToJSONTraversal.js +2 -1
  21. package/dist/sqlite/createJSONQuery/convertPathToJSONTraversal.js.map +1 -1
  22. package/dist/sqlite/createJSONQuery/index.d.ts.map +1 -1
  23. package/dist/sqlite/createJSONQuery/index.js +13 -11
  24. package/dist/sqlite/createJSONQuery/index.js.map +1 -1
  25. package/dist/types.d.ts +1 -0
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/types.js.map +1 -1
  28. package/dist/utilities/createSchemaGenerator.d.ts.map +1 -1
  29. package/dist/utilities/createSchemaGenerator.js +35 -0
  30. package/dist/utilities/createSchemaGenerator.js.map +1 -1
  31. package/dist/utilities/json.d.ts +1 -1
  32. package/dist/utilities/json.d.ts.map +1 -1
  33. package/dist/utilities/json.js +6 -1
  34. package/dist/utilities/json.js.map +1 -1
  35. package/dist/utilities/sanitizePathSegment.d.ts +2 -0
  36. package/dist/utilities/sanitizePathSegment.d.ts.map +1 -0
  37. package/dist/utilities/sanitizePathSegment.js +14 -0
  38. package/dist/utilities/sanitizePathSegment.js.map +1 -0
  39. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"createSchemaGenerator.d.ts","sourceRoot":"","sources":["../../src/utilities/createSchemaGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAM7C,OAAO,KAAK,EAAE,qBAAqB,EAAkB,MAAM,aAAa,CAAA;AAkCxE,eAAO,MAAM,qBAAqB,4GAO/B;IACD,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB,KAAG,cAmQH,CAAA"}
1
+ {"version":3,"file":"createSchemaGenerator.d.ts","sourceRoot":"","sources":["../../src/utilities/createSchemaGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAM7C,OAAO,KAAK,EAAE,qBAAqB,EAAkB,MAAM,aAAa,CAAA;AAkCxE,eAAO,MAAM,qBAAqB,4GAO/B;IACD,qBAAqB,EAAE,qBAAqB,CAAA;IAC5C,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB,KAAG,cAiTH,CAAA"}
@@ -65,6 +65,40 @@ export const createSchemaGenerator = ({ columnToCodeConverter, corePackageSuffix
65
65
  addImport(corePackage, 'foreignKey');
66
66
  addImport(`${this.packageName}/drizzle`, 'sql');
67
67
  addImport(`${this.packageName}/drizzle`, 'relations');
68
+ const fkGraph = {};
69
+ for(const tableName in this.rawTables){
70
+ fkGraph[tableName] = new Set();
71
+ const table = this.rawTables[tableName];
72
+ for(const colKey in table.columns){
73
+ const col = table.columns[colKey];
74
+ if (col.reference && col.reference.table !== tableName) {
75
+ fkGraph[tableName].add(col.reference.table);
76
+ }
77
+ }
78
+ }
79
+ const canReach = (from, target, visited)=>{
80
+ if (from === target) {
81
+ return true;
82
+ }
83
+ if (visited.has(from)) {
84
+ return false;
85
+ }
86
+ visited.add(from);
87
+ for (const neighbor of fkGraph[from] ?? []){
88
+ if (canReach(neighbor, target, visited)) {
89
+ return true;
90
+ }
91
+ }
92
+ return false;
93
+ };
94
+ const circularEdges = new Set();
95
+ for(const tableA in fkGraph){
96
+ for (const tableB of fkGraph[tableA]){
97
+ if (canReach(tableB, tableA, new Set())) {
98
+ circularEdges.add(`${tableA}:${tableB}`);
99
+ }
100
+ }
101
+ }
68
102
  for(const tableName in this.rawTables){
69
103
  const table = this.rawTables[tableName];
70
104
  const extrasDeclarations = [];
@@ -100,6 +134,7 @@ ${Object.entries(table.columns).map(([key, column])=>` ${sanitizeObjectKey(key)
100
134
  adapter: this,
101
135
  addEnum,
102
136
  addImport,
137
+ circularEdges,
103
138
  column,
104
139
  locales: this.payload.config.localization ? this.payload.config.localization.localeCodes : undefined,
105
140
  tableKey: tableName
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/createSchemaGenerator.ts"],"sourcesContent":["import type { GenerateSchema } from 'payload'\n\nimport { existsSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport path from 'path'\n\nimport type { ColumnToCodeConverter, DrizzleAdapter } from '../types.js'\n\n/**\n * @example\n * console.log(sanitizeObjectKey(\"oneTwo\")); // oneTwo\n * console.log(sanitizeObjectKey(\"one-two\")); // 'one-two'\n * console.log(sanitizeObjectKey(\"_one$Two3\")); // _one$Two3\n * console.log(sanitizeObjectKey(\"3invalid\")); // '3invalid'\n */\nconst sanitizeObjectKey = (key: string) => {\n // Regular expression for a valid identifier\n const identifierRegex = /^[a-z_$][\\w$]*$/i\n if (identifierRegex.test(key)) {\n return key\n }\n\n return `'${key}'`\n}\n\n/**\n * @example\n * (columns default-valuesID) -> columns['default-valuesID']\n * (columns defaultValues) -> columns.defaultValues\n */\nconst accessProperty = (objName: string, key: string) => {\n const sanitized = sanitizeObjectKey(key)\n\n if (sanitized.startsWith(\"'\")) {\n return `${objName}[${sanitized}]`\n }\n\n return `${objName}.${key}`\n}\n\nexport const createSchemaGenerator = ({\n columnToCodeConverter,\n corePackageSuffix,\n defaultOutputFile,\n enumImport,\n schemaImport,\n tableImport,\n}: {\n columnToCodeConverter: ColumnToCodeConverter\n corePackageSuffix: string\n defaultOutputFile?: string\n enumImport?: string\n schemaImport?: string\n tableImport: string\n}): GenerateSchema => {\n return async function generateSchema(\n this: DrizzleAdapter,\n { log = true, outputFile = defaultOutputFile, prettify = true } = {},\n ) {\n const importDeclarations: Record<string, Set<string>> = {}\n\n const tableDeclarations: string[] = []\n const enumDeclarations: string[] = []\n const relationsDeclarations: string[] = []\n\n const addImport = (from: string, name: string) => {\n if (!importDeclarations[from]) {\n importDeclarations[from] = new Set()\n }\n\n importDeclarations[from].add(name)\n }\n\n const corePackage = `${this.packageName}/drizzle/${corePackageSuffix}`\n\n let schemaDeclaration: null | string = null\n\n if (this.schemaName) {\n addImport(corePackage, schemaImport)\n schemaDeclaration = `export const db_schema = ${schemaImport}('${this.schemaName}')`\n }\n\n const enumFn = this.schemaName ? `db_schema.enum` : enumImport\n\n const enumsList: string[] = []\n const addEnum = (name: string, options: string[]) => {\n if (enumsList.some((each) => each === name)) {\n return\n }\n enumsList.push(name)\n enumDeclarations.push(\n `export const ${name} = ${enumFn}('${name}', [${options.map((option) => `'${option}'`).join(', ')}])`,\n )\n }\n\n if (this.payload.config.localization && enumImport) {\n addEnum('enum__locales', this.payload.config.localization.localeCodes)\n }\n\n const tableFn = this.schemaName ? `db_schema.table` : tableImport\n\n if (!this.schemaName) {\n addImport(corePackage, tableImport)\n }\n\n addImport(corePackage, 'index')\n addImport(corePackage, 'uniqueIndex')\n addImport(corePackage, 'foreignKey')\n\n addImport(`${this.packageName}/drizzle`, 'sql')\n addImport(`${this.packageName}/drizzle`, 'relations')\n\n for (const tableName in this.rawTables) {\n const table = this.rawTables[tableName]\n\n const extrasDeclarations: string[] = []\n\n if (table.indexes) {\n for (const key in table.indexes) {\n const index = table.indexes[key]\n let indexDeclaration = `${index.unique ? 'uniqueIndex' : 'index'}('${index.name}')`\n indexDeclaration += `.on(${typeof index.on === 'string' ? `${accessProperty('columns', index.on)}` : `${index.on.map((on) => `${accessProperty('columns', on)}`).join(', ')}`}),`\n extrasDeclarations.push(indexDeclaration)\n }\n }\n\n if (table.foreignKeys) {\n for (const key in table.foreignKeys) {\n const foreignKey = table.foreignKeys[key]\n\n let foreignKeyDeclaration = `foreignKey({\n columns: [${foreignKey.columns.map((col) => `columns['${col}']`).join(', ')}],\n foreignColumns: [${foreignKey.foreignColumns.map((col) => `${accessProperty(col.table, col.name)}`).join(', ')}],\n name: '${foreignKey.name}'\n })`\n\n if (foreignKey.onDelete) {\n foreignKeyDeclaration += `.onDelete('${foreignKey.onDelete}')`\n }\n if (foreignKey.onUpdate) {\n foreignKeyDeclaration += `.onUpdate('${foreignKey.onDelete}')`\n }\n\n foreignKeyDeclaration += ','\n\n extrasDeclarations.push(foreignKeyDeclaration)\n }\n }\n\n const tableCode = `\nexport const ${tableName} = ${tableFn}('${tableName}', {\n${Object.entries(table.columns)\n .map(\n ([key, column]) =>\n ` ${sanitizeObjectKey(key)}: ${columnToCodeConverter({\n adapter: this,\n addEnum,\n addImport,\n column,\n locales: this.payload.config.localization\n ? this.payload.config.localization.localeCodes\n : undefined,\n tableKey: tableName,\n })},`,\n )\n .join('\\n')}\n}${\n extrasDeclarations.length\n ? `, (columns) => [\n ${extrasDeclarations.join(' ')}\n]`\n : ''\n }\n)\n`\n\n tableDeclarations.push(tableCode)\n }\n\n for (const tableName in this.rawRelations) {\n const relations = this.rawRelations[tableName]\n const properties: string[] = []\n\n for (const key in relations) {\n const relation = relations[key]\n let declaration: string\n\n if (relation.type === 'one') {\n declaration = `${sanitizeObjectKey(key)}: one(${relation.to}, {\n ${relation.fields.some((field) => field.table !== tableName) ? '// @ts-expect-error Drizzle TypeScript bug for ONE relationships with a field in different table' : ''}\n fields: [${relation.fields.map((field) => `${accessProperty(field.table, field.name)}`).join(', ')}],\n references: [${relation.references.map((col) => `${accessProperty(relation.to, col)}`).join(', ')}],\n ${relation.relationName ? `relationName: '${relation.relationName}',` : ''}\n }),`\n } else {\n declaration = `${sanitizeObjectKey(key)}: many(${relation.to}, {\n ${relation.relationName ? `relationName: '${relation.relationName}',` : ''}\n }),`\n }\n\n properties.push(declaration)\n }\n\n // beautify / lintify relations callback output, when no many for example, don't add it\n const args = []\n\n if (Object.values(relations).some((rel) => rel.type === 'one')) {\n args.push('one')\n }\n\n if (Object.values(relations).some((rel) => rel.type === 'many')) {\n args.push('many')\n }\n\n const arg = args.length ? `{ ${args.join(', ')} }` : ''\n\n const declaration = `export const relations_${tableName} = relations(${tableName}, (${arg}) => ({\n ${properties.join('\\n ')}\n }))`\n\n relationsDeclarations.push(declaration)\n }\n\n if (enumDeclarations.length && !this.schemaName) {\n addImport(corePackage, enumImport)\n }\n\n const importDeclarationsSanitized: string[] = []\n\n for (const moduleName in importDeclarations) {\n const moduleImports = importDeclarations[moduleName]\n\n importDeclarationsSanitized.push(\n `import { ${Array.from(moduleImports).join(', ')} } from '${moduleName}'`,\n )\n }\n\n const schemaType = `\ntype DatabaseSchema = {\n ${[\n this.schemaName ? 'db_schema' : null,\n ...enumsList,\n ...Object.keys(this.rawTables),\n ...Object.keys(this.rawRelations).map((table) => `relations_${table}`),\n ]\n .filter(Boolean)\n .map((name) => `${name}: typeof ${name}`)\n .join('\\n ')}\n}\n `\n\n const finalDeclaration = `\ndeclare module '${this.packageName}' {\n export interface GeneratedDatabaseSchema {\n schema: DatabaseSchema\n }\n}\n `\n\n const warning = `\n/* tslint:disable */\n/* eslint-disable */\n/**\n * This file was automatically generated by Payload.\n * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,\n * and re-run \\`payload generate:db-schema\\` to regenerate this file.\n */\n`\n\n const importTypes = `import type {} from '${this.packageName}'`\n\n let code = [\n warning,\n importTypes,\n ...importDeclarationsSanitized,\n schemaDeclaration,\n ...enumDeclarations,\n ...tableDeclarations,\n ...relationsDeclarations,\n schemaType,\n finalDeclaration,\n ]\n .filter(Boolean)\n .join('\\n')\n\n if (!outputFile) {\n const cwd = process.cwd()\n const srcDir = path.resolve(cwd, 'src')\n\n if (existsSync(srcDir)) {\n outputFile = path.resolve(srcDir, 'payload-generated-schema.ts')\n } else {\n outputFile = path.resolve(cwd, 'payload-generated-schema.ts')\n }\n }\n\n if (prettify) {\n try {\n const prettier = await eval('import(\"prettier\")')\n const configPath = await prettier.resolveConfigFile()\n const config = configPath ? await prettier.resolveConfig(configPath) : {}\n code = await prettier.format(code, { ...config, parser: 'typescript' })\n } catch {\n /* empty */\n }\n }\n\n await writeFile(outputFile, code, 'utf-8')\n\n if (log) {\n this.payload.logger.info(`Written ${outputFile}`)\n }\n }\n}\n"],"names":["existsSync","writeFile","path","sanitizeObjectKey","key","identifierRegex","test","accessProperty","objName","sanitized","startsWith","createSchemaGenerator","columnToCodeConverter","corePackageSuffix","defaultOutputFile","enumImport","schemaImport","tableImport","generateSchema","log","outputFile","prettify","importDeclarations","tableDeclarations","enumDeclarations","relationsDeclarations","addImport","from","name","Set","add","corePackage","packageName","schemaDeclaration","schemaName","enumFn","enumsList","addEnum","options","some","each","push","map","option","join","payload","config","localization","localeCodes","tableFn","tableName","rawTables","table","extrasDeclarations","indexes","index","indexDeclaration","unique","on","foreignKeys","foreignKey","foreignKeyDeclaration","columns","col","foreignColumns","onDelete","onUpdate","tableCode","Object","entries","column","adapter","locales","undefined","tableKey","length","rawRelations","relations","properties","relation","declaration","type","to","fields","field","references","relationName","args","values","rel","arg","importDeclarationsSanitized","moduleName","moduleImports","Array","schemaType","keys","filter","Boolean","finalDeclaration","warning","importTypes","code","cwd","process","srcDir","resolve","prettier","eval","configPath","resolveConfigFile","resolveConfig","format","parser","logger","info"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utilities/createSchemaGenerator.ts"],"sourcesContent":["import type { GenerateSchema } from 'payload'\n\nimport { existsSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport path from 'path'\n\nimport type { ColumnToCodeConverter, DrizzleAdapter } from '../types.js'\n\n/**\n * @example\n * console.log(sanitizeObjectKey(\"oneTwo\")); // oneTwo\n * console.log(sanitizeObjectKey(\"one-two\")); // 'one-two'\n * console.log(sanitizeObjectKey(\"_one$Two3\")); // _one$Two3\n * console.log(sanitizeObjectKey(\"3invalid\")); // '3invalid'\n */\nconst sanitizeObjectKey = (key: string) => {\n // Regular expression for a valid identifier\n const identifierRegex = /^[a-z_$][\\w$]*$/i\n if (identifierRegex.test(key)) {\n return key\n }\n\n return `'${key}'`\n}\n\n/**\n * @example\n * (columns default-valuesID) -> columns['default-valuesID']\n * (columns defaultValues) -> columns.defaultValues\n */\nconst accessProperty = (objName: string, key: string) => {\n const sanitized = sanitizeObjectKey(key)\n\n if (sanitized.startsWith(\"'\")) {\n return `${objName}[${sanitized}]`\n }\n\n return `${objName}.${key}`\n}\n\nexport const createSchemaGenerator = ({\n columnToCodeConverter,\n corePackageSuffix,\n defaultOutputFile,\n enumImport,\n schemaImport,\n tableImport,\n}: {\n columnToCodeConverter: ColumnToCodeConverter\n corePackageSuffix: string\n defaultOutputFile?: string\n enumImport?: string\n schemaImport?: string\n tableImport: string\n}): GenerateSchema => {\n return async function generateSchema(\n this: DrizzleAdapter,\n { log = true, outputFile = defaultOutputFile, prettify = true } = {},\n ) {\n const importDeclarations: Record<string, Set<string>> = {}\n\n const tableDeclarations: string[] = []\n const enumDeclarations: string[] = []\n const relationsDeclarations: string[] = []\n\n const addImport = (from: string, name: string) => {\n if (!importDeclarations[from]) {\n importDeclarations[from] = new Set()\n }\n\n importDeclarations[from].add(name)\n }\n\n const corePackage = `${this.packageName}/drizzle/${corePackageSuffix}`\n\n let schemaDeclaration: null | string = null\n\n if (this.schemaName) {\n addImport(corePackage, schemaImport)\n schemaDeclaration = `export const db_schema = ${schemaImport}('${this.schemaName}')`\n }\n\n const enumFn = this.schemaName ? `db_schema.enum` : enumImport\n\n const enumsList: string[] = []\n const addEnum = (name: string, options: string[]) => {\n if (enumsList.some((each) => each === name)) {\n return\n }\n enumsList.push(name)\n enumDeclarations.push(\n `export const ${name} = ${enumFn}('${name}', [${options.map((option) => `'${option}'`).join(', ')}])`,\n )\n }\n\n if (this.payload.config.localization && enumImport) {\n addEnum('enum__locales', this.payload.config.localization.localeCodes)\n }\n\n const tableFn = this.schemaName ? `db_schema.table` : tableImport\n\n if (!this.schemaName) {\n addImport(corePackage, tableImport)\n }\n\n addImport(corePackage, 'index')\n addImport(corePackage, 'uniqueIndex')\n addImport(corePackage, 'foreignKey')\n\n addImport(`${this.packageName}/drizzle`, 'sql')\n addImport(`${this.packageName}/drizzle`, 'relations')\n\n const fkGraph: Record<string, Set<string>> = {}\n\n for (const tableName in this.rawTables) {\n fkGraph[tableName] = new Set()\n const table = this.rawTables[tableName]\n\n for (const colKey in table.columns) {\n const col = table.columns[colKey]\n\n if (col.reference && col.reference.table !== tableName) {\n fkGraph[tableName].add(col.reference.table)\n }\n }\n }\n\n const canReach = (from: string, target: string, visited: Set<string>): boolean => {\n if (from === target) {\n return true\n }\n\n if (visited.has(from)) {\n return false\n }\n\n visited.add(from)\n\n for (const neighbor of fkGraph[from] ?? []) {\n if (canReach(neighbor, target, visited)) {\n return true\n }\n }\n\n return false\n }\n\n const circularEdges = new Set<string>()\n\n for (const tableA in fkGraph) {\n for (const tableB of fkGraph[tableA]) {\n if (canReach(tableB, tableA, new Set())) {\n circularEdges.add(`${tableA}:${tableB}`)\n }\n }\n }\n\n for (const tableName in this.rawTables) {\n const table = this.rawTables[tableName]\n\n const extrasDeclarations: string[] = []\n\n if (table.indexes) {\n for (const key in table.indexes) {\n const index = table.indexes[key]\n let indexDeclaration = `${index.unique ? 'uniqueIndex' : 'index'}('${index.name}')`\n indexDeclaration += `.on(${typeof index.on === 'string' ? `${accessProperty('columns', index.on)}` : `${index.on.map((on) => `${accessProperty('columns', on)}`).join(', ')}`}),`\n extrasDeclarations.push(indexDeclaration)\n }\n }\n\n if (table.foreignKeys) {\n for (const key in table.foreignKeys) {\n const foreignKey = table.foreignKeys[key]\n\n let foreignKeyDeclaration = `foreignKey({\n columns: [${foreignKey.columns.map((col) => `columns['${col}']`).join(', ')}],\n foreignColumns: [${foreignKey.foreignColumns.map((col) => `${accessProperty(col.table, col.name)}`).join(', ')}],\n name: '${foreignKey.name}'\n })`\n\n if (foreignKey.onDelete) {\n foreignKeyDeclaration += `.onDelete('${foreignKey.onDelete}')`\n }\n if (foreignKey.onUpdate) {\n foreignKeyDeclaration += `.onUpdate('${foreignKey.onDelete}')`\n }\n\n foreignKeyDeclaration += ','\n\n extrasDeclarations.push(foreignKeyDeclaration)\n }\n }\n\n const tableCode = `\nexport const ${tableName} = ${tableFn}('${tableName}', {\n${Object.entries(table.columns)\n .map(\n ([key, column]) =>\n ` ${sanitizeObjectKey(key)}: ${columnToCodeConverter({\n adapter: this,\n addEnum,\n addImport,\n circularEdges,\n column,\n locales: this.payload.config.localization\n ? this.payload.config.localization.localeCodes\n : undefined,\n tableKey: tableName,\n })},`,\n )\n .join('\\n')}\n}${\n extrasDeclarations.length\n ? `, (columns) => [\n ${extrasDeclarations.join(' ')}\n]`\n : ''\n }\n)\n`\n\n tableDeclarations.push(tableCode)\n }\n\n for (const tableName in this.rawRelations) {\n const relations = this.rawRelations[tableName]\n const properties: string[] = []\n\n for (const key in relations) {\n const relation = relations[key]\n let declaration: string\n\n if (relation.type === 'one') {\n declaration = `${sanitizeObjectKey(key)}: one(${relation.to}, {\n ${relation.fields.some((field) => field.table !== tableName) ? '// @ts-expect-error Drizzle TypeScript bug for ONE relationships with a field in different table' : ''}\n fields: [${relation.fields.map((field) => `${accessProperty(field.table, field.name)}`).join(', ')}],\n references: [${relation.references.map((col) => `${accessProperty(relation.to, col)}`).join(', ')}],\n ${relation.relationName ? `relationName: '${relation.relationName}',` : ''}\n }),`\n } else {\n declaration = `${sanitizeObjectKey(key)}: many(${relation.to}, {\n ${relation.relationName ? `relationName: '${relation.relationName}',` : ''}\n }),`\n }\n\n properties.push(declaration)\n }\n\n // beautify / lintify relations callback output, when no many for example, don't add it\n const args = []\n\n if (Object.values(relations).some((rel) => rel.type === 'one')) {\n args.push('one')\n }\n\n if (Object.values(relations).some((rel) => rel.type === 'many')) {\n args.push('many')\n }\n\n const arg = args.length ? `{ ${args.join(', ')} }` : ''\n\n const declaration = `export const relations_${tableName} = relations(${tableName}, (${arg}) => ({\n ${properties.join('\\n ')}\n }))`\n\n relationsDeclarations.push(declaration)\n }\n\n if (enumDeclarations.length && !this.schemaName) {\n addImport(corePackage, enumImport)\n }\n\n const importDeclarationsSanitized: string[] = []\n\n for (const moduleName in importDeclarations) {\n const moduleImports = importDeclarations[moduleName]\n\n importDeclarationsSanitized.push(\n `import { ${Array.from(moduleImports).join(', ')} } from '${moduleName}'`,\n )\n }\n\n const schemaType = `\ntype DatabaseSchema = {\n ${[\n this.schemaName ? 'db_schema' : null,\n ...enumsList,\n ...Object.keys(this.rawTables),\n ...Object.keys(this.rawRelations).map((table) => `relations_${table}`),\n ]\n .filter(Boolean)\n .map((name) => `${name}: typeof ${name}`)\n .join('\\n ')}\n}\n `\n\n const finalDeclaration = `\ndeclare module '${this.packageName}' {\n export interface GeneratedDatabaseSchema {\n schema: DatabaseSchema\n }\n}\n `\n\n const warning = `\n/* tslint:disable */\n/* eslint-disable */\n/**\n * This file was automatically generated by Payload.\n * DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,\n * and re-run \\`payload generate:db-schema\\` to regenerate this file.\n */\n`\n\n const importTypes = `import type {} from '${this.packageName}'`\n\n let code = [\n warning,\n importTypes,\n ...importDeclarationsSanitized,\n schemaDeclaration,\n ...enumDeclarations,\n ...tableDeclarations,\n ...relationsDeclarations,\n schemaType,\n finalDeclaration,\n ]\n .filter(Boolean)\n .join('\\n')\n\n if (!outputFile) {\n const cwd = process.cwd()\n const srcDir = path.resolve(cwd, 'src')\n\n if (existsSync(srcDir)) {\n outputFile = path.resolve(srcDir, 'payload-generated-schema.ts')\n } else {\n outputFile = path.resolve(cwd, 'payload-generated-schema.ts')\n }\n }\n\n if (prettify) {\n try {\n const prettier = await eval('import(\"prettier\")')\n const configPath = await prettier.resolveConfigFile()\n const config = configPath ? await prettier.resolveConfig(configPath) : {}\n code = await prettier.format(code, { ...config, parser: 'typescript' })\n } catch {\n /* empty */\n }\n }\n\n await writeFile(outputFile, code, 'utf-8')\n\n if (log) {\n this.payload.logger.info(`Written ${outputFile}`)\n }\n }\n}\n"],"names":["existsSync","writeFile","path","sanitizeObjectKey","key","identifierRegex","test","accessProperty","objName","sanitized","startsWith","createSchemaGenerator","columnToCodeConverter","corePackageSuffix","defaultOutputFile","enumImport","schemaImport","tableImport","generateSchema","log","outputFile","prettify","importDeclarations","tableDeclarations","enumDeclarations","relationsDeclarations","addImport","from","name","Set","add","corePackage","packageName","schemaDeclaration","schemaName","enumFn","enumsList","addEnum","options","some","each","push","map","option","join","payload","config","localization","localeCodes","tableFn","fkGraph","tableName","rawTables","table","colKey","columns","col","reference","canReach","target","visited","has","neighbor","circularEdges","tableA","tableB","extrasDeclarations","indexes","index","indexDeclaration","unique","on","foreignKeys","foreignKey","foreignKeyDeclaration","foreignColumns","onDelete","onUpdate","tableCode","Object","entries","column","adapter","locales","undefined","tableKey","length","rawRelations","relations","properties","relation","declaration","type","to","fields","field","references","relationName","args","values","rel","arg","importDeclarationsSanitized","moduleName","moduleImports","Array","schemaType","keys","filter","Boolean","finalDeclaration","warning","importTypes","code","cwd","process","srcDir","resolve","prettier","eval","configPath","resolveConfigFile","resolveConfig","format","parser","logger","info"],"mappings":"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"}
@@ -2,7 +2,7 @@ import type { Column, SQL } from 'drizzle-orm';
2
2
  import type { DrizzleAdapter } from '../types.js';
3
3
  export declare function jsonAgg(adapter: DrizzleAdapter, expression: SQL): SQL<unknown>;
4
4
  /**
5
- * @param shape Potential for SQL injections, so you shouldn't allow user-specified key names
5
+ * @param shape Keys are interpolated into raw SQL only use trusted, internally-generated key names
6
6
  */
7
7
  export declare function jsonBuildObject<T extends Record<string, Column | SQL>>(adapter: DrizzleAdapter, shape: T): SQL<unknown>;
8
8
  export declare const jsonAggBuildObject: <T extends Record<string, Column | SQL>>(adapter: DrizzleAdapter, shape: T) => SQL<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/utilities/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAI9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,gBAM/D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,EACpE,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,CAAC,gBAiBT;AAED,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,WAC9D,cAAc,SAChB,CAAC,iBAGT,CAAA"}
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/utilities/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAK9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,gBAM/D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,EACpE,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,CAAC,gBAuBT;AAED,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,WAC9D,cAAc,SAChB,CAAC,iBAGT,CAAA"}
@@ -1,4 +1,6 @@
1
1
  import { sql } from 'drizzle-orm';
2
+ import { APIError } from 'payload';
3
+ const SAFE_KEY_REGEX = /^\w+$/;
2
4
  export function jsonAgg(adapter, expression) {
3
5
  if (adapter.name === 'sqlite') {
4
6
  return sql`coalesce(json_group_array(${expression}), '[]')`;
@@ -6,10 +8,13 @@ export function jsonAgg(adapter, expression) {
6
8
  return sql`coalesce(json_agg(${expression}), '[]'::json)`;
7
9
  }
8
10
  /**
9
- * @param shape Potential for SQL injections, so you shouldn't allow user-specified key names
11
+ * @param shape Keys are interpolated into raw SQL only use trusted, internally-generated key names
10
12
  */ export function jsonBuildObject(adapter, shape) {
11
13
  const chunks = [];
12
14
  Object.entries(shape).forEach(([key, value])=>{
15
+ if (!SAFE_KEY_REGEX.test(key)) {
16
+ throw new APIError('Unsafe key passed to jsonBuildObject. Only alphanumeric characters and underscores are allowed.', 500);
17
+ }
13
18
  if (chunks.length > 0) {
14
19
  chunks.push(sql.raw(','));
15
20
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/json.ts"],"sourcesContent":["import type { Column, SQL } from 'drizzle-orm'\n\nimport { sql } from 'drizzle-orm'\n\nimport type { DrizzleAdapter } from '../types.js'\n\nexport function jsonAgg(adapter: DrizzleAdapter, expression: SQL) {\n if (adapter.name === 'sqlite') {\n return sql`coalesce(json_group_array(${expression}), '[]')`\n }\n\n return sql`coalesce(json_agg(${expression}), '[]'::json)`\n}\n\n/**\n * @param shape Potential for SQL injections, so you shouldn't allow user-specified key names\n */\nexport function jsonBuildObject<T extends Record<string, Column | SQL>>(\n adapter: DrizzleAdapter,\n shape: T,\n) {\n const chunks: SQL[] = []\n\n Object.entries(shape).forEach(([key, value]) => {\n if (chunks.length > 0) {\n chunks.push(sql.raw(','))\n }\n chunks.push(sql.raw(`'${key}',`))\n chunks.push(sql`${value}`)\n })\n\n if (adapter.name === 'sqlite') {\n return sql`json_object(${sql.join(chunks)})`\n }\n\n return sql`json_build_object(${sql.join(chunks)})`\n}\n\nexport const jsonAggBuildObject = <T extends Record<string, Column | SQL>>(\n adapter: DrizzleAdapter,\n shape: T,\n) => {\n return jsonAgg(adapter, jsonBuildObject(adapter, shape))\n}\n"],"names":["sql","jsonAgg","adapter","expression","name","jsonBuildObject","shape","chunks","Object","entries","forEach","key","value","length","push","raw","join","jsonAggBuildObject"],"mappings":"AAEA,SAASA,GAAG,QAAQ,cAAa;AAIjC,OAAO,SAASC,QAAQC,OAAuB,EAAEC,UAAe;IAC9D,IAAID,QAAQE,IAAI,KAAK,UAAU;QAC7B,OAAOJ,GAAG,CAAC,0BAA0B,EAAEG,WAAW,QAAQ,CAAC;IAC7D;IAEA,OAAOH,GAAG,CAAC,kBAAkB,EAAEG,WAAW,cAAc,CAAC;AAC3D;AAEA;;CAEC,GACD,OAAO,SAASE,gBACdH,OAAuB,EACvBI,KAAQ;IAER,MAAMC,SAAgB,EAAE;IAExBC,OAAOC,OAAO,CAACH,OAAOI,OAAO,CAAC,CAAC,CAACC,KAAKC,MAAM;QACzC,IAAIL,OAAOM,MAAM,GAAG,GAAG;YACrBN,OAAOO,IAAI,CAACd,IAAIe,GAAG,CAAC;QACtB;QACAR,OAAOO,IAAI,CAACd,IAAIe,GAAG,CAAC,CAAC,CAAC,EAAEJ,IAAI,EAAE,CAAC;QAC/BJ,OAAOO,IAAI,CAACd,GAAG,CAAC,EAAEY,MAAM,CAAC;IAC3B;IAEA,IAAIV,QAAQE,IAAI,KAAK,UAAU;QAC7B,OAAOJ,GAAG,CAAC,YAAY,EAAEA,IAAIgB,IAAI,CAACT,QAAQ,CAAC,CAAC;IAC9C;IAEA,OAAOP,GAAG,CAAC,kBAAkB,EAAEA,IAAIgB,IAAI,CAACT,QAAQ,CAAC,CAAC;AACpD;AAEA,OAAO,MAAMU,qBAAqB,CAChCf,SACAI;IAEA,OAAOL,QAAQC,SAASG,gBAAgBH,SAASI;AACnD,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/json.ts"],"sourcesContent":["import type { Column, SQL } from 'drizzle-orm'\n\nimport { sql } from 'drizzle-orm'\nimport { APIError } from 'payload'\n\nimport type { DrizzleAdapter } from '../types.js'\n\nconst SAFE_KEY_REGEX = /^\\w+$/\n\nexport function jsonAgg(adapter: DrizzleAdapter, expression: SQL) {\n if (adapter.name === 'sqlite') {\n return sql`coalesce(json_group_array(${expression}), '[]')`\n }\n\n return sql`coalesce(json_agg(${expression}), '[]'::json)`\n}\n\n/**\n * @param shape Keys are interpolated into raw SQL only use trusted, internally-generated key names\n */\nexport function jsonBuildObject<T extends Record<string, Column | SQL>>(\n adapter: DrizzleAdapter,\n shape: T,\n) {\n const chunks: SQL[] = []\n\n Object.entries(shape).forEach(([key, value]) => {\n if (!SAFE_KEY_REGEX.test(key)) {\n throw new APIError(\n 'Unsafe key passed to jsonBuildObject. Only alphanumeric characters and underscores are allowed.',\n 500,\n )\n }\n if (chunks.length > 0) {\n chunks.push(sql.raw(','))\n }\n chunks.push(sql.raw(`'${key}',`))\n chunks.push(sql`${value}`)\n })\n\n if (adapter.name === 'sqlite') {\n return sql`json_object(${sql.join(chunks)})`\n }\n\n return sql`json_build_object(${sql.join(chunks)})`\n}\n\nexport const jsonAggBuildObject = <T extends Record<string, Column | SQL>>(\n adapter: DrizzleAdapter,\n shape: T,\n) => {\n return jsonAgg(adapter, jsonBuildObject(adapter, shape))\n}\n"],"names":["sql","APIError","SAFE_KEY_REGEX","jsonAgg","adapter","expression","name","jsonBuildObject","shape","chunks","Object","entries","forEach","key","value","test","length","push","raw","join","jsonAggBuildObject"],"mappings":"AAEA,SAASA,GAAG,QAAQ,cAAa;AACjC,SAASC,QAAQ,QAAQ,UAAS;AAIlC,MAAMC,iBAAiB;AAEvB,OAAO,SAASC,QAAQC,OAAuB,EAAEC,UAAe;IAC9D,IAAID,QAAQE,IAAI,KAAK,UAAU;QAC7B,OAAON,GAAG,CAAC,0BAA0B,EAAEK,WAAW,QAAQ,CAAC;IAC7D;IAEA,OAAOL,GAAG,CAAC,kBAAkB,EAAEK,WAAW,cAAc,CAAC;AAC3D;AAEA;;CAEC,GACD,OAAO,SAASE,gBACdH,OAAuB,EACvBI,KAAQ;IAER,MAAMC,SAAgB,EAAE;IAExBC,OAAOC,OAAO,CAACH,OAAOI,OAAO,CAAC,CAAC,CAACC,KAAKC,MAAM;QACzC,IAAI,CAACZ,eAAea,IAAI,CAACF,MAAM;YAC7B,MAAM,IAAIZ,SACR,mGACA;QAEJ;QACA,IAAIQ,OAAOO,MAAM,GAAG,GAAG;YACrBP,OAAOQ,IAAI,CAACjB,IAAIkB,GAAG,CAAC;QACtB;QACAT,OAAOQ,IAAI,CAACjB,IAAIkB,GAAG,CAAC,CAAC,CAAC,EAAEL,IAAI,EAAE,CAAC;QAC/BJ,OAAOQ,IAAI,CAACjB,GAAG,CAAC,EAAEc,MAAM,CAAC;IAC3B;IAEA,IAAIV,QAAQE,IAAI,KAAK,UAAU;QAC7B,OAAON,GAAG,CAAC,YAAY,EAAEA,IAAImB,IAAI,CAACV,QAAQ,CAAC,CAAC;IAC9C;IAEA,OAAOT,GAAG,CAAC,kBAAkB,EAAEA,IAAImB,IAAI,CAACV,QAAQ,CAAC,CAAC;AACpD;AAEA,OAAO,MAAMW,qBAAqB,CAChChB,SACAI;IAEA,OAAOL,QAAQC,SAASG,gBAAgBH,SAASI;AACnD,EAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const sanitizePathSegment: (segment: string) => string;
2
+ //# sourceMappingURL=sanitizePathSegment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizePathSegment.d.ts","sourceRoot":"","sources":["../../src/utilities/sanitizePathSegment.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,mBAAmB,YAAa,MAAM,KAAG,MAQrD,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { APIError } from 'payload';
2
+ /**
3
+ * Validates that a path segment contains only allowed characters (word characters: [a-zA-Z0-9_]).
4
+ *
5
+ * @throws {APIError} if the segment contains characters outside /^[\w]+$/
6
+ */ const SAFE_PATH_SEGMENT_REGEX = /^\w+$/;
7
+ export const sanitizePathSegment = (segment)=>{
8
+ if (!SAFE_PATH_SEGMENT_REGEX.test(segment)) {
9
+ throw new APIError('Invalid path segment. Only alphanumeric characters and underscores are permitted.', 400);
10
+ }
11
+ return segment;
12
+ };
13
+
14
+ //# sourceMappingURL=sanitizePathSegment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utilities/sanitizePathSegment.ts"],"sourcesContent":["import { APIError } from 'payload'\n\n/**\n * Validates that a path segment contains only allowed characters (word characters: [a-zA-Z0-9_]).\n *\n * @throws {APIError} if the segment contains characters outside /^[\\w]+$/\n */\nconst SAFE_PATH_SEGMENT_REGEX = /^\\w+$/\n\nexport const sanitizePathSegment = (segment: string): string => {\n if (!SAFE_PATH_SEGMENT_REGEX.test(segment)) {\n throw new APIError(\n 'Invalid path segment. Only alphanumeric characters and underscores are permitted.',\n 400,\n )\n }\n return segment\n}\n"],"names":["APIError","SAFE_PATH_SEGMENT_REGEX","sanitizePathSegment","segment","test"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,UAAS;AAElC;;;;CAIC,GACD,MAAMC,0BAA0B;AAEhC,OAAO,MAAMC,sBAAsB,CAACC;IAClC,IAAI,CAACF,wBAAwBG,IAAI,CAACD,UAAU;QAC1C,MAAM,IAAIH,SACR,qFACA;IAEJ;IACA,OAAOG;AACT,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/drizzle",
3
- "version": "3.79.0",
3
+ "version": "3.79.1",
4
4
  "description": "A library of shared functions used by different payload database adapters",
5
5
  "homepage": "https://payloadcms.com",
6
6
  "repository": {
@@ -59,11 +59,11 @@
59
59
  "@libsql/client": "0.14.0",
60
60
  "@types/pg": "8.10.2",
61
61
  "@types/to-snake-case": "1.0.0",
62
- "payload": "3.79.0",
62
+ "payload": "3.79.1",
63
63
  "@payloadcms/eslint-config": "3.28.0"
64
64
  },
65
65
  "peerDependencies": {
66
- "payload": "3.79.0"
66
+ "payload": "3.79.1"
67
67
  },
68
68
  "scripts": {
69
69
  "build": "pnpm build:swc && pnpm build:types",