Skip to content

Commit 2a462fd

Browse files
authored
chore: auto format the code using husky (#2779)
1 parent 2d239cd commit 2a462fd

108 files changed

Lines changed: 8983 additions & 7073 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pnpm exec lint-staged

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ packages/language/src/generated/**
55
samples/**/schema.ts
66
samples/**/models.ts
77
samples/**/input.ts
8+
tests/e2e/**/schema.ts
9+
tests/e2e/**/models.ts
10+
tests/e2e/**/input.ts

package.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"publish-all": "pnpm --filter \"./packages/**\" -r publish --access public",
3434
"publish-canary": "pnpm --filter \"./packages/**\" -r publish --access public --tag canary --no-git-checks",
3535
"publish-preview": "pnpm --filter \"./packages/**\" -r publish --force --registry https://preview.registry.zenstack.dev/",
36-
"unpublish-preview": "pnpm --filter \"./packages/**\" -r --shell-mode exec -- npm unpublish -f --registry https://preview.registry.zenstack.dev/ \"\\$PNPM_PACKAGE_NAME\""
36+
"unpublish-preview": "pnpm --filter \"./packages/**\" -r --shell-mode exec -- npm unpublish -f --registry https://preview.registry.zenstack.dev/ \"\\$PNPM_PACKAGE_NAME\"",
37+
"prepare": "husky"
3738
},
3839
"keywords": [],
3940
"devDependencies": {
@@ -42,8 +43,11 @@
4243
"@vitest/coverage-v8": "^4.0.16",
4344
"eslint": "~9.29.0",
4445
"glob": "^11.1.0",
46+
"husky": "^9.1.7",
47+
"lint-staged": "^17.3.0",
4548
"npm-run-all": "^4.1.5",
4649
"prettier": "^3.5.3",
50+
"prettier-plugin-tailwindcss": "^0.7.2",
4751
"prisma": "catalog:",
4852
"tsdown": "^0.21.8",
4953
"tsx": "catalog:",
@@ -66,5 +70,8 @@
6670
"@better-auth/core": "1.4.19"
6771
}
6872
},
73+
"lint-staged": {
74+
"*.{ts,tsx,md}": "prettier --write"
75+
},
6976
"funding": "https://github.com/sponsors/zenstackhq"
70-
}
77+
}

