@schemalens/cli 0.1.0

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 (50) hide show
  1. package/README.md +154 -0
  2. package/dist/commands/ci.d.ts +15 -0
  3. package/dist/commands/ci.js +78 -0
  4. package/dist/commands/ci.js.map +1 -0
  5. package/dist/commands/deploy.d.ts +8 -0
  6. package/dist/commands/deploy.js +212 -0
  7. package/dist/commands/deploy.js.map +1 -0
  8. package/dist/commands/diff.d.ts +1 -0
  9. package/dist/commands/diff.js +96 -0
  10. package/dist/commands/diff.js.map +1 -0
  11. package/dist/commands/init.d.ts +1 -0
  12. package/dist/commands/init.js +197 -0
  13. package/dist/commands/init.js.map +1 -0
  14. package/dist/commands/migrate.d.ts +1 -0
  15. package/dist/commands/migrate.js +50 -0
  16. package/dist/commands/migrate.js.map +1 -0
  17. package/dist/commands/pull.d.ts +1 -0
  18. package/dist/commands/pull.js +80 -0
  19. package/dist/commands/pull.js.map +1 -0
  20. package/dist/commands/status.d.ts +1 -0
  21. package/dist/commands/status.js +59 -0
  22. package/dist/commands/status.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +133 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/lib/config.d.ts +34 -0
  27. package/dist/lib/config.js +150 -0
  28. package/dist/lib/config.js.map +1 -0
  29. package/dist/lib/differ.d.ts +13 -0
  30. package/dist/lib/differ.js +130 -0
  31. package/dist/lib/differ.js.map +1 -0
  32. package/dist/lib/git.d.ts +16 -0
  33. package/dist/lib/git.js +65 -0
  34. package/dist/lib/git.js.map +1 -0
  35. package/dist/lib/introspector.d.ts +2 -0
  36. package/dist/lib/introspector.js +7 -0
  37. package/dist/lib/introspector.js.map +1 -0
  38. package/dist/lib/planner.d.ts +26 -0
  39. package/dist/lib/planner.js +501 -0
  40. package/dist/lib/planner.js.map +1 -0
  41. package/dist/lib/reader.d.ts +19 -0
  42. package/dist/lib/reader.js +106 -0
  43. package/dist/lib/reader.js.map +1 -0
  44. package/dist/lib/sync.d.ts +13 -0
  45. package/dist/lib/sync.js +46 -0
  46. package/dist/lib/sync.js.map +1 -0
  47. package/dist/lib/writer.d.ts +7 -0
  48. package/dist/lib/writer.js +191 -0
  49. package/dist/lib/writer.js.map +1 -0
  50. package/package.json +37 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/lib/reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { GitContext } from './git';
