zenstack-kit 0.1.4 → 0.1.5

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.
@@ -0,0 +1,63 @@
1
+ import type { KyselyDialect } from "../../sql/kysely-adapter.js";
2
+ export interface PrismaMigrationOptions {
3
+ /** Migration name */
4
+ name: string;
5
+ /** Path to ZenStack schema file */
6
+ schemaPath: string;
7
+ /** Output directory for migration files */
8
+ outputPath: string;
9
+ /** Database dialect for SQL generation */
10
+ dialect: KyselyDialect;
11
+ /** Table rename mappings */
12
+ renameTables?: Array<{
13
+ from: string;
14
+ to: string;
15
+ }>;
16
+ /** Column rename mappings */
17
+ renameColumns?: Array<{
18
+ table: string;
19
+ from: string;
20
+ to: string;
21
+ }>;
22
+ }
23
+ export interface PrismaMigration {
24
+ /** Migration folder name (timestamp_name) */
25
+ folderName: string;
26
+ /** Full path to migration folder */
27
+ folderPath: string;
28
+ /** SQL content */
29
+ sql: string;
30
+ /** Timestamp */
31
+ timestamp: number;
32
+ }
33
+ export interface CreateInitialMigrationOptions {
34
+ /** Migration name (default: "init") */
35
+ name?: string;
36
+ /** Path to ZenStack schema file */
37
+ schemaPath: string;
38
+ /** Output directory for migration files */
39
+ outputPath: string;
40
+ /** Database dialect for SQL generation */
41
+ dialect: KyselyDialect;
42
+ }
43
+ /**
44
+ * Generate timestamp string for migration folder name
45
+ */
46
+ export declare function generateTimestamp(): string;
47
+ /**
48
+ * Create a Prisma-compatible migration
49
+ */
50
+ export declare function createPrismaMigration(options: PrismaMigrationOptions): Promise<PrismaMigration | null>;
51
+ /**
52
+ * Create an initial migration that creates all tables from scratch.
53
+ * This is used when initializing a project where the database is empty.
54
+ */
55
+ export declare function createInitialMigration(options: CreateInitialMigrationOptions): Promise<PrismaMigration>;
56
+ /**
57
+ * Check if there are schema changes
58
+ */
59
+ export declare function hasPrismaSchemaChanges(options: {
60
+ schemaPath: string;
61
+ outputPath: string;
62
+ }): Promise<boolean>;
63
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/migrations/prisma/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAMjE,MAAM,WAAW,sBAAsB;IACrC,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,OAAO,EAAE,aAAa,CAAC;IACvB,4BAA4B;IAC5B,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,6BAA6B;IAC7B,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC5C,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAU1C;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAiDjC;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,eAAe,CAAC,CAwC1B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBnB"}
@@ -0,0 +1,119 @@
1
+ import * as fs from "fs/promises";
2
+ import * as path from "path";
3
+ import { generateSchemaSnapshot } from "../../schema/snapshot.js";
4
+ import { applyRenameMappings, buildSqlStatements, diffSchemas } from "./diff.js";
5
+ import { appendToMigrationLog, calculateChecksum } from "./log.js";
6
+ import { getSnapshotPaths, readSnapshot, writeSnapshot } from "./snapshot.js";
7
+ /**
8
+ * Generate timestamp string for migration folder name
9
+ */
10
+ export function generateTimestamp() {
11
+ const now = new Date();
12
+ return [
13
+ now.getFullYear(),
14
+ String(now.getMonth() + 1).padStart(2, "0"),
15
+ String(now.getDate()).padStart(2, "0"),
16
+ String(now.getHours()).padStart(2, "0"),
17
+ String(now.getMinutes()).padStart(2, "0"),
18
+ String(now.getSeconds()).padStart(2, "0"),
19
+ ].join("");
20
+ }
21
+ /**
22
+ * Create a Prisma-compatible migration
23
+ */
24
+ export async function createPrismaMigration(options) {
25
+ const currentSchema = await generateSchemaSnapshot(options.schemaPath);
26
+ const { snapshotPath } = getSnapshotPaths(options.outputPath);
27
+ const previousSnapshot = await readSnapshot(snapshotPath);
28
+ const diff = applyRenameMappings(diffSchemas(previousSnapshot?.schema ?? null, currentSchema), options.renameTables, options.renameColumns);
29
+ const { up } = buildSqlStatements(diff, options.dialect);
30
+ if (up.length === 0) {
31
+ return null;
32
+ }
33
+ const timestamp = Date.now();
34
+ const timestampStr = generateTimestamp();
35
+ const safeName = options.name.replace(/[^a-z0-9]/gi, "_").toLowerCase();
36
+ const folderName = `${timestampStr}_${safeName}`;
37
+ const folderPath = path.join(options.outputPath, folderName);
38
+ // Build migration.sql content with comments
39
+ const sqlContent = [
40
+ `-- Migration: ${options.name}`,
41
+ `-- Generated at: ${new Date(timestamp).toISOString()}`,
42
+ "",
43
+ ...up,
44
+ "",
45
+ ].join("\n");
46
+ // Create migration folder and file
47
+ await fs.mkdir(folderPath, { recursive: true });
48
+ await fs.writeFile(path.join(folderPath, "migration.sql"), sqlContent, "utf-8");
49
+ // Update snapshot
50
+ await writeSnapshot(snapshotPath, currentSchema);
51
+ // Append to migration log
52
+ const checksum = calculateChecksum(sqlContent);
53
+ await appendToMigrationLog(options.outputPath, { name: folderName, checksum });
54
+ return {
55
+ folderName,
56
+ folderPath,
57
+ sql: sqlContent,
58
+ timestamp,
59
+ };
60
+ }
61
+ /**
62
+ * Create an initial migration that creates all tables from scratch.
63
+ * This is used when initializing a project where the database is empty.
64
+ */
65
+ export async function createInitialMigration(options) {
66
+ const currentSchema = await generateSchemaSnapshot(options.schemaPath);
67
+ const { snapshotPath } = getSnapshotPaths(options.outputPath);
68
+ // Diff against empty schema to get full creation SQL
69
+ const diff = diffSchemas(null, currentSchema);
70
+ const { up } = buildSqlStatements(diff, options.dialect);
71
+ const timestamp = Date.now();
72
+ const timestampStr = generateTimestamp();
73
+ const safeName = (options.name ?? "init").replace(/[^a-z0-9]/gi, "_").toLowerCase();
74
+ const folderName = `${timestampStr}_${safeName}`;
75
+ const folderPath = path.join(options.outputPath, folderName);
76
+ // Build migration.sql content with comments
77
+ const sqlContent = [
78
+ `-- Migration: ${options.name ?? "init"}`,
79
+ `-- Generated at: ${new Date(timestamp).toISOString()}`,
80
+ "",
81
+ ...up,
82
+ "",
83
+ ].join("\n");
84
+ // Create migration folder and file
85
+ await fs.mkdir(folderPath, { recursive: true });
86
+ await fs.writeFile(path.join(folderPath, "migration.sql"), sqlContent, "utf-8");
87
+ // Update snapshot
88
+ await writeSnapshot(snapshotPath, currentSchema);
89
+ // Append to migration log
90
+ const checksum = calculateChecksum(sqlContent);
91
+ await appendToMigrationLog(options.outputPath, { name: folderName, checksum });
92
+ return {
93
+ folderName,
94
+ folderPath,
95
+ sql: sqlContent,
96
+ timestamp,
97
+ };
98
+ }
99
+ /**
100
+ * Check if there are schema changes
101
+ */
102
+ export async function hasPrismaSchemaChanges(options) {
103
+ const currentSchema = await generateSchemaSnapshot(options.schemaPath);
104
+ const { snapshotPath } = getSnapshotPaths(options.outputPath);
105
+ const previousSnapshot = await readSnapshot(snapshotPath);
106
+ const diff = diffSchemas(previousSnapshot?.schema ?? null, currentSchema);
107
+ return (diff.addedModels.length > 0 ||
108
+ diff.removedModels.length > 0 ||
109
+ diff.addedFields.length > 0 ||
110
+ diff.removedFields.length > 0 ||
111
+ diff.alteredFields.length > 0 ||
112
+ diff.addedUniqueConstraints.length > 0 ||
113
+ diff.removedUniqueConstraints.length > 0 ||
114
+ diff.addedIndexes.length > 0 ||
115
+ diff.removedIndexes.length > 0 ||
116
+ diff.addedForeignKeys.length > 0 ||
117
+ diff.removedForeignKeys.length > 0 ||
118
+ diff.primaryKeyChanges.length > 0);
119
+ }
@@ -0,0 +1,104 @@
1
+ import type { KyselyDialect } from "../../sql/kysely-adapter.js";
2
+ import type { SchemaSnapshot, SchemaTable, SchemaColumn } from "../../schema/snapshot.js";
3
+ export declare function diffSchemas(previous: SchemaSnapshot | null, current: SchemaSnapshot): {
4
+ addedModels: SchemaTable[];
5
+ removedModels: SchemaTable[];
6
+ addedFields: {
7
+ tableName: string;
8
+ column: SchemaColumn;
9
+ }[];
10
+ removedFields: {
11
+ tableName: string;
12
+ column: SchemaColumn;
13
+ }[];
14
+ alteredFields: {
15
+ tableName: string;
16
+ columnName: string;
17
+ previous: SchemaColumn;
18
+ current: SchemaColumn;
19
+ }[];
20
+ addedUniqueConstraints: {
21
+ tableName: string;
22
+ constraint: {
23
+ name: string;
24
+ columns: string[];
25
+ };
26
+ }[];
27
+ removedUniqueConstraints: {
28
+ tableName: string;
29
+ constraint: {
30
+ name: string;
31
+ columns: string[];
32
+ };
33
+ }[];
34
+ addedIndexes: {
35
+ tableName: string;
36
+ index: {
37
+ name: string;
38
+ columns: string[];
39
+ };
40
+ }[];
41
+ removedIndexes: {
42
+ tableName: string;
43
+ index: {
44
+ name: string;
45
+ columns: string[];
46
+ };
47
+ }[];
48
+ addedForeignKeys: {
49
+ tableName: string;
50
+ foreignKey: {
51
+ name: string;
52
+ columns: string[];
53
+ referencedTable: string;
54
+ referencedColumns: string[];
55
+ };
56
+ }[];
57
+ removedForeignKeys: {
58
+ tableName: string;
59
+ foreignKey: {
60
+ name: string;
61
+ columns: string[];
62
+ referencedTable: string;
63
+ referencedColumns: string[];
64
+ };
65
+ }[];
66
+ primaryKeyChanges: {
67
+ tableName: string;
68
+ previous?: {
69
+ name: string;
70
+ columns: string[];
71
+ };
72
+ current?: {
73
+ name: string;
74
+ columns: string[];
75
+ };
76
+ }[];
77
+ renamedTables: Array<{
78
+ from: string;
79
+ to: string;
80
+ }>;
81
+ renamedColumns: Array<{
82
+ tableName: string;
83
+ from: string;
84
+ to: string;
85
+ }>;
86
+ };
87
+ type PrismaDiff = ReturnType<typeof diffSchemas>;
88
+ export declare function applyRenameMappings(diff: PrismaDiff, renameTables?: Array<{
89
+ from: string;
90
+ to: string;
91
+ }>, renameColumns?: Array<{
92
+ table: string;
93
+ from: string;
94
+ to: string;
95
+ }>): PrismaDiff;
96
+ /**
97
+ * Build SQL statements from diff
98
+ */
99
+ export declare function buildSqlStatements(diff: ReturnType<typeof diffSchemas>, dialect: KyselyDialect): {
100
+ up: string[];
101
+ down: string[];
102
+ };
103
+ export {};
104
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/migrations/prisma/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAyK1F,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,EAAE,OAAO,EAAE,cAAc;;;;mBAsB5C,MAAM;gBAAU,YAAY;;;mBAC1B,MAAM;gBAAU,YAAY;;;mBAEvD,MAAM;oBACL,MAAM;kBACR,YAAY;iBACb,YAAY;;;mBAGV,MAAM;oBACL;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAGpC,MAAM;oBACL;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAGpC,MAAM;eACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAG/B,MAAM;eACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAG/B,MAAM;oBACL;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC;YACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;SAC7B;;;mBAGU,MAAM;oBACL;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC;YACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;SAC7B;;;mBAGU,MAAM;mBACN;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;kBACpC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;mBAiCxB,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;oBAClC,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;EAE/E;AAED,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAkGjD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,YAAY,GAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAM,EACtD,aAAa,GAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAM,GACrE,UAAU,CA8FZ;AA2CD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EACpC,OAAO,EAAE,aAAa,GACrB;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAkNlC"}