Files
klz-cables.com/.pnpm-store/v10/files/c7/5a5c41ffa6ca2dda16cae0261156099b54031ab2e1be1c14287652e9be2993351a50150d69f5cc4d03e32f10c5eaa30710d3ffb026a009b890aa4d9343f5b0
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

222 lines
9.4 KiB
Plaintext

import { existsSync } from 'fs';
import { writeFile } from 'fs/promises';
import path from 'path';
/**
* @example
* console.log(sanitizeObjectKey("oneTwo")); // oneTwo
* console.log(sanitizeObjectKey("one-two")); // 'one-two'
* console.log(sanitizeObjectKey("_one$Two3")); // _one$Two3
* console.log(sanitizeObjectKey("3invalid")); // '3invalid'
*/ const sanitizeObjectKey = (key)=>{
// Regular expression for a valid identifier
const identifierRegex = /^[a-z_$][\w$]*$/i;
if (identifierRegex.test(key)) {
return key;
}
return `'${key}'`;
};
/**
* @example
* (columns default-valuesID) -> columns['default-valuesID']
* (columns defaultValues) -> columns.defaultValues
*/ const accessProperty = (objName, key)=>{
const sanitized = sanitizeObjectKey(key);
if (sanitized.startsWith("'")) {
return `${objName}[${sanitized}]`;
}
return `${objName}.${key}`;
};
export const createSchemaGenerator = ({ columnToCodeConverter, corePackageSuffix, defaultOutputFile, enumImport, schemaImport, tableImport })=>{
return async function generateSchema({ log = true, outputFile = defaultOutputFile, prettify = true } = {}) {
const importDeclarations = {};
const tableDeclarations = [];
const enumDeclarations = [];
const relationsDeclarations = [];
const addImport = (from, name)=>{
if (!importDeclarations[from]) {
importDeclarations[from] = new Set();
}
importDeclarations[from].add(name);
};
const corePackage = `${this.packageName}/drizzle/${corePackageSuffix}`;
let schemaDeclaration = null;
if (this.schemaName) {
addImport(corePackage, schemaImport);
schemaDeclaration = `export const db_schema = ${schemaImport}('${this.schemaName}')`;
}
const enumFn = this.schemaName ? `db_schema.enum` : enumImport;
const enumsList = [];
const addEnum = (name, options)=>{
if (enumsList.some((each)=>each === name)) {
return;
}
enumsList.push(name);
enumDeclarations.push(`export const ${name} = ${enumFn}('${name}', [${options.map((option)=>`'${option}'`).join(', ')}])`);
};
if (this.payload.config.localization && enumImport) {
addEnum('enum__locales', this.payload.config.localization.localeCodes);
}
const tableFn = this.schemaName ? `db_schema.table` : tableImport;
if (!this.schemaName) {
addImport(corePackage, tableImport);
}
addImport(corePackage, 'index');
addImport(corePackage, 'uniqueIndex');
addImport(corePackage, 'foreignKey');
addImport(`${this.packageName}/drizzle`, 'sql');
addImport(`${this.packageName}/drizzle`, 'relations');
for(const tableName in this.rawTables){
const table = this.rawTables[tableName];
const extrasDeclarations = [];
if (table.indexes) {
for(const key in table.indexes){
const index = table.indexes[key];
let indexDeclaration = `${index.unique ? 'uniqueIndex' : 'index'}('${index.name}')`;
indexDeclaration += `.on(${typeof index.on === 'string' ? `${accessProperty('columns', index.on)}` : `${index.on.map((on)=>`${accessProperty('columns', on)}`).join(', ')}`}),`;
extrasDeclarations.push(indexDeclaration);
}
}
if (table.foreignKeys) {
for(const key in table.foreignKeys){
const foreignKey = table.foreignKeys[key];
let foreignKeyDeclaration = `foreignKey({
columns: [${foreignKey.columns.map((col)=>`columns['${col}']`).join(', ')}],
foreignColumns: [${foreignKey.foreignColumns.map((col)=>`${accessProperty(col.table, col.name)}`).join(', ')}],
name: '${foreignKey.name}'
})`;
if (foreignKey.onDelete) {
foreignKeyDeclaration += `.onDelete('${foreignKey.onDelete}')`;
}
if (foreignKey.onUpdate) {
foreignKeyDeclaration += `.onUpdate('${foreignKey.onDelete}')`;
}
foreignKeyDeclaration += ',';
extrasDeclarations.push(foreignKeyDeclaration);
}
}
const tableCode = `
export const ${tableName} = ${tableFn}('${tableName}', {
${Object.entries(table.columns).map(([key, column])=>` ${sanitizeObjectKey(key)}: ${columnToCodeConverter({
adapter: this,
addEnum,
addImport,
column,
locales: this.payload.config.localization ? this.payload.config.localization.localeCodes : undefined,
tableKey: tableName
})},`).join('\n')}
}${extrasDeclarations.length ? `, (columns) => [
${extrasDeclarations.join(' ')}
]` : ''}
)
`;
tableDeclarations.push(tableCode);
}
for(const tableName in this.rawRelations){
const relations = this.rawRelations[tableName];
const properties = [];
for(const key in relations){
const relation = relations[key];
let declaration;
if (relation.type === 'one') {
declaration = `${sanitizeObjectKey(key)}: one(${relation.to}, {
${relation.fields.some((field)=>field.table !== tableName) ? '// @ts-expect-error Drizzle TypeScript bug for ONE relationships with a field in different table' : ''}
fields: [${relation.fields.map((field)=>`${accessProperty(field.table, field.name)}`).join(', ')}],
references: [${relation.references.map((col)=>`${accessProperty(relation.to, col)}`).join(', ')}],
${relation.relationName ? `relationName: '${relation.relationName}',` : ''}
}),`;
} else {
declaration = `${sanitizeObjectKey(key)}: many(${relation.to}, {
${relation.relationName ? `relationName: '${relation.relationName}',` : ''}
}),`;
}
properties.push(declaration);
}
// beautify / lintify relations callback output, when no many for example, don't add it
const args = [];
if (Object.values(relations).some((rel)=>rel.type === 'one')) {
args.push('one');
}
if (Object.values(relations).some((rel)=>rel.type === 'many')) {
args.push('many');
}
const arg = args.length ? `{ ${args.join(', ')} }` : '';
const declaration = `export const relations_${tableName} = relations(${tableName}, (${arg}) => ({
${properties.join('\n ')}
}))`;
relationsDeclarations.push(declaration);
}
if (enumDeclarations.length && !this.schemaName) {
addImport(corePackage, enumImport);
}
const importDeclarationsSanitized = [];
for(const moduleName in importDeclarations){
const moduleImports = importDeclarations[moduleName];
importDeclarationsSanitized.push(`import { ${Array.from(moduleImports).join(', ')} } from '${moduleName}'`);
}
const schemaType = `
type DatabaseSchema = {
${[
this.schemaName ? 'db_schema' : null,
...enumsList,
...Object.keys(this.rawTables),
...Object.keys(this.rawRelations).map((table)=>`relations_${table}`)
].filter(Boolean).map((name)=>`${name}: typeof ${name}`).join('\n ')}
}
`;
const finalDeclaration = `
declare module '${this.packageName}' {
export interface GeneratedDatabaseSchema {
schema: DatabaseSchema
}
}
`;
const warning = `
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by Payload.
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
* and re-run \`payload generate:db-schema\` to regenerate this file.
*/
`;
const importTypes = `import type {} from '${this.packageName}'`;
let code = [
warning,
importTypes,
...importDeclarationsSanitized,
schemaDeclaration,
...enumDeclarations,
...tableDeclarations,
...relationsDeclarations,
schemaType,
finalDeclaration
].filter(Boolean).join('\n');
if (!outputFile) {
const cwd = process.cwd();
const srcDir = path.resolve(cwd, 'src');
if (existsSync(srcDir)) {
outputFile = path.resolve(srcDir, 'payload-generated-schema.ts');
} else {
outputFile = path.resolve(cwd, 'payload-generated-schema.ts');
}
}
if (prettify) {
try {
const prettier = await eval('import("prettier")');
const configPath = await prettier.resolveConfigFile();
const config = configPath ? await prettier.resolveConfig(configPath) : {};
code = await prettier.format(code, {
...config,
parser: 'typescript'
});
} catch {
/* empty */ }
}
await writeFile(outputFile, code, 'utf-8');
if (log) {
this.payload.logger.info(`Written ${outputFile}`);
}
};
};
//# sourceMappingURL=createSchemaGenerator.js.map