@lark-apaas/fullstack-cli 1.1.16-alpha.1 → 1.1.16-alpha.2

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 (2) hide show
  1. package/dist/index.js +922 -532
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- import fs20 from "fs";
2
+ import fs21 from "fs";
3
3
  import path17 from "path";
4
4
  import { fileURLToPath as fileURLToPath4 } from "url";
5
5
  import { config as dotenvConfig } from "dotenv";
@@ -117,120 +117,94 @@ Command "${ctx.commandName}" completed in ${elapsed}ms`);
117
117
 
118
118
  // src/commands/db/schema.handler.ts
119
119
  import path2 from "path";
120
- import fs3 from "fs";
120
+ import fs4 from "fs";
121
121
  import { fileURLToPath as fileURLToPath2 } from "url";
122
122
  import { spawnSync } from "child_process";
123
123
  import { createRequire } from "module";
124
124
  import { config as loadEnv } from "dotenv";
125
125
 
126
+ // src/commands/db/gen-dbschema/index.ts
127
+ import fs3 from "fs";
128
+ import path from "path";
129
+
126
130
  // src/commands/db/gen-dbschema/postprocess.ts
127
131
  import fs2 from "fs";
128
- import path from "path";
129
132
 
130
- // src/commands/db/gen-dbschema/helper/header-format.ts
131
- var ESLINT_DISABLE = "/* eslint-disable */";
132
- var HEADER_COMMENT = "/** auto generated, do not edit */";
133
- var FULL_HEADER = `${ESLINT_DISABLE}
134
- ${HEADER_COMMENT}`;
135
- function ensureHeaderComment(source) {
136
- let text = source.startsWith("\uFEFF") ? source.slice(1) : source;
137
- while (text.startsWith(ESLINT_DISABLE)) {
138
- text = text.slice(ESLINT_DISABLE.length);
139
- text = stripLeadingNewlines(text);
140
- }
141
- while (text.startsWith(HEADER_COMMENT)) {
142
- text = text.slice(HEADER_COMMENT.length);
143
- text = stripLeadingNewlines(text);
144
- }
145
- const trimmed = stripLeadingNewlines(text);
146
- if (trimmed.length === 0) {
147
- return `${ESLINT_DISABLE}
148
- ${HEADER_COMMENT}
149
- `;
150
- }
151
- return `${ESLINT_DISABLE}
152
- ${HEADER_COMMENT}
153
- ${trimmed}`;
133
+ // src/commands/db/gen-dbschema/transforms/core.ts
134
+ import { IndentationText, Project, QuoteKind } from "ts-morph";
135
+
136
+ // src/commands/db/gen-dbschema/transforms/types.ts
137
+ function createEmptyStats() {
138
+ return {
139
+ patchedDefects: 0,
140
+ removedPgSchemas: 0,
141
+ convertedSchemaCalls: 0,
142
+ renamedIdentifiers: [],
143
+ replacedUnknown: 0,
144
+ fallbackToText: 0,
145
+ unmatchedUnknown: [],
146
+ replacedTimestamp: 0,
147
+ replacedDefaultNow: 0,
148
+ removedSystemFields: 0,
149
+ addedImports: [],
150
+ removedImports: []
151
+ };
154
152
  }
155
- function stripLeadingNewlines(value) {
156
- let current = value;
157
- while (current.startsWith("\r\n") || current.startsWith("\n")) {
158
- current = current.startsWith("\r\n") ? current.slice(2) : current.slice(1);
153
+
154
+ // src/commands/db/gen-dbschema/transforms/core.ts
155
+ var PROJECT_OPTIONS = {
156
+ skipAddingFilesFromTsConfig: true,
157
+ skipFileDependencyResolution: true,
158
+ manipulationSettings: {
159
+ indentationText: IndentationText.TwoSpaces,
160
+ quoteKind: QuoteKind.Single
159
161
  }
160
- return current;
162
+ };
163
+ function parseSource(source, fileName = "schema.ts") {
164
+ const project = new Project({
165
+ ...PROJECT_OPTIONS,
166
+ useInMemoryFileSystem: true
167
+ });
168
+ const sourceFile = project.createSourceFile(fileName, source);
169
+ return { project, sourceFile };
161
170
  }
162
- function collapseExtraBlankLines(text) {
163
- return text.replace(/\n{3,}/g, "\n\n");
171
+ function applyTransforms(sourceFile, transforms) {
172
+ const stats = createEmptyStats();
173
+ for (const transform of transforms) {
174
+ try {
175
+ transform.transform({ sourceFile, stats });
176
+ } catch (error) {
177
+ console.error(`[ast] Transform "${transform.name}" failed:`, error);
178
+ throw error;
179
+ }
180
+ }
181
+ return stats;
164
182
  }
165
-
166
- // src/commands/db/gen-dbschema/helper/schema-conversion.ts
167
- function removePgSchemaDeclarations(source) {
168
- return source.replace(/export const \w+ = pgSchema\([\s\S]*?\);\n*/g, "");
169
- }
170
- function convertSchemaTableInvocations(source) {
171
- let converted = 0;
172
- let text = source.replace(/([A-Za-z0-9_]+)\.table\(/g, () => {
173
- converted += 1;
174
- return "pgTable(";
183
+ function formatSourceFile(sourceFile) {
184
+ sourceFile.formatText({
185
+ indentSize: 2,
186
+ convertTabsToSpaces: true
175
187
  });
176
- text = text.replace(/([A-Za-z0-9_]+)\.view\(/g, () => {
177
- converted += 1;
178
- return "pgView(";
179
- });
180
- text = text.replace(/([A-Za-z0-9_]+)\.materializedView\(/g, () => {
181
- converted += 1;
182
- return "pgMaterializedView(";
183
- });
184
- text = text.replace(/([A-Za-z0-9_]+)\.enum\(/g, () => {
185
- converted += 1;
186
- return "pgEnum(";
187
- });
188
- text = text.replace(/([A-Za-z0-9_]+)\.sequence\(/g, () => {
189
- converted += 1;
190
- return "pgSequence(";
191
- });
192
- return { text, converted };
193
188
  }
189
+ function printSourceFile(sourceFile) {
190
+ return sourceFile.getFullText();
191
+ }
192
+
193
+ // src/commands/db/gen-dbschema/transforms/ast/rename-identifiers.ts
194
+ import { Node } from "ts-morph";
194
195
 
195
- // src/commands/db/gen-dbschema/helper/table-rename.ts
196
+ // src/commands/db/gen-dbschema/utils/identifier.ts
196
197
  import { pinyin } from "pinyin-pro";
197
- function renamePgTableConstants(source) {
198
- const pgTableRegex = /export const\s+("?)([^"'\s=]+)\1\s*=\s*(?:\w+\.)?(table|view|materializedView|enum|sequence|pgTable|pgView|pgMaterializedView|pgEnum|pgSequence)\(\s*["'`]([^"'`]+)["'`]/gu;
199
- const renames = [];
200
- const updated = source.replace(pgTableRegex, (match, quote, currentName, factory, tableName) => {
201
- const sanitized = sanitizeIdentifier(tableName);
202
- const needsRename = quote === '"' || sanitized !== currentName;
203
- if (!needsRename) {
204
- return match;
205
- }
206
- const originalRef = quote === '"' ? currentName : currentName;
207
- renames.push({ from: originalRef, to: sanitized });
208
- const equalsIndex = match.indexOf("=");
209
- const suffix = equalsIndex >= 0 ? match.slice(equalsIndex) : ` = ${factory}("${tableName}"`;
210
- const normalizedSuffix = suffix.trimStart();
211
- return `export const ${sanitized} ${normalizedSuffix}`;
212
- });
213
- return { text: updated, renames };
214
- }
215
- function updateTableReferenceIdentifiers(source, renames) {
216
- if (renames.length === 0) {
217
- return source;
198
+ function toAsciiName(name) {
199
+ if (!/[^\x00-\x7F]/.test(name)) {
200
+ return name;
201
+ }
202
+ try {
203
+ const transliterated = pinyin(name, { toneType: "none", type: "array" }).join("_");
204
+ return transliterated || name;
205
+ } catch {
206
+ return name;
218
207
  }
219
- return renames.reduce((acc, rename) => {
220
- if (!rename.from || rename.from === rename.to) {
221
- return acc;
222
- }
223
- const pattern = new RegExp(`\\b${escapeRegExp(rename.from)}(\\s*[.(])`, "g");
224
- let result = acc.replace(pattern, `${rename.to}$1`);
225
- const quotedCallPattern = new RegExp(`"${escapeRegExp(rename.from)}"(\\s*\\()`, "g");
226
- result = result.replace(quotedCallPattern, `${rename.to}$1`);
227
- const quotedDotPattern = new RegExp(`"${escapeRegExp(rename.from)}"(\\s*\\.)`, "g");
228
- result = result.replace(quotedDotPattern, `${rename.to}$1`);
229
- return result;
230
- }, source);
231
- }
232
- function escapeRegExp(value) {
233
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\//g, "\\/");
234
208
  }
235
209
  function toCamelCase(str) {
236
210
  const words = str.split(/[_\-\s]+/).filter(Boolean);
@@ -258,129 +232,633 @@ function sanitizeIdentifier(name) {
258
232
  }
259
233
  return sanitized;
260
234
  }
261
- function toAsciiName(name) {
262
- if (!/[^\x00-\x7F]/.test(name)) {
263
- return name;
235
+
236
+ // src/commands/db/gen-dbschema/transforms/ast/rename-identifiers.ts
237
+ var PG_FACTORIES = [
238
+ "pgTable",
239
+ "pgView",
240
+ "pgMaterializedView",
241
+ "pgEnum",
242
+ "pgSequence",
243
+ // Also match schema.xxx() format (before conversion)
244
+ "table",
245
+ "view",
246
+ "materializedView",
247
+ "enum",
248
+ "sequence"
249
+ ];
250
+ function extractFactoryName(initializer) {
251
+ if (!Node.isCallExpression(initializer)) {
252
+ return void 0;
264
253
  }
265
- try {
266
- const transliterated = pinyin(name, { toneType: "none", type: "array" }).join("_");
267
- return transliterated || name;
268
- } catch (error) {
269
- return name;
254
+ const args = initializer.getArguments();
255
+ if (args.length === 0) {
256
+ return void 0;
257
+ }
258
+ const firstArg = args[0];
259
+ if (Node.isStringLiteral(firstArg)) {
260
+ return firstArg.getLiteralText();
270
261
  }
262
+ return void 0;
271
263
  }
264
+ function isPgFactoryCall(initializer) {
265
+ if (!Node.isCallExpression(initializer)) {
266
+ return false;
267
+ }
268
+ const expression = initializer.getExpression();
269
+ const exprText = expression.getText();
270
+ if (PG_FACTORIES.includes(exprText)) {
271
+ return true;
272
+ }
273
+ if (Node.isPropertyAccessExpression(expression)) {
274
+ const propName = expression.getName();
275
+ if (PG_FACTORIES.includes(propName)) {
276
+ return true;
277
+ }
278
+ }
279
+ return false;
280
+ }
281
+ function getCurrentName(decl) {
282
+ const name = decl.getName();
283
+ return name.replace(/^"|"$/g, "");
284
+ }
285
+ var renameIdentifiersTransform = {
286
+ name: "rename-identifiers",
287
+ transform(ctx) {
288
+ const { sourceFile, stats } = ctx;
289
+ const renames = [];
290
+ for (const statement of sourceFile.getStatements()) {
291
+ if (!Node.isVariableStatement(statement)) {
292
+ continue;
293
+ }
294
+ if (!statement.hasExportKeyword()) {
295
+ continue;
296
+ }
297
+ for (const decl of statement.getDeclarations()) {
298
+ const initializer = decl.getInitializer();
299
+ if (!initializer) {
300
+ continue;
301
+ }
302
+ if (!isPgFactoryCall(initializer)) {
303
+ continue;
304
+ }
305
+ const tableName = extractFactoryName(initializer);
306
+ if (!tableName) {
307
+ continue;
308
+ }
309
+ const currentName = getCurrentName(decl);
310
+ const sanitized = sanitizeIdentifier(tableName);
311
+ if (sanitized !== currentName) {
312
+ renames.push({ decl, from: currentName, to: sanitized });
313
+ }
314
+ }
315
+ }
316
+ for (const { decl, from, to } of renames.reverse()) {
317
+ try {
318
+ decl.rename(to);
319
+ stats.renamedIdentifiers.push({ from, to });
320
+ } catch (error) {
321
+ console.warn(`[rename-identifiers] Failed to rename "${from}" to "${to}":`, error);
322
+ }
323
+ }
324
+ stats.renamedIdentifiers.reverse();
325
+ }
326
+ };
272
327
 
273
- // src/commands/db/gen-dbschema/helper/custom-types.ts
274
- var CUSTOM_TYPE_PATTERN = /\/\/ TODO: failed to parse database type '(?:\w+\.)?(user_profile|file_attachment)(\[\])?'/;
275
- var UNKNOWN_TYPE_TODO_PATTERN = /\/\/ TODO: failed to parse database type '([^']+)'/;
276
- function replaceUnknownColumns(source) {
277
- const lines = source.split("\n");
278
- const result = [];
279
- let replaced = 0;
280
- let fallbackToText = 0;
281
- const unmatched = [];
282
- for (let i = 0; i < lines.length; i += 1) {
283
- const line = lines[i];
284
- const knownMatch = line.match(CUSTOM_TYPE_PATTERN);
285
- if (knownMatch) {
286
- const typeName = knownMatch[1];
287
- const factory = typeName === "user_profile" ? "userProfile" : "fileAttachment";
288
- const replacedLine = replaceFollowingUnknown(lines[i + 1], factory);
289
- if (replacedLine) {
290
- result.push(replacedLine);
291
- replaced += 1;
292
- i += 1;
293
- } else {
294
- unmatched.push(line.trim());
295
- result.push(line);
328
+ // src/commands/db/gen-dbschema/transforms/ast/remove-pg-schema.ts
329
+ import { Node as Node2 } from "ts-morph";
330
+ var removePgSchemaTransform = {
331
+ name: "remove-pg-schema",
332
+ transform(ctx) {
333
+ const { sourceFile, stats } = ctx;
334
+ const statementsToRemove = [];
335
+ for (const statement of sourceFile.getStatements()) {
336
+ if (!Node2.isVariableStatement(statement)) {
337
+ continue;
296
338
  }
297
- continue;
339
+ for (const decl of statement.getDeclarations()) {
340
+ const initializer = decl.getInitializer();
341
+ if (!initializer || !Node2.isCallExpression(initializer)) {
342
+ continue;
343
+ }
344
+ const calleeText = initializer.getExpression().getText();
345
+ if (calleeText === "pgSchema") {
346
+ statementsToRemove.push(statement);
347
+ stats.removedPgSchemas++;
348
+ break;
349
+ }
350
+ }
351
+ }
352
+ for (const statement of statementsToRemove.reverse()) {
353
+ statement.remove();
298
354
  }
299
- const unknownMatch = line.match(UNKNOWN_TYPE_TODO_PATTERN);
300
- if (unknownMatch) {
301
- const replacedLine = replaceFollowingUnknown(lines[i + 1], "text");
302
- if (replacedLine) {
303
- result.push(replacedLine);
304
- fallbackToText += 1;
305
- i += 1;
355
+ }
356
+ };
357
+
358
+ // src/commands/db/gen-dbschema/transforms/ast/convert-schema-calls.ts
359
+ import { Node as Node3 } from "ts-morph";
360
+ var SCHEMA_METHOD_TO_PG = {
361
+ table: "pgTable",
362
+ view: "pgView",
363
+ materializedView: "pgMaterializedView",
364
+ enum: "pgEnum",
365
+ sequence: "pgSequence"
366
+ };
367
+ var convertSchemaCallsTransform = {
368
+ name: "convert-schema-calls",
369
+ transform(ctx) {
370
+ const { sourceFile, stats } = ctx;
371
+ sourceFile.forEachDescendant((node) => {
372
+ if (!Node3.isCallExpression(node)) {
373
+ return;
374
+ }
375
+ const expression = node.getExpression();
376
+ if (!Node3.isPropertyAccessExpression(expression)) {
377
+ return;
378
+ }
379
+ const objectExpr = expression.getExpression();
380
+ const methodName = expression.getName();
381
+ const pgFactoryName = SCHEMA_METHOD_TO_PG[methodName];
382
+ if (!pgFactoryName) {
383
+ return;
384
+ }
385
+ if (!Node3.isIdentifier(objectExpr)) {
386
+ return;
387
+ }
388
+ expression.replaceWithText(pgFactoryName);
389
+ stats.convertedSchemaCalls++;
390
+ });
391
+ }
392
+ };
393
+
394
+ // src/commands/db/gen-dbschema/transforms/ast/patch-defects.ts
395
+ import { Node as Node4 } from "ts-morph";
396
+ var patchDefectsTransform = {
397
+ name: "patch-defects",
398
+ transform(ctx) {
399
+ const { sourceFile, stats } = ctx;
400
+ sourceFile.forEachDescendant((node) => {
401
+ if (!Node4.isCallExpression(node)) {
402
+ return;
403
+ }
404
+ const expr = node.getExpression();
405
+ if (!Node4.isPropertyAccessExpression(expr)) {
406
+ return;
407
+ }
408
+ if (expr.getName() !== "default") {
409
+ return;
410
+ }
411
+ const args = node.getArguments();
412
+ if (args.length !== 1) {
413
+ return;
414
+ }
415
+ const arg = args[0];
416
+ if (Node4.isStringLiteral(arg)) {
417
+ const text = arg.getLiteralText();
418
+ if (text === "") {
419
+ stats.patchedDefects++;
420
+ }
421
+ }
422
+ });
423
+ }
424
+ };
425
+
426
+ // src/commands/db/gen-dbschema/transforms/ast/replace-unknown.ts
427
+ import { Node as Node5 } from "ts-morph";
428
+ var KNOWN_TYPE_FACTORIES = {
429
+ user_profile: "userProfile",
430
+ file_attachment: "fileAttachment"
431
+ };
432
+ var replaceUnknownTransform = {
433
+ name: "replace-unknown",
434
+ transform(ctx) {
435
+ const { sourceFile, stats } = ctx;
436
+ const fullText = sourceFile.getFullText();
437
+ sourceFile.forEachDescendant((node) => {
438
+ if (!Node5.isCallExpression(node)) {
439
+ return;
440
+ }
441
+ const expression = node.getExpression();
442
+ if (!Node5.isIdentifier(expression) || expression.getText() !== "unknown") {
443
+ return;
444
+ }
445
+ const nodeStart = node.getStart();
446
+ const textBefore = fullText.slice(Math.max(0, nodeStart - 500), nodeStart);
447
+ const lines = textBefore.split("\n");
448
+ let factoryName = "text";
449
+ let foundKnownType = false;
450
+ for (let i = lines.length - 1; i >= Math.max(0, lines.length - 5); i--) {
451
+ const line = lines[i];
452
+ const todoMatch = line.match(/\/\/ TODO: failed to parse database type '(?:\w+\.)?([\w_]+)(\[\])?'/);
453
+ if (todoMatch) {
454
+ const typeName = todoMatch[1];
455
+ if (KNOWN_TYPE_FACTORIES[typeName]) {
456
+ factoryName = KNOWN_TYPE_FACTORIES[typeName];
457
+ foundKnownType = true;
458
+ }
459
+ break;
460
+ }
461
+ }
462
+ expression.replaceWithText(factoryName);
463
+ if (foundKnownType) {
464
+ stats.replacedUnknown++;
306
465
  } else {
307
- unmatched.push(line.trim());
308
- result.push(line);
466
+ stats.fallbackToText++;
309
467
  }
468
+ });
469
+ const todoCommentRegex = /\/\/ TODO: failed to parse database type '[^']+'\s*\n/g;
470
+ const currentText = sourceFile.getFullText();
471
+ const cleanedText = currentText.replace(todoCommentRegex, "");
472
+ if (cleanedText !== currentText) {
473
+ sourceFile.replaceWithText(cleanedText);
474
+ }
475
+ }
476
+ };
477
+
478
+ // src/commands/db/gen-dbschema/transforms/ast/replace-timestamp.ts
479
+ import { Node as Node6 } from "ts-morph";
480
+ function checkTimestampOptions(optionsArg) {
481
+ let hasWithTimezone = false;
482
+ let hasModeString = false;
483
+ for (const prop of optionsArg.getProperties()) {
484
+ if (!Node6.isPropertyAssignment(prop)) {
310
485
  continue;
311
486
  }
312
- if (line.includes("unknown(")) {
313
- unmatched.push(line.trim());
487
+ const propName = prop.getName();
488
+ const initializer = prop.getInitializer();
489
+ if (propName === "withTimezone") {
490
+ if (Node6.isTrueLiteral(initializer)) {
491
+ hasWithTimezone = true;
492
+ }
493
+ }
494
+ if (propName === "mode") {
495
+ if (Node6.isStringLiteral(initializer) && initializer.getLiteralText() === "string") {
496
+ hasModeString = true;
497
+ }
314
498
  }
315
- result.push(line);
316
499
  }
317
- return {
318
- text: result.join("\n"),
319
- replaced,
320
- fallbackToText,
321
- unmatched
322
- };
500
+ return hasWithTimezone && hasModeString;
323
501
  }
324
- function replaceFollowingUnknown(nextLine, factory) {
325
- if (!nextLine || !nextLine.includes("unknown(")) {
326
- return void 0;
502
+ var replaceTimestampTransform = {
503
+ name: "replace-timestamp",
504
+ transform(ctx) {
505
+ const { sourceFile, stats } = ctx;
506
+ const replacements = [];
507
+ sourceFile.forEachDescendant((node) => {
508
+ if (!Node6.isCallExpression(node)) {
509
+ return;
510
+ }
511
+ const expression = node.getExpression();
512
+ if (!Node6.isIdentifier(expression) || expression.getText() !== "timestamp") {
513
+ return;
514
+ }
515
+ const args = node.getArguments();
516
+ if (args.length === 2) {
517
+ const [fieldArg, optionsArg] = args;
518
+ if (!Node6.isStringLiteral(fieldArg)) {
519
+ return;
520
+ }
521
+ if (!Node6.isObjectLiteralExpression(optionsArg)) {
522
+ return;
523
+ }
524
+ if (checkTimestampOptions(optionsArg)) {
525
+ const quote = fieldArg.getQuoteKind() === 1 ? '"' : "'";
526
+ const fieldName = fieldArg.getLiteralText();
527
+ replacements.push({
528
+ node,
529
+ replacement: `customTimestamptz(${quote}${fieldName}${quote})`
530
+ });
531
+ }
532
+ return;
533
+ }
534
+ if (args.length === 1) {
535
+ const [optionsArg] = args;
536
+ if (!Node6.isObjectLiteralExpression(optionsArg)) {
537
+ return;
538
+ }
539
+ if (checkTimestampOptions(optionsArg)) {
540
+ replacements.push({
541
+ node,
542
+ replacement: "customTimestamptz()"
543
+ });
544
+ }
545
+ return;
546
+ }
547
+ });
548
+ for (const { node, replacement } of replacements.reverse()) {
549
+ node.replaceWithText(replacement);
550
+ stats.replacedTimestamp++;
551
+ }
327
552
  }
328
- return nextLine.replace("unknown(", `${factory}(`);
329
- }
553
+ };
330
554
 
331
- // src/commands/db/gen-dbschema/helper/imports.ts
332
- import fs from "fs";
333
- import { fileURLToPath } from "url";
334
- function tweakImports(source) {
335
- const importRegex = /import \{([^}]*)\} from "drizzle-orm\/pg-core";?/;
336
- const match = source.match(importRegex);
337
- if (!match) {
338
- return source;
555
+ // src/commands/db/gen-dbschema/transforms/ast/replace-default-now.ts
556
+ import { Node as Node7 } from "ts-morph";
557
+ var replaceDefaultNowTransform = {
558
+ name: "replace-default-now",
559
+ transform(ctx) {
560
+ const { sourceFile, stats } = ctx;
561
+ sourceFile.forEachDescendant((node) => {
562
+ if (!Node7.isCallExpression(node)) {
563
+ return;
564
+ }
565
+ const expression = node.getExpression();
566
+ if (!Node7.isPropertyAccessExpression(expression)) {
567
+ return;
568
+ }
569
+ if (expression.getName() !== "defaultNow") {
570
+ return;
571
+ }
572
+ if (node.getArguments().length !== 0) {
573
+ return;
574
+ }
575
+ const objectExpr = expression.getExpression();
576
+ const objectText = objectExpr.getText();
577
+ node.replaceWithText(`${objectText}.default(sql\`CURRENT_TIMESTAMP\`)`);
578
+ stats.replacedDefaultNow++;
579
+ });
339
580
  }
340
- const identifiers = match[1].split(",").map((id) => id.trim()).filter(Boolean).filter((id) => id !== "pgSchema" && id !== "customType");
341
- const filteredIdentifiers = identifiers.filter((id) => {
342
- if (id === "timestamp") {
343
- const timestampUsageRegex = /timestamp\s*\(/;
344
- return timestampUsageRegex.test(source);
345
- }
346
- return true;
347
- });
348
- if (source.includes("pgTable(") && !filteredIdentifiers.includes("pgTable")) {
349
- filteredIdentifiers.push("pgTable");
581
+ };
582
+
583
+ // src/commands/db/gen-dbschema/transforms/ast/remove-system-fields.ts
584
+ import { Node as Node8 } from "ts-morph";
585
+ var SYSTEM_TO_BUSINESS = {
586
+ _created_at: "created_at",
587
+ _created_by: "created_by",
588
+ _updated_at: "updated_at",
589
+ _updated_by: "updated_by"
590
+ };
591
+ var TABLE_FACTORIES = ["pgTable", "pgView", "pgMaterializedView", "table", "view", "materializedView"];
592
+ var removeSystemFieldsTransform = {
593
+ name: "remove-system-fields",
594
+ transform(ctx) {
595
+ const { sourceFile, stats } = ctx;
596
+ sourceFile.forEachDescendant((node) => {
597
+ if (!Node8.isCallExpression(node)) {
598
+ return;
599
+ }
600
+ const expression = node.getExpression();
601
+ let factoryName = "";
602
+ if (Node8.isIdentifier(expression)) {
603
+ factoryName = expression.getText();
604
+ } else if (Node8.isPropertyAccessExpression(expression)) {
605
+ factoryName = expression.getName();
606
+ }
607
+ if (!TABLE_FACTORIES.includes(factoryName)) {
608
+ return;
609
+ }
610
+ const args = node.getArguments();
611
+ if (args.length < 2) {
612
+ return;
613
+ }
614
+ const columnsArg = args[1];
615
+ if (!Node8.isObjectLiteralExpression(columnsArg)) {
616
+ return;
617
+ }
618
+ const fieldNames = /* @__PURE__ */ new Set();
619
+ const properties = columnsArg.getProperties();
620
+ for (const prop of properties) {
621
+ if (!Node8.isPropertyAssignment(prop)) {
622
+ continue;
623
+ }
624
+ const nameNode = prop.getNameNode();
625
+ let fieldName = "";
626
+ if (Node8.isStringLiteral(nameNode)) {
627
+ fieldName = nameNode.getLiteralText();
628
+ } else if (Node8.isIdentifier(nameNode)) {
629
+ fieldName = nameNode.getText();
630
+ }
631
+ if (fieldName) {
632
+ fieldNames.add(fieldName);
633
+ }
634
+ }
635
+ const propsToRemove = [];
636
+ for (const prop of properties) {
637
+ if (!Node8.isPropertyAssignment(prop)) {
638
+ continue;
639
+ }
640
+ const nameNode = prop.getNameNode();
641
+ let fieldName = "";
642
+ if (Node8.isStringLiteral(nameNode)) {
643
+ fieldName = nameNode.getLiteralText();
644
+ } else if (Node8.isIdentifier(nameNode)) {
645
+ fieldName = nameNode.getText();
646
+ }
647
+ const businessField = SYSTEM_TO_BUSINESS[fieldName];
648
+ if (businessField && fieldNames.has(businessField)) {
649
+ propsToRemove.push(prop);
650
+ }
651
+ }
652
+ for (const prop of propsToRemove) {
653
+ const leadingCommentRanges = prop.getLeadingCommentRanges();
654
+ for (const comment of leadingCommentRanges) {
655
+ const commentText = comment.getText();
656
+ if (commentText.includes("System field:")) {
657
+ }
658
+ }
659
+ prop.remove();
660
+ stats.removedSystemFields++;
661
+ }
662
+ });
350
663
  }
351
- if (source.includes("pgView(") && !filteredIdentifiers.includes("pgView")) {
352
- filteredIdentifiers.push("pgView");
664
+ };
665
+
666
+ // src/commands/db/gen-dbschema/transforms/ast/tweak-imports.ts
667
+ var REMOVE_IMPORTS = ["pgSchema", "customType"];
668
+ var PG_FACTORIES2 = ["pgTable", "pgView", "pgMaterializedView", "pgEnum", "pgSequence"];
669
+ var tweakImportsTransform = {
670
+ name: "tweak-imports",
671
+ transform(ctx) {
672
+ const { sourceFile, stats } = ctx;
673
+ const fullText = sourceFile.getFullText();
674
+ const imports = sourceFile.getImportDeclarations();
675
+ const pgCoreImport = imports.find((imp) => {
676
+ const moduleSpec = imp.getModuleSpecifierValue();
677
+ return moduleSpec === "drizzle-orm/pg-core";
678
+ });
679
+ if (!pgCoreImport) {
680
+ return;
681
+ }
682
+ const namedImports = pgCoreImport.getNamedImports();
683
+ const currentImports = namedImports.map((ni) => ni.getName());
684
+ const toRemove = [];
685
+ const toAdd = [];
686
+ for (const identifier of REMOVE_IMPORTS) {
687
+ if (currentImports.includes(identifier)) {
688
+ toRemove.push(identifier);
689
+ stats.removedImports.push(identifier);
690
+ }
691
+ }
692
+ if (currentImports.includes("timestamp")) {
693
+ const timestampUsed = /timestamp\s*\(/.test(fullText);
694
+ if (!timestampUsed) {
695
+ toRemove.push("timestamp");
696
+ stats.removedImports.push("timestamp");
697
+ }
698
+ }
699
+ for (const factory of PG_FACTORIES2) {
700
+ if (!currentImports.includes(factory)) {
701
+ const pattern = new RegExp(`${factory}\\s*\\(`);
702
+ if (pattern.test(fullText)) {
703
+ toAdd.push(factory);
704
+ stats.addedImports.push(factory);
705
+ }
706
+ }
707
+ }
708
+ for (const identifier of toRemove) {
709
+ const freshNamedImports = pgCoreImport.getNamedImports();
710
+ const namedImport = freshNamedImports.find((ni) => ni.getName() === identifier);
711
+ if (namedImport) {
712
+ namedImport.remove();
713
+ }
714
+ }
715
+ for (const identifier of toAdd) {
716
+ pgCoreImport.addNamedImport(identifier);
717
+ }
718
+ if (fullText.includes("sql`CURRENT_TIMESTAMP`")) {
719
+ const drizzleOrmImport = imports.find((imp) => {
720
+ const moduleSpec = imp.getModuleSpecifierValue();
721
+ return moduleSpec === "drizzle-orm";
722
+ });
723
+ if (!drizzleOrmImport) {
724
+ sourceFile.addImportDeclaration({
725
+ moduleSpecifier: "drizzle-orm",
726
+ namedImports: ["sql"]
727
+ });
728
+ stats.addedImports.push("sql");
729
+ } else {
730
+ const hasSql = drizzleOrmImport.getNamedImports().some((ni) => ni.getName() === "sql");
731
+ if (!hasSql) {
732
+ drizzleOrmImport.addNamedImport("sql");
733
+ stats.addedImports.push("sql");
734
+ }
735
+ }
736
+ }
353
737
  }
354
- if (source.includes("pgMaterializedView(") && !filteredIdentifiers.includes("pgMaterializedView")) {
355
- filteredIdentifiers.push("pgMaterializedView");
738
+ };
739
+
740
+ // src/commands/db/gen-dbschema/transforms/ast/index.ts
741
+ var defaultTransforms = [
742
+ patchDefectsTransform,
743
+ // #2 Fix syntax errors first
744
+ removePgSchemaTransform,
745
+ // #3 Remove pgSchema declarations
746
+ convertSchemaCallsTransform,
747
+ // #4 Convert schema.xxx() to pgXxx()
748
+ renameIdentifiersTransform,
749
+ // #5+#6 Rename identifiers (auto-updates refs)
750
+ replaceUnknownTransform,
751
+ // #7 Replace unknown types
752
+ replaceTimestampTransform,
753
+ // #8 Replace timestamp
754
+ replaceDefaultNowTransform,
755
+ // #9 Replace .defaultNow()
756
+ removeSystemFieldsTransform,
757
+ // #10 Remove conflicting system fields
758
+ tweakImportsTransform
759
+ // #12 Adjust imports
760
+ ];
761
+
762
+ // src/commands/db/gen-dbschema/transforms/text/patch-defects.ts
763
+ function patchDefects(source) {
764
+ let fixed = 0;
765
+ const renamedQuotedExports = [];
766
+ let text = source;
767
+ text = text.replace(/\.default\('\)/g, () => {
768
+ fixed += 1;
769
+ return `.default('')`;
770
+ });
771
+ const quotedExportPattern = /export const\s+"([^"]+)"\s*=/g;
772
+ text = text.replace(quotedExportPattern, (match, quotedName) => {
773
+ const sanitized = sanitizeIdentifier(quotedName);
774
+ renamedQuotedExports.push({ from: quotedName, to: sanitized });
775
+ fixed += 1;
776
+ return `export const ${sanitized} =`;
777
+ });
778
+ for (const { from, to } of renamedQuotedExports) {
779
+ const escaped = from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
780
+ const callPattern = new RegExp(`"${escaped}"\\s*\\(`, "g");
781
+ text = text.replace(callPattern, `${to}(`);
782
+ const dotPattern = new RegExp(`"${escaped}"\\s*\\.`, "g");
783
+ text = text.replace(dotPattern, `${to}.`);
356
784
  }
357
- if (source.includes("pgEnum(") && !filteredIdentifiers.includes("pgEnum")) {
358
- filteredIdentifiers.push("pgEnum");
785
+ return { text, fixed, renamedQuotedExports };
786
+ }
787
+
788
+ // src/commands/db/gen-dbschema/transforms/text/header.ts
789
+ var ESLINT_DISABLE = "/* eslint-disable */";
790
+ var HEADER_COMMENT = "/** auto generated, do not edit */";
791
+ var FULL_HEADER = `${ESLINT_DISABLE}
792
+ ${HEADER_COMMENT}`;
793
+ function ensureHeader(source) {
794
+ let trimmed = source;
795
+ const headerPatterns = [
796
+ /^\/\*\s*eslint-disable\s*\*\/\s*\n?/,
797
+ /^\/\*\*\s*auto generated[^*]*\*\/\s*\n?/
798
+ ];
799
+ for (const pattern of headerPatterns) {
800
+ while (pattern.test(trimmed)) {
801
+ trimmed = trimmed.replace(pattern, "");
802
+ }
359
803
  }
360
- if (source.includes("pgSequence(") && !filteredIdentifiers.includes("pgSequence")) {
361
- filteredIdentifiers.push("pgSequence");
804
+ trimmed = trimmed.trimStart();
805
+ return `${FULL_HEADER}
806
+ ${trimmed}`;
807
+ }
808
+
809
+ // src/commands/db/gen-dbschema/transforms/text/system-comments.ts
810
+ var SYSTEM_FIELD_COMMENTS = {
811
+ _created_at: "Creation time",
812
+ _created_by: "Creator",
813
+ _updated_at: "Update time",
814
+ _updated_by: "Updater"
815
+ };
816
+ function addSystemFieldComments(source) {
817
+ const lines = source.split("\n");
818
+ for (let i = 0; i < lines.length; i += 1) {
819
+ const line = lines[i];
820
+ const entry = Object.entries(SYSTEM_FIELD_COMMENTS).find(
821
+ ([key]) => line.includes(`"${key}"`) || line.includes(`'${key}'`)
822
+ );
823
+ if (!entry) {
824
+ continue;
825
+ }
826
+ const [, description] = entry;
827
+ const previousLine = lines[i - 1]?.trim() ?? "";
828
+ if (previousLine.startsWith("//") && previousLine.includes("System field")) {
829
+ continue;
830
+ }
831
+ const indentMatch = line.match(/^\s*/);
832
+ const indent = indentMatch ? indentMatch[0] : "";
833
+ const comment = `${indent}// System field: ${description} (auto-filled, do not modify)`;
834
+ lines.splice(i, 0, comment);
835
+ i += 1;
362
836
  }
363
- const unique = Array.from(new Set(filteredIdentifiers));
364
- const replacement = `import { ${unique.join(", ")} } from "drizzle-orm/pg-core"`;
365
- return source.replace(importRegex, replacement);
837
+ return lines.join("\n");
366
838
  }
839
+
840
+ // src/commands/db/gen-dbschema/transforms/text/inline-types.ts
841
+ import fs from "fs";
842
+ import { fileURLToPath } from "url";
367
843
  function inlineCustomTypes(source) {
368
- const text = source.replace(/import \{[^}]*\} from ["']\.\/types["'];?\n*/g, "");
844
+ let text = source.replace(/import \{[^}]*\} from ["']\.\/types["'];?\n*/g, "");
369
845
  const templatePath = resolveTemplateTypesPath();
370
846
  if (!templatePath) {
371
- console.warn("[postprocess-drizzle-schema] Template types file not found.");
847
+ console.warn("[text/inline-types] Template types file not found.");
372
848
  return text;
373
849
  }
374
- return inlineFromTemplateContent(text, fs.readFileSync(templatePath, "utf8"));
850
+ const templateContent = fs.readFileSync(templatePath, "utf8");
851
+ return inlineFromTemplate(text, templateContent);
375
852
  }
376
- function inlineFromTemplateContent(text, templateContent) {
853
+ function inlineFromTemplate(source, templateContent) {
377
854
  const typeDefinitions = templateContent.replace(/^import\s+.*;\r?\n*/gm, "").trim();
855
+ let text = source;
378
856
  const needsSql = typeDefinitions.includes("sql`") && !text.includes("from 'drizzle-orm'") && !text.includes('from "drizzle-orm"');
379
857
  const needsCustomType = typeDefinitions.includes("customType<") && !text.includes("customType");
380
858
  if (needsCustomType) {
381
859
  text = ensureImportIdentifier(text, "drizzle-orm/pg-core", "customType");
382
860
  }
383
- if (needsSql && !text.includes("from 'drizzle-orm'") && !text.includes('from "drizzle-orm"')) {
861
+ if (needsSql) {
384
862
  const importMatch = text.match(/^import [\s\S]*?from ["']drizzle-orm\/pg-core["'];?\n/m);
385
863
  if (importMatch) {
386
864
  const insertPoint = text.indexOf(importMatch[0]) + importMatch[0].length;
@@ -421,8 +899,8 @@ function ensureImportIdentifier(source, packageName, identifier) {
421
899
  }
422
900
  function resolveTemplateTypesPath() {
423
901
  const candidates = [
424
- new URL("../template/types.ts", import.meta.url),
425
- new URL("./gen-dbschema-template/types.ts", import.meta.url)
902
+ new URL("../../template/types.ts", import.meta.url),
903
+ new URL("../template/types.ts", import.meta.url)
426
904
  ];
427
905
  for (const url of candidates) {
428
906
  const p = fileURLToPath(url);
@@ -433,131 +911,9 @@ function resolveTemplateTypesPath() {
433
911
  return void 0;
434
912
  }
435
913
 
436
- // src/commands/db/gen-dbschema/helper/system-fields.ts
437
- function addSystemFieldComments(source) {
438
- const commentMap = {
439
- "_created_at": "Creation time",
440
- "_created_by": "Creator",
441
- "_updated_at": "Update time",
442
- "_updated_by": "Updater"
443
- };
444
- const lines = source.split("\n");
445
- for (let i = 0; i < lines.length; i += 1) {
446
- const line = lines[i];
447
- const entry = Object.entries(commentMap).find(([key]) => line.includes(`"${key}"`));
448
- if (!entry) {
449
- continue;
450
- }
451
- const [, description] = entry;
452
- const previousLine = lines[i - 1]?.trim() ?? "";
453
- if (previousLine.startsWith("//") && previousLine.includes("System field")) {
454
- continue;
455
- }
456
- const indentMatch = line.match(/^\s*/);
457
- const indent = indentMatch ? indentMatch[0] : "";
458
- const comment = `${indent}// System field: ${description} (auto-filled, do not modify)`;
459
- lines.splice(i, 0, comment);
460
- i += 1;
461
- }
462
- return lines.join("\n");
463
- }
464
- function removeConflictingSystemFields(source) {
465
- const systemFieldMap = {
466
- "_created_at": "created_at",
467
- "_created_by": "created_by",
468
- "_updated_at": "updated_at",
469
- "_updated_by": "updated_by"
470
- };
471
- const lines = source.split("\n");
472
- const result = [];
473
- let inTable = false;
474
- let tableStartLine = -1;
475
- const tableBusinessFields = /* @__PURE__ */ new Set();
476
- let bracketDepth = 0;
477
- for (let i = 0; i < lines.length; i += 1) {
478
- const line = lines[i];
479
- if (!inTable && /=\s*(pgTable|pgView|pgMaterializedView)\s*\(/.test(line)) {
480
- inTable = true;
481
- tableStartLine = result.length;
482
- tableBusinessFields.clear();
483
- bracketDepth = 0;
484
- }
485
- if (inTable) {
486
- for (const char of line) {
487
- if (char === "{") bracketDepth++;
488
- if (char === "}") bracketDepth--;
489
- }
490
- for (const businessField of Object.values(systemFieldMap)) {
491
- if (line.includes(`"${businessField}"`) || line.includes(`'${businessField}'`)) {
492
- tableBusinessFields.add(businessField);
493
- }
494
- }
495
- if (bracketDepth === 0 && line.includes(");")) {
496
- inTable = false;
497
- const tableEndLine = result.length;
498
- for (let j = tableStartLine; j <= tableEndLine; j++) {
499
- const tableLine = result[j] || "";
500
- let shouldRemove = false;
501
- for (const [systemField, businessField] of Object.entries(systemFieldMap)) {
502
- if (tableBusinessFields.has(businessField)) {
503
- if (tableLine.includes(`"${systemField}"`) || tableLine.includes(`'${systemField}'`)) {
504
- shouldRemove = true;
505
- if (j > 0 && result[j - 1]?.includes("// System field:")) {
506
- result[j - 1] = null;
507
- }
508
- break;
509
- }
510
- }
511
- }
512
- if (shouldRemove) {
513
- result[j] = null;
514
- }
515
- }
516
- }
517
- }
518
- result.push(line);
519
- }
520
- return result.filter((line) => line !== null).join("\n");
521
- }
522
-
523
- // src/commands/db/gen-dbschema/helper/patch-helper.ts
524
- function patchDrizzleKitDefects(source) {
525
- let fixed = 0;
526
- const text = source.replace(/\.default\('\)/g, () => {
527
- fixed += 1;
528
- return `.default('')`;
529
- });
530
- return { text, fixed };
531
- }
532
-
533
- // src/commands/db/gen-dbschema/helper/timestamp-replacement.ts
534
- function replaceTimestampWithCustomTypes(source) {
535
- let replaced = 0;
536
- const pattern = /timestamp\((['"])(.*?)\1,\s*(\{[^}]*\})\)/g;
537
- const text = source.replace(pattern, (match, quote, fieldName, options) => {
538
- const hasWithTimezone = /withTimezone:\s*true/.test(options);
539
- const hasModeString = /mode:\s*['"]string['"]/.test(options);
540
- if (hasWithTimezone && hasModeString) {
541
- replaced += 1;
542
- return `customTimestamptz(${quote}${fieldName}${quote})`;
543
- }
544
- return match;
545
- });
546
- return { text, replaced };
547
- }
548
- function replaceDefaultNowWithSql(source) {
549
- let replaced = 0;
550
- const pattern = /\.defaultNow\(\)/g;
551
- const text = source.replace(pattern, () => {
552
- replaced += 1;
553
- return ".default(sql`CURRENT_TIMESTAMP`)";
554
- });
555
- return { text, replaced };
556
- }
557
-
558
- // src/commands/db/gen-dbschema/helper/appendTableAliases.ts
914
+ // src/commands/db/gen-dbschema/transforms/text/table-aliases.ts
559
915
  var TABLE_ALIAS_MARKER = "// table aliases";
560
- function appendTableAliases(source) {
916
+ function generateTableAliases(source) {
561
917
  const markerIndex = source.indexOf(`
562
918
  ${TABLE_ALIAS_MARKER}`);
563
919
  const base = markerIndex === -1 ? source : source.slice(0, markerIndex);
@@ -579,66 +935,100 @@ ${aliasLines}
579
935
  `;
580
936
  }
581
937
 
938
+ // src/commands/db/gen-dbschema/transforms/text/format.ts
939
+ function formatSource(source) {
940
+ let text = source;
941
+ text = text.replace(/\r\n/g, "\n");
942
+ text = text.replace(/\n{3,}/g, "\n\n");
943
+ if (!text.endsWith("\n")) {
944
+ text += "\n";
945
+ }
946
+ return text;
947
+ }
948
+
582
949
  // src/commands/db/gen-dbschema/postprocess.ts
950
+ function postprocessSchema(rawSource) {
951
+ const patchResult = patchDefects(rawSource);
952
+ let source = patchResult.text;
953
+ const { sourceFile } = parseSource(source);
954
+ const astStats = applyTransforms(sourceFile, defaultTransforms);
955
+ formatSourceFile(sourceFile);
956
+ source = printSourceFile(sourceFile);
957
+ source = ensureHeader(source);
958
+ source = addSystemFieldComments(source);
959
+ source = inlineCustomTypes(source);
960
+ source = generateTableAliases(source);
961
+ source = formatSource(source);
962
+ return {
963
+ source,
964
+ astStats,
965
+ patchedDefects: patchResult.fixed
966
+ };
967
+ }
968
+ function logStats(result, prefix = "[postprocess]") {
969
+ const { astStats, patchedDefects } = result;
970
+ if (patchedDefects > 0) {
971
+ console.info(`${prefix} Patched ${patchedDefects} syntax defects`);
972
+ }
973
+ if (astStats.removedPgSchemas > 0) {
974
+ console.info(`${prefix} Removed ${astStats.removedPgSchemas} pgSchema declarations`);
975
+ }
976
+ if (astStats.convertedSchemaCalls > 0) {
977
+ console.info(`${prefix} Converted ${astStats.convertedSchemaCalls} schema.xxx() calls`);
978
+ }
979
+ if (astStats.renamedIdentifiers.length > 0) {
980
+ console.info(`${prefix} Renamed ${astStats.renamedIdentifiers.length} identifiers:`);
981
+ for (const { from, to } of astStats.renamedIdentifiers) {
982
+ console.info(`${prefix} ${from} -> ${to}`);
983
+ }
984
+ }
985
+ if (astStats.replacedUnknown > 0) {
986
+ console.info(`${prefix} Replaced ${astStats.replacedUnknown} unknown types with custom types`);
987
+ }
988
+ if (astStats.fallbackToText > 0) {
989
+ console.info(`${prefix} Replaced ${astStats.fallbackToText} unknown types with text (fallback)`);
990
+ }
991
+ if (astStats.unmatchedUnknown.length > 0) {
992
+ console.warn(`${prefix} Unmatched unknown types:`);
993
+ for (const line of astStats.unmatchedUnknown) {
994
+ console.warn(`${prefix} ${line}`);
995
+ }
996
+ }
997
+ if (astStats.replacedTimestamp > 0) {
998
+ console.info(`${prefix} Replaced ${astStats.replacedTimestamp} timestamp with customTimestamptz`);
999
+ }
1000
+ if (astStats.replacedDefaultNow > 0) {
1001
+ console.info(`${prefix} Replaced ${astStats.replacedDefaultNow} .defaultNow() calls`);
1002
+ }
1003
+ if (astStats.removedSystemFields > 0) {
1004
+ console.info(`${prefix} Removed ${astStats.removedSystemFields} conflicting system fields`);
1005
+ }
1006
+ if (astStats.addedImports.length > 0) {
1007
+ console.info(`${prefix} Added imports: ${astStats.addedImports.join(", ")}`);
1008
+ }
1009
+ if (astStats.removedImports.length > 0) {
1010
+ console.info(`${prefix} Removed imports: ${astStats.removedImports.join(", ")}`);
1011
+ }
1012
+ }
1013
+
1014
+ // src/commands/db/gen-dbschema/index.ts
583
1015
  function postprocessDrizzleSchema(targetPath) {
584
1016
  const resolvedPath = path.resolve(targetPath);
585
- if (!fs2.existsSync(resolvedPath)) {
1017
+ if (!fs3.existsSync(resolvedPath)) {
586
1018
  console.warn(`[postprocess-drizzle-schema] File not found: ${resolvedPath}`);
587
1019
  return void 0;
588
1020
  }
589
- let text = fs2.readFileSync(resolvedPath, "utf8");
590
- text = ensureHeaderComment(text);
591
- const patchResult = patchDrizzleKitDefects(text);
592
- text = patchResult.text;
593
- text = removePgSchemaDeclarations(text);
594
- const tableConversion = convertSchemaTableInvocations(text);
595
- text = tableConversion.text;
596
- const renameResult = renamePgTableConstants(text);
597
- text = renameResult.text;
598
- text = updateTableReferenceIdentifiers(text, renameResult.renames);
599
- const replacement = replaceUnknownColumns(text);
600
- text = replacement.text;
601
- const timestampReplacement = replaceTimestampWithCustomTypes(text);
602
- text = timestampReplacement.text;
603
- const defaultNowReplacement = replaceDefaultNowWithSql(text);
604
- text = defaultNowReplacement.text;
605
- text = removeConflictingSystemFields(text);
606
- text = addSystemFieldComments(text);
607
- text = tweakImports(text);
608
- text = inlineCustomTypes(text);
609
- text = appendTableAliases(text);
610
- text = text.replace(/\r?\n/g, "\n");
611
- text = collapseExtraBlankLines(text);
612
- fs2.writeFileSync(resolvedPath, text, "utf8");
613
- if (patchResult.fixed > 0) {
614
- console.info(`[postprocess-drizzle-schema] Patched ${patchResult.fixed} drizzle-kit defects (.default(') -> .default(''))`);
615
- }
616
- if (replacement.replaced > 0) {
617
- console.info(`[postprocess-drizzle-schema] Replaced ${replacement.replaced} unknown columns with custom types`);
618
- }
619
- if (replacement.fallbackToText > 0) {
620
- console.info(`[postprocess-drizzle-schema] Replaced ${replacement.fallbackToText} unknown columns with text (fallback)`);
621
- }
622
- if (replacement.unmatched.length > 0) {
623
- console.warn("[postprocess-drizzle-schema] Unmatched unknown columns:", replacement.unmatched.length);
624
- replacement.unmatched.forEach((line) => console.warn(` ${line}`));
625
- }
626
- if (tableConversion.converted > 0) {
627
- console.info(`[postprocess-drizzle-schema] Converted ${tableConversion.converted} schema.table invocations to pgTable`);
628
- }
629
- if (timestampReplacement.replaced > 0) {
630
- console.info(`[postprocess-drizzle-schema] Replaced ${timestampReplacement.replaced} timestamp fields with customTimestamptz`);
631
- }
632
- if (defaultNowReplacement.replaced > 0) {
633
- console.info(`[postprocess-drizzle-schema] Replaced ${defaultNowReplacement.replaced} .defaultNow() with .default(sql\`CURRENT_TIMESTAMP\`)`);
634
- }
1021
+ const rawSource = fs3.readFileSync(resolvedPath, "utf8");
1022
+ const result = postprocessSchema(rawSource);
1023
+ fs3.writeFileSync(resolvedPath, result.source, "utf8");
1024
+ logStats(result, "[postprocess-drizzle-schema]");
635
1025
  return {
636
- replacedUnknown: replacement.replaced,
637
- fallbackToText: replacement.fallbackToText,
638
- unmatchedUnknown: replacement.unmatched,
639
- patchedDefects: patchResult.fixed,
640
- replacedTimestamps: timestampReplacement.replaced,
641
- replacedDefaultNow: defaultNowReplacement.replaced
1026
+ replacedUnknown: result.astStats.replacedUnknown,
1027
+ fallbackToText: result.astStats.fallbackToText,
1028
+ unmatchedUnknown: result.astStats.unmatchedUnknown,
1029
+ patchedDefects: result.patchedDefects,
1030
+ replacedTimestamps: result.astStats.replacedTimestamp,
1031
+ replacedDefaultNow: result.astStats.replacedDefaultNow
642
1032
  };
643
1033
  }
644
1034
 
@@ -1060,10 +1450,10 @@ export class ${className}Module {}
1060
1450
  }
1061
1451
 
1062
1452
  // src/commands/db/gen-nest-resource/schema-parser.ts
1063
- import { Project, Node } from "ts-morph";
1453
+ import { Project as Project2, Node as Node9 } from "ts-morph";
1064
1454
  var DrizzleSchemaParser = class {
1065
1455
  constructor(projectOptions) {
1066
- this.project = new Project(projectOptions);
1456
+ this.project = new Project2(projectOptions);
1067
1457
  }
1068
1458
  parseSchemaFile(filePath) {
1069
1459
  const sourceFile = this.project.addSourceFileAtPath(filePath);
@@ -1073,7 +1463,7 @@ var DrizzleSchemaParser = class {
1073
1463
  const declarations = statement.getDeclarations();
1074
1464
  for (const declaration of declarations) {
1075
1465
  const initializer = declaration.getInitializer();
1076
- if (initializer && Node.isCallExpression(initializer)) {
1466
+ if (initializer && Node9.isCallExpression(initializer)) {
1077
1467
  const expression = initializer.getExpression();
1078
1468
  if (expression.getText() === "pgTable") {
1079
1469
  const tableInfo = this.parsePgTable(
@@ -1096,13 +1486,13 @@ var DrizzleSchemaParser = class {
1096
1486
  }
1097
1487
  const tableName = args[0].getText().replace(/['"]/g, "");
1098
1488
  const fieldsArg = args[1];
1099
- if (!Node.isObjectLiteralExpression(fieldsArg)) {
1489
+ if (!Node9.isObjectLiteralExpression(fieldsArg)) {
1100
1490
  return null;
1101
1491
  }
1102
1492
  const fields = [];
1103
1493
  const properties = fieldsArg.getProperties();
1104
1494
  for (const prop of properties) {
1105
- if (Node.isPropertyAssignment(prop)) {
1495
+ if (Node9.isPropertyAssignment(prop)) {
1106
1496
  const fieldName = prop.getName();
1107
1497
  const initializer = prop.getInitializer();
1108
1498
  const leadingComments = prop.getLeadingCommentRanges();
@@ -1110,7 +1500,7 @@ var DrizzleSchemaParser = class {
1110
1500
  if (leadingComments.length > 0) {
1111
1501
  comment = leadingComments.map((c) => c.getText()).join("\n").replace(/\/\//g, "").trim();
1112
1502
  }
1113
- if (initializer && Node.isCallExpression(initializer)) {
1503
+ if (initializer && Node9.isCallExpression(initializer)) {
1114
1504
  const fieldInfo = this.parseField(fieldName, initializer, comment);
1115
1505
  fields.push(fieldInfo);
1116
1506
  }
@@ -1142,10 +1532,10 @@ var DrizzleSchemaParser = class {
1142
1532
  parseBaseType(callExpr, fieldInfo) {
1143
1533
  let current = callExpr;
1144
1534
  let baseCall = null;
1145
- while (Node.isCallExpression(current)) {
1535
+ while (Node9.isCallExpression(current)) {
1146
1536
  baseCall = current;
1147
1537
  const expression2 = current.getExpression();
1148
- if (Node.isPropertyAccessExpression(expression2)) {
1538
+ if (Node9.isPropertyAccessExpression(expression2)) {
1149
1539
  current = expression2.getExpression();
1150
1540
  } else {
1151
1541
  break;
@@ -1156,7 +1546,7 @@ var DrizzleSchemaParser = class {
1156
1546
  }
1157
1547
  const expression = baseCall.getExpression();
1158
1548
  let typeName = "";
1159
- if (Node.isPropertyAccessExpression(expression)) {
1549
+ if (Node9.isPropertyAccessExpression(expression)) {
1160
1550
  typeName = expression.getName();
1161
1551
  } else {
1162
1552
  typeName = expression.getText();
@@ -1165,25 +1555,25 @@ var DrizzleSchemaParser = class {
1165
1555
  const args = baseCall.getArguments();
1166
1556
  if (args.length > 0) {
1167
1557
  const firstArg = args[0];
1168
- if (Node.isStringLiteral(firstArg)) {
1558
+ if (Node9.isStringLiteral(firstArg)) {
1169
1559
  fieldInfo.columnName = firstArg.getLiteralText();
1170
- } else if (Node.isObjectLiteralExpression(firstArg)) {
1560
+ } else if (Node9.isObjectLiteralExpression(firstArg)) {
1171
1561
  this.parseTypeConfig(firstArg, fieldInfo);
1172
- } else if (Node.isArrayLiteralExpression(firstArg)) {
1562
+ } else if (Node9.isArrayLiteralExpression(firstArg)) {
1173
1563
  fieldInfo.enumValues = firstArg.getElements().map((el) => el.getText().replace(/['"]/g, ""));
1174
1564
  }
1175
1565
  }
1176
- if (args.length > 1 && Node.isObjectLiteralExpression(args[1])) {
1566
+ if (args.length > 1 && Node9.isObjectLiteralExpression(args[1])) {
1177
1567
  this.parseTypeConfig(args[1], fieldInfo);
1178
1568
  }
1179
1569
  }
1180
1570
  parseTypeConfig(objLiteral, fieldInfo) {
1181
- if (!Node.isObjectLiteralExpression(objLiteral)) {
1571
+ if (!Node9.isObjectLiteralExpression(objLiteral)) {
1182
1572
  return;
1183
1573
  }
1184
1574
  const properties = objLiteral.getProperties();
1185
1575
  for (const prop of properties) {
1186
- if (Node.isPropertyAssignment(prop)) {
1576
+ if (Node9.isPropertyAssignment(prop)) {
1187
1577
  const propName = prop.getName();
1188
1578
  const value = prop.getInitializer()?.getText();
1189
1579
  switch (propName) {
@@ -1215,9 +1605,9 @@ var DrizzleSchemaParser = class {
1215
1605
  }
1216
1606
  parseCallChain(callExpr, fieldInfo) {
1217
1607
  let current = callExpr;
1218
- while (Node.isCallExpression(current)) {
1608
+ while (Node9.isCallExpression(current)) {
1219
1609
  const expression = current.getExpression();
1220
- if (Node.isPropertyAccessExpression(expression)) {
1610
+ if (Node9.isPropertyAccessExpression(expression)) {
1221
1611
  const methodName = expression.getName();
1222
1612
  const args = current.getArguments();
1223
1613
  switch (methodName) {
@@ -1314,7 +1704,7 @@ var require2 = createRequire(import.meta.url);
1314
1704
  async function run(options = {}) {
1315
1705
  let exitCode = 0;
1316
1706
  const envPath2 = path2.resolve(process.cwd(), ".env");
1317
- if (fs3.existsSync(envPath2)) {
1707
+ if (fs4.existsSync(envPath2)) {
1318
1708
  loadEnv({ path: envPath2 });
1319
1709
  console.log("[gen-db-schema] \u2713 Loaded .env file");
1320
1710
  }
@@ -1334,7 +1724,7 @@ async function run(options = {}) {
1334
1724
  path2.resolve(__dirname2, "../../config/drizzle.config.js"),
1335
1725
  path2.resolve(__dirname2, "../../../dist/config/drizzle.config.js")
1336
1726
  ];
1337
- const configPath = configPathCandidates.find((p) => fs3.existsSync(p));
1727
+ const configPath = configPathCandidates.find((p) => fs4.existsSync(p));
1338
1728
  console.log("[gen-db-schema] Using drizzle config from:", configPath ?? "(not found)");
1339
1729
  if (!configPath) {
1340
1730
  console.error("[gen-db-schema] Error: drizzle config not found in CLI package");
@@ -1346,8 +1736,8 @@ async function run(options = {}) {
1346
1736
  let lastDir = null;
1347
1737
  while (currentDir !== lastDir) {
1348
1738
  const pkgJsonPath = path2.join(currentDir, "package.json");
1349
- if (fs3.existsSync(pkgJsonPath)) {
1350
- const pkgJsonRaw = fs3.readFileSync(pkgJsonPath, "utf8");
1739
+ if (fs4.existsSync(pkgJsonPath)) {
1740
+ const pkgJsonRaw = fs4.readFileSync(pkgJsonPath, "utf8");
1351
1741
  const pkgJson = JSON.parse(pkgJsonRaw);
1352
1742
  if (pkgJson.name === "drizzle-kit") {
1353
1743
  const binField = pkgJson.bin;
@@ -1382,7 +1772,7 @@ async function run(options = {}) {
1382
1772
  throw new Error(`drizzle-kit introspect failed with status ${result.status}`);
1383
1773
  }
1384
1774
  const generatedSchema = path2.join(OUT_DIR, "schema.ts");
1385
- if (!fs3.existsSync(generatedSchema)) {
1775
+ if (!fs4.existsSync(generatedSchema)) {
1386
1776
  console.error("[gen-db-schema] schema.ts not generated");
1387
1777
  throw new Error("drizzle-kit introspect failed to generate schema.ts");
1388
1778
  }
@@ -1391,8 +1781,8 @@ async function run(options = {}) {
1391
1781
  console.warn("[gen-db-schema] Unmatched custom types detected:", stats.unmatchedUnknown);
1392
1782
  }
1393
1783
  console.log("[gen-db-schema] \u2713 Postprocessed schema");
1394
- fs3.mkdirSync(path2.dirname(SCHEMA_FILE), { recursive: true });
1395
- fs3.copyFileSync(generatedSchema, SCHEMA_FILE);
1784
+ fs4.mkdirSync(path2.dirname(SCHEMA_FILE), { recursive: true });
1785
+ fs4.copyFileSync(generatedSchema, SCHEMA_FILE);
1396
1786
  console.log(`[gen-db-schema] \u2713 Copied to ${outputPath}`);
1397
1787
  try {
1398
1788
  if (options.enableNestModuleGenerate) {
@@ -1413,8 +1803,8 @@ async function run(options = {}) {
1413
1803
  console.error("[gen-db-schema] Failed:", err instanceof Error ? err.message : String(err));
1414
1804
  exitCode = 1;
1415
1805
  } finally {
1416
- if (fs3.existsSync(OUT_DIR)) {
1417
- fs3.rmSync(OUT_DIR, { recursive: true, force: true });
1806
+ if (fs4.existsSync(OUT_DIR)) {
1807
+ fs4.rmSync(OUT_DIR, { recursive: true, force: true });
1418
1808
  }
1419
1809
  process.exit(exitCode);
1420
1810
  }
@@ -1433,7 +1823,7 @@ var genDbSchemaCommand = {
1433
1823
 
1434
1824
  // src/commands/sync/run.handler.ts
1435
1825
  import path4 from "path";
1436
- import fs5 from "fs";
1826
+ import fs6 from "fs";
1437
1827
  import { fileURLToPath as fileURLToPath3 } from "url";
1438
1828
 
1439
1829
  // src/config/sync.ts
@@ -1497,14 +1887,14 @@ function genSyncConfig(perms = {}) {
1497
1887
  }
1498
1888
 
1499
1889
  // src/utils/file-ops.ts
1500
- import fs4 from "fs";
1890
+ import fs5 from "fs";
1501
1891
  import path3 from "path";
1502
1892
  function removeLineFromFile(filePath, pattern) {
1503
- if (!fs4.existsSync(filePath)) {
1893
+ if (!fs5.existsSync(filePath)) {
1504
1894
  console.log(`[fullstack-cli] \u25CB ${path3.basename(filePath)} (not found)`);
1505
1895
  return false;
1506
1896
  }
1507
- const content = fs4.readFileSync(filePath, "utf-8");
1897
+ const content = fs5.readFileSync(filePath, "utf-8");
1508
1898
  const lines = content.split("\n");
1509
1899
  const trimmedPattern = pattern.trim();
1510
1900
  const filteredLines = lines.filter((line) => line.trim() !== trimmedPattern);
@@ -1512,7 +1902,7 @@ function removeLineFromFile(filePath, pattern) {
1512
1902
  console.log(`[fullstack-cli] \u25CB ${path3.basename(filePath)} (pattern not found: ${pattern})`);
1513
1903
  return false;
1514
1904
  }
1515
- fs4.writeFileSync(filePath, filteredLines.join("\n"));
1905
+ fs5.writeFileSync(filePath, filteredLines.join("\n"));
1516
1906
  console.log(`[fullstack-cli] \u2713 ${path3.basename(filePath)} (removed: ${pattern})`);
1517
1907
  return true;
1518
1908
  }
@@ -1528,7 +1918,7 @@ async function run2(options) {
1528
1918
  process.exit(0);
1529
1919
  }
1530
1920
  const userPackageJson = path4.join(userProjectRoot, "package.json");
1531
- if (!fs5.existsSync(userPackageJson)) {
1921
+ if (!fs6.existsSync(userPackageJson)) {
1532
1922
  console.log("[fullstack-cli] Skip syncing (not a valid npm project)");
1533
1923
  process.exit(0);
1534
1924
  }
@@ -1574,7 +1964,7 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
1574
1964
  }
1575
1965
  const srcPath = path4.join(pluginRoot, rule.from);
1576
1966
  const destPath = path4.join(userProjectRoot, rule.to);
1577
- if (!fs5.existsSync(srcPath)) {
1967
+ if (!fs6.existsSync(srcPath)) {
1578
1968
  console.warn(`[fullstack-cli] Source not found: ${rule.from}`);
1579
1969
  return;
1580
1970
  }
@@ -1592,31 +1982,31 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
1592
1982
  }
1593
1983
  function syncFile(src, dest, overwrite = true) {
1594
1984
  const destDir = path4.dirname(dest);
1595
- if (!fs5.existsSync(destDir)) {
1596
- fs5.mkdirSync(destDir, { recursive: true });
1985
+ if (!fs6.existsSync(destDir)) {
1986
+ fs6.mkdirSync(destDir, { recursive: true });
1597
1987
  }
1598
- if (fs5.existsSync(dest) && !overwrite) {
1988
+ if (fs6.existsSync(dest) && !overwrite) {
1599
1989
  console.log(`[fullstack-cli] \u25CB ${path4.basename(dest)} (skipped, already exists)`);
1600
1990
  return;
1601
1991
  }
1602
- fs5.copyFileSync(src, dest);
1992
+ fs6.copyFileSync(src, dest);
1603
1993
  console.log(`[fullstack-cli] \u2713 ${path4.basename(dest)}`);
1604
1994
  }
1605
1995
  function syncDirectory(src, dest, overwrite = true) {
1606
- if (!fs5.existsSync(dest)) {
1607
- fs5.mkdirSync(dest, { recursive: true });
1996
+ if (!fs6.existsSync(dest)) {
1997
+ fs6.mkdirSync(dest, { recursive: true });
1608
1998
  }
1609
- const files = fs5.readdirSync(src);
1999
+ const files = fs6.readdirSync(src);
1610
2000
  let count = 0;
1611
2001
  files.forEach((file) => {
1612
2002
  const srcFile = path4.join(src, file);
1613
2003
  const destFile = path4.join(dest, file);
1614
- const stats = fs5.statSync(srcFile);
2004
+ const stats = fs6.statSync(srcFile);
1615
2005
  if (stats.isDirectory()) {
1616
2006
  syncDirectory(srcFile, destFile, overwrite);
1617
2007
  } else {
1618
- if (overwrite || !fs5.existsSync(destFile)) {
1619
- fs5.copyFileSync(srcFile, destFile);
2008
+ if (overwrite || !fs6.existsSync(destFile)) {
2009
+ fs6.copyFileSync(srcFile, destFile);
1620
2010
  console.log(`[fullstack-cli] \u2713 ${path4.relative(dest, destFile)}`);
1621
2011
  count++;
1622
2012
  }
@@ -1627,28 +2017,28 @@ function syncDirectory(src, dest, overwrite = true) {
1627
2017
  }
1628
2018
  }
1629
2019
  function appendToFile(src, dest) {
1630
- const content = fs5.readFileSync(src, "utf-8");
2020
+ const content = fs6.readFileSync(src, "utf-8");
1631
2021
  let existingContent = "";
1632
- if (fs5.existsSync(dest)) {
1633
- existingContent = fs5.readFileSync(dest, "utf-8");
2022
+ if (fs6.existsSync(dest)) {
2023
+ existingContent = fs6.readFileSync(dest, "utf-8");
1634
2024
  }
1635
2025
  if (existingContent.includes(content.trim())) {
1636
2026
  console.log(`[fullstack-cli] \u25CB ${path4.basename(dest)} (already contains content)`);
1637
2027
  return;
1638
2028
  }
1639
- fs5.appendFileSync(dest, content);
2029
+ fs6.appendFileSync(dest, content);
1640
2030
  console.log(`[fullstack-cli] \u2713 ${path4.basename(dest)} (appended)`);
1641
2031
  }
1642
2032
  function setPermissions(permissions, projectRoot) {
1643
2033
  for (const [pattern, mode] of Object.entries(permissions)) {
1644
2034
  if (pattern === "**/*.sh") {
1645
2035
  const scriptsDir = path4.join(projectRoot, "scripts");
1646
- if (fs5.existsSync(scriptsDir)) {
1647
- const files = fs5.readdirSync(scriptsDir);
2036
+ if (fs6.existsSync(scriptsDir)) {
2037
+ const files = fs6.readdirSync(scriptsDir);
1648
2038
  files.forEach((file) => {
1649
2039
  if (file.endsWith(".sh")) {
1650
2040
  const filePath = path4.join(scriptsDir, file);
1651
- fs5.chmodSync(filePath, mode);
2041
+ fs6.chmodSync(filePath, mode);
1652
2042
  }
1653
2043
  });
1654
2044
  }
@@ -1656,16 +2046,16 @@ function setPermissions(permissions, projectRoot) {
1656
2046
  }
1657
2047
  }
1658
2048
  function deleteFile(filePath) {
1659
- if (fs5.existsSync(filePath)) {
1660
- fs5.unlinkSync(filePath);
2049
+ if (fs6.existsSync(filePath)) {
2050
+ fs6.unlinkSync(filePath);
1661
2051
  console.log(`[fullstack-cli] \u2713 ${path4.basename(filePath)} (deleted)`);
1662
2052
  } else {
1663
2053
  console.log(`[fullstack-cli] \u25CB ${path4.basename(filePath)} (not found)`);
1664
2054
  }
1665
2055
  }
1666
2056
  function deleteDirectory(dirPath) {
1667
- if (fs5.existsSync(dirPath)) {
1668
- fs5.rmSync(dirPath, { recursive: true });
2057
+ if (fs6.existsSync(dirPath)) {
2058
+ fs6.rmSync(dirPath, { recursive: true });
1669
2059
  console.log(`[fullstack-cli] \u2713 ${path4.basename(dirPath)} (deleted)`);
1670
2060
  } else {
1671
2061
  console.log(`[fullstack-cli] \u25CB ${path4.basename(dirPath)} (not found)`);
@@ -1684,7 +2074,7 @@ var syncCommand = {
1684
2074
  };
1685
2075
 
1686
2076
  // src/commands/action-plugin/utils.ts
1687
- import fs6 from "fs";
2077
+ import fs7 from "fs";
1688
2078
  import path5 from "path";
1689
2079
  import { spawnSync as spawnSync2, execSync } from "child_process";
1690
2080
  function parsePluginName(input) {
@@ -1710,11 +2100,11 @@ function getPluginPath(pluginName) {
1710
2100
  }
1711
2101
  function readPackageJson() {
1712
2102
  const pkgPath = getPackageJsonPath();
1713
- if (!fs6.existsSync(pkgPath)) {
2103
+ if (!fs7.existsSync(pkgPath)) {
1714
2104
  throw new Error("package.json not found in current directory");
1715
2105
  }
1716
2106
  try {
1717
- const content = fs6.readFileSync(pkgPath, "utf-8");
2107
+ const content = fs7.readFileSync(pkgPath, "utf-8");
1718
2108
  return JSON.parse(content);
1719
2109
  } catch {
1720
2110
  throw new Error("Failed to parse package.json");
@@ -1722,7 +2112,7 @@ function readPackageJson() {
1722
2112
  }
1723
2113
  function writePackageJson(pkg2) {
1724
2114
  const pkgPath = getPackageJsonPath();
1725
- fs6.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
2115
+ fs7.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
1726
2116
  }
1727
2117
  function readActionPlugins() {
1728
2118
  const pkg2 = readPackageJson();
@@ -1756,11 +2146,11 @@ function npmInstall(tgzPath) {
1756
2146
  }
1757
2147
  function getPackageVersion(pluginName) {
1758
2148
  const pkgJsonPath = path5.join(getPluginPath(pluginName), "package.json");
1759
- if (!fs6.existsSync(pkgJsonPath)) {
2149
+ if (!fs7.existsSync(pkgJsonPath)) {
1760
2150
  return null;
1761
2151
  }
1762
2152
  try {
1763
- const content = fs6.readFileSync(pkgJsonPath, "utf-8");
2153
+ const content = fs7.readFileSync(pkgJsonPath, "utf-8");
1764
2154
  const pkg2 = JSON.parse(content);
1765
2155
  return pkg2.version || null;
1766
2156
  } catch {
@@ -1769,11 +2159,11 @@ function getPackageVersion(pluginName) {
1769
2159
  }
1770
2160
  function readPluginPackageJson(pluginPath) {
1771
2161
  const pkgJsonPath = path5.join(pluginPath, "package.json");
1772
- if (!fs6.existsSync(pkgJsonPath)) {
2162
+ if (!fs7.existsSync(pkgJsonPath)) {
1773
2163
  return null;
1774
2164
  }
1775
2165
  try {
1776
- const content = fs6.readFileSync(pkgJsonPath, "utf-8");
2166
+ const content = fs7.readFileSync(pkgJsonPath, "utf-8");
1777
2167
  return JSON.parse(content);
1778
2168
  } catch {
1779
2169
  return null;
@@ -1783,34 +2173,34 @@ function extractTgzToNodeModules(tgzPath, pluginName) {
1783
2173
  const nodeModulesPath = path5.join(getProjectRoot(), "node_modules");
1784
2174
  const targetDir = path5.join(nodeModulesPath, pluginName);
1785
2175
  const scopeDir = path5.dirname(targetDir);
1786
- if (!fs6.existsSync(scopeDir)) {
1787
- fs6.mkdirSync(scopeDir, { recursive: true });
2176
+ if (!fs7.existsSync(scopeDir)) {
2177
+ fs7.mkdirSync(scopeDir, { recursive: true });
1788
2178
  }
1789
- if (fs6.existsSync(targetDir)) {
1790
- fs6.rmSync(targetDir, { recursive: true });
2179
+ if (fs7.existsSync(targetDir)) {
2180
+ fs7.rmSync(targetDir, { recursive: true });
1791
2181
  }
1792
2182
  const tempDir = path5.join(nodeModulesPath, ".cache", "fullstack-cli", "extract-temp");
1793
- if (fs6.existsSync(tempDir)) {
1794
- fs6.rmSync(tempDir, { recursive: true });
2183
+ if (fs7.existsSync(tempDir)) {
2184
+ fs7.rmSync(tempDir, { recursive: true });
1795
2185
  }
1796
- fs6.mkdirSync(tempDir, { recursive: true });
2186
+ fs7.mkdirSync(tempDir, { recursive: true });
1797
2187
  try {
1798
2188
  execSync(`tar -xzf "${tgzPath}" -C "${tempDir}"`, { stdio: "pipe" });
1799
2189
  const extractedDir = path5.join(tempDir, "package");
1800
- if (fs6.existsSync(extractedDir)) {
1801
- fs6.renameSync(extractedDir, targetDir);
2190
+ if (fs7.existsSync(extractedDir)) {
2191
+ fs7.renameSync(extractedDir, targetDir);
1802
2192
  } else {
1803
- const files = fs6.readdirSync(tempDir);
2193
+ const files = fs7.readdirSync(tempDir);
1804
2194
  if (files.length === 1) {
1805
- fs6.renameSync(path5.join(tempDir, files[0]), targetDir);
2195
+ fs7.renameSync(path5.join(tempDir, files[0]), targetDir);
1806
2196
  } else {
1807
2197
  throw new Error("Unexpected tgz structure");
1808
2198
  }
1809
2199
  }
1810
2200
  return targetDir;
1811
2201
  } finally {
1812
- if (fs6.existsSync(tempDir)) {
1813
- fs6.rmSync(tempDir, { recursive: true });
2202
+ if (fs7.existsSync(tempDir)) {
2203
+ fs7.rmSync(tempDir, { recursive: true });
1814
2204
  }
1815
2205
  }
1816
2206
  }
@@ -1822,7 +2212,7 @@ function checkMissingPeerDeps(peerDeps) {
1822
2212
  const nodeModulesPath = path5.join(getProjectRoot(), "node_modules");
1823
2213
  for (const [depName, _version] of Object.entries(peerDeps)) {
1824
2214
  const depPath = path5.join(nodeModulesPath, depName);
1825
- if (!fs6.existsSync(depPath)) {
2215
+ if (!fs7.existsSync(depPath)) {
1826
2216
  missing.push(depName);
1827
2217
  }
1828
2218
  }
@@ -1846,15 +2236,15 @@ function installMissingDeps(deps) {
1846
2236
  }
1847
2237
  function removePluginDirectory(pluginName) {
1848
2238
  const pluginPath = getPluginPath(pluginName);
1849
- if (fs6.existsSync(pluginPath)) {
1850
- fs6.rmSync(pluginPath, { recursive: true });
2239
+ if (fs7.existsSync(pluginPath)) {
2240
+ fs7.rmSync(pluginPath, { recursive: true });
1851
2241
  console.log(`[action-plugin] Removed ${pluginName}`);
1852
2242
  }
1853
2243
  }
1854
2244
 
1855
2245
  // src/commands/action-plugin/api-client.ts
1856
2246
  import { HttpClient as HttpClient2 } from "@lark-apaas/http-client";
1857
- import fs7 from "fs";
2247
+ import fs8 from "fs";
1858
2248
  import path6 from "path";
1859
2249
 
1860
2250
  // src/utils/http-client.ts
@@ -1947,8 +2337,8 @@ function getPluginCacheDir() {
1947
2337
  }
1948
2338
  function ensureCacheDir() {
1949
2339
  const cacheDir = getPluginCacheDir();
1950
- if (!fs7.existsSync(cacheDir)) {
1951
- fs7.mkdirSync(cacheDir, { recursive: true });
2340
+ if (!fs8.existsSync(cacheDir)) {
2341
+ fs8.mkdirSync(cacheDir, { recursive: true });
1952
2342
  }
1953
2343
  }
1954
2344
  function getTempFilePath(pluginKey, version) {
@@ -1971,7 +2361,7 @@ async function downloadPlugin(pluginKey, requestedVersion) {
1971
2361
  tgzBuffer = await downloadFromPublic(pluginInfo.downloadURL);
1972
2362
  }
1973
2363
  const tgzPath = getTempFilePath(pluginKey, pluginInfo.version);
1974
- fs7.writeFileSync(tgzPath, tgzBuffer);
2364
+ fs8.writeFileSync(tgzPath, tgzBuffer);
1975
2365
  console.log(`[action-plugin] Downloaded to ${tgzPath} (${(tgzBuffer.length / 1024).toFixed(2)} KB)`);
1976
2366
  return {
1977
2367
  tgzPath,
@@ -1981,8 +2371,8 @@ async function downloadPlugin(pluginKey, requestedVersion) {
1981
2371
  }
1982
2372
  function cleanupTempFile(tgzPath) {
1983
2373
  try {
1984
- if (fs7.existsSync(tgzPath)) {
1985
- fs7.unlinkSync(tgzPath);
2374
+ if (fs8.existsSync(tgzPath)) {
2375
+ fs8.unlinkSync(tgzPath);
1986
2376
  }
1987
2377
  } catch {
1988
2378
  }
@@ -2318,7 +2708,7 @@ var actionPluginCommandGroup = {
2318
2708
  };
2319
2709
 
2320
2710
  // src/commands/capability/utils.ts
2321
- import fs8 from "fs";
2711
+ import fs9 from "fs";
2322
2712
  import path7 from "path";
2323
2713
  var CAPABILITIES_DIR = "server/capabilities";
2324
2714
  function getProjectRoot2() {
@@ -2334,23 +2724,23 @@ function getPluginManifestPath(pluginKey) {
2334
2724
  return path7.join(getProjectRoot2(), "node_modules", pluginKey, "manifest.json");
2335
2725
  }
2336
2726
  function capabilitiesDirExists() {
2337
- return fs8.existsSync(getCapabilitiesDir());
2727
+ return fs9.existsSync(getCapabilitiesDir());
2338
2728
  }
2339
2729
  function listCapabilityIds() {
2340
2730
  const dir = getCapabilitiesDir();
2341
- if (!fs8.existsSync(dir)) {
2731
+ if (!fs9.existsSync(dir)) {
2342
2732
  return [];
2343
2733
  }
2344
- const files = fs8.readdirSync(dir);
2734
+ const files = fs9.readdirSync(dir);
2345
2735
  return files.filter((f) => f.endsWith(".json") && f !== "capabilities.json").map((f) => f.replace(/\.json$/, ""));
2346
2736
  }
2347
2737
  function readCapability(id) {
2348
2738
  const filePath = getCapabilityPath(id);
2349
- if (!fs8.existsSync(filePath)) {
2739
+ if (!fs9.existsSync(filePath)) {
2350
2740
  throw new Error(`Capability not found: ${id}`);
2351
2741
  }
2352
2742
  try {
2353
- const content = fs8.readFileSync(filePath, "utf-8");
2743
+ const content = fs9.readFileSync(filePath, "utf-8");
2354
2744
  return JSON.parse(content);
2355
2745
  } catch (error) {
2356
2746
  if (error instanceof SyntaxError) {
@@ -2377,11 +2767,11 @@ function readAllCapabilities() {
2377
2767
  }
2378
2768
  function readPluginManifest(pluginKey) {
2379
2769
  const manifestPath = getPluginManifestPath(pluginKey);
2380
- if (!fs8.existsSync(manifestPath)) {
2770
+ if (!fs9.existsSync(manifestPath)) {
2381
2771
  throw new Error(`Plugin not installed: ${pluginKey} (manifest.json not found)`);
2382
2772
  }
2383
2773
  try {
2384
- const content = fs8.readFileSync(manifestPath, "utf-8");
2774
+ const content = fs9.readFileSync(manifestPath, "utf-8");
2385
2775
  return JSON.parse(content);
2386
2776
  } catch (error) {
2387
2777
  if (error instanceof SyntaxError) {
@@ -2555,7 +2945,7 @@ var capabilityCommandGroup = {
2555
2945
  };
2556
2946
 
2557
2947
  // src/commands/migration/version-manager.ts
2558
- import fs9 from "fs";
2948
+ import fs10 from "fs";
2559
2949
  import path8 from "path";
2560
2950
  var PACKAGE_JSON = "package.json";
2561
2951
  var VERSION_FIELD = "migrationVersion";
@@ -2564,25 +2954,25 @@ function getPackageJsonPath2() {
2564
2954
  }
2565
2955
  function getCurrentVersion() {
2566
2956
  const pkgPath = getPackageJsonPath2();
2567
- if (!fs9.existsSync(pkgPath)) {
2957
+ if (!fs10.existsSync(pkgPath)) {
2568
2958
  throw new Error("package.json not found");
2569
2959
  }
2570
- const pkg2 = JSON.parse(fs9.readFileSync(pkgPath, "utf-8"));
2960
+ const pkg2 = JSON.parse(fs10.readFileSync(pkgPath, "utf-8"));
2571
2961
  return pkg2[VERSION_FIELD] ?? 0;
2572
2962
  }
2573
2963
  function setCurrentVersion(version) {
2574
2964
  const pkgPath = getPackageJsonPath2();
2575
- const pkg2 = JSON.parse(fs9.readFileSync(pkgPath, "utf-8"));
2965
+ const pkg2 = JSON.parse(fs10.readFileSync(pkgPath, "utf-8"));
2576
2966
  pkg2[VERSION_FIELD] = version;
2577
- fs9.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
2967
+ fs10.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
2578
2968
  }
2579
2969
 
2580
2970
  // src/commands/migration/versions/v001_capability/json-migrator/detector.ts
2581
- import fs11 from "fs";
2971
+ import fs12 from "fs";
2582
2972
  import path10 from "path";
2583
2973
 
2584
2974
  // src/commands/migration/versions/v001_capability/utils.ts
2585
- import fs10 from "fs";
2975
+ import fs11 from "fs";
2586
2976
  import path9 from "path";
2587
2977
  var CAPABILITIES_DIR2 = "server/capabilities";
2588
2978
  function getProjectRoot3() {
@@ -2599,14 +2989,14 @@ function getPluginManifestPath2(pluginKey) {
2599
2989
  function detectJsonMigration() {
2600
2990
  const capabilitiesDir = getCapabilitiesDir2();
2601
2991
  const oldFilePath = path10.join(capabilitiesDir, "capabilities.json");
2602
- if (!fs11.existsSync(oldFilePath)) {
2992
+ if (!fs12.existsSync(oldFilePath)) {
2603
2993
  return {
2604
2994
  needsMigration: false,
2605
2995
  reason: "capabilities.json not found"
2606
2996
  };
2607
2997
  }
2608
2998
  try {
2609
- const content = fs11.readFileSync(oldFilePath, "utf-8");
2999
+ const content = fs12.readFileSync(oldFilePath, "utf-8");
2610
3000
  const parsed = JSON.parse(content);
2611
3001
  if (!Array.isArray(parsed)) {
2612
3002
  return {
@@ -2657,7 +3047,7 @@ async function check(options) {
2657
3047
  }
2658
3048
 
2659
3049
  // src/commands/migration/versions/v001_capability/json-migrator/index.ts
2660
- import fs12 from "fs";
3050
+ import fs13 from "fs";
2661
3051
  import path11 from "path";
2662
3052
 
2663
3053
  // src/commands/migration/versions/v001_capability/mapping.ts
@@ -2888,10 +3278,10 @@ function transformCapabilities(oldCapabilities) {
2888
3278
  // src/commands/migration/versions/v001_capability/json-migrator/index.ts
2889
3279
  function loadExistingCapabilities() {
2890
3280
  const capabilitiesDir = getCapabilitiesDir2();
2891
- if (!fs12.existsSync(capabilitiesDir)) {
3281
+ if (!fs13.existsSync(capabilitiesDir)) {
2892
3282
  return [];
2893
3283
  }
2894
- const files = fs12.readdirSync(capabilitiesDir);
3284
+ const files = fs13.readdirSync(capabilitiesDir);
2895
3285
  const capabilities = [];
2896
3286
  for (const file of files) {
2897
3287
  if (file === "capabilities.json" || !file.endsWith(".json")) {
@@ -2899,7 +3289,7 @@ function loadExistingCapabilities() {
2899
3289
  }
2900
3290
  try {
2901
3291
  const filePath = path11.join(capabilitiesDir, file);
2902
- const content = fs12.readFileSync(filePath, "utf-8");
3292
+ const content = fs13.readFileSync(filePath, "utf-8");
2903
3293
  const capability = JSON.parse(content);
2904
3294
  if (capability.id && capability.pluginKey) {
2905
3295
  capabilities.push(capability);
@@ -2959,7 +3349,7 @@ async function migrateJsonFiles(options) {
2959
3349
  for (const cap of newCapabilities) {
2960
3350
  const filePath = path11.join(capabilitiesDir, `${cap.id}.json`);
2961
3351
  const content = JSON.stringify(cap, null, 2);
2962
- fs12.writeFileSync(filePath, content, "utf-8");
3352
+ fs13.writeFileSync(filePath, content, "utf-8");
2963
3353
  console.log(` \u2713 Created: ${cap.id}.json`);
2964
3354
  }
2965
3355
  return {
@@ -2971,11 +3361,11 @@ async function migrateJsonFiles(options) {
2971
3361
  }
2972
3362
 
2973
3363
  // src/commands/migration/versions/v001_capability/plugin-installer/detector.ts
2974
- import fs13 from "fs";
3364
+ import fs14 from "fs";
2975
3365
  function isPluginInstalled2(pluginKey) {
2976
3366
  const actionPlugins = readActionPlugins();
2977
3367
  const manifestPath = getPluginManifestPath2(pluginKey);
2978
- return fs13.existsSync(manifestPath) && !!actionPlugins[pluginKey];
3368
+ return fs14.existsSync(manifestPath) && !!actionPlugins[pluginKey];
2979
3369
  }
2980
3370
  function detectPluginsToInstall(capabilities) {
2981
3371
  const pluginKeys = /* @__PURE__ */ new Set();
@@ -3052,10 +3442,10 @@ async function installPlugins(capabilities, options) {
3052
3442
 
3053
3443
  // src/commands/migration/versions/v001_capability/code-migrator/index.ts
3054
3444
  import path13 from "path";
3055
- import { Project as Project2 } from "ts-morph";
3445
+ import { Project as Project3 } from "ts-morph";
3056
3446
 
3057
3447
  // src/commands/migration/versions/v001_capability/code-migrator/scanner.ts
3058
- import fs14 from "fs";
3448
+ import fs15 from "fs";
3059
3449
  import path12 from "path";
3060
3450
  var EXCLUDED_DIRS = [
3061
3451
  "node_modules",
@@ -3071,7 +3461,7 @@ var EXCLUDED_PATTERNS = [
3071
3461
  /\.d\.ts$/
3072
3462
  ];
3073
3463
  function scanDirectory(dir, files = []) {
3074
- const entries = fs14.readdirSync(dir, { withFileTypes: true });
3464
+ const entries = fs15.readdirSync(dir, { withFileTypes: true });
3075
3465
  for (const entry of entries) {
3076
3466
  const fullPath = path12.join(dir, entry.name);
3077
3467
  if (entry.isDirectory()) {
@@ -3090,13 +3480,13 @@ function scanDirectory(dir, files = []) {
3090
3480
  }
3091
3481
  function scanServerFiles() {
3092
3482
  const serverDir = path12.join(getProjectRoot3(), "server");
3093
- if (!fs14.existsSync(serverDir)) {
3483
+ if (!fs15.existsSync(serverDir)) {
3094
3484
  return [];
3095
3485
  }
3096
3486
  return scanDirectory(serverDir);
3097
3487
  }
3098
3488
  function hasCapabilityImport(filePath) {
3099
- const content = fs14.readFileSync(filePath, "utf-8");
3489
+ const content = fs15.readFileSync(filePath, "utf-8");
3100
3490
  return /import\s+.*from\s+['"][^'"]*capabilities[^'"]*['"]/.test(content);
3101
3491
  }
3102
3492
  function scanFilesToMigrate() {
@@ -3160,17 +3550,17 @@ function analyzeImports(sourceFile) {
3160
3550
  }
3161
3551
 
3162
3552
  // src/commands/migration/versions/v001_capability/code-migrator/analyzers/call-site-analyzer.ts
3163
- import { SyntaxKind } from "ts-morph";
3553
+ import { SyntaxKind as SyntaxKind6 } from "ts-morph";
3164
3554
  function analyzeCallSites(sourceFile, imports) {
3165
3555
  const callSites = [];
3166
3556
  const importMap = /* @__PURE__ */ new Map();
3167
3557
  for (const imp of imports) {
3168
3558
  importMap.set(imp.importName, imp.capabilityId);
3169
3559
  }
3170
- const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);
3560
+ const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind6.CallExpression);
3171
3561
  for (const callExpr of callExpressions) {
3172
3562
  const expression = callExpr.getExpression();
3173
- if (expression.getKind() === SyntaxKind.Identifier) {
3563
+ if (expression.getKind() === SyntaxKind6.Identifier) {
3174
3564
  const functionName = expression.getText();
3175
3565
  const capabilityId = importMap.get(functionName);
3176
3566
  if (capabilityId) {
@@ -3183,11 +3573,11 @@ function analyzeCallSites(sourceFile, imports) {
3183
3573
  text: callExpr.getText()
3184
3574
  });
3185
3575
  }
3186
- } else if (expression.getKind() === SyntaxKind.PropertyAccessExpression) {
3187
- const propAccess = expression.asKind(SyntaxKind.PropertyAccessExpression);
3576
+ } else if (expression.getKind() === SyntaxKind6.PropertyAccessExpression) {
3577
+ const propAccess = expression.asKind(SyntaxKind6.PropertyAccessExpression);
3188
3578
  if (propAccess) {
3189
3579
  const objectExpr = propAccess.getExpression();
3190
- if (objectExpr.getKind() === SyntaxKind.Identifier) {
3580
+ if (objectExpr.getKind() === SyntaxKind6.Identifier) {
3191
3581
  const objectName = objectExpr.getText();
3192
3582
  const capabilityId = importMap.get(objectName);
3193
3583
  if (capabilityId) {
@@ -3416,7 +3806,7 @@ function addInjection(sourceFile) {
3416
3806
  }
3417
3807
 
3418
3808
  // src/commands/migration/versions/v001_capability/code-migrator/transformers/call-site-transformer.ts
3419
- import { SyntaxKind as SyntaxKind2 } from "ts-morph";
3809
+ import { SyntaxKind as SyntaxKind7 } from "ts-morph";
3420
3810
  var DEFAULT_ACTION_NAME = "run";
3421
3811
  function generateNewCallText(capabilityId, actionName, args) {
3422
3812
  const argsText = args.trim() || "{}";
@@ -3431,19 +3821,19 @@ function transformCallSites(sourceFile, imports) {
3431
3821
  });
3432
3822
  }
3433
3823
  let replacedCount = 0;
3434
- const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind2.CallExpression);
3824
+ const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind7.CallExpression);
3435
3825
  const sortedCalls = [...callExpressions].sort((a, b) => b.getStart() - a.getStart());
3436
3826
  for (const callExpr of sortedCalls) {
3437
3827
  const expression = callExpr.getExpression();
3438
3828
  let importInfo;
3439
- if (expression.getKind() === SyntaxKind2.Identifier) {
3829
+ if (expression.getKind() === SyntaxKind7.Identifier) {
3440
3830
  const functionName = expression.getText();
3441
3831
  importInfo = importMap.get(functionName);
3442
- } else if (expression.getKind() === SyntaxKind2.PropertyAccessExpression) {
3443
- const propAccess = expression.asKind(SyntaxKind2.PropertyAccessExpression);
3832
+ } else if (expression.getKind() === SyntaxKind7.PropertyAccessExpression) {
3833
+ const propAccess = expression.asKind(SyntaxKind7.PropertyAccessExpression);
3444
3834
  if (propAccess) {
3445
3835
  const objectExpr = propAccess.getExpression();
3446
- if (objectExpr.getKind() === SyntaxKind2.Identifier) {
3836
+ if (objectExpr.getKind() === SyntaxKind7.Identifier) {
3447
3837
  const objectName = objectExpr.getText();
3448
3838
  importInfo = importMap.get(objectName);
3449
3839
  }
@@ -3544,7 +3934,7 @@ async function migrateCode(options, capabilities) {
3544
3934
  console.log(" No files need code migration.\n");
3545
3935
  return result;
3546
3936
  }
3547
- const project = new Project2({
3937
+ const project = new Project3({
3548
3938
  skipAddingFilesFromTsConfig: true,
3549
3939
  compilerOptions: {
3550
3940
  allowJs: true
@@ -3587,17 +3977,17 @@ function getSuggestion(analysis) {
3587
3977
  }
3588
3978
 
3589
3979
  // src/commands/migration/versions/v001_capability/cleanup.ts
3590
- import fs15 from "fs";
3980
+ import fs16 from "fs";
3591
3981
  import path14 from "path";
3592
3982
  function cleanupOldFiles(capabilities, dryRun) {
3593
3983
  const deletedFiles = [];
3594
3984
  const errors = [];
3595
3985
  const capabilitiesDir = getCapabilitiesDir2();
3596
3986
  const oldJsonPath = path14.join(capabilitiesDir, "capabilities.json");
3597
- if (fs15.existsSync(oldJsonPath)) {
3987
+ if (fs16.existsSync(oldJsonPath)) {
3598
3988
  try {
3599
3989
  if (!dryRun) {
3600
- fs15.unlinkSync(oldJsonPath);
3990
+ fs16.unlinkSync(oldJsonPath);
3601
3991
  }
3602
3992
  deletedFiles.push("capabilities.json");
3603
3993
  } catch (error) {
@@ -3606,10 +3996,10 @@ function cleanupOldFiles(capabilities, dryRun) {
3606
3996
  }
3607
3997
  for (const cap of capabilities) {
3608
3998
  const tsFilePath = path14.join(capabilitiesDir, `${cap.id}.ts`);
3609
- if (fs15.existsSync(tsFilePath)) {
3999
+ if (fs16.existsSync(tsFilePath)) {
3610
4000
  try {
3611
4001
  if (!dryRun) {
3612
- fs15.unlinkSync(tsFilePath);
4002
+ fs16.unlinkSync(tsFilePath);
3613
4003
  }
3614
4004
  deletedFiles.push(`${cap.id}.ts`);
3615
4005
  } catch (error) {
@@ -3625,7 +4015,7 @@ function cleanupOldFiles(capabilities, dryRun) {
3625
4015
  }
3626
4016
 
3627
4017
  // src/commands/migration/versions/v001_capability/report-generator.ts
3628
- import fs16 from "fs";
4018
+ import fs17 from "fs";
3629
4019
  import path15 from "path";
3630
4020
  var REPORT_FILE = "capability-migration-report.md";
3631
4021
  function printSummary(result) {
@@ -3789,15 +4179,15 @@ async function generateReport(result) {
3789
4179
  }
3790
4180
  lines.push("");
3791
4181
  const logDir = process.env.LOG_DIR || "logs";
3792
- if (!fs16.existsSync(logDir)) {
4182
+ if (!fs17.existsSync(logDir)) {
3793
4183
  return;
3794
4184
  }
3795
4185
  const reportDir = path15.join(logDir, "migration");
3796
- if (!fs16.existsSync(reportDir)) {
3797
- fs16.mkdirSync(reportDir, { recursive: true });
4186
+ if (!fs17.existsSync(reportDir)) {
4187
+ fs17.mkdirSync(reportDir, { recursive: true });
3798
4188
  }
3799
4189
  const reportPath = path15.join(reportDir, REPORT_FILE);
3800
- fs16.writeFileSync(reportPath, lines.join("\n"), "utf-8");
4190
+ fs17.writeFileSync(reportPath, lines.join("\n"), "utf-8");
3801
4191
  console.log(`\u{1F4C4} Report generated: ${reportPath}`);
3802
4192
  }
3803
4193
 
@@ -4332,7 +4722,7 @@ var migrationCommand = {
4332
4722
  import path16 from "path";
4333
4723
 
4334
4724
  // src/commands/read-logs/std-utils.ts
4335
- import fs17 from "fs";
4725
+ import fs18 from "fs";
4336
4726
  function formatStdPrefixTime(localTime) {
4337
4727
  const match = localTime.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
4338
4728
  if (!match) return localTime;
@@ -4362,11 +4752,11 @@ function stripPrefixFromStdLine(line) {
4362
4752
  return `[${time}] ${content}`;
4363
4753
  }
4364
4754
  function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarker) {
4365
- const stat = fs17.statSync(filePath);
4755
+ const stat = fs18.statSync(filePath);
4366
4756
  if (stat.size === 0) {
4367
4757
  return { lines: [], markerFound: false, totalLinesCount: 0 };
4368
4758
  }
4369
- const fd = fs17.openSync(filePath, "r");
4759
+ const fd = fs18.openSync(filePath, "r");
4370
4760
  const chunkSize = 64 * 1024;
4371
4761
  let position = stat.size;
4372
4762
  let remainder = "";
@@ -4380,7 +4770,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
4380
4770
  const length = Math.min(chunkSize, position);
4381
4771
  position -= length;
4382
4772
  const buffer = Buffer.alloc(length);
4383
- fs17.readSync(fd, buffer, 0, length, position);
4773
+ fs18.readSync(fd, buffer, 0, length, position);
4384
4774
  let chunk = buffer.toString("utf8");
4385
4775
  if (remainder) {
4386
4776
  chunk += remainder;
@@ -4422,7 +4812,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
4422
4812
  }
4423
4813
  }
4424
4814
  } finally {
4425
- fs17.closeSync(fd);
4815
+ fs18.closeSync(fd);
4426
4816
  }
4427
4817
  return { lines: collected.reverse(), markerFound, totalLinesCount };
4428
4818
  }
@@ -4443,21 +4833,21 @@ function readServerStdSegment(filePath, maxLines, offset) {
4443
4833
  }
4444
4834
 
4445
4835
  // src/commands/read-logs/tail.ts
4446
- import fs18 from "fs";
4836
+ import fs19 from "fs";
4447
4837
  function fileExists(filePath) {
4448
4838
  try {
4449
- fs18.accessSync(filePath, fs18.constants.F_OK | fs18.constants.R_OK);
4839
+ fs19.accessSync(filePath, fs19.constants.F_OK | fs19.constants.R_OK);
4450
4840
  return true;
4451
4841
  } catch {
4452
4842
  return false;
4453
4843
  }
4454
4844
  }
4455
4845
  function readFileTailLines(filePath, maxLines) {
4456
- const stat = fs18.statSync(filePath);
4846
+ const stat = fs19.statSync(filePath);
4457
4847
  if (stat.size === 0) {
4458
4848
  return [];
4459
4849
  }
4460
- const fd = fs18.openSync(filePath, "r");
4850
+ const fd = fs19.openSync(filePath, "r");
4461
4851
  const chunkSize = 64 * 1024;
4462
4852
  const chunks = [];
4463
4853
  let position = stat.size;
@@ -4467,13 +4857,13 @@ function readFileTailLines(filePath, maxLines) {
4467
4857
  const length = Math.min(chunkSize, position);
4468
4858
  position -= length;
4469
4859
  const buffer = Buffer.alloc(length);
4470
- fs18.readSync(fd, buffer, 0, length, position);
4860
+ fs19.readSync(fd, buffer, 0, length, position);
4471
4861
  chunks.unshift(buffer.toString("utf8"));
4472
4862
  const chunkLines = buffer.toString("utf8").split("\n").length - 1;
4473
4863
  collectedLines += chunkLines;
4474
4864
  }
4475
4865
  } finally {
4476
- fs18.closeSync(fd);
4866
+ fs19.closeSync(fd);
4477
4867
  }
4478
4868
  const content = chunks.join("");
4479
4869
  const allLines = content.split("\n");
@@ -4489,11 +4879,11 @@ function readFileTailLines(filePath, maxLines) {
4489
4879
  return allLines.slice(allLines.length - maxLines);
4490
4880
  }
4491
4881
  function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
4492
- const stat = fs18.statSync(filePath);
4882
+ const stat = fs19.statSync(filePath);
4493
4883
  if (stat.size === 0) {
4494
4884
  return { lines: [], totalLinesCount: 0 };
4495
4885
  }
4496
- const fd = fs18.openSync(filePath, "r");
4886
+ const fd = fs19.openSync(filePath, "r");
4497
4887
  const chunkSize = 64 * 1024;
4498
4888
  let position = stat.size;
4499
4889
  let remainder = "";
@@ -4505,7 +4895,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
4505
4895
  const length = Math.min(chunkSize, position);
4506
4896
  position -= length;
4507
4897
  const buffer = Buffer.alloc(length);
4508
- fs18.readSync(fd, buffer, 0, length, position);
4898
+ fs19.readSync(fd, buffer, 0, length, position);
4509
4899
  let chunk = buffer.toString("utf8");
4510
4900
  if (remainder) {
4511
4901
  chunk += remainder;
@@ -4536,7 +4926,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
4536
4926
  }
4537
4927
  }
4538
4928
  } finally {
4539
- fs18.closeSync(fd);
4929
+ fs19.closeSync(fd);
4540
4930
  }
4541
4931
  return { lines: collected.reverse(), totalLinesCount };
4542
4932
  }
@@ -4638,7 +5028,7 @@ function extractClientStdSegment(lines, maxLines, offset) {
4638
5028
  }
4639
5029
 
4640
5030
  // src/commands/read-logs/json-lines.ts
4641
- import fs19 from "fs";
5031
+ import fs20 from "fs";
4642
5032
  function normalizePid(value) {
4643
5033
  if (typeof value === "number") {
4644
5034
  return String(value);
@@ -4689,11 +5079,11 @@ function buildWantedLevelSet(levels) {
4689
5079
  return set.size > 0 ? set : null;
4690
5080
  }
4691
5081
  function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
4692
- const stat = fs19.statSync(filePath);
5082
+ const stat = fs20.statSync(filePath);
4693
5083
  if (stat.size === 0) {
4694
5084
  return { lines: [], totalLinesCount: 0 };
4695
5085
  }
4696
- const fd = fs19.openSync(filePath, "r");
5086
+ const fd = fs20.openSync(filePath, "r");
4697
5087
  const chunkSize = 64 * 1024;
4698
5088
  let position = stat.size;
4699
5089
  let remainder = "";
@@ -4708,7 +5098,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
4708
5098
  const length = Math.min(chunkSize, position);
4709
5099
  position -= length;
4710
5100
  const buffer = Buffer.alloc(length);
4711
- fs19.readSync(fd, buffer, 0, length, position);
5101
+ fs20.readSync(fd, buffer, 0, length, position);
4712
5102
  let chunk = buffer.toString("utf8");
4713
5103
  if (remainder) {
4714
5104
  chunk += remainder;
@@ -4770,7 +5160,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
4770
5160
  }
4771
5161
  }
4772
5162
  } finally {
4773
- fs19.closeSync(fd);
5163
+ fs20.closeSync(fd);
4774
5164
  }
4775
5165
  return { lines: collected.reverse(), totalLinesCount };
4776
5166
  }
@@ -4813,11 +5203,11 @@ function extractTraceId(obj) {
4813
5203
  function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
4814
5204
  const wanted = traceId.trim();
4815
5205
  if (!wanted) return { lines: [], totalLinesCount: 0 };
4816
- const stat = fs19.statSync(filePath);
5206
+ const stat = fs20.statSync(filePath);
4817
5207
  if (stat.size === 0) {
4818
5208
  return { lines: [], totalLinesCount: 0 };
4819
5209
  }
4820
- const fd = fs19.openSync(filePath, "r");
5210
+ const fd = fs20.openSync(filePath, "r");
4821
5211
  const chunkSize = 64 * 1024;
4822
5212
  let position = stat.size;
4823
5213
  let remainder = "";
@@ -4830,7 +5220,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
4830
5220
  const length = Math.min(chunkSize, position);
4831
5221
  position -= length;
4832
5222
  const buffer = Buffer.alloc(length);
4833
- fs19.readSync(fd, buffer, 0, length, position);
5223
+ fs20.readSync(fd, buffer, 0, length, position);
4834
5224
  let chunk = buffer.toString("utf8");
4835
5225
  if (remainder) {
4836
5226
  chunk += remainder;
@@ -4883,7 +5273,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
4883
5273
  }
4884
5274
  }
4885
5275
  } finally {
4886
- fs19.closeSync(fd);
5276
+ fs20.closeSync(fd);
4887
5277
  }
4888
5278
  return { lines: collected.reverse(), totalLinesCount };
4889
5279
  }
@@ -4892,11 +5282,11 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
4892
5282
  if (!wantedLevelSet) {
4893
5283
  return { lines: [], totalLinesCount: 0 };
4894
5284
  }
4895
- const stat = fs19.statSync(filePath);
5285
+ const stat = fs20.statSync(filePath);
4896
5286
  if (stat.size === 0) {
4897
5287
  return { lines: [], totalLinesCount: 0 };
4898
5288
  }
4899
- const fd = fs19.openSync(filePath, "r");
5289
+ const fd = fs20.openSync(filePath, "r");
4900
5290
  const chunkSize = 64 * 1024;
4901
5291
  let position = stat.size;
4902
5292
  let remainder = "";
@@ -4908,7 +5298,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
4908
5298
  const length = Math.min(chunkSize, position);
4909
5299
  position -= length;
4910
5300
  const buffer = Buffer.alloc(length);
4911
- fs19.readSync(fd, buffer, 0, length, position);
5301
+ fs20.readSync(fd, buffer, 0, length, position);
4912
5302
  let chunk = buffer.toString("utf8");
4913
5303
  if (remainder) {
4914
5304
  chunk += remainder;
@@ -4955,7 +5345,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
4955
5345
  }
4956
5346
  }
4957
5347
  } finally {
4958
- fs19.closeSync(fd);
5348
+ fs20.closeSync(fd);
4959
5349
  }
4960
5350
  return { lines: collected.reverse(), totalLinesCount };
4961
5351
  }
@@ -5176,11 +5566,11 @@ var commands = [
5176
5566
 
5177
5567
  // src/index.ts
5178
5568
  var envPath = path17.join(process.cwd(), ".env");
5179
- if (fs20.existsSync(envPath)) {
5569
+ if (fs21.existsSync(envPath)) {
5180
5570
  dotenvConfig({ path: envPath });
5181
5571
  }
5182
5572
  var __dirname = path17.dirname(fileURLToPath4(import.meta.url));
5183
- var pkg = JSON.parse(fs20.readFileSync(path17.join(__dirname, "../package.json"), "utf-8"));
5573
+ var pkg = JSON.parse(fs21.readFileSync(path17.join(__dirname, "../package.json"), "utf-8"));
5184
5574
  var cli = new FullstackCLI(pkg.version);
5185
5575
  cli.useAll(commands);
5186
5576
  cli.run();