2
+ export type SyncTrigger = 'pull' | 'deploy';
3
+ export interface SyncResult {
4
+ snapshot_id: string;
5
+ object_count: number;
6
+ changed_count: number;
7
+ }
8
+ /**
9
+ * Notify the SchemeLens SaaS to take a snapshot after a CLI operation.
10
+ * Silently skips if projectId or apiKey are missing.
11
+ * Never throws — errors are returned as warnings so the CLI command still succeeds.
12
+ */
13
+ export declare function syncToCloud(projectId: string, apiKey: string, trigger: SyncTrigger, environment: string, gitContext?: GitContext | null): Promise<SyncResult | null>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.syncToCloud = syncToCloud;
4
+ const BASE_URL = process.env.SCHEMALENS_BASE_URL ??
5
+ (process.env.SCHEMALENS_API_URL
6
+ ? new URL(process.env.SCHEMALENS_API_URL).origin
7
+ : 'https://schemalens.vercel.app');
8
+ const SYNC_URL = `${BASE_URL}/api/cli/sync`;
9
+ /**
10
+ * Notify the SchemeLens SaaS to take a snapshot after a CLI operation.
11
+ * Silently skips if projectId or apiKey are missing.
12
+ * Never throws — errors are returned as warnings so the CLI command still succeeds.
13
+ */
14
+ async function syncToCloud(projectId, apiKey, trigger, environment, gitContext) {
15
+ try {
16
+ const response = await fetch(SYNC_URL, {
17
+ method: 'POST',
18
+ headers: {
19
+ 'Content-Type': 'application/json',
20
+ 'Authorization': `Bearer ${apiKey}`,
21
+ },
22
+ body: JSON.stringify({
23
+ project_id: projectId,
24
+ trigger,
25
+ environment,
26
+ ...(gitContext && {
27
+ git_commit_sha: gitContext.commit_sha,
28
+ git_branch: gitContext.branch,
29
+ git_repo_url: gitContext.repo_url,
30
+ git_dirty: gitContext.dirty,
31
+ }),
32
+ }),
33
+ });
34
+ if (!response.ok) {
35
+ const body = await response.text();
36
+ process.stderr.write(` ⚠ SchemeLens sync warning: ${response.status} ${body}\n`);
37
+ return null;
38
+ }
39
+ return await response.json();
40
+ }
41
+ catch (err) {
42
+ process.stderr.write(` ⚠ SchemeLens sync warning: ${err.message}\n`);
43
+ return null;
44
+ }
45
+ }
46
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":";;AAuBA,kCAsCC;AA3DD,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,mBAAmB;IAC/B,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC7B,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,MAAM;QAChD,CAAC,CAAC,+BAA+B,CAAC,CAAC;AAEvC,MAAM,QAAQ,GAAG,GAAG,QAAQ,eAAe,CAAC;AAU5C;;;;GAIG;AACI,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,MAAc,EACd,OAAoB,EACpB,WAAmB,EACnB,UAA8B;IAE9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,MAAM,EAAE;aACpC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU,EAAE,SAAS;gBACrB,OAAO;gBACP,WAAW;gBACX,GAAG,CAAC,UAAU,IAAI;oBAChB,cAAc,EAAE,UAAU,CAAC,UAAU;oBACrC,UAAU,EAAE,UAAU,CAAC,MAAM;oBAC7B,YAAY,EAAE,UAAU,CAAC,QAAQ;oBACjC,SAAS,EAAE,UAAU,CAAC,KAAK;iBAC5B,CAAC;aACH,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,QAAQ,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC;YACnF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAgB,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAkC,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { SchemaSnapshot } from './introspector';
2
+ export interface WriteResult {
3
+ created: string[];
4
+ updated: string[];
5
+ unchanged: string[];
6
+ }
7
+ export declare function writeSchemaFiles(snapshot: SchemaSnapshot, env: string): WriteResult;
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeSchemaFiles = writeSchemaFiles;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const crypto_1 = __importDefault(require("crypto"));
10
+ const SCHEMA_DIR = 'schema';
11
+ function header(type, schemaName, objectName) {
12
+ const ts = new Date().toISOString();
13
+ return `-- object: ${type} \u00b7 ${schemaName}.${objectName}\n-- version: auto \u00b7 ${ts}\n`;
14
+ }
15
+ function md5(content) {
16
+ return crypto_1.default.createHash('md5').update(content).digest('hex');
17
+ }
18
+ /**
19
+ * Write a file only if its content hash differs from what's on disk.
20
+ * Returns 'created' | 'updated' | 'unchanged'.
21
+ */
22
+ function writeIfChanged(filePath, content) {
23
+ const absPath = path_1.default.resolve(filePath);
24
+ const dir = path_1.default.dirname(absPath);
25
+ if (!fs_1.default.existsSync(dir)) {
26
+ fs_1.default.mkdirSync(dir, { recursive: true });
27
+ }
28
+ const newHash = md5(content);
29
+ if (fs_1.default.existsSync(absPath)) {
30
+ const existing = fs_1.default.readFileSync(absPath, 'utf-8');
31
+ // Compare ignoring the header (first 2 lines) since timestamp changes each run
32
+ const stripHeader = (s) => s.split('\n').slice(2).join('\n');
33
+ if (md5(stripHeader(existing)) === md5(stripHeader(content))) {
34
+ return 'unchanged';
35
+ }
36
+ fs_1.default.writeFileSync(absPath, content, 'utf-8');
37
+ return 'updated';
38
+ }
39
+ fs_1.default.writeFileSync(absPath, content, 'utf-8');
40
+ return 'created';
41
+ }
42
+ // ---------------------------------------------------------------------------
43
+ // SQL generators — each returns idempotent DDL
44
+ // ---------------------------------------------------------------------------
45
+ function generateExtensionsSql(snapshot) {
46
+ if (snapshot.extensions.length === 0) {
47
+ return '-- No extensions found\n';
48
+ }
49
+ return snapshot.extensions
50
+ .map(ext => `CREATE EXTENSION IF NOT EXISTS "${ext.name}" WITH SCHEMA "${ext.schema}";`)
51
+ .join('\n') + '\n';
52
+ }
53
+ function generateEnumSql(e) {
54
+ const vals = e.values.map(v => ` '${v}'`).join(',\n');
55
+ return [
56
+ `DO $$ BEGIN`,
57
+ ` CREATE TYPE "${e.schema}"."${e.name}" AS ENUM (`,
58
+ vals,
59
+ ` );`,
60
+ `EXCEPTION WHEN duplicate_object THEN NULL;`,
61
+ `END $$;`,
62
+ '',
63
+ ].join('\n');
64
+ }
65
+ function generateTableDefinitionSql(table) {
66
+ const cols = table.columns.map(col => {
67
+ const parts = [` "${col.name}" ${col.type}`];
68
+ if (!col.nullable)
69
+ parts.push('NOT NULL');
70
+ if (col.default)
71
+ parts.push(`DEFAULT ${col.default}`);
72
+ return parts.join(' ');
73
+ });
74
+ const constraints = table.constraints.map(c => ` CONSTRAINT "${c.name}" ${c.definition}`);
75
+ const body = [...cols, ...constraints].join(',\n');
76
+ return [
77
+ `CREATE TABLE IF NOT EXISTS "${table.schema}"."${table.name}" (`,
78
+ body,
79
+ `);`,
80
+ '',
81
+ ].join('\n');
82
+ }
83
+ function generateIndexesSql(table, indexes) {
84
+ const tableIndexes = indexes.filter(i => i.schema === table.schema && i.table === table.name && !i.isPrimary);
85
+ if (tableIndexes.length === 0) {
86
+ return `-- No non-primary indexes on ${table.schema}.${table.name}\n`;
87
+ }
88
+ return tableIndexes
89
+ .map(idx => {
90
+ // pg_indexes.indexdef is already a full CREATE INDEX statement
91
+ // Make it idempotent by injecting IF NOT EXISTS
92
+ const def = idx.definition.replace(/^CREATE (UNIQUE )?INDEX /, 'CREATE $1INDEX IF NOT EXISTS ');
93
+ return `${def};`;
94
+ })
95
+ .join('\n') + '\n';
96
+ }
97
+ function generatePoliciesSql(table, policies) {
98
+ const tablePolicies = policies.filter(p => p.schema === table.schema && p.table === table.name);
99
+ if (tablePolicies.length === 0) {
100
+ return `-- No RLS policies on ${table.schema}.${table.name}\n`;
101
+ }
102
+ const lines = [
103
+ `ALTER TABLE "${table.schema}"."${table.name}" ENABLE ROW LEVEL SECURITY;`,
104
+ '',
105
+ ];
106
+ for (const pol of tablePolicies) {
107
+ const rolePart = pol.roles.length > 0 ? ` TO ${pol.roles.join(', ')}` : '';
108
+ const permPart = pol.permissive ? 'PERMISSIVE' : 'RESTRICTIVE';
109
+ lines.push(`DROP POLICY IF EXISTS "${pol.name}" ON "${pol.schema}"."${pol.table}";`);
110
+ const parts = [
111
+ `CREATE POLICY "${pol.name}"`,
112
+ ` ON "${pol.schema}"."${pol.table}"`,
113
+ ` AS ${permPart}`,
114
+ ` FOR ${pol.cmd}`,
115
+ rolePart ? ` ${rolePart}` : null,
116
+ pol.qual ? ` USING (${pol.qual})` : null,
117
+ pol.withCheck ? ` WITH CHECK (${pol.withCheck})` : null,
118
+ ].filter(Boolean);
119
+ lines.push(parts.join('\n') + ';');
120
+ lines.push('');
121
+ }
122
+ return lines.join('\n');
123
+ }
124
+ function generateTriggersSql(table, triggers) {
125
+ const tableTriggers = triggers.filter(t => t.schema === table.schema && t.table === table.name);
126
+ if (tableTriggers.length === 0) {
127
+ return `-- No triggers on ${table.schema}.${table.name}\n`;
128
+ }
129
+ return tableTriggers
130
+ .map(trig => {
131
+ // trig.body is the full CREATE TRIGGER from pg_get_triggerdef
132
+ return [
133
+ `DROP TRIGGER IF EXISTS "${trig.name}" ON "${trig.schema}"."${trig.table}";`,
134
+ `${trig.body};`,
135
+ ].join('\n');
136
+ })
137
+ .join('\n\n') + '\n';
138
+ }
139
+ function generateViewSql(v) {
140
+ return `CREATE OR REPLACE VIEW "${v.schema}"."${v.name}" AS\n${v.definition}\n`;
141
+ }
142
+ function generateFunctionSql(f) {
143
+ // f.body is the full CREATE FUNCTION from pg_get_functiondef — already idempotent
144
+ if (f.body) {
145
+ return f.body.endsWith(';') ? f.body + '\n' : f.body + ';\n';
146
+ }
147
+ return `-- Function body not available for ${f.schema}.${f.name}\n`;
148
+ }
149
+ // ---------------------------------------------------------------------------
150
+ // Main write orchestrator
151
+ // ---------------------------------------------------------------------------
152
+ function writeSchemaFiles(snapshot, env) {
153
+ const result = { created: [], updated: [], unchanged: [] };
154
+ const envDir = path_1.default.join(SCHEMA_DIR, env);
155
+ function track(filePath, content) {
156
+ const status = writeIfChanged(filePath, content);
157
+ result[status].push(filePath);
158
+ }
159
+ // Extensions
160
+ const extContent = header('extensions', 'global', 'enabled') + generateExtensionsSql(snapshot);
161
+ track(path_1.default.join(envDir, 'extensions', 'enabled.sql'), extContent);
162
+ // Enums
163
+ for (const e of snapshot.enums) {
164
+ const content = header('enum', e.schema, e.name) + generateEnumSql(e);
165
+ track(path_1.default.join(envDir, 'enums', `${e.name}.sql`), content);
166
+ }
167
+ // Tables — each gets a folder with 4 files
168
+ for (const table of snapshot.tables) {
169
+ const tableDir = path_1.default.join(envDir, 'tables', table.name);
170
+ const defContent = header('table', table.schema, table.name) + generateTableDefinitionSql(table);
171
+ track(path_1.default.join(tableDir, 'definition.sql'), defContent);
172
+ const idxContent = header('indexes', table.schema, table.name) + generateIndexesSql(table, snapshot.indexes);
173
+ track(path_1.default.join(tableDir, 'indexes.sql'), idxContent);
174
+ const polContent = header('policies', table.schema, table.name) + generatePoliciesSql(table, snapshot.policies);
175
+ track(path_1.default.join(tableDir, 'policies.sql'), polContent);
176
+ const trigContent = header('triggers', table.schema, table.name) + generateTriggersSql(table, snapshot.triggers);
177
+ track(path_1.default.join(tableDir, 'triggers.sql'), trigContent);
178
+ }
179
+ // Views
180
+ for (const v of snapshot.views) {
181
+ const content = header('view', v.schema, v.name) + generateViewSql(v);
182
+ track(path_1.default.join(envDir, 'views', `${v.name}.sql`), content);
183
+ }
184
+ // Functions
185
+ for (const f of snapshot.functions) {
186
+ const content = header('function', f.schema, f.name) + generateFunctionSql(f);
187
+ track(path_1.default.join(envDir, 'functions', `${f.name}.sql`), content);
188
+ }
189
+ return result;
190
+ }
191
+ //# sourceMappingURL=writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/lib/writer.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@schemalens/cli",
3
+ "version": "0.1.0",
4
+ "description": "SchemaLens CLI — pull, diff, and deploy PostgreSQL schemas",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "schemalens": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsx src/index.ts",
13
+ "prepare": "npm run build"
14
+ },
15
+ "dependencies": {
16
+ "@inquirer/prompts": "^8.3.2",
17
+ "@schemalens/introspector": "^0.1.0",
18
+ "chalk": "^4.1.2",
19
+ "commander": "^12.1.0",
20
+ "js-yaml": "^4.1.0",
21
+ "ora": "^5.4.1"
22
+ },
23
+ "devDependencies": {
24
+ "@types/js-yaml": "^4.0.9",
25
+ "@types/node": "^22.0.0",
26
+ "dotenv": "^16.4.7",
27
+ "tsx": "^4.19.0",
28
+ "typescript": "^5.7.0"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "README.md"
36
+ ]
37
+ }