packages/cli/src/actions/check.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ async function checkPluginResolution(schemaFile: string, model: Model) {
2929
for (const plugin of plugins) {
3030
const provider = getPluginProvider(plugin);
3131
if (!provider.startsWith('@core/')) {
32-
const pluginSourcePath =
33-
plugin.$cstNode?.container?.astNode.$document?.uri?.fsPath ?? schemaFile;
32+
const pluginSourcePath = plugin.$cstNode?.container?.astNode.$document?.uri?.fsPath ?? schemaFile;
3433
await loadPluginModule(provider, path.dirname(pluginSourcePath));
3534
}
3635
}

packages/cli/src/actions/generate.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ async function runPlugins(schemaFile: string, model: Model, outputPath: string,
188188
} else {
189189
// resolve relative plugin paths against the schema file where the plugin is declared,
190190
// not the entry schema file
191-
const pluginSourcePath =
192-
plugin.$cstNode?.container?.astNode.$document?.uri?.fsPath ?? schemaFile;
191+
const pluginSourcePath = plugin.$cstNode?.container?.astNode.$document?.uri?.fsPath ?? schemaFile;
193192
cliPlugin = await loadPluginModule(provider, path.dirname(pluginSourcePath));
194193
}
195194

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

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import type { ZModelServices } from '@zenstackhq/language';
22
import colors from 'colors';
3-
import {
4-
isEnum,
5-
type DataField,
6-
type DataModel,
7-
type Enum,
8-
type Model,
9-
} from '@zenstackhq/language/ast';
3+
import { isEnum, type DataField, type DataModel, type Enum, type Model } from '@zenstackhq/language/ast';
104
import {
115
DataFieldAttributeFactory,
126
DataFieldFactory,
@@ -79,8 +73,12 @@ export function syncEnums({
7973
// For providers that don't support native enums (e.g., SQLite), carry over
8074
// enum declarations from the existing schema as-is by deep-cloning the AST nodes.
8175
// A dummy buildReference is used since we don't need cross-reference resolution.
82-
const dummyBuildReference = (_node: AstNode, _property: string, _refNode: CstNode | undefined, refText: string): Reference<AstNode> =>
83-
({ $refText: refText }) as Reference<AstNode>;
76+
const dummyBuildReference = (
77+
_node: AstNode,
78+
_property: string,
79+
_refNode: CstNode | undefined,
80+
refText: string,
81+
): Reference<AstNode> => ({ $refText: refText }) as Reference<AstNode>;
8482

8583
oldModel.declarations
8684
.filter((d) => isEnum(d))
@@ -181,7 +179,6 @@ export function syncTable({
181179
}
182180

183181
table.columns.forEach((column) => {
184-
185182
const { name, modified } = resolveNameCasing(options.fieldCasing, column.name);
186183

187184
const builtinType = provider.getBuiltinType(column.datatype);
@@ -259,9 +256,10 @@ export function syncTable({
259256
b.setDecl(uniqueAttribute);
260257
// Only add map if the unique constraint name differs from default patterns
261258
// Default patterns: TableName_columnName_key (Prisma) or just columnName (MySQL)
262-
const isDefaultName = !column.unique_name
263-
|| column.unique_name === `${table.name}_${column.name}_key`
264-
|| column.unique_name === column.name;
259+
const isDefaultName =
260+
!column.unique_name ||
261+
column.unique_name === `${table.name}_${column.name}_key` ||
262+
column.unique_name === column.name;
265263
if (!isDefaultName) {
266264
b.addArg((ab) => ab.StringLiteral.setValue(column.unique_name!), 'map');
267265
}
@@ -296,9 +294,7 @@ export function syncTable({
296294
);
297295
}
298296

299-
const hasUniqueConstraint =
300-
table.columns.some((c) => c.unique || c.pk) ||
301-
table.indexes.some((i) => i.unique);
297+
const hasUniqueConstraint = table.columns.some((c) => c.unique || c.pk) || table.indexes.some((i) => i.unique);
302298
if (!hasUniqueConstraint) {
303299
modelFactory.addAttribute((a) => a.setDecl(getAttributeRef('@@ignore', services)));
304300
modelFactory.addComment(
@@ -342,8 +338,7 @@ export function syncTable({
342338
return;
343339
}
344340

345-
modelFactory.addAttribute((builder) =>
346-
{
341+
modelFactory.addAttribute((builder) => {
347342
const attr = builder
348343
.setDecl(index.unique ? modelUniqueAttribute : modelindexAttribute)
349344
.addArg((argBuilder) => {
@@ -364,16 +359,14 @@ export function syncTable({
364359
return arrayExpr;
365360
});
366361

367-
const suffix = index.unique ? '_key' : '_idx';
362+
const suffix = index.unique ? '_key' : '_idx';
368363

369-
if(index.name !== `${table.name}_${index.columns.map(c => c.name).join('_')}${suffix}`){
370-
attr.addArg((argBuilder) => argBuilder.StringLiteral.setValue(index.name), 'map');
371-
}
372-
373-
return attr
374-
}
364+
if (index.name !== `${table.name}_${index.columns.map((c) => c.name).join('_')}${suffix}`) {
365+
attr.addArg((argBuilder) => argBuilder.StringLiteral.setValue(index.name), 'map');
366+
}
375367

376-
);
368+
return attr;
369+
});
377370
});
378371
if (table.schema && table.schema !== '' && table.schema !== defaultSchema) {
379372
modelFactory.addAttribute((b) =>
@@ -450,7 +443,9 @@ export function syncRelation({
450443

451444
// Derive a relation field name from the FK scalar field: if the field ends with "Id",
452445
// strip the suffix and use the remainder (e.g., "authorId" -> "author").
453-
const sourceNameFromReference = firstSourceField.name.toLowerCase().endsWith('id') ? `${resolveNameCasing(options.fieldCasing, firstSourceField.name.slice(0, -2)).name}${relation.type === 'many'? 's' : ''}` : undefined;
446+
const sourceNameFromReference = firstSourceField.name.toLowerCase().endsWith('id')
447+
? `${resolveNameCasing(options.fieldCasing, firstSourceField.name.slice(0, -2)).name}${relation.type === 'many' ? 's' : ''}`
448+
: undefined;
454449

455450
// Check if the derived name would clash with an existing field
456451
const sourceFieldFromReference = sourceModel.fields.find((f) => f.name === sourceNameFromReference);
@@ -462,7 +457,7 @@ export function syncRelation({
462457
options.fieldCasing,
463458
similarRelations > 0
464459
? `${fieldPrefix}${lowerCaseFirst(sourceModel.name)}_${firstColumn}`
465-
: `${(!sourceFieldFromReference? sourceNameFromReference : undefined) || lowerCaseFirst(resolveNameCasing(options.fieldCasing, targetModel.name).name)}${relation.type === 'many'? 's' : ''}`,
460+
: `${(!sourceFieldFromReference ? sourceNameFromReference : undefined) || lowerCaseFirst(resolveNameCasing(options.fieldCasing, targetModel.name).name)}${relation.type === 'many' ? 's' : ''}`,
466461
);
467462

468463
if (sourceModel.fields.find((f) => f.name === sourceFieldName)) {
@@ -525,7 +520,8 @@ export function syncRelation({
525520

526521
// Check if the FK constraint name differs from the default pattern
527522
const defaultFkName = `${relation.table}_${relation.columns.join('_')}_fkey`;
528-
if (relation.fk_name && relation.fk_name !== defaultFkName) ab.addArg((ab) => ab.StringLiteral.setValue(relation.fk_name), 'map');
523+
if (relation.fk_name && relation.fk_name !== defaultFkName)
524+
ab.addArg((ab) => ab.StringLiteral.setValue(relation.fk_name), 'map');
529525

530526
return ab;
531527
});
@@ -537,7 +533,7 @@ export function syncRelation({
537533
options.fieldCasing,
538534
similarRelations > 0
539535
? `${oppositeFieldPrefix}${lowerCaseFirst(sourceModel.name)}_${firstColumn}`
540-
: `${lowerCaseFirst(resolveNameCasing(options.fieldCasing, sourceModel.name).name)}${relation.references.type === 'many'? 's' : ''}`,
536+
: `${lowerCaseFirst(resolveNameCasing(options.fieldCasing, sourceModel.name).name)}${relation.references.type === 'many' ? 's' : ''}`,
541537
);
542538

543539
if (targetModel.fields.find((f) => f.name === oppositeFieldName)) {
@@ -573,13 +569,7 @@ export function syncRelation({
573569
* mapping via field references and consolidates the synthetic enums back into
574570
* the original shared enum so the merge phase can match them correctly.
575571
*/
576-
export function consolidateEnums({
577-
newModel,
578-
oldModel,
579-
}: {
580-
newModel: Model;
581-
oldModel: Model;
582-
}) {
572+
export function consolidateEnums({ newModel, oldModel }: { newModel: Model; oldModel: Model }) {
583573
const newEnums = newModel.declarations.filter((d) => isEnum(d)) as Enum[];
584574
const newDataModels = newModel.declarations.filter((d) => d.$type === 'DataModel') as DataModel[];
585575
const oldDataModels = oldModel.declarations.filter((d) => d.$type === 'DataModel') as DataModel[];

packages/cli/src/actions/pull/provider/mysql.ts

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,15 @@ export const mysql: IntrospectionProvider = {
131131
return { type: 'longblob' };
132132
}
133133
},
134-
async introspect(connectionString: string, options: { schemas: string[]; modelCasing: 'pascal' | 'camel' | 'snake' | 'none' }): Promise<IntrospectedSchema> {
134+
async introspect(
135+
connectionString: string,
136+
options: { schemas: string[]; modelCasing: 'pascal' | 'camel' | 'snake' | 'none' },
137+
): Promise<IntrospectedSchema> {
135138
const mod = await loadPackage('mysql2/promise');
136139
if (!mod) {
137-
throw new CliError('Package "mysql2" is required for MySQL support. Please install it with: npm install mysql2');
140+
throw new CliError(
141+
'Package "mysql2" is required for MySQL support. Please install it with: npm install mysql2',
142+
);
138143
}
139144
const mysql = mod.createConnection ? mod : (mod.default ?? mod);
140145
const connection = await mysql.createConnection(connectionString);
@@ -160,29 +165,32 @@ export const mysql: IntrospectionProvider = {
160165
const indexes = typeof row.indexes === 'string' ? JSON.parse(row.indexes) : row.indexes;
161166

162167
// Sort columns by ordinal_position to preserve database column order
163-
const sortedColumns = (columns || [])
164-
.sort(
165-
(a: { ordinal_position?: number }, b: { ordinal_position?: number }) =>
166-
(a.ordinal_position ?? 0) - (b.ordinal_position ?? 0)
167-
)
168-
.map((col: any) => {
169-
// MySQL enum datatype_name is synthetic (TableName_ColumnName).
170-
// Apply model casing so it matches the cased enum_type.
171-
if (col.datatype === 'enum' && col.datatype_name) {
172-
return { ...col, datatype_name: resolveNameCasing(options.modelCasing, col.datatype_name).name };
173-
}
174-
// Normalize generated column expressions for stable output.
175-
if (col.computed && typeof col.datatype === 'string') {
176-
return { ...col, datatype: normalizeGenerationExpression(col.datatype) };
177-
}
178-
return col;
179-
});
168+
const sortedColumns = (columns || [])
169+
.sort(
170+
(a: { ordinal_position?: number }, b: { ordinal_position?: number }) =>
171+
(a.ordinal_position ?? 0) - (b.ordinal_position ?? 0),
172+
)
173+
.map((col: any) => {
174+
// MySQL enum datatype_name is synthetic (TableName_ColumnName).
175+
// Apply model casing so it matches the cased enum_type.
176+
if (col.datatype === 'enum' && col.datatype_name) {
177+
return {
178+
...col,
179+
datatype_name: resolveNameCasing(options.modelCasing, col.datatype_name).name,
180+
};
181+
}
182+
// Normalize generated column expressions for stable output.
183+
if (col.computed && typeof col.datatype === 'string') {
184+
return { ...col, datatype: normalizeGenerationExpression(col.datatype) };
185+
}
186+
return col;
187+
});
180188

181189
// Filter out auto-generated FK indexes (MySQL creates these automatically)
182190
// Pattern: {Table}_{column}_fkey for single-column FK indexes
183191
const filteredIndexes = (indexes || []).filter(
184192
(idx: { name: string; columns: { name: string }[] }) =>
185-
!(idx.columns.length === 1 && idx.name === `${row.name}_${idx.columns[0]?.name}_fkey`)
193+
!(idx.columns.length === 1 && idx.name === `${row.name}_${idx.columns[0]?.name}_fkey`),
186194
);
187195

188196
tables.push({
@@ -244,7 +252,11 @@ export const mysql: IntrospectionProvider = {
244252

245253
switch (fieldType) {
246254
case 'DateTime':
247-
if (/^CURRENT_TIMESTAMP(\(\d*\))?$/i.test(val) || val.toLowerCase() === 'current_timestamp()' || val.toLowerCase() === 'now()') {
255+
if (
256+
/^CURRENT_TIMESTAMP(\(\d*\))?$/i.test(val) ||
257+
val.toLowerCase() === 'current_timestamp()' ||
258+
val.toLowerCase() === 'now()'
259+
) {
248260
return (ab) => ab.InvocationExpr.setFunction(getFunctionRef('now', services));
249261
}
250262
// Fallback to string literal for other DateTime defaults
@@ -264,7 +276,8 @@ export const mysql: IntrospectionProvider = {
264276
return normalizeDecimalDefault(val);
265277

266278
case 'Boolean':
267-
return (ab) => ab.BooleanLiteral.setValue(val.toLowerCase() === 'true' || val === '1' || val === "b'1'");
279+
return (ab) =>
280+
ab.BooleanLiteral.setValue(val.toLowerCase() === 'true' || val === '1' || val === "b'1'");
268281

269282
case 'String':
270283
if (val.toLowerCase() === 'uuid()') {
@@ -285,15 +298,20 @@ export const mysql: IntrospectionProvider = {
285298
);
286299
}
287300

288-
console.warn(`Unsupported default value type: "${defaultValue}" for field type "${fieldType}". Skipping default value.`);
301+
console.warn(
302+
`Unsupported default value type: "${defaultValue}" for field type "${fieldType}". Skipping default value.`,
303+
);
289304
return null;
290305
},
291306

292307
getFieldAttributes({ fieldName, fieldType, datatype, length, precision, services }) {
293308
const factories: DataFieldAttributeFactory[] = [];
294309

295310
// Add @updatedAt for DateTime fields named updatedAt or updated_at
296-
if (fieldType === 'DateTime' && (fieldName.toLowerCase() === 'updatedat' || fieldName.toLowerCase() === 'updated_at')) {
311+
if (
312+
fieldType === 'DateTime' &&
313+
(fieldName.toLowerCase() === 'updatedat' || fieldName.toLowerCase() === 'updated_at')
314+
) {
297315
factories.push(new DataFieldAttributeFactory().setDecl(getAttributeRef('@updatedAt', services)));
298316
}
299317

@@ -308,8 +326,7 @@ export const mysql: IntrospectionProvider = {
308326
dbAttr &&
309327
defaultDatabaseType &&
310328
(defaultDatabaseType.type !== datatype ||
311-
(defaultDatabaseType.precision &&
312-
defaultDatabaseType.precision !== (length ?? precision)))
329+
(defaultDatabaseType.precision && defaultDatabaseType.precision !== (length ?? precision)))
313330
) {
314331
const dbAttrFactory = new DataFieldAttributeFactory().setDecl(dbAttr);
315332
const sizeValue = length ?? precision;

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ export type IntrospectedSchema = {
6161
export type DatabaseFeature = 'Schema' | 'NativeEnum';
6262

6363
export interface IntrospectionProvider {
64-
introspect(connectionString: string, options: { schemas: string[]; modelCasing: 'pascal' | 'camel' | 'snake' | 'none' }): Promise<IntrospectedSchema>;
64+
introspect(
65+
connectionString: string,
66+
options: { schemas: string[]; modelCasing: 'pascal' | 'camel' | 'snake' | 'none' },
67+
): Promise<IntrospectedSchema>;
6568
getBuiltinType(type: string): {
6669
type: BuiltinType | 'Unsupported';
6770
isArray: boolean;

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,9 @@ export function getDatasource(model: Model) {
7171

7272
const schemasField = datasource.fields.find((f) => f.name === 'schemas');
7373
const schemas =
74-
(schemasField &&
75-
getLiteralArray(schemasField.value)
76-
?.filter((s) => s !== undefined)) as string[] ||
77-
[];
78-
79-
const provider = getStringLiteral(
80-
datasource.fields.find((f) => f.name === 'provider')?.value,
81-
);
74+
((schemasField && getLiteralArray(schemasField.value)?.filter((s) => s !== undefined)) as string[]) || [];
75+
76+
const provider = getStringLiteral(datasource.fields.find((f) => f.name === 'provider')?.value);
8277
if (!provider) {
8378
throw new CliError(`Datasource "${datasource.name}" is missing a "provider" field.`);
8479
}

0 commit comments

Comments
 (0)