@pgpmjs/transform 0.18.0 → 0.19.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.
@@ -210,32 +210,46 @@ function diffTable(from, to, diff, warnings) {
210
210
  stmts.push(alter({ subtype: 'AT_DropColumn', name }));
211
211
  }
212
212
  }
213
- for (const [print, extra] of to.extras) {
214
- if (!from.extras.has(print)) {
215
- const at = extra.AlterTableCmd;
216
- if (at)
217
- stmts.push(alter(at));
218
- else if (extra.Constraint) {
219
- stmts.push(alter({ subtype: 'AT_AddConstraint', def: extra }));
220
- }
221
- else {
222
- warnings.push(`${diff.path}: unrecognized added table element; emit a manual ALTER`);
223
- }
224
- }
225
- }
213
+ // Self-inverse ALTER TABLE subtypes: a removed extra with one of these
214
+ // undoes with the paired subtype rather than a DROP CONSTRAINT.
215
+ const INVERSE_SUBTYPE = {
216
+ AT_EnableRowSecurity: 'AT_DisableRowSecurity',
217
+ AT_DisableRowSecurity: 'AT_EnableRowSecurity',
218
+ AT_ForceRowSecurity: 'AT_NoForceRowSecurity',
219
+ AT_NoForceRowSecurity: 'AT_ForceRowSecurity'
220
+ };
221
+ // Removed extras drop before added ones: a changed constraint that keeps
222
+ // its name must DROP CONSTRAINT before the replacement ADD CONSTRAINT.
226
223
  for (const [print, extra] of from.extras) {
227
224
  if (to.extras.has(print))
228
225
  continue;
229
226
  const conname = extra.Constraint?.conname
230
227
  ?? extra
231
228
  .AlterTableCmd?.def?.Constraint?.conname;
229
+ const subtype = extra.AlterTableCmd?.subtype;
232
230
  if (conname) {
233
231
  stmts.push(alter({ subtype: 'AT_DropConstraint', name: conname }));
234
232
  }
233
+ else if (subtype && INVERSE_SUBTYPE[subtype]) {
234
+ stmts.push(alter({ subtype: INVERSE_SUBTYPE[subtype] }));
235
+ }
235
236
  else {
236
237
  warnings.push(`${diff.path}: removed table element has no name to drop; emit a manual ALTER`);
237
238
  }
238
239
  }
240
+ for (const [print, extra] of to.extras) {
241
+ if (!from.extras.has(print)) {
242
+ const at = extra.AlterTableCmd;
243
+ if (at)
244
+ stmts.push(alter(at));
245
+ else if (extra.Constraint) {
246
+ stmts.push(alter({ subtype: 'AT_AddConstraint', def: extra }));
247
+ }
248
+ else {
249
+ warnings.push(`${diff.path}: unrecognized added table element; emit a manual ALTER`);
250
+ }
251
+ }
252
+ }
239
253
  return stmts;
240
254
  }
241
255
  /**
@@ -1,5 +1,5 @@
1
- import { CategoryProfile, ChangeCategory } from './categorize';
2
1
  import { QualifiedName } from '@pgsql/transform';
2
+ import { CategoryProfile, ChangeCategory } from './categorize';
3
3
  /**
4
4
  * A change plus its deploy SQL. Optional plan `dependencies` (from `pgpm.plan`)
5
5
  * are followed as authoritative prerequisites in addition to AST-derived edges.
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveFixtureClosure = resolveFixtureClosure;
4
- const categorize_1 = require("./categorize");
5
4
  const transform_1 = require("@pgsql/transform");
5
+ const categorize_1 = require("./categorize");
6
6
  function objectKey(schema, name) {
7
7
  return `${schema ?? ''}\u0000${name}`;
8
8
  }
package/index.d.ts CHANGED
@@ -1,18 +1,28 @@
1
- export * from '@pgsql/transform';
2
- export { loadModule } from 'plpgsql-parser';
3
1
  export type { BundleScriptContext, ExtensionRoutingInput, NamespaceValidatorOptions, SchemaObjectRoute, SchemaTranspiler, SchemaTranspilerOptions, } from './bundle-driver';
4
2
  export { buildExtensionRouter, buildSchemaRouter, makeNamespaceValidator, makeSchemaTranspiler, } from './bundle-driver';
5
- export type { GranularityChange, RestructuredChange, RestructureModuleOptions, RestructureModuleResult, } from './granularity-driver';
6
- export { defaultChangeName, restructureChanges, } from './granularity-driver';
7
- export type { DiffInputChange, ObjectDelta, SemanticDeltaChange, SemanticDiffOptions, SemanticDiffResult, SemanticObjectDiff, } from './semantic-diff-driver';
8
- export { diffChangeSets, diffSchemas, } from './semantic-diff-driver';
9
- export type { PartitionConfig, PartitionedChange, PartitionedPackage, PartitionInputChange, PartitionRule, PartitionUnit, PartitionUnitsResult, UnitSelector, } from './partition-driver';
10
- export { PartitionCycleError, partitionUnits, RESIDUAL_UNIT_PATH, } from './partition-driver';
3
+ export type { CatalogQueryable, CatalogSnapshot } from './catalog-check';
4
+ export { diffCatalogSnapshots, snapshotCatalog, withoutColumnOrder } from './catalog-check';
11
5
  export type { CategoryProfile, ChangeCategory, } from './categorize';
12
6
  export { buildCategoryOf, categorizeChange, TIER_PROFILE, } from './categorize';
13
7
  export type { ClosureChange, ClosureInputChange, ClosureReason, FixtureClosure, ResolveFixtureClosureOptions, } from './fixture-closure';
14
8
  export { resolveFixtureClosure } from './fixture-closure';
15
- export type { GeneratedScript, RegeneratedScripts, } from './regen';
16
- export { classifyScript, isStubScript, regenerateScripts, } from './regen';
9
+ export type { GranularityChange, RestructuredChange, RestructureModuleOptions, RestructureModuleResult, } from './granularity-driver';
10
+ export { defaultChangeName, restructureChanges, } from './granularity-driver';
11
+ export type { PgpmModuleModel } from './module-emit';
12
+ export { checkOverwrite, writeControlFile, writeModule } from './module-emit';
13
+ export type { ModuleSource, ModuleSourceChange } from './module-source';
14
+ export { loadModuleSource, stripTransactionWrapper } from './module-source';
15
+ export type { PartitionedPackageRows, PartitionExportRowsResult } from './partition';
16
+ export { parsePartitionConfig, partitionExportRows } from './partition';
17
+ export type { PartitionConfig, PartitionedChange, PartitionedPackage, PartitionInputChange, PartitionRule, PartitionUnit, PartitionUnitsResult, UnitSelector, } from './partition-driver';
18
+ export { PartitionCycleError, partitionUnits, RESIDUAL_UNIT_PATH, } from './partition-driver';
17
19
  export type { SqlProgram, SqlStatementAst, SqlStatementSpan, } from './program';
18
20
  export { emitSqlProgram, parseSqlProgram } from './program';
21
+ export type { GeneratedScript, RegeneratedScripts, } from './regen';
22
+ export { classifyScript, isStubScript, regenerateScripts, } from './regen';
23
+ export type { ExportGranularity, RestructureExportRowsOptions, RestructureExportRowsResult } from './restructure';
24
+ export { EXPORT_GRANULARITIES, isExportGranularity, restructureExportRows } from './restructure';
25
+ export type { DiffInputChange, ObjectDelta, SemanticDeltaChange, SemanticDiffOptions, SemanticDiffResult, SemanticObjectDiff, } from './semantic-diff-driver';
26
+ export { diffChangeSets, diffSchemas, } from './semantic-diff-driver';
27
+ export * from '@pgsql/transform';
28
+ export { loadModule } from 'plpgsql-parser';
package/index.js CHANGED
@@ -14,35 +14,53 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.parseSqlProgram = exports.emitSqlProgram = exports.regenerateScripts = exports.isStubScript = exports.classifyScript = exports.resolveFixtureClosure = exports.TIER_PROFILE = exports.categorizeChange = exports.buildCategoryOf = exports.RESIDUAL_UNIT_PATH = exports.partitionUnits = exports.PartitionCycleError = exports.diffSchemas = exports.diffChangeSets = exports.restructureChanges = exports.defaultChangeName = exports.makeSchemaTranspiler = exports.makeNamespaceValidator = exports.buildSchemaRouter = exports.buildExtensionRouter = exports.loadModule = void 0;
18
- __exportStar(require("@pgsql/transform"), exports);
19
- var plpgsql_parser_1 = require("plpgsql-parser");
20
- Object.defineProperty(exports, "loadModule", { enumerable: true, get: function () { return plpgsql_parser_1.loadModule; } });
17
+ exports.loadModule = exports.diffSchemas = exports.diffChangeSets = exports.restructureExportRows = exports.isExportGranularity = exports.EXPORT_GRANULARITIES = exports.regenerateScripts = exports.isStubScript = exports.classifyScript = exports.parseSqlProgram = exports.emitSqlProgram = exports.RESIDUAL_UNIT_PATH = exports.partitionUnits = exports.PartitionCycleError = exports.partitionExportRows = exports.parsePartitionConfig = exports.stripTransactionWrapper = exports.loadModuleSource = exports.writeModule = exports.writeControlFile = exports.checkOverwrite = exports.restructureChanges = exports.defaultChangeName = exports.resolveFixtureClosure = exports.TIER_PROFILE = exports.categorizeChange = exports.buildCategoryOf = exports.withoutColumnOrder = exports.snapshotCatalog = exports.diffCatalogSnapshots = exports.makeSchemaTranspiler = exports.makeNamespaceValidator = exports.buildSchemaRouter = exports.buildExtensionRouter = void 0;
21
18
  var bundle_driver_1 = require("./bundle-driver");
22
19
  Object.defineProperty(exports, "buildExtensionRouter", { enumerable: true, get: function () { return bundle_driver_1.buildExtensionRouter; } });
23
20
  Object.defineProperty(exports, "buildSchemaRouter", { enumerable: true, get: function () { return bundle_driver_1.buildSchemaRouter; } });
24
21
  Object.defineProperty(exports, "makeNamespaceValidator", { enumerable: true, get: function () { return bundle_driver_1.makeNamespaceValidator; } });
25
22
  Object.defineProperty(exports, "makeSchemaTranspiler", { enumerable: true, get: function () { return bundle_driver_1.makeSchemaTranspiler; } });
23
+ var catalog_check_1 = require("./catalog-check");
24
+ Object.defineProperty(exports, "diffCatalogSnapshots", { enumerable: true, get: function () { return catalog_check_1.diffCatalogSnapshots; } });
25
+ Object.defineProperty(exports, "snapshotCatalog", { enumerable: true, get: function () { return catalog_check_1.snapshotCatalog; } });
26
+ Object.defineProperty(exports, "withoutColumnOrder", { enumerable: true, get: function () { return catalog_check_1.withoutColumnOrder; } });
27
+ var categorize_1 = require("./categorize");
28
+ Object.defineProperty(exports, "buildCategoryOf", { enumerable: true, get: function () { return categorize_1.buildCategoryOf; } });
29
+ Object.defineProperty(exports, "categorizeChange", { enumerable: true, get: function () { return categorize_1.categorizeChange; } });
30
+ Object.defineProperty(exports, "TIER_PROFILE", { enumerable: true, get: function () { return categorize_1.TIER_PROFILE; } });
31
+ var fixture_closure_1 = require("./fixture-closure");
32
+ Object.defineProperty(exports, "resolveFixtureClosure", { enumerable: true, get: function () { return fixture_closure_1.resolveFixtureClosure; } });
26
33
  var granularity_driver_1 = require("./granularity-driver");
27
34
  Object.defineProperty(exports, "defaultChangeName", { enumerable: true, get: function () { return granularity_driver_1.defaultChangeName; } });
28
35
  Object.defineProperty(exports, "restructureChanges", { enumerable: true, get: function () { return granularity_driver_1.restructureChanges; } });
29
- var semantic_diff_driver_1 = require("./semantic-diff-driver");
30
- Object.defineProperty(exports, "diffChangeSets", { enumerable: true, get: function () { return semantic_diff_driver_1.diffChangeSets; } });
31
- Object.defineProperty(exports, "diffSchemas", { enumerable: true, get: function () { return semantic_diff_driver_1.diffSchemas; } });
36
+ var module_emit_1 = require("./module-emit");
37
+ Object.defineProperty(exports, "checkOverwrite", { enumerable: true, get: function () { return module_emit_1.checkOverwrite; } });
38
+ Object.defineProperty(exports, "writeControlFile", { enumerable: true, get: function () { return module_emit_1.writeControlFile; } });
39
+ Object.defineProperty(exports, "writeModule", { enumerable: true, get: function () { return module_emit_1.writeModule; } });
40
+ var module_source_1 = require("./module-source");
41
+ Object.defineProperty(exports, "loadModuleSource", { enumerable: true, get: function () { return module_source_1.loadModuleSource; } });
42
+ Object.defineProperty(exports, "stripTransactionWrapper", { enumerable: true, get: function () { return module_source_1.stripTransactionWrapper; } });
43
+ var partition_1 = require("./partition");
44
+ Object.defineProperty(exports, "parsePartitionConfig", { enumerable: true, get: function () { return partition_1.parsePartitionConfig; } });
45
+ Object.defineProperty(exports, "partitionExportRows", { enumerable: true, get: function () { return partition_1.partitionExportRows; } });
32
46
  var partition_driver_1 = require("./partition-driver");
33
47
  Object.defineProperty(exports, "PartitionCycleError", { enumerable: true, get: function () { return partition_driver_1.PartitionCycleError; } });
34
48
  Object.defineProperty(exports, "partitionUnits", { enumerable: true, get: function () { return partition_driver_1.partitionUnits; } });
35
49
  Object.defineProperty(exports, "RESIDUAL_UNIT_PATH", { enumerable: true, get: function () { return partition_driver_1.RESIDUAL_UNIT_PATH; } });
36
- var categorize_1 = require("./categorize");
37
- Object.defineProperty(exports, "buildCategoryOf", { enumerable: true, get: function () { return categorize_1.buildCategoryOf; } });
38
- Object.defineProperty(exports, "categorizeChange", { enumerable: true, get: function () { return categorize_1.categorizeChange; } });
39
- Object.defineProperty(exports, "TIER_PROFILE", { enumerable: true, get: function () { return categorize_1.TIER_PROFILE; } });
40
- var fixture_closure_1 = require("./fixture-closure");
41
- Object.defineProperty(exports, "resolveFixtureClosure", { enumerable: true, get: function () { return fixture_closure_1.resolveFixtureClosure; } });
50
+ var program_1 = require("./program");
51
+ Object.defineProperty(exports, "emitSqlProgram", { enumerable: true, get: function () { return program_1.emitSqlProgram; } });
52
+ Object.defineProperty(exports, "parseSqlProgram", { enumerable: true, get: function () { return program_1.parseSqlProgram; } });
42
53
  var regen_1 = require("./regen");
43
54
  Object.defineProperty(exports, "classifyScript", { enumerable: true, get: function () { return regen_1.classifyScript; } });
44
55
  Object.defineProperty(exports, "isStubScript", { enumerable: true, get: function () { return regen_1.isStubScript; } });
45
56
  Object.defineProperty(exports, "regenerateScripts", { enumerable: true, get: function () { return regen_1.regenerateScripts; } });
46
- var program_1 = require("./program");
47
- Object.defineProperty(exports, "emitSqlProgram", { enumerable: true, get: function () { return program_1.emitSqlProgram; } });
48
- Object.defineProperty(exports, "parseSqlProgram", { enumerable: true, get: function () { return program_1.parseSqlProgram; } });
57
+ var restructure_1 = require("./restructure");
58
+ Object.defineProperty(exports, "EXPORT_GRANULARITIES", { enumerable: true, get: function () { return restructure_1.EXPORT_GRANULARITIES; } });
59
+ Object.defineProperty(exports, "isExportGranularity", { enumerable: true, get: function () { return restructure_1.isExportGranularity; } });
60
+ Object.defineProperty(exports, "restructureExportRows", { enumerable: true, get: function () { return restructure_1.restructureExportRows; } });
61
+ var semantic_diff_driver_1 = require("./semantic-diff-driver");
62
+ Object.defineProperty(exports, "diffChangeSets", { enumerable: true, get: function () { return semantic_diff_driver_1.diffChangeSets; } });
63
+ Object.defineProperty(exports, "diffSchemas", { enumerable: true, get: function () { return semantic_diff_driver_1.diffSchemas; } });
64
+ __exportStar(require("@pgsql/transform"), exports);
65
+ var plpgsql_parser_1 = require("plpgsql-parser");
66
+ Object.defineProperty(exports, "loadModule", { enumerable: true, get: function () { return plpgsql_parser_1.loadModule; } });
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Module emission — the single seam every dials command renders through.
3
+ *
4
+ * The engine (semantic diff, granularity, partition) produces plan-ordered
5
+ * {@link PgpmRow}s; a {@link PgpmModuleModel} is just those rows plus the
6
+ * module's name and control-file requires. `writeModule` is the one writer
7
+ * that turns a model into an on-disk pgpm module (`.control` + `pgpm.plan` +
8
+ * deploy/revert/verify trees) — so `pgpm diff`, `pgpm transform`, and
9
+ * `pgpm import` all emit byte-identical module layouts instead of each
10
+ * carrying its own copy of the writer.
11
+ */
12
+ import { PgpmRow } from '@pgpmjs/ast';
13
+ /**
14
+ * A pgpm module as an in-memory value: a name, the extensions it requires
15
+ * (control-file names), and its changes in plan order. `writeModule` and the
16
+ * other projections (linear SQL, bundle) are pure functions of this model.
17
+ */
18
+ export interface PgpmModuleModel {
19
+ /** Package (module) name. */
20
+ name: string;
21
+ /** Module names this package requires (control-file names). */
22
+ requires: string[];
23
+ /** Changes in plan order. */
24
+ rows: PgpmRow[];
25
+ }
26
+ /** Write a module's Postgres extension `.control` file. */
27
+ export declare const writeControlFile: (dir: string, name: string, requires: string[]) => void;
28
+ /**
29
+ * Write a {@link PgpmModuleModel} to `<outBase>/<name>` as a full pgpm module:
30
+ * a `.control` file, `pgpm.plan`, and deploy/revert/verify script trees.
31
+ * The deploy/revert/verify directories are cleared first so a re-emit never
32
+ * leaves stale scripts behind. Returns the module directory.
33
+ */
34
+ export declare const writeModule: (outBase: string, model: PgpmModuleModel, extraRequires?: string[]) => string;
35
+ /**
36
+ * Guard against clobbering: writing into the source directory requires
37
+ * `--write`, as does overwriting any existing package directory.
38
+ */
39
+ export declare const checkOverwrite: (targetDir: string, sourcePath: string, write: boolean) => string | null;
package/module-emit.js ADDED
@@ -0,0 +1,104 @@
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
+ exports.checkOverwrite = exports.writeModule = exports.writeControlFile = void 0;
37
+ /**
38
+ * Module emission — the single seam every dials command renders through.
39
+ *
40
+ * The engine (semantic diff, granularity, partition) produces plan-ordered
41
+ * {@link PgpmRow}s; a {@link PgpmModuleModel} is just those rows plus the
42
+ * module's name and control-file requires. `writeModule` is the one writer
43
+ * that turns a model into an on-disk pgpm module (`.control` + `pgpm.plan` +
44
+ * deploy/revert/verify trees) — so `pgpm diff`, `pgpm transform`, and
45
+ * `pgpm import` all emit byte-identical module layouts instead of each
46
+ * carrying its own copy of the writer.
47
+ */
48
+ const ast_1 = require("@pgpmjs/ast");
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ /** Write a module's Postgres extension `.control` file. */
52
+ const writeControlFile = (dir, name, requires) => {
53
+ const lines = [
54
+ `# ${name} extension`,
55
+ `comment = '${name} extension'`,
56
+ `default_version = '0.0.1'`,
57
+ `relocatable = false`,
58
+ `superuser = false`
59
+ ];
60
+ if (requires.length) {
61
+ lines.push(`requires = '${requires.join(',')}'`);
62
+ }
63
+ fs.writeFileSync(path.join(dir, `${name}.control`), lines.join('\n') + '\n');
64
+ };
65
+ exports.writeControlFile = writeControlFile;
66
+ /**
67
+ * Write a {@link PgpmModuleModel} to `<outBase>/<name>` as a full pgpm module:
68
+ * a `.control` file, `pgpm.plan`, and deploy/revert/verify script trees.
69
+ * The deploy/revert/verify directories are cleared first so a re-emit never
70
+ * leaves stale scripts behind. Returns the module directory.
71
+ */
72
+ const writeModule = (outBase, model, extraRequires = []) => {
73
+ const dir = path.join(outBase, model.name);
74
+ fs.rmSync(path.join(dir, 'deploy'), { recursive: true, force: true });
75
+ fs.rmSync(path.join(dir, 'revert'), { recursive: true, force: true });
76
+ fs.rmSync(path.join(dir, 'verify'), { recursive: true, force: true });
77
+ fs.mkdirSync(dir, { recursive: true });
78
+ (0, exports.writeControlFile)(dir, model.name, [...extraRequires, ...model.requires]);
79
+ const opts = {
80
+ outdir: outBase,
81
+ name: model.name,
82
+ replacer: (str) => str.split('constructive-extension-name').join(model.name)
83
+ };
84
+ (0, ast_1.writePgpmPlan)(model.rows, opts);
85
+ (0, ast_1.writePgpmFiles)(model.rows, opts);
86
+ return dir;
87
+ };
88
+ exports.writeModule = writeModule;
89
+ /**
90
+ * Guard against clobbering: writing into the source directory requires
91
+ * `--write`, as does overwriting any existing package directory.
92
+ */
93
+ const checkOverwrite = (targetDir, sourcePath, write) => {
94
+ const resolvedTarget = path.resolve(targetDir);
95
+ const resolvedSource = path.resolve(sourcePath);
96
+ if (resolvedTarget === resolvedSource && !write) {
97
+ return `Refusing to overwrite the source module at ${resolvedSource} (pass --write to allow).`;
98
+ }
99
+ if (resolvedTarget !== resolvedSource && fs.existsSync(resolvedTarget) && !write) {
100
+ return `Output directory ${resolvedTarget} already exists (pass --write to overwrite).`;
101
+ }
102
+ return null;
103
+ };
104
+ exports.checkOverwrite = checkOverwrite;
@@ -0,0 +1,33 @@
1
+ /** One change of a loaded module: headerless, unwrapped deploy SQL. */
2
+ export interface ModuleSourceChange {
3
+ /** Change name (plan token). */
4
+ name: string;
5
+ /** Change names this change requires, as recorded in the plan. */
6
+ dependencies: string[];
7
+ /** Deploy SQL with the pgpm header and BEGIN/COMMIT wrapper stripped. */
8
+ deploy: string;
9
+ }
10
+ /** A pgpm module loaded from disk, flattened in plan order. */
11
+ export interface ModuleSource {
12
+ /** Module (project) name from pgpm.plan. */
13
+ name: string;
14
+ /** Absolute module directory. */
15
+ modulePath: string;
16
+ /** Changes in plan order. */
17
+ changes: ModuleSourceChange[];
18
+ /** Non-fatal notes (missing deploy scripts, etc.). */
19
+ warnings: string[];
20
+ }
21
+ /**
22
+ * Strip the transaction wrapper some modules carry inside their scripts
23
+ * (standalone `BEGIN;` / `COMMIT;` / `ROLLBACK;` lines). The caller owns
24
+ * transaction control.
25
+ */
26
+ export declare const stripTransactionWrapper: (sql: string) => string;
27
+ /**
28
+ * Load a pgpm module from disk: parse pgpm.plan and read each change's
29
+ * deploy script, stripping pgpm headers and transaction wrappers so the
30
+ * result can be flattened straight into the dials pipeline
31
+ * (`restructureChanges` / `partitionUnits`).
32
+ */
33
+ export declare const loadModuleSource: (moduleDir: string) => ModuleSource;
@@ -0,0 +1,92 @@
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
+ exports.loadModuleSource = exports.stripTransactionWrapper = void 0;
37
+ /**
38
+ * Module ingestion for the dials pipeline: load an on-disk pgpm module into
39
+ * the flattened, classified change list the transform/partition drivers
40
+ * consume. `pgpm transform` uses this today; a future `pgpm import` (dumps)
41
+ * and `pgpm diff` are expected to reuse the same seam.
42
+ */
43
+ const ast_1 = require("@pgpmjs/ast");
44
+ const path = __importStar(require("path"));
45
+ const TX_LINE = /^\s*(BEGIN|COMMIT|ROLLBACK)\s*;\s*$/i;
46
+ /**
47
+ * Strip the transaction wrapper some modules carry inside their scripts
48
+ * (standalone `BEGIN;` / `COMMIT;` / `ROLLBACK;` lines). The caller owns
49
+ * transaction control.
50
+ */
51
+ const stripTransactionWrapper = (sql) => sql
52
+ .split('\n')
53
+ .filter(line => !TX_LINE.test(line))
54
+ .join('\n')
55
+ .trim();
56
+ exports.stripTransactionWrapper = stripTransactionWrapper;
57
+ /**
58
+ * Load a pgpm module from disk: parse pgpm.plan and read each change's
59
+ * deploy script, stripping pgpm headers and transaction wrappers so the
60
+ * result can be flattened straight into the dials pipeline
61
+ * (`restructureChanges` / `partitionUnits`).
62
+ */
63
+ const loadModuleSource = (moduleDir) => {
64
+ const modulePath = path.resolve(moduleDir);
65
+ const planResult = (0, ast_1.parsePlanFile)(path.join(modulePath, 'pgpm.plan'));
66
+ if (!planResult.data) {
67
+ const reasons = planResult.errors.map(e => e.message).join(', ');
68
+ throw new Error(`Failed to parse pgpm.plan in ${modulePath}: ${reasons}`);
69
+ }
70
+ const warnings = [];
71
+ const changes = [];
72
+ for (const change of planResult.data.changes) {
73
+ const raw = (0, ast_1.readScript)(modulePath, 'deploy', change.name);
74
+ if (!raw) {
75
+ warnings.push(`${change.name}: no deploy script found, skipping`);
76
+ continue;
77
+ }
78
+ const { body } = (0, ast_1.parsePgpmHeader)(raw);
79
+ changes.push({
80
+ name: change.name,
81
+ dependencies: change.dependencies ?? [],
82
+ deploy: (0, exports.stripTransactionWrapper)(body)
83
+ });
84
+ }
85
+ return {
86
+ name: planResult.data.package,
87
+ modulePath,
88
+ changes,
89
+ warnings
90
+ };
91
+ };
92
+ exports.loadModuleSource = loadModuleSource;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/transform",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "Change-aware SQL transformation for PGPM — superset of @pgsql/transform plus change categorization, fixture closure, and bundle transpile/apply drivers",
6
6
  "main": "index.js",
@@ -39,14 +39,15 @@
39
39
  "plpgsql"
40
40
  ],
41
41
  "devDependencies": {
42
- "@pgpmjs/bundle": "^0.13.2",
42
+ "@pgpmjs/bundle": "^0.13.3",
43
43
  "makage": "^0.3.0"
44
44
  },
45
45
  "dependencies": {
46
+ "@pgpmjs/ast": "^0.10.3",
46
47
  "@pgpmjs/naming-spec": "^0.1.2",
47
- "@pgsql/scripts": "^18.1.0",
48
- "@pgsql/transform": "^18.11.0",
49
- "plpgsql-parser": "^18.2.3"
48
+ "@pgsql/scripts": "^18.3.1",
49
+ "@pgsql/transform": "^18.14.1",
50
+ "plpgsql-parser": "^18.5.1"
50
51
  },
51
- "gitHead": "6d3e25dc5c9f93421dba49ddedf93239f87213a8"
52
+ "gitHead": "c20b6be96b39bf71c0e2df0f4b51e05deacd006b"
52
53
  }
package/partition.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Partition dial wiring shared by `pgpm transform --partition` and
3
+ * `pgpm export --partition`: parse a partition config file, run
4
+ * `partitionUnits` (`@pgpmjs/transform`), and lift the emitted packages back
5
+ * onto the PgpmRow seam with generated revert/verify per change.
6
+ */
7
+ import { PgpmRow } from '@pgpmjs/ast';
8
+ import { PartitionConfig } from './partition-driver';
9
+ export type { PartitionConfig } from './partition-driver';
10
+ /**
11
+ * Parse and validate a partition config file (JSON matching
12
+ * `PartitionConfig`: rules, defaultPackage, optional style/splitRiders).
13
+ * Throws with a message naming the offending field.
14
+ */
15
+ export declare const parsePartitionConfig: (filePath: string) => PartitionConfig;
16
+ /** One partitioned package on the PgpmRow seam, ready to write to disk. */
17
+ export interface PartitionedPackageRows {
18
+ name: string;
19
+ /** Package names this package requires (cross-package edges). */
20
+ requires: string[];
21
+ rows: PgpmRow[];
22
+ }
23
+ export interface PartitionExportRowsResult {
24
+ packages: PartitionedPackageRows[];
25
+ warnings: string[];
26
+ }
27
+ /**
28
+ * Partition changes into packages and generate revert/verify for every
29
+ * emitted change. Cross-package dependencies keep the `<pkg>:<path>`
30
+ * convention in `deps`. May throw `PartitionCycleError`.
31
+ */
32
+ export declare const partitionExportRows: (rows: PgpmRow[], config: PartitionConfig) => Promise<PartitionExportRowsResult>;