pgpm 5.19.1 → 5.21.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 (46) hide show
  1. package/commands/cache.js +1 -1
  2. package/commands/diff.d.ts +3 -0
  3. package/commands/diff.js +359 -0
  4. package/commands/dump.js +3 -3
  5. package/commands/export.js +24 -5
  6. package/commands/import.d.ts +3 -0
  7. package/commands/import.js +235 -0
  8. package/commands/init/boilerplate.js +1 -1
  9. package/commands/init/index.js +3 -3
  10. package/commands/package.js +0 -1
  11. package/commands/slice.js +1 -1
  12. package/commands/test-packages.js +1 -1
  13. package/commands/transform.d.ts +13 -0
  14. package/commands/transform.js +317 -0
  15. package/commands/update.js +1 -1
  16. package/commands.js +7 -0
  17. package/esm/commands/cache.js +1 -1
  18. package/esm/commands/diff.js +324 -0
  19. package/esm/commands/dump.js +3 -3
  20. package/esm/commands/export.js +22 -3
  21. package/esm/commands/import.js +200 -0
  22. package/esm/commands/init/boilerplate.js +1 -1
  23. package/esm/commands/init/index.js +3 -3
  24. package/esm/commands/package.js +0 -1
  25. package/esm/commands/slice.js +1 -1
  26. package/esm/commands/test-packages.js +1 -1
  27. package/esm/commands/transform.js +278 -0
  28. package/esm/commands/update.js +1 -1
  29. package/esm/commands.js +7 -0
  30. package/esm/utils/display.js +3 -0
  31. package/esm/utils/driver.js +1 -1
  32. package/esm/utils/emit-package.js +1 -0
  33. package/esm/utils/engine.js +1 -1
  34. package/esm/utils/module-projections.js +82 -0
  35. package/esm/utils/scratch-db.js +61 -0
  36. package/package.json +14 -12
  37. package/utils/display.d.ts +1 -1
  38. package/utils/display.js +3 -0
  39. package/utils/driver.js +1 -1
  40. package/utils/emit-package.d.ts +9 -0
  41. package/utils/emit-package.js +7 -0
  42. package/utils/engine.js +1 -1
  43. package/utils/module-projections.d.ts +36 -0
  44. package/utils/module-projections.js +123 -0
  45. package/utils/scratch-db.d.ts +16 -0
  46. package/utils/scratch-db.js +66 -0
package/commands/cache.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const inquirerer_1 = require("inquirerer");
4
3
  const genomic_1 = require("genomic");
