@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,150 @@
|
|
|
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.resolveEnvVar = resolveEnvVar;
|
|
7
|
+
exports.loadConfig = loadConfig;
|
|
8
|
+
exports.resolveConnectionString = resolveConnectionString;
|
|
9
|
+
exports.fetchEnvironmentsFromSaaS = fetchEnvironmentsFromSaaS;
|
|
10
|
+
exports.getConnectionString = getConnectionString;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
14
|
+
const CONFIG_PATH = path_1.default.join('schema', '_meta', '.schemalens.yml');
|
|
15
|
+
// SCHEMALENS_BASE_URL overrides the SaaS base (e.g. for self-hosted or local dev).
|
|
16
|
+
// Legacy SCHEMALENS_API_URL pointed at the full sync endpoint; we fall back to stripping
|
|
17
|
+
// the known path suffix so existing configs continue to work.
|
|
18
|
+
const BASE_API_URL = process.env.SCHEMALENS_BASE_URL ??
|
|
19
|
+
(process.env.SCHEMALENS_API_URL
|
|
20
|
+
? new URL(process.env.SCHEMALENS_API_URL).origin
|
|
21
|
+
: 'https://schema-lens-steel.vercel.app');
|
|
22
|
+
/**
|
|
23
|
+
* Resolve `env(VAR_NAME)` placeholders to process.env values.
|
|
24
|
+
* Returns undefined if the value itself is undefined.
|
|
25
|
+
*/
|
|
26
|
+
function resolveEnvVar(value) {
|
|
27
|
+
if (!value)
|
|
28
|
+
return undefined;
|
|
29
|
+
return resolveEnvVars(value);
|
|
30
|
+
}
|
|
31
|
+
function resolveEnvVars(value) {
|
|
32
|
+
return value.replace(/env\(([^)]+)\)/g, (_match, varName) => {
|
|
33
|
+
const resolved = process.env[varName.trim()];
|
|
34
|
+
if (!resolved) {
|
|
35
|
+
throw new Error(`Environment variable "${varName.trim()}" is not set`);
|
|
36
|
+
}
|
|
37
|
+
return resolved;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function loadConfig() {
|
|
41
|
+
const fullPath = path_1.default.resolve(CONFIG_PATH);
|
|
42
|
+
if (!fs_1.default.existsSync(fullPath)) {
|
|
43
|
+
throw new Error(`Config not found at ${fullPath}\nRun 'schemalens init' to set up this project.`);
|
|
44
|
+
}
|
|
45
|
+
const raw = fs_1.default.readFileSync(fullPath, 'utf-8');
|
|
46
|
+
const doc = js_yaml_1.default.load(raw);
|
|
47
|
+
if (!doc.environments || typeof doc.environments !== 'object') {
|
|
48
|
+
throw new Error('Invalid config: missing "environments" section');
|
|
49
|
+
}
|
|
50
|
+
// Default allow_destructive to false if not set
|
|
51
|
+
if (doc.allow_destructive === undefined) {
|
|
52
|
+
doc.allow_destructive = false;
|
|
53
|
+
}
|
|
54
|
+
return doc;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Returns the resolved connection string for the given environment.
|
|
58
|
+
*
|
|
59
|
+
* Resolution order:
|
|
60
|
+
* 1. connection_string from config (resolved env vars) — existing behaviour
|
|
61
|
+
* 2. Fetch from SaaS using project_id + api_key — passwordless linked mode
|
|
62
|
+
* 3. Throw with a clear message
|
|
63
|
+
*/
|
|
64
|
+
async function resolveConnectionString(config, env) {
|
|
65
|
+
const envConfig = config.environments[env];
|
|
66
|
+
if (!envConfig) {
|
|
67
|
+
const available = Object.keys(config.environments).join(', ');
|
|
68
|
+
throw new Error(`Environment "${env}" not found. Available: ${available}`);
|
|
69
|
+
}
|
|
70
|
+
// 1. Local connection string (existing behaviour)
|
|
71
|
+
if (envConfig.connection_string) {
|
|
72
|
+
return resolveEnvVars(envConfig.connection_string);
|
|
73
|
+
}
|
|
74
|
+
// 2. Linked mode — fetch from SaaS
|
|
75
|
+
const projectId = config.project_id;
|
|
76
|
+
const apiKey = resolveEnvVar(config.api_key);
|
|
77
|
+
if (projectId && apiKey) {
|
|
78
|
+
return fetchConnectionFromSaaS(projectId, apiKey, env);
|
|
79
|
+
}
|
|
80
|
+
// 3. Nothing configured
|
|
81
|
+
throw new Error(`No connection_string configured for environment "${env}".\n` +
|
|
82
|
+
`Either add a connection_string to .schemalens.yml, or link to SchemeLens SaaS:\n` +
|
|
83
|
+
` - Set project_id and api_key in .schemalens.yml\n` +
|
|
84
|
+
` - Run 'schemalens init' to reconfigure`);
|
|
85
|
+
}
|
|
86
|
+
async function fetchEnvironmentsFromSaaS(projectId, apiKey) {
|
|
87
|
+
const url = `${BASE_API_URL}/api/projects/${projectId}/environments`;
|
|
88
|
+
let response;
|
|
89
|
+
try {
|
|
90
|
+
response = await fetch(url, {
|
|
91
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
throw new Error(`Could not reach SchemeLens SaaS: ${err.message}`);
|
|
96
|
+
}
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
if (response.status === 401) {
|
|
99
|
+
throw new Error('API key is invalid or expired.');
|
|
100
|
+
}
|
|
101
|
+
if (response.status === 404) {
|
|
102
|
+
throw new Error(`Project ${projectId} not found.`);
|
|
103
|
+
}
|
|
104
|
+
const body = await response.text().catch(() => '');
|
|
105
|
+
throw new Error(`SchemeLens returned ${response.status}: ${body}`);
|
|
106
|
+
}
|
|
107
|
+
const data = await response.json();
|
|
108
|
+
return Array.isArray(data) ? data : [];
|
|
109
|
+
}
|
|
110
|
+
async function fetchConnectionFromSaaS(projectId, apiKey, env) {
|
|
111
|
+
const url = `${BASE_API_URL}/api/projects/${projectId}/connection?env=${encodeURIComponent(env)}`;
|
|
112
|
+
let response;
|
|
113
|
+
try {
|
|
114
|
+
response = await fetch(url, {
|
|
115
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
throw new Error(`Could not reach SchemeLens SaaS to fetch connection details: ${err.message}`);
|
|
120
|
+
}
|
|
121
|
+
if (!response.ok) {
|
|
122
|
+
const body = await response.text().catch(() => '');
|
|
123
|
+
if (response.status === 401) {
|
|
124
|
+
throw new Error(`SchemeLens API key is invalid or expired. Regenerate it in Project Settings.`);
|
|
125
|
+
}
|
|
126
|
+
if (response.status === 404) {
|
|
127
|
+
throw new Error(`Project ${projectId} not found in SchemeLens. Check your project_id in .schemalens.yml.`);
|
|
128
|
+
}
|
|
129
|
+
throw new Error(`SchemeLens returned ${response.status}: ${body}`);
|
|
130
|
+
}
|
|
131
|
+
const data = await response.json();
|
|
132
|
+
if (!data.connection_string) {
|
|
133
|
+
throw new Error(`SchemeLens project has no database credentials stored. ` +
|
|
134
|
+
`Add your database host and password in the SchemeLens dashboard → Project Settings.`);
|
|
135
|
+
}
|
|
136
|
+
return data.connection_string;
|
|
137
|
+
}
|
|
138
|
+
/** @deprecated Use resolveConnectionString() instead */
|
|
139
|
+
function getConnectionString(config, env) {
|
|
140
|
+
const envConfig = config.environments[env];
|
|
141
|
+
if (!envConfig) {
|
|
142
|
+
const available = Object.keys(config.environments).join(', ');
|
|
143
|
+
throw new Error(`Environment "${env}" not found. Available: ${available}`);
|
|
144
|
+
}
|
|
145
|
+
if (!envConfig.connection_string) {
|
|
146
|
+
throw new Error(`No connection_string for environment "${env}". Use resolveConnectionString() for linked-mode support.`);
|
|
147
|
+
}
|
|
148
|
+
return resolveEnvVars(envConfig.connection_string);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SchemaSnapshot } from './introspector';
|
|
2
|
+
export interface DiffEntry {
|
|
3
|
+
type: 'table' | 'view' | 'function' | 'enum' | 'extension' | 'index' | 'policy' | 'trigger';
|
|
4
|
+
schema: string;
|
|
5
|
+
name: string;
|
|
6
|
+
status: 'new' | 'changed' | 'deleted' | 'unchanged';
|
|
7
|
+
filePath: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Compare a live schema snapshot against what's on disk.
|
|
11
|
+
* Returns a list of diffs without writing anything.
|
|
12
|
+
*/
|
|
13
|
+
export declare function diffSchema(snapshot: SchemaSnapshot, env: string): DiffEntry[];
|
|
@@ -0,0 +1,130 @@
|
|
|
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.diffSchema = diffSchema;
|
|
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 md5(content) {
|
|
12
|
+
return crypto_1.default.createHash('md5').update(content).digest('hex');
|
|
13
|
+
}
|
|
14
|
+
function stripHeader(content) {
|
|
15
|
+
return content.split('\n').slice(2).join('\n');
|
|
16
|
+
}
|
|
17
|
+
function fileHash(filePath) {
|
|
18
|
+
const absPath = path_1.default.resolve(filePath);
|
|
19
|
+
if (!fs_1.default.existsSync(absPath))
|
|
20
|
+
return null;
|
|
21
|
+
const content = fs_1.default.readFileSync(absPath, 'utf-8');
|
|
22
|
+
return md5(stripHeader(content));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Compare a live schema snapshot against what's on disk.
|
|
26
|
+
* Returns a list of diffs without writing anything.
|
|
27
|
+
*/
|
|
28
|
+
function diffSchema(snapshot, env) {
|
|
29
|
+
const envDir = path_1.default.join(SCHEMA_DIR, env);
|
|
30
|
+
const entries = [];
|
|
31
|
+
// Tables
|
|
32
|
+
for (const table of snapshot.tables) {
|
|
33
|
+
const tableDir = path_1.default.join(envDir, 'tables', table.name);
|
|
34
|
+
const defPath = path_1.default.join(tableDir, 'definition.sql');
|
|
35
|
+
const exists = fs_1.default.existsSync(path_1.default.resolve(defPath));
|
|
36
|
+
entries.push({
|
|
37
|
+
type: 'table',
|
|
38
|
+
schema: table.schema,
|
|
39
|
+
name: table.name,
|
|
40
|
+
status: exists ? 'unchanged' : 'new', // simplified; full content diff below
|
|
41
|
+
filePath: defPath,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// Views
|
|
45
|
+
for (const v of snapshot.views) {
|
|
46
|
+
const fp = path_1.default.join(envDir, 'views', `${v.name}.sql`);
|
|
47
|
+
entries.push({
|
|
48
|
+
type: 'view',
|
|
49
|
+
schema: v.schema,
|
|
50
|
+
name: v.name,
|
|
51
|
+
status: fs_1.default.existsSync(path_1.default.resolve(fp)) ? 'unchanged' : 'new',
|
|
52
|
+
filePath: fp,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Functions
|
|
56
|
+
for (const f of snapshot.functions) {
|
|
57
|
+
const fp = path_1.default.join(envDir, 'functions', `${f.name}.sql`);
|
|
58
|
+
entries.push({
|
|
59
|
+
type: 'function',
|
|
60
|
+
schema: f.schema,
|
|
61
|
+
name: f.name,
|
|
62
|
+
status: fs_1.default.existsSync(path_1.default.resolve(fp)) ? 'unchanged' : 'new',
|
|
63
|
+
filePath: fp,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Enums
|
|
67
|
+
for (const e of snapshot.enums) {
|
|
68
|
+
const fp = path_1.default.join(envDir, 'enums', `${e.name}.sql`);
|
|
69
|
+
entries.push({
|
|
70
|
+
type: 'enum',
|
|
71
|
+
schema: e.schema,
|
|
72
|
+
name: e.name,
|
|
73
|
+
status: fs_1.default.existsSync(path_1.default.resolve(fp)) ? 'unchanged' : 'new',
|
|
74
|
+
filePath: fp,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Detect deleted objects — files on disk with no match in snapshot
|
|
78
|
+
const diskTables = safeLs(path_1.default.join(envDir, 'tables'));
|
|
79
|
+
const liveTableNames = new Set(snapshot.tables.map(t => t.name));
|
|
80
|
+
for (const dirName of diskTables) {
|
|
81
|
+
if (!liveTableNames.has(dirName)) {
|
|
82
|
+
entries.push({
|
|
83
|
+
type: 'table',
|
|
84
|
+
schema: 'public',
|
|
85
|
+
name: dirName,
|
|
86
|
+
status: 'deleted',
|
|
87
|
+
filePath: path_1.default.join(envDir, 'tables', dirName, 'definition.sql'),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const diskViews = safeLsSql(path_1.default.join(envDir, 'views'));
|
|
92
|
+
const liveViewNames = new Set(snapshot.views.map(v => v.name));
|
|
93
|
+
for (const name of diskViews) {
|
|
94
|
+
if (!liveViewNames.has(name)) {
|
|
95
|
+
entries.push({
|
|
96
|
+
type: 'view',
|
|
97
|
+
schema: 'public',
|
|
98
|
+
name,
|
|
99
|
+
status: 'deleted',
|
|
100
|
+
filePath: path_1.default.join(envDir, 'views', `${name}.sql`),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const diskFunctions = safeLsSql(path_1.default.join(envDir, 'functions'));
|
|
105
|
+
const liveFnNames = new Set(snapshot.functions.map(f => f.name));
|
|
106
|
+
for (const name of diskFunctions) {
|
|
107
|
+
if (!liveFnNames.has(name)) {
|
|
108
|
+
entries.push({
|
|
109
|
+
type: 'function',
|
|
110
|
+
schema: 'public',
|
|
111
|
+
name,
|
|
112
|
+
status: 'deleted',
|
|
113
|
+
filePath: path_1.default.join(envDir, 'functions', `${name}.sql`),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return entries;
|
|
118
|
+
}
|
|
119
|
+
function safeLs(dir) {
|
|
120
|
+
const absDir = path_1.default.resolve(dir);
|
|
121
|
+
if (!fs_1.default.existsSync(absDir))
|
|
122
|
+
return [];
|
|
123
|
+
return fs_1.default.readdirSync(absDir).filter(f => !f.startsWith('.'));
|
|
124
|
+
}
|
|
125
|
+
function safeLsSql(dir) {
|
|
126
|
+
return safeLs(dir)
|
|
127
|
+
.filter(f => f.endsWith('.sql'))
|
|
128
|
+
.map(f => f.replace(/\.sql$/, ''));
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=differ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"differ.js","sourceRoot":"","sources":["../../src/lib/differ.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface GitContext {
|
|
2
|
+
/** Full 40-character SHA of HEAD */
|
|
3
|
+
commit_sha: string;
|
|
4
|
+
/** Current branch name, or null if detached HEAD */
|
|
5
|
+
branch: string | null;
|
|
6
|
+
/** Remote origin URL with credentials stripped, or null if no remote */
|
|
7
|
+
repo_url: string | null;
|
|
8
|
+
/** True if the working tree has uncommitted changes */
|
|
9
|
+
dirty: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Auto-detect git context from the current working directory.
|
|
13
|
+
* Returns null if not inside a git repository or if git is not installed.
|
|
14
|
+
* Never throws.
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectGitContext(): GitContext | null;
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectGitContext = detectGitContext;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const EXEC_OPTS = { encoding: 'utf-8', timeout: 5000 };
|
|
6
|
+
function git(...args) {
|
|
7
|
+
return (0, child_process_1.execFileSync)('git', args, EXEC_OPTS).trim();
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Strip embedded credentials from an HTTPS remote URL.
|
|
11
|
+
* `https://user:token@github.com/org/repo.git` → `https://github.com/org/repo.git`
|
|
12
|
+
* SSH URLs (`git@github.com:org/repo.git`) are returned as-is.
|
|
13
|
+
*/
|
|
14
|
+
function sanitizeRemoteUrl(raw) {
|
|
15
|
+
// Only HTTPS URLs can embed credentials
|
|
16
|
+
if (!raw.startsWith('http://') && !raw.startsWith('https://')) {
|
|
17
|
+
return raw;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const url = new URL(raw);
|
|
21
|
+
url.username = '';
|
|
22
|
+
url.password = '';
|
|
23
|
+
return url.toString().replace(/\/$/, ''); // strip trailing slash added by URL
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return raw;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Auto-detect git context from the current working directory.
|
|
31
|
+
* Returns null if not inside a git repository or if git is not installed.
|
|
32
|
+
* Never throws.
|
|
33
|
+
*/
|
|
34
|
+
function detectGitContext() {
|
|
35
|
+
try {
|
|
36
|
+
const commitSha = git('rev-parse', 'HEAD');
|
|
37
|
+
if (!commitSha)
|
|
38
|
+
return null;
|
|
39
|
+
let branch = null;
|
|
40
|
+
try {
|
|
41
|
+
const ref = git('rev-parse', '--abbrev-ref', 'HEAD');
|
|
42
|
+
branch = ref === 'HEAD' ? null : ref; // detached HEAD → null
|
|
43
|
+
}
|
|
44
|
+
catch { /* detached or other edge case */ }
|
|
45
|
+
let repoUrl = null;
|
|
46
|
+
try {
|
|
47
|
+
const raw = git('config', '--get', 'remote.origin.url');
|
|
48
|
+
if (raw)
|
|
49
|
+
repoUrl = sanitizeRemoteUrl(raw);
|
|
50
|
+
}
|
|
51
|
+
catch { /* no remote configured */ }
|
|
52
|
+
let dirty = false;
|
|
53
|
+
try {
|
|
54
|
+
const status = git('status', '--porcelain');
|
|
55
|
+
dirty = status.length > 0;
|
|
56
|
+
}
|
|
57
|
+
catch { /* best effort */ }
|
|
58
|
+
return { commit_sha: commitSha, branch, repo_url: repoUrl, dirty };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// git not installed, not a repo, or other fatal error
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":";;AA4CA,4CA4BC;AAxED,iDAA6C;AAa7C,MAAM,SAAS,GAAG,EAAE,QAAQ,EAAE,OAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhE,SAAS,GAAG,CAAC,GAAG,IAAc;IAC5B,OAAO,IAAA,4BAAY,EAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,wCAAwC;IACxC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;QAClB,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;QAClB,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,oCAAoC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB;IAC9B,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5B,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;YACrD,MAAM,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,uBAAuB;QAC/D,CAAC;QAAC,MAAM,CAAC,CAAC,iCAAiC,CAAC,CAAC;QAE7C,IAAI,OAAO,GAAkB,IAAI,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;YACxD,IAAI,GAAG;gBAAE,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;QAEtC,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;YAC5C,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAE7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.introspectSchema = void 0;
|
|
4
|
+
// Re-export from the root introspector package
|
|
5
|
+
var introspector_1 = require("@schemalens/introspector");
|
|
6
|
+
Object.defineProperty(exports, "introspectSchema", { enumerable: true, get: function () { return introspector_1.introspectSchema; } });
|
|
7
|
+
//# sourceMappingURL=introspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspector.js","sourceRoot":"","sources":["../../src/lib/introspector.ts"],"names":[],"mappings":";;;AAAA,+CAA+C;AAC/C,yDAA4D;AAAnD,gHAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SchemaSnapshot } from './introspector';
|
|
2
|
+
import type { DiskFile } from './reader';
|
|
3
|
+
export type OperationType = 'CREATE' | 'ALTER' | 'REPLACE' | 'DROP' | 'SKIP';
|
|
4
|
+
export interface DeployStep {
|
|
5
|
+
step: number;
|
|
6
|
+
filePath: string;
|
|
7
|
+
objectType: string;
|
|
8
|
+
objectName: string;
|
|
9
|
+
operation: OperationType;
|
|
10
|
+
sql: string;
|
|
11
|
+
destructive: boolean;
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface RenameCandidate {
|
|
15
|
+
table: string;
|
|
16
|
+
schema: string;
|
|
17
|
+
oldColumn: string;
|
|
18
|
+
newColumn: string;
|
|
19
|
+
type: string;
|
|
20
|
+
}
|
|
21
|
+
export interface DeployPlan {
|
|
22
|
+
steps: DeployStep[];
|
|
23
|
+
renames: RenameCandidate[];
|
|
24
|
+
hasDestructive: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function buildDeployPlan(diskFiles: DiskFile[], liveSnapshot: SchemaSnapshot, renames: Map<string, string>): DeployPlan;
|