@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.
- package/README.md +154 -0
- package/dist/commands/ci.d.ts +15 -0
- package/dist/commands/ci.js +78 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/deploy.d.ts +8 -0
- package/dist/commands/deploy.js +212 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/diff.d.ts +1 -0
- package/dist/commands/diff.js +96 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +197 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/migrate.d.ts +1 -0
- package/dist/commands/migrate.js +50 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/pull.d.ts +1 -0
- package/dist/commands/pull.js +80 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +59 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +133 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +34 -0
- package/dist/lib/config.js +150 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/differ.d.ts +13 -0
- package/dist/lib/differ.js +130 -0
- package/dist/lib/differ.js.map +1 -0
- package/dist/lib/git.d.ts +16 -0
- package/dist/lib/git.js +65 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/introspector.d.ts +2 -0
- package/dist/lib/introspector.js +7 -0
- package/dist/lib/introspector.js.map +1 -0
- package/dist/lib/planner.d.ts +26 -0
- package/dist/lib/planner.js +501 -0
- package/dist/lib/planner.js.map +1 -0
- package/dist/lib/reader.d.ts +19 -0
- package/dist/lib/reader.js +106 -0
- package/dist/lib/reader.js.map +1 -0
- package/dist/lib/sync.d.ts +13 -0
- package/dist/lib/sync.js +46 -0
- package/dist/lib/sync.js.map +1 -0
- package/dist/lib/writer.d.ts +7 -0
- package/dist/lib/writer.js +191 -0
- package/dist/lib/writer.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,197 @@
|
|
|
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.initCommand = initCommand;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const prompts_1 = require("@inquirer/prompts");
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
12
|
+
const config_1 = require("../lib/config");
|
|
13
|
+
const CONFIG_PATH = path_1.default.join('schema', '_meta', '.schemalens.yml');
|
|
14
|
+
/** Maximum number of environments the init wizard will prompt for. */
|
|
15
|
+
const MAX_ENVIRONMENTS = 5;
|
|
16
|
+
async function initCommand() {
|
|
17
|
+
const fullPath = path_1.default.resolve(CONFIG_PATH);
|
|
18
|
+
if (fs_1.default.existsSync(fullPath)) {
|
|
19
|
+
console.error(chalk_1.default.red(`\nConfig already exists at ${fullPath}\n`));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
console.log(chalk_1.default.bold('\n SchemeLens — Project Setup\n'));
|
|
23
|
+
console.log(chalk_1.default.dim(' This creates schema/_meta/.schemalens.yml in your repo.\n'));
|
|
24
|
+
// --- Phase A: SaaS Linking (asked first) ---
|
|
25
|
+
console.log(chalk_1.default.dim(' Optional: link to SchemeLens SaaS for dashboard sync.\n'));
|
|
26
|
+
const linkToSaas = await (0, prompts_1.confirm)({
|
|
27
|
+
message: 'Link to SchemeLens SaaS project?',
|
|
28
|
+
default: true,
|
|
29
|
+
});
|
|
30
|
+
let projectId;
|
|
31
|
+
let apiKeyVarName;
|
|
32
|
+
let resolvedApiKey;
|
|
33
|
+
let useLinkedMode = false;
|
|
34
|
+
let remoteEnvNames = [];
|
|
35
|
+
if (linkToSaas) {
|
|
36
|
+
projectId = await (0, prompts_1.input)({
|
|
37
|
+
message: 'Project ID (copy from dashboard → Project Settings)',
|
|
38
|
+
validate: (v) => /^[0-9a-f-]{36}$/.test(v.trim()) || 'Must be a valid UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)',
|
|
39
|
+
});
|
|
40
|
+
projectId = projectId.trim();
|
|
41
|
+
const apiKeyInput = (await (0, prompts_1.input)({
|
|
42
|
+
message: 'API key or env var name (e.g. SCHEMALENS_API_KEY or slk_...)',
|
|
43
|
+
default: 'SCHEMALENS_API_KEY',
|
|
44
|
+
})).trim();
|
|
45
|
+
if (apiKeyInput.startsWith('slk_')) {
|
|
46
|
+
// User pasted the actual key — store the var name, use raw key for fetch
|
|
47
|
+
apiKeyVarName = 'SCHEMALENS_API_KEY';
|
|
48
|
+
resolvedApiKey = apiKeyInput;
|
|
49
|
+
console.log(chalk_1.default.yellow('\n ⚠ Detected a raw API key. It will be referenced as env(SCHEMALENS_API_KEY).\n') +
|
|
50
|
+
chalk_1.default.dim(` Set it in your shell:\n`) +
|
|
51
|
+
chalk_1.default.cyan(` export SCHEMALENS_API_KEY=${apiKeyInput}\n`));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
apiKeyVarName = apiKeyInput;
|
|
55
|
+
try {
|
|
56
|
+
resolvedApiKey = (0, config_1.resolveEnvVar)(`env(${apiKeyInput})`);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
console.log(chalk_1.default.yellow(`\n ⚠ Env var "${apiKeyInput}" is not set. Cannot fetch environments from SaaS.\n`));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// --- Phase B: Fetch environments from SaaS ---
|
|
63
|
+
if (resolvedApiKey) {
|
|
64
|
+
try {
|
|
65
|
+
console.log(chalk_1.default.dim(' Fetching environments from SaaS...\n'));
|
|
66
|
+
const remoteEnvs = await (0, config_1.fetchEnvironmentsFromSaaS)(projectId, resolvedApiKey);
|
|
67
|
+
remoteEnvNames = remoteEnvs.map(e => e.name);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
console.log(chalk_1.default.yellow(` ⚠ ${err.message}\n`));
|
|
71
|
+
console.log(chalk_1.default.dim(' You can enter environments manually instead.\n'));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// --- Phase B/D: Environment selection ---
|
|
76
|
+
const environments = [];
|
|
77
|
+
if (remoteEnvNames.length > 0) {
|
|
78
|
+
// SaaS environments found — let user select
|
|
79
|
+
console.log(chalk_1.default.green(` Found ${remoteEnvNames.length} environment(s) in SaaS: ${remoteEnvNames.join(', ')}\n`));
|
|
80
|
+
const selected = await (0, prompts_1.checkbox)({
|
|
81
|
+
message: 'Select environments to configure locally',
|
|
82
|
+
choices: remoteEnvNames.map(name => ({
|
|
83
|
+
name,
|
|
84
|
+
value: name,
|
|
85
|
+
checked: true,
|
|
86
|
+
})),
|
|
87
|
+
validate: (v) => v.length > 0 || 'Select at least one environment',
|
|
88
|
+
});
|
|
89
|
+
for (const name of selected) {
|
|
90
|
+
environments.push({ name, connectionString: '' });
|
|
91
|
+
}
|
|
92
|
+
// Offer to add more local-only environments
|
|
93
|
+
if (environments.length < MAX_ENVIRONMENTS) {
|
|
94
|
+
const addMore = await (0, prompts_1.confirm)({
|
|
95
|
+
message: 'Add additional local-only environments?',
|
|
96
|
+
default: false,
|
|
97
|
+
});
|
|
98
|
+
if (addMore) {
|
|
99
|
+
await collectManualEnvironments(environments);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// No SaaS environments — manual entry
|
|
105
|
+
await collectManualEnvironments(environments);
|
|
106
|
+
}
|
|
107
|
+
// --- Phase C: Linked mode decision ---
|
|
108
|
+
if (linkToSaas) {
|
|
109
|
+
useLinkedMode = await (0, prompts_1.confirm)({
|
|
110
|
+
message: 'Use SaaS credentials for DB connection? (no local DATABASE_URL needed)',
|
|
111
|
+
default: remoteEnvNames.length > 0,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
// If not linked mode, collect connection strings for envs that don't have them
|
|
115
|
+
if (!useLinkedMode) {
|
|
116
|
+
for (const env of environments) {
|
|
117
|
+
if (!env.connectionString) {
|
|
118
|
+
const suffix = env.name === 'dev' ? '' : `_${env.name.toUpperCase()}`;
|
|
119
|
+
env.connectionString = await (0, prompts_1.input)({
|
|
120
|
+
message: `Connection string for "${env.name}"`,
|
|
121
|
+
default: `env(DATABASE_URL${suffix})`,
|
|
122
|
+
validate: (v) => v.trim().length > 0 || 'Required',
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// --- Phase E: Build config + write file ---
|
|
128
|
+
const environmentsObj = {};
|
|
129
|
+
for (const env of environments) {
|
|
130
|
+
if (useLinkedMode) {
|
|
131
|
+
environmentsObj[env.name] = {};
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
environmentsObj[env.name] = { connection_string: env.connectionString };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const config = {
|
|
138
|
+
version: 1,
|
|
139
|
+
schema_dir: 'schema',
|
|
140
|
+
allow_destructive: false,
|
|
141
|
+
environments: environmentsObj,
|
|
142
|
+
};
|
|
143
|
+
if (projectId) {
|
|
144
|
+
config.project_id = projectId;
|
|
145
|
+
}
|
|
146
|
+
if (apiKeyVarName) {
|
|
147
|
+
config.api_key = `env(${apiKeyVarName})`;
|
|
148
|
+
}
|
|
149
|
+
const dir = path_1.default.dirname(fullPath);
|
|
150
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
151
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
152
|
+
}
|
|
153
|
+
const yamlContent = js_yaml_1.default.dump(config, { lineWidth: 120 });
|
|
154
|
+
fs_1.default.writeFileSync(fullPath, yamlContent, 'utf-8');
|
|
155
|
+
// --- Success ---
|
|
156
|
+
console.log(chalk_1.default.green(`\n ✓ Created ${CONFIG_PATH}\n`));
|
|
157
|
+
if (useLinkedMode) {
|
|
158
|
+
console.log(chalk_1.default.dim(' Connection credentials will be fetched from SchemeLens SaaS.\n'));
|
|
159
|
+
console.log(chalk_1.default.dim(' Make sure your API key is set:\n') +
|
|
160
|
+
chalk_1.default.cyan(` export ${apiKeyVarName}=slk_...\n`));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.log(chalk_1.default.dim(' Make sure your database connection env vars are set.\n'));
|
|
164
|
+
}
|
|
165
|
+
const firstEnv = environments[0].name;
|
|
166
|
+
console.log(chalk_1.default.bold(' Next steps:\n'));
|
|
167
|
+
console.log(` ${chalk_1.default.cyan(`schemalens pull --env ${firstEnv}`)} # snapshot your live database`);
|
|
168
|
+
console.log(` ${chalk_1.default.cyan(`schemalens status --env ${firstEnv}`)} # see what changed\n`);
|
|
169
|
+
}
|
|
170
|
+
/** Collects environments manually via interactive prompts. */
|
|
171
|
+
async function collectManualEnvironments(environments) {
|
|
172
|
+
let addingEnvs = true;
|
|
173
|
+
while (addingEnvs) {
|
|
174
|
+
const isFirst = environments.length === 0;
|
|
175
|
+
const envName = await (0, prompts_1.input)({
|
|
176
|
+
message: 'Environment name',
|
|
177
|
+
default: isFirst ? 'dev' : undefined,
|
|
178
|
+
validate: (v) => v.trim().length > 0 || 'Required',
|
|
179
|
+
});
|
|
180
|
+
const connString = await (0, prompts_1.input)({
|
|
181
|
+
message: `Connection string for "${envName}"`,
|
|
182
|
+
default: `env(DATABASE_URL${isFirst ? '' : `_${envName.toUpperCase()}`})`,
|
|
183
|
+
validate: (v) => v.trim().length > 0 || 'Required',
|
|
184
|
+
});
|
|
185
|
+
environments.push({ name: envName.trim(), connectionString: connString.trim() });
|
|
186
|
+
if (environments.length < MAX_ENVIRONMENTS) {
|
|
187
|
+
addingEnvs = await (0, prompts_1.confirm)({
|
|
188
|
+
message: 'Add another environment?',
|
|
189
|
+
default: false,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
addingEnvs = false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateCommand(): Promise<void>;
|
|
@@ -0,0 +1,50 @@
|
|
|
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.migrateCommand = migrateCommand;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const ora_1 = __importDefault(require("ora"));
|
|
11
|
+
const config_1 = require("../lib/config");
|
|
12
|
+
const SCHEMA_DIR = 'schema';
|
|
13
|
+
const OBJECT_DIRS = ['tables', 'views', 'functions', 'enums', 'extensions'];
|
|
14
|
+
function isLegacyLayout() {
|
|
15
|
+
for (const dir of OBJECT_DIRS) {
|
|
16
|
+
if (fs_1.default.existsSync(path_1.default.resolve(SCHEMA_DIR, dir))) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
async function migrateCommand() {
|
|
23
|
+
console.log(chalk_1.default.bold('\n SchemeLens Migrate — Schema Directory Layout\n'));
|
|
24
|
+
if (!isLegacyLayout()) {
|
|
25
|
+
console.log(chalk_1.default.green(' Already using environment-scoped layout. Nothing to do.\n'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const config = (0, config_1.loadConfig)();
|
|
29
|
+
const envNames = Object.keys(config.environments);
|
|
30
|
+
const defaultEnv = envNames[0] || 'dev';
|
|
31
|
+
console.log(chalk_1.default.yellow(` Detected legacy flat layout (schema/tables/...).`));
|
|
32
|
+
console.log(chalk_1.default.dim(` Moving schema files into schema/${defaultEnv}/\n`));
|
|
33
|
+
const spinner = (0, ora_1.default)('Migrating...').start();
|
|
34
|
+
const targetDir = path_1.default.resolve(SCHEMA_DIR, defaultEnv);
|
|
35
|
+
if (!fs_1.default.existsSync(targetDir)) {
|
|
36
|
+
fs_1.default.mkdirSync(targetDir, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
let moved = 0;
|
|
39
|
+
for (const dir of OBJECT_DIRS) {
|
|
40
|
+
const srcDir = path_1.default.resolve(SCHEMA_DIR, dir);
|
|
41
|
+
if (!fs_1.default.existsSync(srcDir))
|
|
42
|
+
continue;
|
|
43
|
+
const destDir = path_1.default.join(targetDir, dir);
|
|
44
|
+
fs_1.default.renameSync(srcDir, destDir);
|
|
45
|
+
moved++;
|
|
46
|
+
}
|
|
47
|
+
spinner.succeed(chalk_1.default.green(`Moved ${moved} directories into schema/${defaultEnv}/`));
|
|
48
|
+
console.log(chalk_1.default.dim(`\n Run ${chalk_1.default.cyan(`schemalens pull --env ${defaultEnv}`)} to verify.\n`));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":";;;;;AAkBA,wCAkCC;AApDD,4CAAoB;AACpB,gDAAwB;AACxB,kDAA0B;AAC1B,8CAAsB;AACtB,0CAA2C;AAE3C,MAAM,UAAU,GAAG,QAAQ,CAAC;AAC5B,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;AAE5E,SAAS,cAAc;IACrB,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAEM,KAAK,UAAU,cAAc;IAClC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAE9E,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC,CAAC;QACxF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,qCAAqC,UAAU,KAAK,CAAC,CAAC,CAAC;IAE7E,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,cAAc,CAAC,CAAC,KAAK,EAAE,CAAC;IAE5C,MAAM,SAAS,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACvD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,YAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAS;QAErC,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC1C,YAAE,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,KAAK,EAAE,CAAC;IACV,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,SAAS,KAAK,4BAA4B,UAAU,GAAG,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,WAAW,eAAK,CAAC,IAAI,CAAC,yBAAyB,UAAU,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AACtG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function pullCommand(env: string): Promise<void>;
|
|
@@ -0,0 +1,80 @@
|
|
|
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.pullCommand = pullCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const config_1 = require("../lib/config");
|
|
10
|
+
const introspector_1 = require("../lib/introspector");
|
|
11
|
+
const writer_1 = require("../lib/writer");
|
|
12
|
+
const sync_1 = require("../lib/sync");
|
|
13
|
+
const git_1 = require("../lib/git");
|
|
14
|
+
async function pullCommand(env) {
|
|
15
|
+
console.log(chalk_1.default.bold(`\nSchemaLens Pull — env: ${chalk_1.default.cyan(env)}\n`));
|
|
16
|
+
// 1. Load config
|
|
17
|
+
const config = (0, config_1.loadConfig)();
|
|
18
|
+
const connectionString = await (0, config_1.resolveConnectionString)(config, env);
|
|
19
|
+
// Detect git context
|
|
20
|
+
const gitContext = (0, git_1.detectGitContext)();
|
|
21
|
+
if (gitContext) {
|
|
22
|
+
const branch = gitContext.branch ?? 'detached HEAD';
|
|
23
|
+
const sha = gitContext.commit_sha.substring(0, 7);
|
|
24
|
+
const dirty = gitContext.dirty ? chalk_1.default.yellow(' (dirty)') : '';
|
|
25
|
+
console.log(chalk_1.default.dim(` git: ${branch} @ ${sha}${dirty}`));
|
|
26
|
+
}
|
|
27
|
+
// 2. Introspect
|
|
28
|
+
const spinner = (0, ora_1.default)('Connecting to database...').start();
|
|
29
|
+
let snapshot;
|
|
30
|
+
try {
|
|
31
|
+
snapshot = await (0, introspector_1.introspectSchema)(connectionString);
|
|
32
|
+
spinner.succeed(chalk_1.default.green('Schema introspected successfully'));
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
spinner.fail(chalk_1.default.red('Failed to introspect schema'));
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
console.log(chalk_1.default.dim(` ${snapshot.tables.length} tables, ` +
|
|
39
|
+
`${snapshot.views.length} views, ` +
|
|
40
|
+
`${snapshot.functions.length} functions, ` +
|
|
41
|
+
`${snapshot.enums.length} enums, ` +
|
|
42
|
+
`${snapshot.extensions.length} extensions`));
|
|
43
|
+
// 3. Write schema files
|
|
44
|
+
const writeSpinner = (0, ora_1.default)('Writing schema files...').start();
|
|
45
|
+
const result = (0, writer_1.writeSchemaFiles)(snapshot, env);
|
|
46
|
+
writeSpinner.succeed(chalk_1.default.green('Schema files written'));
|
|
47
|
+
// 4. Summary
|
|
48
|
+
console.log('');
|
|
49
|
+
if (result.created.length > 0) {
|
|
50
|
+
console.log(chalk_1.default.green.bold(` + ${result.created.length} created`));
|
|
51
|
+
for (const f of result.created) {
|
|
52
|
+
console.log(chalk_1.default.green(` + ${f}`));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (result.updated.length > 0) {
|
|
56
|
+
console.log(chalk_1.default.yellow.bold(` ~ ${result.updated.length} updated`));
|
|
57
|
+
for (const f of result.updated) {
|
|
58
|
+
console.log(chalk_1.default.yellow(` ~ ${f}`));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (result.unchanged.length > 0) {
|
|
62
|
+
console.log(chalk_1.default.dim(` = ${result.unchanged.length} unchanged`));
|
|
63
|
+
}
|
|
64
|
+
const total = result.created.length + result.updated.length + result.unchanged.length;
|
|
65
|
+
console.log(chalk_1.default.bold(`\n Total: ${total} files\n`));
|
|
66
|
+
// Auto-sync to SchemeLens cloud if configured
|
|
67
|
+
const projectId = config.project_id;
|
|
68
|
+
const apiKey = (0, config_1.resolveEnvVar)(config.api_key);
|
|
69
|
+
if (projectId && apiKey) {
|
|
70
|
+
const syncSpinner = (0, ora_1.default)('Syncing snapshot to SchemeLens...').start();
|
|
71
|
+
const syncResult = await (0, sync_1.syncToCloud)(projectId, apiKey, 'pull', env, gitContext);
|
|
72
|
+
if (syncResult) {
|
|
73
|
+
syncSpinner.succeed(chalk_1.default.green(`Snapshot synced to SchemeLens cloud (${syncResult.object_count} objects, ${syncResult.changed_count} changed)`));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
syncSpinner.warn(chalk_1.default.yellow('SchemeLens sync skipped (see warning above)'));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function statusCommand(env: string): Promise<void>;
|
|
@@ -0,0 +1,59 @@
|
|
|
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.statusCommand = statusCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const config_1 = require("../lib/config");
|
|
10
|
+
const introspector_1 = require("../lib/introspector");
|
|
11
|
+
const differ_1 = require("../lib/differ");
|
|
12
|
+
async function statusCommand(env) {
|
|
13
|
+
console.log(chalk_1.default.bold(`\nSchemaLens Status — env: ${chalk_1.default.cyan(env)}\n`));
|
|
14
|
+
// 1. Load config
|
|
15
|
+
const config = (0, config_1.loadConfig)();
|
|
16
|
+
const connectionString = await (0, config_1.resolveConnectionString)(config, env);
|
|
17
|
+
// 2. Introspect
|
|
18
|
+
const spinner = (0, ora_1.default)('Connecting to database...').start();
|
|
19
|
+
let snapshot;
|
|
20
|
+
try {
|
|
21
|
+
snapshot = await (0, introspector_1.introspectSchema)(connectionString);
|
|
22
|
+
spinner.succeed(chalk_1.default.green('Schema introspected successfully'));
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
spinner.fail(chalk_1.default.red('Failed to introspect schema'));
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
// 3. Diff against disk
|
|
29
|
+
const entries = (0, differ_1.diffSchema)(snapshot, env);
|
|
30
|
+
const newItems = entries.filter(e => e.status === 'new');
|
|
31
|
+
const changed = entries.filter(e => e.status === 'changed');
|
|
32
|
+
const deleted = entries.filter(e => e.status === 'deleted');
|
|
33
|
+
const unchanged = entries.filter(e => e.status === 'unchanged');
|
|
34
|
+
console.log('');
|
|
35
|
+
if (newItems.length > 0) {
|
|
36
|
+
console.log(chalk_1.default.green.bold(` + ${newItems.length} new objects`));
|
|
37
|
+
for (const e of newItems) {
|
|
38
|
+
console.log(chalk_1.default.green(` + [${e.type}] ${e.schema}.${e.name}`));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (changed.length > 0) {
|
|
42
|
+
console.log(chalk_1.default.yellow.bold(` ~ ${changed.length} changed objects`));
|
|
43
|
+
for (const e of changed) {
|
|
44
|
+
console.log(chalk_1.default.yellow(` ~ [${e.type}] ${e.schema}.${e.name}`));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (deleted.length > 0) {
|
|
48
|
+
console.log(chalk_1.default.red.bold(` - ${deleted.length} deleted objects`));
|
|
49
|
+
for (const e of deleted) {
|
|
50
|
+
console.log(chalk_1.default.red(` - [${e.type}] ${e.schema}.${e.name}`));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (newItems.length === 0 && changed.length === 0 && deleted.length === 0) {
|
|
54
|
+
console.log(chalk_1.default.green(' Schema is up to date — no differences found.'));
|
|
55
|
+
}
|
|
56
|
+
console.log(chalk_1.default.dim(`\n ${unchanged.length} objects unchanged`));
|
|
57
|
+
console.log('');
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
require("dotenv/config");
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const init_1 = require("./commands/init");
|
|
11
|
+
const pull_1 = require("./commands/pull");
|
|
12
|
+
const status_1 = require("./commands/status");
|
|
13
|
+
const diff_1 = require("./commands/diff");
|
|
14
|
+
const deploy_1 = require("./commands/deploy");
|
|
15
|
+
const migrate_1 = require("./commands/migrate");
|
|
16
|
+
const ci_1 = require("./commands/ci");
|
|
17
|
+
const program = new commander_1.Command();
|
|
18
|
+
program
|
|
19
|
+
.name('schemalens')
|
|
20
|
+
.description('Schema version control for PostgreSQL / Supabase')
|
|
21
|
+
.version('0.1.0');
|
|
22
|
+
program
|
|
23
|
+
.command('init')
|
|
24
|
+
.description('Set up SchemeLens in this repository (creates schema/_meta/.schemalens.yml)')
|
|
25
|
+
.action(async () => {
|
|
26
|
+
try {
|
|
27
|
+
await (0, init_1.initCommand)();
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
// Handle Ctrl+C from inquirer gracefully
|
|
31
|
+
if (err.name === 'ExitPromptError') {
|
|
32
|
+
console.log(chalk_1.default.dim('\n Setup cancelled.\n'));
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
console.error(chalk_1.default.red(`\nError: ${err.message}\n`));
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
program
|
|
40
|
+
.command('pull')
|
|
41
|
+
.description('Pull the live database schema into local files')
|
|
42
|
+
.requiredOption('--env <env>', 'Target environment (dev, staging, prod)')
|
|
43
|
+
.action(async (opts) => {
|
|
44
|
+
try {
|
|
45
|
+
await (0, pull_1.pullCommand)(opts.env);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
console.error(chalk_1.default.red(`\nError: ${err.message}\n`));
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
program
|
|
53
|
+
.command('status')
|
|
54
|
+
.description('Show diff between live DB and local schema files')
|
|
55
|
+
.requiredOption('--env <env>', 'Target environment (dev, staging, prod)')
|
|
56
|
+
.action(async (opts) => {
|
|
57
|
+
try {
|
|
58
|
+
await (0, status_1.statusCommand)(opts.env);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
console.error(chalk_1.default.red(`\nError: ${err.message}\n`));
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
program
|
|
66
|
+
.command('diff')
|
|
67
|
+
.description('Compare schema files between two environments')
|
|
68
|
+
.requiredOption('--from <env>', 'Source environment')
|
|
69
|
+
.requiredOption('--to <env>', 'Target environment')
|
|
70
|
+
.action(async (opts) => {
|
|
71
|
+
try {
|
|
72
|
+
await (0, diff_1.diffCommand)(opts.from, opts.to);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
console.error(chalk_1.default.red(`\nError: ${err.message}\n`));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
program
|
|
80
|
+
.command('deploy')
|
|
81
|
+
.description('Deploy local schema changes to the target environment')
|
|
82
|
+
.requiredOption('--env <env>', 'Target environment')
|
|
83
|
+
.option('--confirm', 'Actually apply changes (default is dry-run)', false)
|
|
84
|
+
.option('--dry-run', 'Print the plan without executing (default)', true)
|
|
85
|
+
.option('--rename <renames...>', 'Confirm column renames: table.oldCol:newCol')
|
|
86
|
+
.option('--allow-destructive', 'Allow destructive operations (DROP COLUMN, etc.)', false)
|
|
87
|
+
.action(async (opts) => {
|
|
88
|
+
try {
|
|
89
|
+
await (0, deploy_1.deployCommand)({
|
|
90
|
+
env: opts.env,
|
|
91
|
+
confirm: opts.confirm,
|
|
92
|
+
dryRun: !opts.confirm,
|
|
93
|
+
rename: opts.rename || [],
|
|
94
|
+
allowDestructive: opts.allowDestructive,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
console.error(chalk_1.default.red(`\nError: ${err.message}\n`));
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
program
|
|
103
|
+
.command('ci')
|
|
104
|
+
.description('Non-interactive CI mode: pull schema, sync to cloud, and check for issues')
|
|
105
|
+
.requiredOption('--env <env>', 'Target environment (dev, staging, prod)')
|
|
106
|
+
.option('--block-destructive', 'Exit with code 2 if destructive changes are detected', false)
|
|
107
|
+
.action(async (opts) => {
|
|
108
|
+
try {
|
|
109
|
+
await (0, ci_1.ciCommand)(opts);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
console.error(chalk_1.default.red(`\nError: ${err.message}\n`));
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
program
|
|
117
|
+
.command('migrate')
|
|
118
|
+
.description('Migrate legacy flat schema/ layout to environment-scoped schema/<env>/ layout')
|
|
119
|
+
.action(async () => {
|
|
120
|
+
try {
|
|
121
|
+
await (0, migrate_1.migrateCommand)();
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
if (err.name === 'ExitPromptError') {
|
|
125
|
+
console.log(chalk_1.default.dim('\n Migration cancelled.\n'));
|
|
126
|
+
process.exit(0);
|
|
127
|
+
}
|
|
128
|
+
console.error(chalk_1.default.red(`\nError: ${err.message}\n`));
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
program.parse();
|
|
133
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface EnvConfig {
|
|
2
|
+
/** Direct connection string or env(VAR_NAME) reference. Optional when project is linked to SaaS. */
|
|
3
|
+
connection_string?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface SchemaLensConfig {
|
|
6
|
+
version: number;
|
|
7
|
+
schema_dir: string;
|
|
8
|
+
allow_destructive: boolean;
|
|
9
|
+
environments: Record<string, EnvConfig>;
|
|
10
|
+
/** SaaS project UUID — copied from Project Settings in the web UI */
|
|
11
|
+
project_id?: string;
|
|
12
|
+
/** API key for auto-syncing snapshots after pull/deploy. Use env(SCHEMALENS_API_KEY). */
|
|
13
|
+
api_key?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve `env(VAR_NAME)` placeholders to process.env values.
|
|
17
|
+
* Returns undefined if the value itself is undefined.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveEnvVar(value: string | undefined): string | undefined;
|
|
20
|
+
export declare function loadConfig(): SchemaLensConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the resolved connection string for the given environment.
|
|
23
|
+
*
|
|
24
|
+
* Resolution order:
|
|
25
|
+
* 1. connection_string from config (resolved env vars) — existing behaviour
|
|
26
|
+
* 2. Fetch from SaaS using project_id + api_key — passwordless linked mode
|
|
27
|
+
* 3. Throw with a clear message
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveConnectionString(config: SchemaLensConfig, env: string): Promise<string>;
|
|
30
|
+
export declare function fetchEnvironmentsFromSaaS(projectId: string, apiKey: string): Promise<{
|
|
31
|
+
name: string;
|
|
32
|
+
}[]>;
|
|
33
|
+
/** @deprecated Use resolveConnectionString() instead */
|
|
34
|
+
export declare function getConnectionString(config: SchemaLensConfig, env: string): string;
|