4
+ const inquirerer_1 = require("inquirerer");
5
5
  const cacheUsageText = `
6
6
  Cache Command:
7
7
 
@@ -0,0 +1,3 @@
1
+ import { CLIOptions, Inquirerer, ParsedArgs } from 'inquirerer';
2
+ declare const _default: (argv: Partial<ParsedArgs>, prompter: Inquirerer, _options: CLIOptions) => Promise<Partial<ParsedArgs>>;
3
+ export default _default;
@@ -0,0 +1,359 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const core_1 = require("@pgpmjs/core");
37
+ const diff_1 = require("@pgpmjs/diff");
38
+ const logger_1 = require("@pgpmjs/logger");
39
+ const transform_1 = require("@pgpmjs/transform");
40
+ const child_process_1 = require("child_process");
41
+ const fs = __importStar(require("fs"));
42
+ const inquirerer_1 = require("inquirerer");
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ const pg_cache_1 = require("pg-cache");
46
+ const pg_env_1 = require("pg-env");
47
+ const module_projections_1 = require("../utils/module-projections");
48
+ const scratch_db_1 = require("../utils/scratch-db");
49
+ const log = new logger_1.Logger('diff');
50
+ const diffUsageText = `
51
+ Diff Command:
52
+
53
+ pgpm diff <A> <B> [OPTIONS]
54
+
55
+ Identity-keyed semantic diff between two schema sources. Each side is
56
+ normalized to an object set keyed by identity (kind/schema/name), so the
57
+ same schema authored at different granularity, naming, or partitioning
58
+ diffs as empty. Tables are compared column-by-column and
59
+ constraint-by-constraint, so table changes emit ALTER TABLE, not a rebuild.
60
+
61
+ Sides:
62
+ <A> / <B> may each be:
63
+ - a pgpm module directory (flattened in plan order)
64
+ - a raw .sql file
65
+ - a live database: a postgres:// connection string, or db:<name>
66
+ (uses PG* env for host/port/user; schema is read via pg_dump)
67
+
68
+ The delta is one model; every --emit-* flag is a projection of it, so they
69
+ compose (a single run can emit a module, a linear SQL file, and a bundle).
70
+
71
+ Options:
72
+ --help, -h Show this help message
73
+ --emit-migration <dir> Write the delta as a pgpm module (deploy/revert/
74
+ verify per change, spec-derived paths, graph-derived
75
+ requires) into <dir>/<pkg>
76
+ --emit-module <dir> Alias of --emit-migration
77
+ --append-module <dir> Append the delta into an EXISTING pgpm module at
78
+ <dir> (new changes only; existing changes, scripts,
79
+ and .control are left untouched). Standalone: not
80
+ combinable with --emit-*/--verify.
81
+ --emit-sql <file|-> Also project the delta to a single consolidated SQL
82
+ file (deparsed in plan order); - writes to stdout
83
+ --emit-bundle <file> Also project the delta to a content-addressed
84
+ .bundle.tar.gz archive
85
+ --pkg <name> Emitted migration package name (default: diff-migration)
86
+ --granularity <level> Granularity for emitted changes: atomic | object |
87
+ consolidated (default: object)
88
+ --change-granularity <level>
89
+ Change-level distribution for emitted changes:
90
+ alteration | object | single (default: object)
91
+ --naming <style> Change path naming style: directory | flat (default: directory)
92
+ --json Machine-readable output
93
+ --verify Oracle mode: deploy A plus the emitted migration into
94
+ a scratch database and assert catalog equivalence
95
+ with B deployed fresh
96
+ --cwd <directory> Working directory (default: current directory)
97
+
98
+ Exit status: 0 when the sides are identical or the diff succeeds; non-zero on
99
+ error or when --verify finds the migrated catalog differs from B.
100
+
101
+ Examples:
102
+ pgpm diff ./v1-module ./v2-module
103
+ pgpm diff ./v1-module ./schema-v2.sql --json
104
+ pgpm diff db:app_v1 db:app_v2 --emit-migration ./out --verify
105
+ `;
106
+ const NAMING_STYLES = ['directory', 'flat'];
107
+ /** pg_dump a side's schema: `db:<name>` uses PG* env; DSNs pass through. */
108
+ const dumpDatabase = async (spec) => {
109
+ const args = ['--schema-only', '--no-owner'];
110
+ let env = process.env;
111
+ if (spec.startsWith('db:')) {
112
+ const config = (0, pg_env_1.getPgEnvOptions)({ database: spec.slice(3) });
113
+ env = (0, pg_env_1.getSpawnEnvWithPg)(config);
114
+ }
115
+ else {
116
+ args.push('--dbname', spec);
117
+ }
118
+ return new Promise((resolve, reject) => {
119
+ const child = (0, child_process_1.spawn)('pg_dump', args, { env, stdio: ['ignore', 'pipe', 'pipe'] });
120
+ let out = '';
121
+ let err = '';
122
+ child.stdout.on('data', chunk => { out += chunk; });
123
+ child.stderr.on('data', chunk => { err += chunk; });
124
+ child.on('error', (e) => {
125
+ if (e.code === 'ENOENT') {
126
+ reject(new Error('pg_dump not found; ensure PostgreSQL client tools are installed and in PATH'));
127
+ return;
128
+ }
129
+ reject(e);
130
+ });
131
+ child.on('close', code => {
132
+ if (code === 0)
133
+ resolve(out);
134
+ else
135
+ reject(new Error(`pg_dump exited with code ${code}: ${err.trim()}`));
136
+ });
137
+ });
138
+ };
139
+ /** Resolve one side spec into diff input changes. */
140
+ const loadSide = async (spec, cwd) => {
141
+ if (resolveDiffSideKindSafe(spec) === 'database') {
142
+ const label = spec.startsWith('db:') ? spec.slice(3) : spec;
143
+ return {
144
+ kind: 'database',
145
+ label,
146
+ changes: (0, diff_1.sqlToDiffChanges)(await dumpDatabase(spec), label),
147
+ warnings: []
148
+ };
149
+ }
150
+ return (0, diff_1.loadDiffSideFromDisk)(path.resolve(cwd, spec));
151
+ };
152
+ /** `resolveDiffSideKind` without throwing on relative on-disk paths. */
153
+ const resolveDiffSideKindSafe = (spec) => /^postgres(ql)?:\/\//.test(spec) || spec.startsWith('db:') ? 'database' : 'disk';
154
+ /** Apply one diff side into a scratch database (module deploy or raw SQL). */
155
+ const applySide = async (config, side, spec, cwd) => {
156
+ if (side.kind === 'module') {
157
+ const client = new core_1.PgpmMigrate(config);
158
+ const result = await client.deploy({ modulePath: path.resolve(cwd, spec) });
159
+ if (result.failed) {
160
+ throw new Error(`deploy failed at change ${result.failed} (module ${spec})`);
161
+ }
162
+ return;
163
+ }
164
+ const pool = (0, pg_cache_1.getPgPool)(config);
165
+ const sql = side.changes.map(c => c.deploy).filter(Boolean).join('\n\n');
166
+ if (sql.trim())
167
+ await pool.query(sql);
168
+ };
169
+ /**
170
+ * Oracle mode: deploy A into a scratch database, deploy the emitted migration
171
+ * module on top (when there is one), and assert catalog equivalence with B
172
+ * deployed fresh into a second scratch database. Column order is physical — a
173
+ * drop+add migration cannot reproduce a fresh deploy's ordinals — so
174
+ * equivalence is checked order-insensitively via `withoutColumnOrder`.
175
+ */
176
+ const runVerify = async (sideA, sideB, specA, specB, migrationDir, cwd) => {
177
+ const config = (0, pg_env_1.getPgEnvOptions)();
178
+ const stamp = Date.now();
179
+ const names = [`pgpm_diff_verify_a_${stamp}`, `pgpm_diff_verify_b_${stamp}`];
180
+ return (0, scratch_db_1.withScratchDatabases)(config, names, async ([cfgMigrated, cfgTarget]) => {
181
+ await applySide(cfgMigrated, sideA, specA, cwd);
182
+ if (migrationDir) {
183
+ const result = await new core_1.PgpmMigrate(cfgMigrated).deploy({ modulePath: migrationDir });
184
+ if (result.failed) {
185
+ throw new Error(`migration deploy failed at change ${result.failed}`);
186
+ }
187
+ }
188
+ await applySide(cfgTarget, sideB, specB, cwd);
189
+ return (0, scratch_db_1.catalogDifferences)(cfgMigrated, cfgTarget, transform_1.withoutColumnOrder);
190
+ });
191
+ };
192
+ const printSummary = (result, labelA, labelB) => {
193
+ if (result.identical) {
194
+ console.log(`No differences: ${labelA} and ${labelB} describe the same objects.`);
195
+ return;
196
+ }
197
+ const byDelta = (delta) => result.objects.filter(o => o.delta === delta);
198
+ const section = (title, objects) => {
199
+ if (objects.length === 0)
200
+ return;
201
+ console.log(`${title} (${objects.length}):`);
202
+ for (const obj of objects) {
203
+ const detail = [];
204
+ if (obj.columnsAdded?.length)
205
+ detail.push(`+cols: ${obj.columnsAdded.join(', ')}`);
206
+ if (obj.columnsRemoved?.length)
207
+ detail.push(`-cols: ${obj.columnsRemoved.join(', ')}`);
208
+ if (obj.columnsModified?.length)
209
+ detail.push(`~cols: ${obj.columnsModified.join(', ')}`);
210
+ console.log(` ${obj.identity.kind} ${obj.path}${detail.length ? ` (${detail.join('; ')})` : ''}`);
211
+ }
212
+ };
213
+ section('Added', byDelta('added'));
214
+ section('Removed', byDelta('removed'));
215
+ section('Changed', byDelta('modified'));
216
+ console.log(`${result.changes.length} migration change(s) derivable.`);
217
+ };
218
+ exports.default = async (argv, prompter, _options) => {
219
+ if (argv.help || argv.h) {
220
+ console.log(diffUsageText);
221
+ process.exit(0);
222
+ }
223
+ const { first: specA, newArgv } = (0, inquirerer_1.extractFirst)(argv);
224
+ const { first: specB, newArgv: restArgv } = (0, inquirerer_1.extractFirst)(newArgv);
225
+ argv = restArgv;
226
+ if (!specA || !specB) {
227
+ await (0, inquirerer_1.cliExitWithError)('pgpm diff requires two sides: pgpm diff <A> <B> (module dir, .sql file, db:<name>, or connection string).');
228
+ }
229
+ const granularityRaw = argv.granularity ?? 'object';
230
+ if (!(0, transform_1.isExportGranularity)(granularityRaw)) {
231
+ await (0, inquirerer_1.cliExitWithError)(`Invalid --granularity "${granularityRaw}". Expected one of: ${transform_1.EXPORT_GRANULARITIES.join(', ')}.`);
232
+ }
233
+ const granularity = granularityRaw;
234
+ const changeGranularityRaw = argv['change-granularity'] ?? argv.changeGranularity ?? 'object';
235
+ if (!(0, transform_1.isChangeGranularity)(changeGranularityRaw)) {
236
+ await (0, inquirerer_1.cliExitWithError)(`Invalid --change-granularity "${changeGranularityRaw}". Expected one of: ${transform_1.CHANGE_GRANULARITIES.join(', ')}.`);
237
+ }
238
+ const changeGranularity = changeGranularityRaw;
239
+ const namingRaw = argv.naming ?? 'directory';
240
+ if (!NAMING_STYLES.includes(namingRaw)) {
241
+ await (0, inquirerer_1.cliExitWithError)(`Invalid --naming "${namingRaw}". Expected one of: ${NAMING_STYLES.join(', ')}.`);
242
+ }
243
+ const naming = namingRaw;
244
+ const cwd = argv.cwd || process.cwd();
245
+ const json = Boolean(argv.json);
246
+ const verify = Boolean(argv.verify);
247
+ const emitModuleRaw = argv['emit-migration'] ?? argv.emitMigration ?? argv['emit-module'] ?? argv.emitModule;
248
+ const emitModuleDir = typeof emitModuleRaw === 'string' && emitModuleRaw
249
+ ? path.resolve(cwd, emitModuleRaw)
250
+ : undefined;
251
+ const appendModuleRaw = argv['append-module'] ?? argv.appendModule;
252
+ const appendModuleDir = typeof appendModuleRaw === 'string' && appendModuleRaw
253
+ ? path.resolve(cwd, appendModuleRaw)
254
+ : undefined;
255
+ const emitSqlRaw = argv['emit-sql'] ?? argv.emitSql;
256
+ const emitSql = typeof emitSqlRaw === 'string' && emitSqlRaw
257
+ ? (emitSqlRaw === module_projections_1.STDOUT_TARGET ? module_projections_1.STDOUT_TARGET : path.resolve(cwd, emitSqlRaw))
258
+ : undefined;
259
+ const emitBundleRaw = argv['emit-bundle'] ?? argv.emitBundle;
260
+ const emitBundle = typeof emitBundleRaw === 'string' && emitBundleRaw
261
+ ? path.resolve(cwd, emitBundleRaw)
262
+ : undefined;
263
+ const sqlToStdout = emitSql === module_projections_1.STDOUT_TARGET;
264
+ const pkgName = argv.pkg || 'diff-migration';
265
+ if (appendModuleDir && (emitModuleDir || emitSql || emitBundle || verify)) {
266
+ await (0, inquirerer_1.cliExitWithError)('--append-module is standalone; it cannot be combined with --emit-migration/--emit-module/--emit-sql/--emit-bundle/--verify.');
267
+ }
268
+ await (0, transform_1.loadModule)();
269
+ let sideA;
270
+ let sideB;
271
+ try {
272
+ sideA = await loadSide(specA, cwd);
273
+ sideB = await loadSide(specB, cwd);
274
+ }
275
+ catch (err) {
276
+ await (0, inquirerer_1.cliExitWithError)(err instanceof Error ? err.message : String(err));
277
+ return;
278
+ }
279
+ const result = (0, transform_1.diffChangeSets)(sideA.changes, sideB.changes, { granularity, changeGranularity, style: naming });
280
+ const warnings = [
281
+ ...sideA.warnings.map(w => `${sideA.label}: ${w}`),
282
+ ...sideB.warnings.map(w => `${sideB.label}: ${w}`),
283
+ ...result.warnings
284
+ ];
285
+ if (json) {
286
+ console.log(JSON.stringify({
287
+ identical: result.identical,
288
+ objects: result.objects,
289
+ changes: result.changes.map(c => ({
290
+ name: c.name,
291
+ dependencies: c.dependencies,
292
+ deploy: c.deploy,
293
+ revert: c.revert,
294
+ verify: c.verify
295
+ })),
296
+ warnings
297
+ }, null, 2));
298
+ }
299
+ else {
300
+ for (const warning of warnings)
301
+ console.warn(`diff: ${warning}`);
302
+ // Keep stdout clean when the SQL projection is piped there.
303
+ if (!sqlToStdout)
304
+ printSummary(result, sideA.label, sideB.label);
305
+ }
306
+ if (appendModuleDir) {
307
+ const rows = (0, diff_1.deltaChangesToRows)(result.changes);
308
+ if (rows.length === 0) {
309
+ log.info('no migration changes to append (sides are identical).');
310
+ }
311
+ else {
312
+ const appended = (0, transform_1.appendModule)(appendModuleDir, rows);
313
+ for (const w of appended.warnings)
314
+ console.warn(`diff: ${w}`);
315
+ log.success(`appended ${appended.added.length} change(s) to ${appended.dir}` +
316
+ (appended.skipped.length ? ` (${appended.skipped.length} skipped)` : ''));
317
+ }
318
+ prompter.close();
319
+ return argv;
320
+ }
321
+ let migrationDir;
322
+ const needModule = Boolean(emitModuleDir || emitSql || emitBundle) || (verify && !result.identical);
323
+ if (needModule) {
324
+ const outBase = emitModuleDir ?? fs.mkdtempSync(path.join(os.tmpdir(), 'pgpm-diff-'));
325
+ const rows = (0, diff_1.deltaChangesToRows)(result.changes);
326
+ if (rows.length === 0) {
327
+ if (!sqlToStdout)
328
+ log.info('no migration changes to emit (sides are identical).');
329
+ }
330
+ else {
331
+ migrationDir = (0, transform_1.writeModule)(outBase, { name: pkgName, requires: [], rows });
332
+ if (emitModuleDir && !sqlToStdout)
333
+ log.success(`wrote ${rows.length} migration change(s) to ${migrationDir}`);
334
+ if (emitSql) {
335
+ await (0, module_projections_1.emitModuleSql)(migrationDir, emitSql);
336
+ if (!sqlToStdout)
337
+ log.success(`wrote linear SQL to ${emitSql}`);
338
+ }
339
+ if (emitBundle) {
340
+ await (0, module_projections_1.emitModuleBundle)(migrationDir, emitBundle);
341
+ if (!sqlToStdout)
342
+ log.success(`wrote bundle to ${emitBundle}`);
343
+ }
344
+ }
345
+ }
346
+ if (verify) {
347
+ log.info('running --verify: deploying A plus the migration and B into scratch databases...');
348
+ const diffs = await runVerify(sideA, sideB, specA, specB, migrationDir, cwd);
349
+ if (diffs.length) {
350
+ console.error(`--verify failed: catalogs differ (${diffs.length} differences):`);
351
+ for (const diff of diffs)
352
+ console.error(` ${diff}`);
353
+ await (0, inquirerer_1.cliExitWithError)('Migrated catalog does not match the target.');
354
+ }
355
+ log.success('--verify passed: migrated catalog is structurally equivalent to the target.');
356
+ }
357
+ prompter.close();
358
+ return argv;
359
+ };
package/commands/dump.js CHANGED
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const logger_1 = require("@pgpmjs/logger");
7
- const pg_env_1 = require("pg-env");
8
- const pg_cache_1 = require("pg-cache");
7
+ const quotes_1 = require("@pgsql/quotes");
9
8
  const child_process_1 = require("child_process");
10
9
  const fs_1 = __importDefault(require("fs"));
11
10
  const path_1 = __importDefault(require("path"));
12
- const quotes_1 = require("@pgsql/quotes");
11
+ const pg_cache_1 = require("pg-cache");
12
+ const pg_env_1 = require("pg-env");
13
13
  const utils_1 = require("../utils");
14
14
  const log = new logger_1.Logger('dump');
15
15
  const dumpUsageText = `
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@pgpmjs/core");
4
- const export_1 = require("@pgpmjs/export");
5
4
  const env_1 = require("@pgpmjs/env");
