Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

Commit 4212b3e

Browse files
committed
fix: address PR comments
1 parent e489042 commit 4212b3e

18 files changed

Lines changed: 570 additions & 559 deletions

File tree

packages/cli/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
"./package.json": "./package.json"
3737
},
3838
"dependencies": {
39-
"@dotenvx/dotenvx": "^1.51.0",
4039
"@zenstackhq/common-helpers": "workspace:*",
4140
"@zenstackhq/schema": "workspace:*",
4241
"@zenstackhq/language": "workspace:*",

packages/cli/src/actions/action-utils.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,20 @@ export function getSchemaFile(file?: string) {
4343

4444
export async function loadSchemaDocument(
4545
schemaFile: string,
46-
opts?: { keepImports?: boolean; returnServices?: false },
46+
opts?: { mergeImports?: boolean; returnServices?: false },
4747
): Promise<Model>;
4848
export async function loadSchemaDocument(
4949
schemaFile: string,
50-
opts: { returnServices: true; keepImports?: boolean },
50+
opts: { returnServices: true; mergeImports?: boolean },
5151
): Promise<{ model: Model; services: ZModelServices }>;
5252
export async function loadSchemaDocument(
5353
schemaFile: string,
54-
opts: { returnServices?: boolean; keepImports?: boolean } = {},
54+
opts: { returnServices?: boolean; mergeImports?: boolean } = {},
5555
) {
56-
const returnServices = opts.returnServices || false;
57-
const keepImports = opts.keepImports || false;
56+
const returnServices = opts.returnServices ?? false;
57+
const mergeImports = opts.mergeImports ?? true;
5858

59-
const loadResult = await loadDocument(schemaFile, [], keepImports);
59+
const loadResult = await loadDocument(schemaFile, [], mergeImports);
6060
if (!loadResult.success) {
6161
loadResult.errors.forEach((err) => {
6262
console.error(colors.red(err));

packages/cli/src/actions/db.ts

Lines changed: 184 additions & 62 deletions
Large diffs are not rendered by default.

packages/cli/src/actions/pull/index.ts

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import type { PullOptions } from '../db';
1717
import type { Cascade, IntrospectedEnum, IntrospectedTable, IntrospectionProvider } from './provider';
1818
import { getAttributeRef, getDbName, getEnumRef } from './utils';
19+
import { CliError } from '../../cli-error';
1920

2021
export function syncEnums({
2122
dbEnums,
@@ -90,7 +91,9 @@ export function syncEnums({
9091
builder.setName(v.name);
9192
// Copy field-level comments
9293
if (v.comments?.length) {
93-
v.comments.forEach((c) => builder.addComment(c));
94+
v.comments.forEach((c) => {
95+
builder.addComment(c);
96+
});
9497
}
9598
// Copy field-level attributes (@map, etc.)
9699
if (v.attributes?.length) {
@@ -104,7 +107,7 @@ export function syncEnums({
104107
}
105108
}
106109

107-
function resolveNameCasing(casing: 'pascal' | 'camel' | 'snake' | 'kebab' | 'none', originalName: string) {
110+
function resolveNameCasing(casing: 'pascal' | 'camel' | 'snake' | 'none', originalName: string) {
108111
let name = originalName;
109112
const fieldPrefix = /[0-9]/g.test(name.charAt(0)) ? '_' : '';
110113

@@ -118,9 +121,6 @@ function resolveNameCasing(casing: 'pascal' | 'camel' | 'snake' | 'kebab' | 'non
118121
case 'snake':
119122
name = toSnakeCase(originalName);
120123
break;
121-
case 'kebab':
122-
name = toKebabCase(originalName);
123-
break;
124124
}
125125

126126
return {
@@ -144,13 +144,6 @@ function toSnakeCase(str: string): string {
144144
.toLowerCase();
145145
}
146146

147-
function toKebabCase(str: string): string {
148-
return str
149-
.replace(/[_ ]+/g, '-')
150-
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
151-
.toLowerCase();
152-
}
153-
154147
export type Relation = {
155148
schema: string;
156149
table: string;
@@ -203,7 +196,7 @@ export function syncTable({
203196
!modelUniqueAttribute ||
204197
!modelindexAttribute
205198
) {
206-
throw new Error('Cannot find required attributes in the model.');
199+
throw new CliError('Cannot find required attributes in the model.');
207200
}
208201

209202
const relations: Relation[] = [];
@@ -248,13 +241,13 @@ export function syncTable({
248241
typeBuilder.setArray(builtinType.isArray);
249242
typeBuilder.setOptional(column.nullable);
250243

251-
if (column.options.length > 0) {
252-
const ref = model.declarations.find((d) => isEnum(d) && getDbName(d) === column.datatype) as
244+
if (column.datatype === 'enum') {
245+
const ref = model.declarations.find((d) => isEnum(d) && getDbName(d) === column.datatype_name) as
253246
| Enum
254247
| undefined;
255248

256249
if (!ref) {
257-
throw new Error(`Enum ${column.datatype} not found`);
250+
throw new CliError(`Enum ${column.datatype_name} not found`);
258251
}
259252
typeBuilder.setReference(ref);
260253
} else {
@@ -288,6 +281,8 @@ export function syncTable({
288281
if (column.default) {
289282
const defaultExprBuilder = provider.getDefaultValue({
290283
fieldType: builtinType.type,
284+
datatype: column.datatype,
285+
datatype_name: column.datatype_name,
291286
defaultValue: column.default,
292287
services,
293288
enums: model.declarations.filter((d) => d.$type === 'Enum') as Enum[],
@@ -333,7 +328,7 @@ export function syncTable({
333328
pkColumns.forEach((c) => {
334329
const ref = modelFactory.node.fields.find((f) => getDbName(f) === c);
335330
if (!ref) {
336-
throw new Error(`Field ${c} not found`);
331+
throw new CliError(`Field ${c} not found`);
337332
}
338333
arrayExpr.addItem((itemBuilder) => itemBuilder.ReferenceExpr.setTarget(ref));
339334
});
@@ -397,7 +392,7 @@ export function syncTable({
397392
index.columns.forEach((c) => {
398393
const ref = modelFactory.node.fields.find((f) => getDbName(f) === c.name);
399394
if (!ref) {
400-
throw new Error(`Column ${c.name} not found in model ${table.name}`);
395+
throw new CliError(`Column ${c.name} not found in model ${table.name}`);
401396
}
402397
arrayExpr.addItem((itemBuilder) => {
403398
const refExpr = itemBuilder.ReferenceExpr.setTarget(ref);
@@ -418,7 +413,7 @@ export function syncTable({
418413

419414
return attr
420415
}
421-
416+
422417
);
423418
});
424419
if (table.schema && table.schema !== '' && table.schema !== defaultSchema) {
@@ -456,7 +451,7 @@ export function syncRelation({
456451
const includeRelationName = selfRelation || similarRelations > 0;
457452

458453
if (!idAttribute || !uniqueAttribute || !relationAttribute || !fieldMapAttribute || !tableMapAttribute) {
459-
throw new Error('Cannot find required attributes in the model.');
454+
throw new CliError('Cannot find required attributes in the model.');
460455
}
461456

462457
const sourceModel = model.declarations.find((d) => d.$type === 'DataModel' && getDbName(d) === relation.table) as
@@ -483,7 +478,7 @@ export function syncRelation({
483478
const sourceNameFromReference = sourceField.name.toLowerCase().endsWith('id') ? `${resolveNameCasing("camel", sourceField.name.slice(0, -2)).name}${relation.type === 'many'? 's' : ''}` : undefined;
484479

485480
const sourceFieldFromReference = sourceModel.fields.find((f) => f.name === sourceNameFromReference);
486-
481+
487482
let { name: sourceFieldName } = resolveNameCasing(
488483
options.fieldCasing,
489484
similarRelations > 0
@@ -516,22 +511,22 @@ export function syncRelation({
516511
const onDeleteDefault = relation.nullable ? 'SET NULL' : 'RESTRICT';
517512
if (relation.foreign_key_on_delete && relation.foreign_key_on_delete !== onDeleteDefault) {
518513
const enumRef = getEnumRef('ReferentialAction', services);
519-
if (!enumRef) throw new Error('ReferentialAction enum not found');
514+
if (!enumRef) throw new CliError('ReferentialAction enum not found');
520515
const enumFieldRef = enumRef.fields.find(
521516
(f) => f.name.toLowerCase() === relation.foreign_key_on_delete!.replace(/ /g, '').toLowerCase(),
522517
);
523-
if (!enumFieldRef) throw new Error(`ReferentialAction ${relation.foreign_key_on_delete} not found`);
518+
if (!enumFieldRef) throw new CliError(`ReferentialAction ${relation.foreign_key_on_delete} not found`);
524519
ab.addArg((a) => a.ReferenceExpr.setTarget(enumFieldRef), 'onDelete');
525520
}
526521

527522
// Prisma default: onUpdate is Cascade
528523
if (relation.foreign_key_on_update && relation.foreign_key_on_update !== 'CASCADE') {
529524
const enumRef = getEnumRef('ReferentialAction', services);
530-
if (!enumRef) throw new Error('ReferentialAction enum not found');
525+
if (!enumRef) throw new CliError('ReferentialAction enum not found');
531526
const enumFieldRef = enumRef.fields.find(
532527
(f) => f.name.toLowerCase() === relation.foreign_key_on_update!.replace(/ /g, '').toLowerCase(),
533528
);
534-
if (!enumFieldRef) throw new Error(`ReferentialAction ${relation.foreign_key_on_update} not found`);
529+
if (!enumFieldRef) throw new CliError(`ReferentialAction ${relation.foreign_key_on_update} not found`);
535530
ab.addArg((a) => a.ReferenceExpr.setTarget(enumFieldRef), 'onUpdate');
536531
}
537532

0 commit comments

Comments
 (0)