relq 1.0.35 → 1.0.37
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.
|
@@ -255,10 +255,10 @@ async function pullCommand(context) {
|
|
|
255
255
|
{ id: 'extensions', label: 'extensions', status: 'pending', count: 0 },
|
|
256
256
|
...(includeFunctions ? [{ id: 'functions', label: 'functions', status: 'pending', count: 0 }] : []),
|
|
257
257
|
...(includeTriggers ? [{ id: 'triggers', label: 'triggers', status: 'pending', count: 0 }] : []),
|
|
258
|
-
{ id: 'types', label: 'types', status: 'pending', count: 0 },
|
|
259
258
|
{ id: 'collations', label: 'collations', status: 'pending', count: 0 },
|
|
260
259
|
{ id: 'foreign_servers', label: 'foreign servers', status: 'pending', count: 0 },
|
|
261
260
|
{ id: 'foreign_tables', label: 'foreign tables', status: 'pending', count: 0 },
|
|
261
|
+
{ id: 'types', label: 'types', status: 'pending', count: 0 },
|
|
262
262
|
];
|
|
263
263
|
progress.setItems(progressItems);
|
|
264
264
|
progress.start();
|
|
@@ -269,7 +269,7 @@ async function pullCommand(context) {
|
|
|
269
269
|
progress.updateItem(update.step, { status: update.status, count: update.count });
|
|
270
270
|
},
|
|
271
271
|
});
|
|
272
|
-
progress.updateItem('types', { status: '
|
|
272
|
+
progress.updateItem('types', { status: 'fetching', count: 0 });
|
|
273
273
|
const typesForProgress = await (0, types_manager_1.getTypesFromDb)(connection);
|
|
274
274
|
progress.updateItem('types', { status: 'done', count: typesForProgress.length });
|
|
275
275
|
progress.complete();
|
|
@@ -567,6 +567,38 @@ async function pullCommand(context) {
|
|
|
567
567
|
console.log(`Synced ${typesResult.typesCount} type(s) from remote`);
|
|
568
568
|
hasSynced = true;
|
|
569
569
|
}
|
|
570
|
+
if (typesForProgress.length > 0 && fs.existsSync(schemaPath)) {
|
|
571
|
+
const schemaContent = fs.readFileSync(schemaPath, 'utf-8');
|
|
572
|
+
const schemaBaseName = path.basename(schemaPath, '.ts');
|
|
573
|
+
const typesImportPattern = new RegExp(`from\\s+['"]\\./${schemaBaseName}\\.types['"]`);
|
|
574
|
+
const hasTypesImport = typesImportPattern.test(schemaContent);
|
|
575
|
+
const typesWithUsages = typesForProgress.filter(t => t.usages && t.usages.length > 0);
|
|
576
|
+
if (typesWithUsages.length > 0 && !hasTypesImport) {
|
|
577
|
+
spinner.start(`Applying ${typesWithUsages.length} type(s) to schema...`);
|
|
578
|
+
const columnTypeMap = {};
|
|
579
|
+
for (const typeDef of typesForProgress) {
|
|
580
|
+
if (typeDef.usages) {
|
|
581
|
+
for (const usage of typeDef.usages) {
|
|
582
|
+
columnTypeMap[usage] = typeDef.name;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
const parsedSchema = await (0, ast_transformer_1.introspectedToParsedSchema)(dbSchema);
|
|
587
|
+
(0, ast_codegen_1.assignTrackingIds)(parsedSchema);
|
|
588
|
+
const typesImportPath = `./${schemaBaseName}.types`;
|
|
589
|
+
const typescript = (0, ast_codegen_1.generateTypeScriptFromAST)(parsedSchema, {
|
|
590
|
+
camelCase: config.generate?.camelCase ?? true,
|
|
591
|
+
importPath: 'relq/schema-builder',
|
|
592
|
+
includeFunctions: false,
|
|
593
|
+
includeTriggers: false,
|
|
594
|
+
columnTypeMap,
|
|
595
|
+
typesImportPath,
|
|
596
|
+
});
|
|
597
|
+
fs.writeFileSync(schemaPath, typescript, 'utf-8');
|
|
598
|
+
spinner.succeed(`Updated ${cli_utils_1.colors.cyan(schemaPath)} with type annotations`);
|
|
599
|
+
hasSynced = true;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
570
602
|
if (!hasSynced) {
|
|
571
603
|
console.log('Already up to date with remote');
|
|
572
604
|
}
|
|
@@ -694,12 +726,15 @@ async function pullCommand(context) {
|
|
|
694
726
|
}
|
|
695
727
|
}
|
|
696
728
|
}
|
|
729
|
+
const schemaBaseName = path.basename(schemaPath, '.ts');
|
|
730
|
+
const typesImportPath = `./${schemaBaseName}.types`;
|
|
697
731
|
const typescript = (0, ast_codegen_1.generateTypeScriptFromAST)(parsedSchema, {
|
|
698
732
|
camelCase: config.generate?.camelCase ?? true,
|
|
699
733
|
importPath: 'relq/schema-builder',
|
|
700
734
|
includeFunctions: false,
|
|
701
735
|
includeTriggers: false,
|
|
702
736
|
columnTypeMap,
|
|
737
|
+
typesImportPath,
|
|
703
738
|
});
|
|
704
739
|
spinner.succeed('Generated TypeScript schema');
|
|
705
740
|
const schemaDir = path.dirname(schemaPath);
|
|
@@ -724,7 +724,7 @@ function generateTriggerCode(trigger, useCamelCase, functionNames) {
|
|
|
724
724
|
return parts.join('\n');
|
|
725
725
|
}
|
|
726
726
|
function generateTypeScriptFromAST(schema, options = {}) {
|
|
727
|
-
const { camelCase = true, importPath = 'relq/schema-builder', includeEnums = true, includeDomains = true, includeTables = true, includeFunctions = true, includeTriggers = true, columnTypeMap = {}, } = options;
|
|
727
|
+
const { camelCase = true, importPath = 'relq/schema-builder', includeEnums = true, includeDomains = true, includeTables = true, includeFunctions = true, includeTriggers = true, columnTypeMap = {}, typesImportPath, } = options;
|
|
728
728
|
const parts = [];
|
|
729
729
|
parts.push('/**');
|
|
730
730
|
parts.push(' * Auto-generated by Relq CLI (AST-based)');
|
|
@@ -816,6 +816,11 @@ function generateTypeScriptFromAST(schema, options = {}) {
|
|
|
816
816
|
parts.push(` ${imports.join(',\n ')},`);
|
|
817
817
|
parts.push(` type RelqDatabaseSchema,`);
|
|
818
818
|
parts.push(`} from '${importPath}';`);
|
|
819
|
+
const usedTypeNames = new Set(Object.values(columnTypeMap));
|
|
820
|
+
if (usedTypeNames.size > 0 && typesImportPath) {
|
|
821
|
+
const typeNames = Array.from(usedTypeNames).sort();
|
|
822
|
+
parts.push(`import type { ${typeNames.join(', ')} } from '${typesImportPath}';`);
|
|
823
|
+
}
|
|
819
824
|
parts.push('');
|
|
820
825
|
if (needsPgExtensions) {
|
|
821
826
|
parts.push('// =============================================================================');
|
|
@@ -219,10 +219,10 @@ export async function pullCommand(context) {
|
|
|
219
219
|
{ id: 'extensions', label: 'extensions', status: 'pending', count: 0 },
|
|
220
220
|
...(includeFunctions ? [{ id: 'functions', label: 'functions', status: 'pending', count: 0 }] : []),
|
|
221
221
|
...(includeTriggers ? [{ id: 'triggers', label: 'triggers', status: 'pending', count: 0 }] : []),
|
|
222
|
-
{ id: 'types', label: 'types', status: 'pending', count: 0 },
|
|
223
222
|
{ id: 'collations', label: 'collations', status: 'pending', count: 0 },
|
|
224
223
|
{ id: 'foreign_servers', label: 'foreign servers', status: 'pending', count: 0 },
|
|
225
224
|
{ id: 'foreign_tables', label: 'foreign tables', status: 'pending', count: 0 },
|
|
225
|
+
{ id: 'types', label: 'types', status: 'pending', count: 0 },
|
|
226
226
|
];
|
|
227
227
|
progress.setItems(progressItems);
|
|
228
228
|
progress.start();
|
|
@@ -233,7 +233,7 @@ export async function pullCommand(context) {
|
|
|
233
233
|
progress.updateItem(update.step, { status: update.status, count: update.count });
|
|
234
234
|
},
|
|
235
235
|
});
|
|
236
|
-
progress.updateItem('types', { status: '
|
|
236
|
+
progress.updateItem('types', { status: 'fetching', count: 0 });
|
|
237
237
|
const typesForProgress = await getTypesFromDb(connection);
|
|
238
238
|
progress.updateItem('types', { status: 'done', count: typesForProgress.length });
|
|
239
239
|
progress.complete();
|
|
@@ -531,6 +531,38 @@ export async function pullCommand(context) {
|
|
|
531
531
|
console.log(`Synced ${typesResult.typesCount} type(s) from remote`);
|
|
532
532
|
hasSynced = true;
|
|
533
533
|
}
|
|
534
|
+
if (typesForProgress.length > 0 && fs.existsSync(schemaPath)) {
|
|
535
|
+
const schemaContent = fs.readFileSync(schemaPath, 'utf-8');
|
|
536
|
+
const schemaBaseName = path.basename(schemaPath, '.ts');
|
|
537
|
+
const typesImportPattern = new RegExp(`from\\s+['"]\\./${schemaBaseName}\\.types['"]`);
|
|
538
|
+
const hasTypesImport = typesImportPattern.test(schemaContent);
|
|
539
|
+
const typesWithUsages = typesForProgress.filter(t => t.usages && t.usages.length > 0);
|
|
540
|
+
if (typesWithUsages.length > 0 && !hasTypesImport) {
|
|
541
|
+
spinner.start(`Applying ${typesWithUsages.length} type(s) to schema...`);
|
|
542
|
+
const columnTypeMap = {};
|
|
543
|
+
for (const typeDef of typesForProgress) {
|
|
544
|
+
if (typeDef.usages) {
|
|
545
|
+
for (const usage of typeDef.usages) {
|
|
546
|
+
columnTypeMap[usage] = typeDef.name;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
const parsedSchema = await introspectedToParsedSchema(dbSchema);
|
|
551
|
+
assignTrackingIds(parsedSchema);
|
|
552
|
+
const typesImportPath = `./${schemaBaseName}.types`;
|
|
553
|
+
const typescript = generateTypeScriptFromAST(parsedSchema, {
|
|
554
|
+
camelCase: config.generate?.camelCase ?? true,
|
|
555
|
+
importPath: 'relq/schema-builder',
|
|
556
|
+
includeFunctions: false,
|
|
557
|
+
includeTriggers: false,
|
|
558
|
+
columnTypeMap,
|
|
559
|
+
typesImportPath,
|
|
560
|
+
});
|
|
561
|
+
fs.writeFileSync(schemaPath, typescript, 'utf-8');
|
|
562
|
+
spinner.succeed(`Updated ${colors.cyan(schemaPath)} with type annotations`);
|
|
563
|
+
hasSynced = true;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
534
566
|
if (!hasSynced) {
|
|
535
567
|
console.log('Already up to date with remote');
|
|
536
568
|
}
|
|
@@ -658,12 +690,15 @@ export async function pullCommand(context) {
|
|
|
658
690
|
}
|
|
659
691
|
}
|
|
660
692
|
}
|
|
693
|
+
const schemaBaseName = path.basename(schemaPath, '.ts');
|
|
694
|
+
const typesImportPath = `./${schemaBaseName}.types`;
|
|
661
695
|
const typescript = generateTypeScriptFromAST(parsedSchema, {
|
|
662
696
|
camelCase: config.generate?.camelCase ?? true,
|
|
663
697
|
importPath: 'relq/schema-builder',
|
|
664
698
|
includeFunctions: false,
|
|
665
699
|
includeTriggers: false,
|
|
666
700
|
columnTypeMap,
|
|
701
|
+
typesImportPath,
|
|
667
702
|
});
|
|
668
703
|
spinner.succeed('Generated TypeScript schema');
|
|
669
704
|
const schemaDir = path.dirname(schemaPath);
|
|
@@ -716,7 +716,7 @@ function generateTriggerCode(trigger, useCamelCase, functionNames) {
|
|
|
716
716
|
return parts.join('\n');
|
|
717
717
|
}
|
|
718
718
|
export function generateTypeScriptFromAST(schema, options = {}) {
|
|
719
|
-
const { camelCase = true, importPath = 'relq/schema-builder', includeEnums = true, includeDomains = true, includeTables = true, includeFunctions = true, includeTriggers = true, columnTypeMap = {}, } = options;
|
|
719
|
+
const { camelCase = true, importPath = 'relq/schema-builder', includeEnums = true, includeDomains = true, includeTables = true, includeFunctions = true, includeTriggers = true, columnTypeMap = {}, typesImportPath, } = options;
|
|
720
720
|
const parts = [];
|
|
721
721
|
parts.push('/**');
|
|
722
722
|
parts.push(' * Auto-generated by Relq CLI (AST-based)');
|
|
@@ -808,6 +808,11 @@ export function generateTypeScriptFromAST(schema, options = {}) {
|
|
|
808
808
|
parts.push(` ${imports.join(',\n ')},`);
|
|
809
809
|
parts.push(` type RelqDatabaseSchema,`);
|
|
810
810
|
parts.push(`} from '${importPath}';`);
|
|
811
|
+
const usedTypeNames = new Set(Object.values(columnTypeMap));
|
|
812
|
+
if (usedTypeNames.size > 0 && typesImportPath) {
|
|
813
|
+
const typeNames = Array.from(usedTypeNames).sort();
|
|
814
|
+
parts.push(`import type { ${typeNames.join(', ')} } from '${typesImportPath}';`);
|
|
815
|
+
}
|
|
811
816
|
parts.push('');
|
|
812
817
|
if (needsPgExtensions) {
|
|
813
818
|
parts.push('// =============================================================================');
|