5
+ const export_1 = require("@pgpmjs/export");
6
+ const transform_1 = require("@pgpmjs/transform");
6
7
  const types_1 = require("@pgpmjs/types");
7
8
  const path_1 = require("path");
8
9
  const pg_cache_1 = require("pg-cache");
@@ -30,12 +31,16 @@ Options:
30
31
  Change paths are derived from the naming spec and
31
32
  requires from the statement graph. When omitted,
32
33
  sql_actions rows are exported unchanged.
34
+ --partition <file> Partition config (JSON: rules/defaultPackage/splitRiders)
35
+ splitting the exported database module into multiple
36
+ pgpm packages with derived cross-package requires.
33
37
  --cwd <directory> Working directory (default: current directory)
34
38
 
35
39
  Examples:
36
40
  pgpm export Export migrations from selected database (SQL mode)
37
41
  pgpm export --exclude-categories security,permissions,auth,memberships
38
42
  pgpm export --granularity consolidated
43
+ pgpm export --granularity object --partition partition.json
39
44
  pgpm export --graphql-endpoint 'http://[::1]:3002/graphql' --migrate-endpoint 'http://[::1]:3000/graphql' --migrate-host db_migrate.localhost:3000
40
45
  `;
41
46
  exports.default = async (argv, prompter, _options) => {
@@ -61,12 +66,24 @@ exports.default = async (argv, prompter, _options) => {
61
66
  ? excludeCategoriesRaw
62
67
  : undefined;
63
68
  const granularityRaw = argv.granularity;
64
- if (granularityRaw !== undefined && !(0, export_1.isExportGranularity)(granularityRaw)) {
65
- console.error(`Invalid --granularity "${granularityRaw}". Expected one of: ${export_1.EXPORT_GRANULARITIES.join(', ')}.`);
69
+ if (granularityRaw !== undefined && !(0, transform_1.isExportGranularity)(granularityRaw)) {
70
+ console.error(`Invalid --granularity "${granularityRaw}". Expected one of: ${transform_1.EXPORT_GRANULARITIES.join(', ')}.`);
66
71
  prompter.close();
67
72
  return;
68
73
  }
69
74
  const granularity = granularityRaw;
75
+ const partitionRaw = argv.partition;
76
+ let partition;
77
+ if (typeof partitionRaw === 'string' && partitionRaw) {
78
+ try {
79
+ partition = (0, transform_1.parsePartitionConfig)((0, path_1.resolve)(cwd, partitionRaw));
80
+ }
81
+ catch (err) {
82
+ console.error(err instanceof Error ? err.message : String(err));
83
+ prompter.close();
84
+ return;
85
+ }
86
+ }
70
87
  if (graphqlEndpoint) {
71
88
  // =========================================================================
72
89
  // GraphQL export mode
@@ -164,7 +181,8 @@ exports.default = async (argv, prompter, _options) => {
164
181
  argv,
165
182
  username,
166
183
  excludeCategories,
167
- granularity
184
+ granularity,
185
+ partition
168
186
  });
169
187
  }
170
188
  else {
@@ -285,7 +303,8 @@ exports.default = async (argv, prompter, _options) => {
285
303
  argv,
286
304
  username,
287
305
  excludeCategories,
288
- granularity
306
+ granularity,
307
+ partition
289
308
  });
290
309
  }
291
310
  prompter.close();
@@ -0,0 +1,3 @@
1
+ import { CLIOptions, Inquirerer, ParsedArgs } from 'inquirerer';
2
+ declare const _default: (argv: Partial<ParsedArgs>, prompter: Inquirerer, _options: CLIOptions) => Promise<Partial<ParsedArgs>>;
3
+ export default _default;