hazo_env 0.4.0 → 0.5.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/CHANGE_LOG.md +15 -0
- package/config/hazo_env_config.ini.sample +18 -0
- package/dist/cli.js +38 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/migrate/clear.d.ts +3 -0
- package/dist/migrate/clear.d.ts.map +1 -0
- package/dist/migrate/clear.js +117 -0
- package/dist/migrate/db.d.ts +1 -0
- package/dist/migrate/db.d.ts.map +1 -1
- package/dist/migrate/db.postgrest.d.ts.map +1 -1
- package/dist/migrate/db.postgrest.js +3 -1
- package/dist/migrate/files.d.ts +2 -1
- package/dist/migrate/files.d.ts.map +1 -1
- package/dist/migrate/files.js +83 -0
- package/dist/migrate/run.d.ts.map +1 -1
- package/dist/migrate/run.js +5 -0
- package/dist/migrate/transport.d.ts +1 -1
- package/dist/migrate/transport.d.ts.map +1 -1
- package/dist/migrate/transport.js +2 -9
- package/dist/resolve/ssh.d.ts +15 -0
- package/dist/resolve/ssh.d.ts.map +1 -0
- package/dist/resolve/ssh.js +36 -0
- package/dist/types/index.d.ts +20 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGE_LOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# hazo_env — Change Log
|
|
2
2
|
|
|
3
|
+
## 0.5.0 — 2026-06-25
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `clearEnv()` — delete all non-preserved tables via PostgREST (reverse FK order) + optional file-dir wipe. Exported from `src/index.ts`. CLI: `hazo-env clear <env>` (prod-target guard: `--allow-prod-target --confirm=<token>`).
|
|
7
|
+
- `ClearRequest` / `ClearResult` types in `src/types/index.ts`; `'clear'` added to `MigrationProgress.phase` union.
|
|
8
|
+
- rsync-over-SSH file transport — `copyFiles()` auto-dispatches to rsync when `[transport.ssh.<fromEnv>]` is configured. `copyFilesRsync()` in `src/migrate/files.ts` spawns `rsync -az --partial --info=progress2`, parses `to-chk=N/TOTAL` for live percent. `onProgress` signature extended with optional `percent` arg.
|
|
9
|
+
- `resolveSshConfig(env)` in `src/resolve/ssh.ts` — reads `[transport.ssh.<env>]` section (host/user/key/path) with `${VAR}` expansion.
|
|
10
|
+
- `resolveTransport()` return type widened to `'local' | 'api' | 'rsync'`; `'ssh'` input now returns `'rsync'` instead of throwing.
|
|
11
|
+
- Per-table DB progress — `DbCopyOptions.onTableProgress` callback fires once per table during PostgREST copy pass; `run.ts` maps it to the 20→70% band with a `"table N/M: <name>"` message.
|
|
12
|
+
- `[transport.ssh.<env>]` section added to `config/hazo_env_config.ini.sample`.
|
|
13
|
+
|
|
14
|
+
### Test-app
|
|
15
|
+
- `POST /api/clear` route added (mirrors `/api/migrate`).
|
|
16
|
+
- `'clear-env'` autotest scenario added (dry-run guard: verifies prod-target refuses without confirm).
|
|
17
|
+
|
|
3
18
|
## 0.4.0 — 2026-06-25
|
|
4
19
|
|
|
5
20
|
### Added
|
|
@@ -62,3 +62,21 @@ location = remote
|
|
|
62
62
|
|
|
63
63
|
[host.prod]
|
|
64
64
|
location = remote
|
|
65
|
+
|
|
66
|
+
; ─── SSH transport for cross-host file rsync ─────────────────────────────────
|
|
67
|
+
; When [transport.ssh.<env>] is present, copyFiles will use rsync-over-SSH
|
|
68
|
+
; to pull files from that environment's file server instead of local copy.
|
|
69
|
+
; This enables prod→dev migration when both envs run on separate hosts.
|
|
70
|
+
|
|
71
|
+
[transport.ssh.prod]
|
|
72
|
+
; SSH connection to the prod file server (used when pulling prod→dev).
|
|
73
|
+
; The worker runs rsync FROM prod TO dev — prod stays read-only.
|
|
74
|
+
host = ${SSH_HOST_PROD}
|
|
75
|
+
user = ${SSH_USER_PROD}
|
|
76
|
+
key = ${SSH_KEY_PATH_PROD}
|
|
77
|
+
path = /home/pubs/kinstripe/var/uploads
|
|
78
|
+
; Optional: pin the server's host key (output of `ssh-keyscan <host>` minus the
|
|
79
|
+
; leading hostname, e.g. "ssh-ed25519 AAAA..."). When set, host-key checking is
|
|
80
|
+
; strict and pinned — no trust-on-first-use. When omitted, the first connection
|
|
81
|
+
; is accepted (accept-new) and persisted to config/hazo_env_known_hosts.
|
|
82
|
+
; host_key = ${SSH_HOST_KEY_PROD}
|
package/dist/cli.js
CHANGED
|
@@ -167,6 +167,39 @@ async function runRestore() {
|
|
|
167
167
|
restoreSnapshot(toConfig, snapshotId);
|
|
168
168
|
console.log(` ${pc.green('✓')} Restored\n`);
|
|
169
169
|
}
|
|
170
|
+
async function runClear() {
|
|
171
|
+
const targetEnv = args[0] ?? getEnv();
|
|
172
|
+
const allowProd = args.includes('--allow-prod-target');
|
|
173
|
+
const confirm = args.find((a) => a.startsWith('--confirm='))?.split('=')[1];
|
|
174
|
+
console.log(`\n${pc.bold('hazo-env clear')} ${pc.dim(targetEnv)}\n`);
|
|
175
|
+
const { clearEnv } = await import('./migrate/clear.js');
|
|
176
|
+
try {
|
|
177
|
+
let lastMsg = '';
|
|
178
|
+
const result = await clearEnv({
|
|
179
|
+
env: targetEnv,
|
|
180
|
+
allowProdTarget: allowProd,
|
|
181
|
+
confirmToken: confirm,
|
|
182
|
+
onProgress: (p) => {
|
|
183
|
+
if (p.message !== lastMsg) {
|
|
184
|
+
const pctStr = p.percent != null ? ` [${p.percent}%]` : '';
|
|
185
|
+
console.log(` ${pc.dim('·')} ${p.message}${pctStr}`);
|
|
186
|
+
lastMsg = p.message;
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
if (result.ok) {
|
|
191
|
+
console.log(` ${pc.green('✓')} Cleared ${result.tablesCleared} tables${result.filesCleared ? ' + files' : ''} in ${result.durationMs}ms\n`);
|
|
192
|
+
if (result.warnings.length)
|
|
193
|
+
result.warnings.forEach((w) => console.log(` ${pc.yellow('⚠')} ${w}`));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
198
|
+
console.error(`\n ${pc.red('✗')} ${msg}\n`);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
console.log('');
|
|
202
|
+
}
|
|
170
203
|
async function runMask() {
|
|
171
204
|
const subCmd = args[0];
|
|
172
205
|
if (subCmd === 'sync') {
|
|
@@ -239,6 +272,8 @@ Usage:
|
|
|
239
272
|
hazo-env snapshot <env> Take a snapshot of an environment
|
|
240
273
|
hazo-env mask sync Load masking ruleset from INI into DB
|
|
241
274
|
hazo-env mask list List registered mask transforms
|
|
275
|
+
hazo-env clear <env> Wipe DB tables + files for an environment
|
|
276
|
+
--allow-prod-target --confirm=<token> Override prod-target safety
|
|
242
277
|
`);
|
|
243
278
|
}
|
|
244
279
|
(async () => {
|
|
@@ -264,6 +299,9 @@ Usage:
|
|
|
264
299
|
else if (command === 'mask') {
|
|
265
300
|
await runMask();
|
|
266
301
|
}
|
|
302
|
+
else if (command === 'clear') {
|
|
303
|
+
await runClear();
|
|
304
|
+
}
|
|
267
305
|
else {
|
|
268
306
|
printHelp();
|
|
269
307
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './resolve/connect.js';
|
|
|
6
6
|
export * from './resolve/files.js';
|
|
7
7
|
export * from './doctor.js';
|
|
8
8
|
export { runMigration } from './migrate/run.js';
|
|
9
|
+
export { clearEnv } from './migrate/clear.js';
|
|
9
10
|
export { verifyFiles } from './migrate/verify.js';
|
|
10
11
|
export { takeSnapshot, restoreSnapshot } from './migrate/snapshot.js';
|
|
11
12
|
export { writeMigrationProgress, readMigrationProgress, clearMigrationProgress } from './migrate/progress.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEvG,cAAc,kBAAkB,CAAC;AAEjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE9G,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEvG,cAAc,kBAAkB,CAAC;AAEjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE9G,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export * from './resolve/files.js';
|
|
|
13
13
|
export * from './doctor.js';
|
|
14
14
|
// Migration engine (Phase 2)
|
|
15
15
|
export { runMigration } from './migrate/run.js';
|
|
16
|
+
export { clearEnv } from './migrate/clear.js';
|
|
16
17
|
export { verifyFiles } from './migrate/verify.js';
|
|
17
18
|
export { takeSnapshot, restoreSnapshot } from './migrate/snapshot.js';
|
|
18
19
|
export { writeMigrationProgress, readMigrationProgress, clearMigrationProgress } from './migrate/progress.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../src/migrate/clear.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,mBAAmB,CAAC;AAYtF,wBAAsB,QAAQ,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAoHtE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// hazo_env/src/migrate/clear.ts — clearEnv: wipe DB tables + files for a target environment
|
|
2
|
+
import { HazoError, optional_import } from 'hazo_core';
|
|
3
|
+
import { getEnvRole } from '../env.server.js';
|
|
4
|
+
import { resolveMigrateConfig } from '../resolve/migrate.js';
|
|
5
|
+
import { resolveConnectConfig } from '../resolve/connect.js';
|
|
6
|
+
import { resolveFilesRoot } from '../resolve/files.js';
|
|
7
|
+
import { writeMigrationProgress } from './progress.js';
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
function emitProgress(req, p) {
|
|
10
|
+
req.onProgress?.(p);
|
|
11
|
+
if (req.jobId && req.progressDir) {
|
|
12
|
+
writeMigrationProgress(req.progressDir, req.jobId, p);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function clearEnv(req) {
|
|
16
|
+
const startMs = Date.now();
|
|
17
|
+
const warnings = [];
|
|
18
|
+
// Guard: refuse production target unless explicitly unlocked with a confirm token
|
|
19
|
+
const role = getEnvRole(req.env);
|
|
20
|
+
if (role === 'production' && !req.allowProdTarget) {
|
|
21
|
+
throw new HazoError({
|
|
22
|
+
code: 'HAZO_ENV_PROD_TARGET_REFUSED',
|
|
23
|
+
pkg: 'hazo_env',
|
|
24
|
+
message: `Refusing to clear production environment "${req.env}". Pass allowProdTarget:true and a confirmToken to override.`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (role === 'production' && req.allowProdTarget && !req.confirmToken) {
|
|
28
|
+
throw new HazoError({
|
|
29
|
+
code: 'HAZO_ENV_PROD_TARGET_REFUSED',
|
|
30
|
+
pkg: 'hazo_env',
|
|
31
|
+
message: 'Production target requires a confirmToken for safety.',
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
emitProgress(req, { phase: 'validate', message: 'Validating clear request', percent: 0 });
|
|
35
|
+
const migrateConfig = resolveMigrateConfig();
|
|
36
|
+
const { tables, preserve = [], pkOverrides = {} } = migrateConfig;
|
|
37
|
+
if (!tables || tables.length === 0) {
|
|
38
|
+
throw new HazoError({
|
|
39
|
+
code: 'HAZO_ENV_MISSING_TABLE_LIST',
|
|
40
|
+
pkg: 'hazo_env',
|
|
41
|
+
message: 'clearEnv requires an explicit table list. ' +
|
|
42
|
+
'Set [migrate] tables = ... in hazo_env_config.ini.',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const tablesToClear = [...tables.filter((t) => !preserve.includes(t))].reverse();
|
|
46
|
+
const dbConfig = resolveConnectConfig({ env: req.env, allowOtherEnv: true });
|
|
47
|
+
if (dbConfig.type !== 'postgrest') {
|
|
48
|
+
throw new HazoError({
|
|
49
|
+
code: 'HAZO_ENV_NOT_IMPLEMENTED',
|
|
50
|
+
pkg: 'hazo_env',
|
|
51
|
+
message: `clearEnv only supports PostgREST connections (got "${dbConfig.type}").`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (!dbConfig.postgrest) {
|
|
55
|
+
throw new HazoError({
|
|
56
|
+
code: 'HAZO_ENV_NOT_IMPLEMENTED',
|
|
57
|
+
pkg: 'hazo_env',
|
|
58
|
+
message: 'PostgREST config missing base_url/api_key.',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const connect = await optional_import('hazo_connect/server');
|
|
62
|
+
if (!connect) {
|
|
63
|
+
throw new HazoError({
|
|
64
|
+
code: 'HAZO_ENV_MISSING_DEPENDENCY',
|
|
65
|
+
pkg: 'hazo_env',
|
|
66
|
+
message: 'hazo_connect is required for clearEnv. Install hazo_connect to continue.',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const tgtAdapter = connect.createHazoConnect({
|
|
70
|
+
type: 'postgrest',
|
|
71
|
+
postgrest: {
|
|
72
|
+
base_url: dbConfig.postgrest.base_url,
|
|
73
|
+
api_key: dbConfig.postgrest.api_key,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
// DB clear (only if not explicitly disabled)
|
|
77
|
+
let tablesCleared = 0;
|
|
78
|
+
if (req.include?.db !== false) {
|
|
79
|
+
for (let idx = 0; idx < tablesToClear.length; idx++) {
|
|
80
|
+
const table = tablesToClear[idx];
|
|
81
|
+
const percent = Math.round(((idx + 1) / tablesToClear.length) * 90);
|
|
82
|
+
emitProgress(req, {
|
|
83
|
+
phase: 'clear',
|
|
84
|
+
message: `Clearing table ${idx + 1}/${tablesToClear.length}: ${table}`,
|
|
85
|
+
percent,
|
|
86
|
+
});
|
|
87
|
+
const pk = pkOverrides[table] ?? 'id';
|
|
88
|
+
try {
|
|
89
|
+
await tgtAdapter.rawQuery(`/${table}?${pk}=not.is.null`, { method: 'DELETE' });
|
|
90
|
+
tablesCleared++;
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
94
|
+
warnings.push(`Warning: could not clear ${table}: ${msg}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// File clear
|
|
99
|
+
let filesCleared = false;
|
|
100
|
+
if (req.include?.files !== false) {
|
|
101
|
+
emitProgress(req, { phase: 'clear', message: 'Clearing files...', percent: 92 });
|
|
102
|
+
const filesRoot = resolveFilesRoot(req.env);
|
|
103
|
+
if (fs.existsSync(filesRoot)) {
|
|
104
|
+
fs.rmSync(filesRoot, { recursive: true, force: true });
|
|
105
|
+
}
|
|
106
|
+
fs.mkdirSync(filesRoot, { recursive: true });
|
|
107
|
+
filesCleared = true;
|
|
108
|
+
}
|
|
109
|
+
emitProgress(req, { phase: 'done', message: 'Clear complete', percent: 100 });
|
|
110
|
+
return {
|
|
111
|
+
ok: true,
|
|
112
|
+
tablesCleared,
|
|
113
|
+
filesCleared,
|
|
114
|
+
durationMs: Date.now() - startMs,
|
|
115
|
+
warnings,
|
|
116
|
+
};
|
|
117
|
+
}
|
package/dist/migrate/db.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface DbCopyOptions {
|
|
|
6
6
|
pkOverrides?: Record<string, string>;
|
|
7
7
|
scrubHook?: (tableName: string, row: Record<string, unknown>) => Record<string, unknown>;
|
|
8
8
|
onProgress?: (msg: string) => void;
|
|
9
|
+
onTableProgress?: (tableIdx: number, totalTables: number, tableName: string) => void;
|
|
9
10
|
}
|
|
10
11
|
export interface DbCopyResult {
|
|
11
12
|
tables: number;
|
package/dist/migrate/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/migrate/db.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC9B,MAAM,CAAC,EAAE,GAAG,GAAG,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/migrate/db.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC9B,MAAM,CAAC,EAAE,GAAG,GAAG,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACtF;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AA6BD,wBAAsB,MAAM,CAC1B,UAAU,EAAE,kBAAkB,EAC9B,UAAU,EAAE,kBAAkB,EAC9B,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,YAAY,CAAC,CAqHvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.postgrest.d.ts","sourceRoot":"","sources":["../../src/migrate/db.postgrest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAM3D,wBAAsB,eAAe,CACnC,UAAU,EAAE,kBAAkB,EAC9B,UAAU,EAAE,kBAAkB,EAC9B,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"db.postgrest.d.ts","sourceRoot":"","sources":["../../src/migrate/db.postgrest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAM3D,wBAAsB,eAAe,CACnC,UAAU,EAAE,kBAAkB,EAC9B,UAAU,EAAE,kBAAkB,EAC9B,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,YAAY,CAAC,CA+GvB"}
|
|
@@ -43,7 +43,9 @@ export async function copyDbPostgrest(srcAdapter, tgtAdapter, opts = {}) {
|
|
|
43
43
|
let totalScrubbed = 0;
|
|
44
44
|
// --- Copy pass: forward dependency order ---
|
|
45
45
|
for (const table of tablesToProcess) {
|
|
46
|
-
|
|
46
|
+
const tableIdx = tablesToProcess.indexOf(table);
|
|
47
|
+
opts.onProgress?.(`Copying table ${tableIdx + 1}/${tablesToProcess.length}: ${table}`);
|
|
48
|
+
opts.onTableProgress?.(tableIdx + 1, tablesToProcess.length, table);
|
|
47
49
|
const pk = pkOverrides[table] ?? 'id';
|
|
48
50
|
const srcService = connect.createCrudService(srcAdapter, table, { autoId: false });
|
|
49
51
|
const tgtService = connect.createCrudService(tgtAdapter, table, { autoId: false });
|
package/dist/migrate/files.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ import type { HazoEnv } from '../types/index.js';
|
|
|
2
2
|
export interface FilesCopyOptions {
|
|
3
3
|
fromEnv: HazoEnv;
|
|
4
4
|
toEnv: HazoEnv;
|
|
5
|
+
transport?: 'local' | 'rsync';
|
|
5
6
|
fileScrubHook?: (filePath: string) => Promise<void>;
|
|
6
|
-
onProgress?: (msg: string) => void;
|
|
7
|
+
onProgress?: (msg: string, percent?: number) => void;
|
|
7
8
|
}
|
|
8
9
|
export interface FilesCopyResult {
|
|
9
10
|
copied: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/migrate/files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/migrate/files.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;CACvB;AA6GD,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAkDhF"}
|
package/dist/migrate/files.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
// Failures are non-fatal warnings — the file copy still completes.
|
|
7
7
|
import fs from 'node:fs';
|
|
8
8
|
import path from 'node:path';
|
|
9
|
+
import { spawn } from 'node:child_process';
|
|
9
10
|
import { resolveFilesRoot } from '../resolve/files.js';
|
|
11
|
+
import { resolveSshConfig } from '../resolve/ssh.js';
|
|
10
12
|
function resolveEnvFilesRoot(env) {
|
|
11
13
|
return resolveFilesRoot(env);
|
|
12
14
|
}
|
|
@@ -29,7 +31,88 @@ async function scrubPdfFile(filePath) {
|
|
|
29
31
|
// Non-fatal — PDF scrubbing failure is a warning, not an abort
|
|
30
32
|
}
|
|
31
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Reject ssh config values that could smuggle extra ssh options through rsync's
|
|
36
|
+
* `-e` command string. rsync re-splits `-e` on whitespace, so a value starting
|
|
37
|
+
* with `-` (e.g. `-oProxyCommand=...`) or containing whitespace would be parsed
|
|
38
|
+
* as additional ssh flags rather than data. Fail loud instead of running.
|
|
39
|
+
*/
|
|
40
|
+
function assertSafeSshField(name, value) {
|
|
41
|
+
if (/^-/.test(value) || /\s/.test(value)) {
|
|
42
|
+
throw new Error(`Unsafe transport.ssh.${name} value: must not start with '-' or contain whitespace`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function copyFilesRsync(opts, ssh) {
|
|
46
|
+
const tgtRoot = resolveEnvFilesRoot(opts.toEnv);
|
|
47
|
+
fs.mkdirSync(tgtRoot, { recursive: true });
|
|
48
|
+
assertSafeSshField('user', ssh.user);
|
|
49
|
+
assertSafeSshField('host', ssh.host);
|
|
50
|
+
assertSafeSshField('key', ssh.key);
|
|
51
|
+
assertSafeSshField('path', ssh.path);
|
|
52
|
+
// Persistent known_hosts so host-key trust survives across runs (no TOFU reset).
|
|
53
|
+
const knownHosts = path.resolve(process.cwd(), 'config', 'hazo_env_known_hosts');
|
|
54
|
+
fs.mkdirSync(path.dirname(knownHosts), { recursive: true });
|
|
55
|
+
if (ssh.hostKey) {
|
|
56
|
+
// Pin the operator-provided host key; strict checking, no first-use prompt.
|
|
57
|
+
const line = `${ssh.host} ${ssh.hostKey}\n`;
|
|
58
|
+
const existing = fs.existsSync(knownHosts) ? fs.readFileSync(knownHosts, 'utf8') : '';
|
|
59
|
+
if (!existing.includes(line.trim()))
|
|
60
|
+
fs.appendFileSync(knownHosts, line);
|
|
61
|
+
}
|
|
62
|
+
// Pinned key → strict verify; otherwise accept-new (trust on first use, then
|
|
63
|
+
// persist) — never disable host-key checking outright.
|
|
64
|
+
const strict = ssh.hostKey ? 'yes' : 'accept-new';
|
|
65
|
+
const remote = `${ssh.user}@${ssh.host}:${ssh.path}/`;
|
|
66
|
+
const sshCmd = `ssh -i ${ssh.key} -o StrictHostKeyChecking=${strict} -o UserKnownHostsFile=${knownHosts}`;
|
|
67
|
+
const args = ['-az', '--partial', '--info=progress2', '-e', sshCmd, remote, tgtRoot + '/'];
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const proc = spawn('rsync', args);
|
|
70
|
+
let totalFiles = 0;
|
|
71
|
+
let doneFiles = 0;
|
|
72
|
+
let totalBytes = 0;
|
|
73
|
+
proc.stdout.on('data', (chunk) => {
|
|
74
|
+
const text = chunk.toString();
|
|
75
|
+
// Parse --info=progress2: lines like " 117,504,614 100% 108.64MB/s 0:00:01 (xfr#123, to-chk=0/456)"
|
|
76
|
+
for (const line of text.split('\n')) {
|
|
77
|
+
// Extract to-chk=N/TOTAL
|
|
78
|
+
const chkMatch = line.match(/to-chk=(\d+)\/(\d+)/);
|
|
79
|
+
if (chkMatch) {
|
|
80
|
+
const remaining = parseInt(chkMatch[1], 10);
|
|
81
|
+
const total = parseInt(chkMatch[2], 10);
|
|
82
|
+
if (totalFiles === 0)
|
|
83
|
+
totalFiles = total;
|
|
84
|
+
doneFiles = total - remaining;
|
|
85
|
+
const pct = total > 0 ? Math.round((doneFiles / total) * 100) : 0;
|
|
86
|
+
opts.onProgress?.(`rsync: ${doneFiles}/${total} files (${pct}%)`, pct);
|
|
87
|
+
}
|
|
88
|
+
// Extract bytes: first number on lines with a %
|
|
89
|
+
const bytesMatch = line.match(/^\s+([\d,]+)\s+\d+%/);
|
|
90
|
+
if (bytesMatch) {
|
|
91
|
+
totalBytes = parseInt(bytesMatch[1].replace(/,/g, ''), 10);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
proc.stderr.on('data', (chunk) => {
|
|
96
|
+
opts.onProgress?.(`rsync: ${chunk.toString().trim()}`, undefined);
|
|
97
|
+
});
|
|
98
|
+
proc.on('error', (err) => reject(err));
|
|
99
|
+
proc.on('close', (code) => {
|
|
100
|
+
if (code !== 0) {
|
|
101
|
+
reject(new Error(`rsync exited with code ${code}`));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
resolve({ copied: doneFiles || totalFiles, bytes: totalBytes, placeholdered: 0 });
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
32
109
|
export async function copyFiles(opts) {
|
|
110
|
+
const ssh = resolveSshConfig(opts.fromEnv);
|
|
111
|
+
if (opts.transport === 'rsync' || (opts.transport !== 'local' && ssh !== null)) {
|
|
112
|
+
if (!ssh)
|
|
113
|
+
throw new Error(`rsync requested but no [transport.ssh.${opts.fromEnv}] config found`);
|
|
114
|
+
return copyFilesRsync(opts, ssh);
|
|
115
|
+
}
|
|
33
116
|
const srcRoot = resolveEnvFilesRoot(opts.fromEnv);
|
|
34
117
|
const tgtRoot = resolveEnvFilesRoot(opts.toEnv);
|
|
35
118
|
if (!fs.existsSync(srcRoot)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/migrate/run.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAkC,MAAM,mBAAmB,CAAC;AA0D3G,wBAAsB,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/migrate/run.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAkC,MAAM,mBAAmB,CAAC;AA0D3G,wBAAsB,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwLlF"}
|
package/dist/migrate/run.js
CHANGED
|
@@ -180,6 +180,11 @@ export async function runMigration(req) {
|
|
|
180
180
|
pkOverrides: migrateConfig.pkOverrides,
|
|
181
181
|
scrubHook,
|
|
182
182
|
onProgress: (msg) => emitProgress(req, { phase: 'db', message: msg }),
|
|
183
|
+
onTableProgress: (idx, total, name) => emitProgress(req, {
|
|
184
|
+
phase: 'db',
|
|
185
|
+
message: `table ${idx}/${total}: ${name}`,
|
|
186
|
+
percent: 20 + Math.round((idx / total) * 50),
|
|
187
|
+
}),
|
|
183
188
|
});
|
|
184
189
|
dbResult = result;
|
|
185
190
|
emitProgress(req, { phase: 'db', message: `DB copy complete: ${result.tables} tables, ${result.rows} rows`, percent: 70 });
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { TransportMode, DbEnvConfig } from '../types/index.js';
|
|
2
|
-
export declare function resolveTransport(fromConfig: DbEnvConfig, toConfig: DbEnvConfig, requested?: TransportMode): 'local' | 'api';
|
|
2
|
+
export declare function resolveTransport(fromConfig: DbEnvConfig, toConfig: DbEnvConfig, requested?: TransportMode): 'local' | 'api' | 'rsync';
|
|
3
3
|
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/migrate/transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/migrate/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEpE,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,WAAW,EACvB,QAAQ,EAAE,WAAW,EACrB,SAAS,GAAE,aAAsB,GAChC,OAAO,GAAG,KAAK,GAAG,OAAO,CAM3B"}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
// hazo_env/src/migrate/transport.ts — resolve transport mode for a migration
|
|
2
|
-
import { HazoError } from 'hazo_core';
|
|
3
1
|
export function resolveTransport(fromConfig, toConfig, requested = 'auto') {
|
|
4
|
-
if (requested === 'ssh')
|
|
5
|
-
|
|
6
|
-
code: 'HAZO_ENV_NOT_IMPLEMENTED',
|
|
7
|
-
pkg: 'hazo_env',
|
|
8
|
-
message: 'SSH transport is not yet implemented. Use local or api transport.',
|
|
9
|
-
});
|
|
10
|
-
}
|
|
2
|
+
if (requested === 'ssh')
|
|
3
|
+
return 'rsync';
|
|
11
4
|
if (requested === 'api')
|
|
12
5
|
return 'api';
|
|
13
6
|
// auto: both sqlite → local
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface SshConfig {
|
|
2
|
+
host: string;
|
|
3
|
+
user: string;
|
|
4
|
+
key: string;
|
|
5
|
+
path: string;
|
|
6
|
+
/**
|
|
7
|
+
* Optional pinned host public key (the right-hand side of a known_hosts line,
|
|
8
|
+
* e.g. "ssh-ed25519 AAAA...."). When set, host-key checking is strict and the
|
|
9
|
+
* key is pinned — no TOFU. When absent, the transport falls back to
|
|
10
|
+
* accept-new against a persistent known_hosts file.
|
|
11
|
+
*/
|
|
12
|
+
hostKey?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function resolveSshConfig(env: string): SshConfig | null;
|
|
15
|
+
//# sourceMappingURL=ssh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../src/resolve/ssh.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAcD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAsB9D"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// hazo_env/src/resolve/ssh.ts — SSH transport config resolver
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { HazoConfig } from 'hazo_config/server';
|
|
4
|
+
function tryLoadEnvConfig() {
|
|
5
|
+
try {
|
|
6
|
+
return new HazoConfig({ filePath: path.resolve(process.cwd(), 'config', 'hazo_env_config.ini') });
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function expandEnvVars(value) {
|
|
13
|
+
return value.replace(/\$\{([^}]+)\}/g, (_, name) => process.env[name] ?? '');
|
|
14
|
+
}
|
|
15
|
+
export function resolveSshConfig(env) {
|
|
16
|
+
const config = tryLoadEnvConfig();
|
|
17
|
+
if (!config)
|
|
18
|
+
return null;
|
|
19
|
+
const section = config.getSection(`transport.ssh.${env}`);
|
|
20
|
+
if (!section)
|
|
21
|
+
return null;
|
|
22
|
+
const host = section['host'];
|
|
23
|
+
const user = section['user'];
|
|
24
|
+
const key = section['key'];
|
|
25
|
+
const remotePath = section['path'];
|
|
26
|
+
const hostKey = section['host_key'];
|
|
27
|
+
if (!host || !user || !key || !remotePath)
|
|
28
|
+
return null;
|
|
29
|
+
return {
|
|
30
|
+
host: expandEnvVars(host),
|
|
31
|
+
user: expandEnvVars(user),
|
|
32
|
+
key: expandEnvVars(key),
|
|
33
|
+
path: expandEnvVars(remotePath),
|
|
34
|
+
hostKey: hostKey ? expandEnvVars(hostKey) : undefined,
|
|
35
|
+
};
|
|
36
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export type TransportMode = 'auto' | 'local' | 'ssh' | 'api';
|
|
|
47
47
|
export type ScrubMode = 'auto' | 'none';
|
|
48
48
|
export type HashMode = 'none' | 'sample' | 'full';
|
|
49
49
|
export interface MigrationProgress {
|
|
50
|
-
phase: 'validate' | 'snapshot' | 'plan' | 'schema-check' | 'db' | 'files' | 'verify' | 'finalize' | 'done';
|
|
50
|
+
phase: 'validate' | 'snapshot' | 'plan' | 'schema-check' | 'db' | 'files' | 'verify' | 'finalize' | 'done' | 'clear';
|
|
51
51
|
message: string;
|
|
52
52
|
percent?: number;
|
|
53
53
|
}
|
|
@@ -102,5 +102,24 @@ export interface MigrateConfig {
|
|
|
102
102
|
preserve?: string[];
|
|
103
103
|
pkOverrides?: Record<string, string>;
|
|
104
104
|
}
|
|
105
|
+
export interface ClearRequest {
|
|
106
|
+
env: HazoEnv;
|
|
107
|
+
include?: {
|
|
108
|
+
db?: boolean;
|
|
109
|
+
files?: boolean;
|
|
110
|
+
};
|
|
111
|
+
allowProdTarget?: boolean;
|
|
112
|
+
confirmToken?: string;
|
|
113
|
+
jobId?: string;
|
|
114
|
+
progressDir?: string;
|
|
115
|
+
onProgress?: (p: MigrationProgress) => void;
|
|
116
|
+
}
|
|
117
|
+
export interface ClearResult {
|
|
118
|
+
ok: boolean;
|
|
119
|
+
tablesCleared: number;
|
|
120
|
+
filesCleared: boolean;
|
|
121
|
+
durationMs: number;
|
|
122
|
+
warnings: string[];
|
|
123
|
+
}
|
|
105
124
|
export type MaskTransform = (value: unknown, key: string, maskKey: string) => unknown;
|
|
106
125
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAEA,sDAAsD;AACtD,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnE,mCAAmC;AACnC,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;AAE5E,iFAAiF;AACjF,MAAM,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC;AAElC,0EAA0E;AAC1E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAErD,2CAA2C;AAC3C,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtD,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC7B,MAAM,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACnD;AAED,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;CACH;AAED,8BAA8B;AAC9B,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,uCAAuC;AACvC,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAID,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC;AAC7D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AACxC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,cAAc,GAAG,IAAI,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED