@pgpmjs/export 1.13.4 → 1.14.1

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.
@@ -3,8 +3,9 @@ import { createClient } from '@pgpmjs/migrate-client';
3
3
  import { GraphQLClient } from './graphql-client';
4
4
  import { exportGraphQLMeta } from './export-graphql-meta';
5
5
  import { graphqlRowToPostgresRow } from './graphql-naming';
6
+ import { restructureExportRows } from './restructure';
6
7
  import { DB_REQUIRED_EXTENSIONS, SERVICE_REQUIRED_EXTENSIONS, META_COMMON_HEADER, META_COMMON_FOOTER, META_TABLE_ORDER, detectMissingModules, installMissingModules, makeReplacer, preparePackage, normalizeOutdir } from './export-utils';
7
- export const exportGraphQL = async ({ project, metaEndpoint, migrateEndpoint, token, headers, migrateHeaders, databaseId, databaseName, schema_names, schemas, author, outdir, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false }) => {
8
+ export const exportGraphQL = async ({ project, metaEndpoint, migrateEndpoint, token, headers, migrateHeaders, databaseId, databaseName, schema_names, schemas, author, outdir, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false, granularity }) => {
8
9
  const normalizedOutdir = normalizeOutdir(outdir);
9
10
  const svcOutdir = normalizeOutdir(serviceOutdir || outdir);
10
11
  const name = extensionName;
@@ -97,8 +98,14 @@ export const exportGraphQL = async ({ project, metaEndpoint, migrateEndpoint, to
97
98
  if (dbMissingResult.shouldInstall) {
98
99
  await installMissingModules(dbModuleDir, dbMissingResult.missingModules);
99
100
  }
100
- writePgpmPlan(sqlActionRows, opts);
101
- writePgpmFiles(sqlActionRows, opts);
101
+ let dbRows = sqlActionRows;
102
+ if (granularity) {
103
+ const { rows, warnings } = await restructureExportRows(dbRows, granularity);
104
+ dbRows = rows;
105
+ warnings.forEach(warning => console.warn(`restructure (${granularity}): ${warning}`));
106
+ }
107
+ writePgpmPlan(dbRows, opts);
108
+ writePgpmFiles(dbRows, opts);
102
109
  }
103
110
  else {
104
111
  console.log('No sql_actions found. Skipping database module export.');
@@ -1,8 +1,9 @@
1
1
  import { getPgPool } from 'pg-cache';
2
2
  import { writePgpmFiles, writePgpmPlan } from '@pgpmjs/core';
3
3
  import { exportMeta } from './export-meta';
4
+ import { restructureExportRows } from './restructure';
4
5
  import { DB_REQUIRED_EXTENSIONS, SERVICE_REQUIRED_EXTENSIONS, META_COMMON_HEADER, META_COMMON_FOOTER, META_TABLE_ORDER, detectMissingModules, installMissingModules, makeReplacer, preparePackage, normalizeOutdir } from './export-utils';
5
- const exportMigrationsToDisk = async ({ project, options, database, databaseId, databaseName, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false, excludeCategories }) => {
6
+ const exportMigrationsToDisk = async ({ project, options, database, databaseId, databaseName, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false, excludeCategories, granularity }) => {
6
7
  const normalizedOutdir = normalizeOutdir(outdir);
7
8
  // Use serviceOutdir for service module, defaulting to outdir if not provided
8
9
  const svcOutdir = normalizeOutdir(serviceOutdir || outdir);
@@ -76,8 +77,14 @@ const exportMigrationsToDisk = async ({ project, options, database, databaseId,
76
77
  if (dbMissingResult.shouldInstall) {
77
78
  await installMissingModules(dbModuleDir, dbMissingResult.missingModules);
78
79
  }
79
- writePgpmPlan(appRows, opts);
80
- writePgpmFiles(appRows, opts);
80
+ let dbRows = appRows;
81
+ if (granularity) {
82
+ const { rows, warnings } = await restructureExportRows(appRows, granularity);
83
+ dbRows = rows;
84
+ warnings.forEach(warning => console.warn(`restructure (${granularity}): ${warning}`));
85
+ }
86
+ writePgpmPlan(dbRows, opts);
87
+ writePgpmFiles(dbRows, opts);
81
88
  }
82
89
  else {
83
90
  console.log('No sql_actions found — skipping database module. Meta/service module will still be exported.');
@@ -179,7 +186,7 @@ ${META_COMMON_FOOTER}
179
186
  writePgpmPlan(metaPackage, opts);
180
187
  writePgpmFiles(metaPackage, opts);
181
188
  };
182
- export const exportMigrations = async ({ project, options, dbInfo, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming, excludeCategories }) => {
189
+ export const exportMigrations = async ({ project, options, dbInfo, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming, excludeCategories, granularity }) => {
183
190
  for (let v = 0; v < dbInfo.database_ids.length; v++) {
184
191
  const databaseId = dbInfo.database_ids[v];
185
192
  await exportMigrationsToDisk({
@@ -201,7 +208,8 @@ export const exportMigrations = async ({ project, options, dbInfo, author, outdi
201
208
  username,
202
209
  serviceOutdir,
203
210
  skipSchemaRenaming,
204
- excludeCategories
211
+ excludeCategories,
212
+ granularity
205
213
  });
206
214
  }
207
215
  };
package/esm/index.js CHANGED
@@ -3,6 +3,7 @@ export * from './export-meta';
3
3
  export * from './export-migrations';
4
4
  export * from './export-graphql';
5
5
  export * from './export-graphql-meta';
6
+ export { EXPORT_GRANULARITIES, isExportGranularity, restructureExportRows } from './restructure';
6
7
  export { GraphQLClient } from './graphql-client';
7
8
  export { getGraphQLQueryName, getGraphQLTypeName, graphqlRowToPostgresRow, buildFieldsFragment, mapGraphQLTypeToFieldType, unwrapGraphQLType } from './graphql-naming';
8
9
  export { DB_REQUIRED_EXTENSIONS, SERVICE_REQUIRED_EXTENSIONS, META_COMMON_HEADER, META_COMMON_FOOTER, META_TABLE_ORDER, META_TABLE_CONFIG, META_TABLE_OVERRIDES, mapPgTypeToFieldType, makeReplacer, preparePackage, normalizeOutdir, detectMissingModules, installMissingModules } from './export-utils';
@@ -0,0 +1,53 @@
1
+ import { alterationPathFor } from '@pgpmjs/naming-spec';
2
+ import { loadModule, restructureChanges } from '@pgpmjs/transform';
3
+ export const EXPORT_GRANULARITIES = ['atomic', 'object', 'consolidated'];
4
+ export const isExportGranularity = (value) => typeof value === 'string' && EXPORT_GRANULARITIES.includes(value);
5
+ /**
6
+ * Restructure exported migration rows to the target granularity.
7
+ *
8
+ * The rows' deploy SQL is flattened in export order, restructured, and
9
+ * re-sliced into per-object changes whose paths come from the naming spec and
10
+ * whose deps come from the statement graph. When two changes derive the same
11
+ * path (the same object altered again), later occurrences get the spec's
12
+ * alteration convention via `alterationPathFor` (monotonic per-parent
13
+ * counter), with the parent added to their deps.
14
+ *
15
+ * Revert/verify scripts are not carried through from the original rows (the
16
+ * restructured grouping no longer matches them one-to-one); instead each
17
+ * change gets scripts generated from its own statements via
18
+ * `revertFor`/`verifyFor` (drops in reverse topological order, one existence
19
+ * check per created object).
20
+ */
21
+ export const restructureExportRows = async (rows, granularity) => {
22
+ await loadModule();
23
+ const { changes, warnings } = restructureChanges(rows.map(row => ({
24
+ name: row.deploy,
25
+ dependencies: row.deps ?? [],
26
+ deploy: row.content
27
+ })), { granularity });
28
+ const counters = new Map();
29
+ const taken = new Set();
30
+ const restructured = changes.map(change => {
31
+ let deploy = change.name;
32
+ const deps = [...change.dependencies];
33
+ if (taken.has(deploy)) {
34
+ let n = (counters.get(change.name) ?? 0) + 1;
35
+ while (taken.has(alterationPathFor(change.name, n)))
36
+ n++;
37
+ counters.set(change.name, n);
38
+ deploy = alterationPathFor(change.name, n);
39
+ if (!deps.includes(change.name))
40
+ deps.push(change.name);
41
+ }
42
+ taken.add(deploy);
43
+ return {
44
+ name: deploy,
45
+ deploy,
46
+ deps,
47
+ content: change.deploy,
48
+ revert: change.revert,
49
+ verify: change.verify
50
+ };
51
+ });
52
+ return { rows: restructured, warnings };
53
+ };
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import { Inquirerer } from 'inquirerer';
11
11
  import { PgpmPackage } from '@pgpmjs/core';
12
+ import { ExportGranularity } from './restructure';
12
13
  import { Schema } from './export-utils';
13
14
  export interface ExportGraphQLOptions {
14
15
  project: PgpmPackage;
@@ -55,5 +56,12 @@ export interface ExportGraphQLOptions {
55
56
  * policy (export.exclude_categories), so this flag is not applied client-side.
56
57
  */
57
58
  excludeCategories?: string[];
59
+ /**
60
+ * Granularity dial for the exported database module. When set, exported SQL
61
+ * is routed through `restructureChanges` (`@pgpmjs/transform`): change paths
62
+ * are derived from the naming spec and `requires` from the statement graph.
63
+ * When omitted, sql_actions rows are written through unchanged.
64
+ */
65
+ granularity?: ExportGranularity;
58
66
  }
59
- export declare const exportGraphQL: ({ project, metaEndpoint, migrateEndpoint, token, headers, migrateHeaders, databaseId, databaseName, schema_names, schemas, author, outdir, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming }: ExportGraphQLOptions) => Promise<void>;
67
+ export declare const exportGraphQL: ({ project, metaEndpoint, migrateEndpoint, token, headers, migrateHeaders, databaseId, databaseName, schema_names, schemas, author, outdir, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming, granularity }: ExportGraphQLOptions) => Promise<void>;
package/export-graphql.js CHANGED
@@ -6,8 +6,9 @@ const migrate_client_1 = require("@pgpmjs/migrate-client");
6
6
  const graphql_client_1 = require("./graphql-client");
7
7
  const export_graphql_meta_1 = require("./export-graphql-meta");
8
8
  const graphql_naming_1 = require("./graphql-naming");
9
+ const restructure_1 = require("./restructure");
9
10
  const export_utils_1 = require("./export-utils");
10
- const exportGraphQL = async ({ project, metaEndpoint, migrateEndpoint, token, headers, migrateHeaders, databaseId, databaseName, schema_names, schemas, author, outdir, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false }) => {
11
+ const exportGraphQL = async ({ project, metaEndpoint, migrateEndpoint, token, headers, migrateHeaders, databaseId, databaseName, schema_names, schemas, author, outdir, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false, granularity }) => {
11
12
  const normalizedOutdir = (0, export_utils_1.normalizeOutdir)(outdir);
12
13
  const svcOutdir = (0, export_utils_1.normalizeOutdir)(serviceOutdir || outdir);
13
14
  const name = extensionName;
@@ -100,8 +101,14 @@ const exportGraphQL = async ({ project, metaEndpoint, migrateEndpoint, token, he
100
101
  if (dbMissingResult.shouldInstall) {
101
102
  await (0, export_utils_1.installMissingModules)(dbModuleDir, dbMissingResult.missingModules);
102
103
  }
103
- (0, core_1.writePgpmPlan)(sqlActionRows, opts);
104
- (0, core_1.writePgpmFiles)(sqlActionRows, opts);
104
+ let dbRows = sqlActionRows;
105
+ if (granularity) {
106
+ const { rows, warnings } = await (0, restructure_1.restructureExportRows)(dbRows, granularity);
107
+ dbRows = rows;
108
+ warnings.forEach(warning => console.warn(`restructure (${granularity}): ${warning}`));
109
+ }
110
+ (0, core_1.writePgpmPlan)(dbRows, opts);
111
+ (0, core_1.writePgpmFiles)(dbRows, opts);
105
112
  }
106
113
  else {
107
114
  console.log('No sql_actions found. Skipping database module export.');
@@ -1,6 +1,7 @@
1
1
  import { PgpmOptions } from '@pgpmjs/types';
2
2
  import { Inquirerer } from 'inquirerer';
3
3
  import { PgpmPackage } from '@pgpmjs/core';
4
+ import { ExportGranularity } from './restructure';
4
5
  interface ExportOptions {
5
6
  project: PgpmPackage;
6
7
  options: PgpmOptions;
@@ -36,6 +37,13 @@ interface ExportOptions {
36
37
  * generated pgpm plan and SQL files. Rows with a NULL category are always kept.
37
38
  */
38
39
  excludeCategories?: string[];
40
+ /**
41
+ * Granularity dial for the exported database module. When set, exported SQL
42
+ * is routed through `restructureChanges` (`@pgpmjs/transform`): change paths
43
+ * are derived from the naming spec and `requires` from the statement graph.
44
+ * When omitted, sql_actions rows are written through unchanged.
45
+ */
46
+ granularity?: ExportGranularity;
39
47
  }
40
- export declare const exportMigrations: ({ project, options, dbInfo, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming, excludeCategories }: ExportOptions) => Promise<void>;
48
+ export declare const exportMigrations: ({ project, options, dbInfo, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming, excludeCategories, granularity }: ExportOptions) => Promise<void>;
41
49
  export {};
@@ -4,8 +4,9 @@ exports.exportMigrations = void 0;
4
4
  const pg_cache_1 = require("pg-cache");
5
5
  const core_1 = require("@pgpmjs/core");
6
6
  const export_meta_1 = require("./export-meta");
7
+ const restructure_1 = require("./restructure");
7
8
  const export_utils_1 = require("./export-utils");
8
- const exportMigrationsToDisk = async ({ project, options, database, databaseId, databaseName, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false, excludeCategories }) => {
9
+ const exportMigrationsToDisk = async ({ project, options, database, databaseId, databaseName, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming = false, excludeCategories, granularity }) => {
9
10
  const normalizedOutdir = (0, export_utils_1.normalizeOutdir)(outdir);
10
11
  // Use serviceOutdir for service module, defaulting to outdir if not provided
11
12
  const svcOutdir = (0, export_utils_1.normalizeOutdir)(serviceOutdir || outdir);
@@ -79,8 +80,14 @@ const exportMigrationsToDisk = async ({ project, options, database, databaseId,
79
80
  if (dbMissingResult.shouldInstall) {
80
81
  await (0, export_utils_1.installMissingModules)(dbModuleDir, dbMissingResult.missingModules);
81
82
  }
82
- (0, core_1.writePgpmPlan)(appRows, opts);
83
- (0, core_1.writePgpmFiles)(appRows, opts);
83
+ let dbRows = appRows;
84
+ if (granularity) {
85
+ const { rows, warnings } = await (0, restructure_1.restructureExportRows)(appRows, granularity);
86
+ dbRows = rows;
87
+ warnings.forEach(warning => console.warn(`restructure (${granularity}): ${warning}`));
88
+ }
89
+ (0, core_1.writePgpmPlan)(dbRows, opts);
90
+ (0, core_1.writePgpmFiles)(dbRows, opts);
84
91
  }
85
92
  else {
86
93
  console.log('No sql_actions found — skipping database module. Meta/service module will still be exported.');
@@ -182,7 +189,7 @@ ${export_utils_1.META_COMMON_FOOTER}
182
189
  (0, core_1.writePgpmPlan)(metaPackage, opts);
183
190
  (0, core_1.writePgpmFiles)(metaPackage, opts);
184
191
  };
185
- const exportMigrations = async ({ project, options, dbInfo, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming, excludeCategories }) => {
192
+ const exportMigrations = async ({ project, options, dbInfo, author, outdir, schema_names, extensionName, extensionDesc, metaExtensionName, metaExtensionDesc, prompter, argv, repoName, username, serviceOutdir, skipSchemaRenaming, excludeCategories, granularity }) => {
186
193
  for (let v = 0; v < dbInfo.database_ids.length; v++) {
187
194
  const databaseId = dbInfo.database_ids[v];
188
195
  await exportMigrationsToDisk({
@@ -204,7 +211,8 @@ const exportMigrations = async ({ project, options, dbInfo, author, outdir, sche
204
211
  username,
205
212
  serviceOutdir,
206
213
  skipSchemaRenaming,
207
- excludeCategories
214
+ excludeCategories,
215
+ granularity
208
216
  });
209
217
  }
210
218
  };
package/index.d.ts CHANGED
@@ -3,6 +3,8 @@ export * from './export-meta';
3
3
  export * from './export-migrations';
4
4
  export * from './export-graphql';
5
5
  export * from './export-graphql-meta';
6
+ export { EXPORT_GRANULARITIES, isExportGranularity, restructureExportRows } from './restructure';
7
+ export type { ExportGranularity, RestructureExportRowsResult } from './restructure';
6
8
  export { GraphQLClient } from './graphql-client';
7
9
  export { getGraphQLQueryName, getGraphQLTypeName, graphqlRowToPostgresRow, buildFieldsFragment, mapGraphQLTypeToFieldType, unwrapGraphQLType, GraphQLTypeInfo } from './graphql-naming';
8
10
  export { DB_REQUIRED_EXTENSIONS, SERVICE_REQUIRED_EXTENSIONS, META_COMMON_HEADER, META_COMMON_FOOTER, META_TABLE_ORDER, META_TABLE_CONFIG, META_TABLE_OVERRIDES, mapPgTypeToFieldType, makeReplacer, preparePackage, normalizeOutdir, detectMissingModules, installMissingModules } from './export-utils';
package/index.js CHANGED
@@ -14,12 +14,16 @@ 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.parsePgInterval = exports.intervalToPostgres = exports.lookupByGqlType = exports.lookupByPgUdt = exports.PG_TYPE_MAP = exports.installMissingModules = exports.detectMissingModules = exports.normalizeOutdir = exports.preparePackage = exports.makeReplacer = exports.mapPgTypeToFieldType = exports.META_TABLE_OVERRIDES = exports.META_TABLE_CONFIG = exports.META_TABLE_ORDER = exports.META_COMMON_FOOTER = exports.META_COMMON_HEADER = exports.SERVICE_REQUIRED_EXTENSIONS = exports.DB_REQUIRED_EXTENSIONS = exports.unwrapGraphQLType = exports.mapGraphQLTypeToFieldType = exports.buildFieldsFragment = exports.graphqlRowToPostgresRow = exports.getGraphQLTypeName = exports.getGraphQLQueryName = exports.GraphQLClient = void 0;
17
+ exports.parsePgInterval = exports.intervalToPostgres = exports.lookupByGqlType = exports.lookupByPgUdt = exports.PG_TYPE_MAP = exports.installMissingModules = exports.detectMissingModules = exports.normalizeOutdir = exports.preparePackage = exports.makeReplacer = exports.mapPgTypeToFieldType = exports.META_TABLE_OVERRIDES = exports.META_TABLE_CONFIG = exports.META_TABLE_ORDER = exports.META_COMMON_FOOTER = exports.META_COMMON_HEADER = exports.SERVICE_REQUIRED_EXTENSIONS = exports.DB_REQUIRED_EXTENSIONS = exports.unwrapGraphQLType = exports.mapGraphQLTypeToFieldType = exports.buildFieldsFragment = exports.graphqlRowToPostgresRow = exports.getGraphQLTypeName = exports.getGraphQLQueryName = exports.GraphQLClient = exports.restructureExportRows = exports.isExportGranularity = exports.EXPORT_GRANULARITIES = void 0;
18
18
  __exportStar(require("./export-data"), exports);
19
19
  __exportStar(require("./export-meta"), exports);
20
20
  __exportStar(require("./export-migrations"), exports);
21
21
  __exportStar(require("./export-graphql"), exports);
22
22
  __exportStar(require("./export-graphql-meta"), exports);
23
+ var restructure_1 = require("./restructure");
24
+ Object.defineProperty(exports, "EXPORT_GRANULARITIES", { enumerable: true, get: function () { return restructure_1.EXPORT_GRANULARITIES; } });
25
+ Object.defineProperty(exports, "isExportGranularity", { enumerable: true, get: function () { return restructure_1.isExportGranularity; } });
26
+ Object.defineProperty(exports, "restructureExportRows", { enumerable: true, get: function () { return restructure_1.restructureExportRows; } });
23
27
  var graphql_client_1 = require("./graphql-client");
24
28
  Object.defineProperty(exports, "GraphQLClient", { enumerable: true, get: function () { return graphql_client_1.GraphQLClient; } });
25
29
  var graphql_naming_1 = require("./graphql-naming");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/export",
3
- "version": "1.13.4",
3
+ "version": "1.14.1",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PGPM export tools for SQL and GraphQL database migration extraction",
6
6
  "main": "index.js",
@@ -41,14 +41,16 @@
41
41
  "@pgsql/types": "^18.0.0",
42
42
  "@types/pg": "^8.20.0",
43
43
  "makage": "^0.3.0",
44
- "pgsql-test": "^5.9.4"
44
+ "pgsql-test": "^5.9.6"
45
45
  },
46
46
  "dependencies": {
47
- "@constructive-io/query-builder": "^3.9.3",
48
- "@pgpmjs/core": "^7.20.4",
49
- "@pgpmjs/migrate-client": "^1.10.4",
47
+ "@constructive-io/query-builder": "^3.9.4",
48
+ "@pgpmjs/core": "^7.21.1",
49
+ "@pgpmjs/migrate-client": "^1.10.6",
50
+ "@pgpmjs/naming-spec": "^0.1.2",
51
+ "@pgpmjs/transform": "^0.17.0",
50
52
  "@pgpmjs/types": "^2.49.2",
51
- "csv-to-pg": "^4.9.2",
53
+ "csv-to-pg": "^4.9.3",
52
54
  "glob": "^13.0.6",
53
55
  "inflekt": "^0.7.1",
54
56
  "inquirerer": "^4.9.1",
@@ -56,5 +58,5 @@
56
58
  "pg-cache": "^3.24.2",
57
59
  "pg-env": "^1.27.2"
58
60
  },
59
- "gitHead": "90f447482b056a4949134565db2665f21d11aca3"
61
+ "gitHead": "45cd961cf956d2d28e4d09b20db4204982c33593"
60
62
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Granularity dial for `pgpm export`: route exported sql_actions rows through
3
+ * the dials pipeline (`restructureChanges` in `@pgpmjs/transform`) so change
4
+ * paths are derived from the naming spec (`identityOf` + `pathFor`) and
5
+ * `requires` come from the statement dependency graph instead of the
6
+ * hand-chained deps recorded at action time.
7
+ */
8
+ import { PgpmRow } from '@pgpmjs/core';
9
+ import { Granularity } from '@pgpmjs/transform';
10
+ export type ExportGranularity = Granularity;
11
+ export declare const EXPORT_GRANULARITIES: readonly ExportGranularity[];
12
+ export declare const isExportGranularity: (value: unknown) => value is ExportGranularity;
13
+ export interface RestructureExportRowsResult {
14
+ rows: PgpmRow[];
15
+ warnings: string[];
16
+ }
17
+ /**
18
+ * Restructure exported migration rows to the target granularity.
19
+ *
20
+ * The rows' deploy SQL is flattened in export order, restructured, and
21
+ * re-sliced into per-object changes whose paths come from the naming spec and
22
+ * whose deps come from the statement graph. When two changes derive the same
23
+ * path (the same object altered again), later occurrences get the spec's
24
+ * alteration convention via `alterationPathFor` (monotonic per-parent
25
+ * counter), with the parent added to their deps.
26
+ *
27
+ * Revert/verify scripts are not carried through from the original rows (the
28
+ * restructured grouping no longer matches them one-to-one); instead each
29
+ * change gets scripts generated from its own statements via
30
+ * `revertFor`/`verifyFor` (drops in reverse topological order, one existence
31
+ * check per created object).
32
+ */
33
+ export declare const restructureExportRows: (rows: PgpmRow[], granularity: ExportGranularity) => Promise<RestructureExportRowsResult>;
package/restructure.js ADDED
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.restructureExportRows = exports.isExportGranularity = exports.EXPORT_GRANULARITIES = void 0;
4
+ const naming_spec_1 = require("@pgpmjs/naming-spec");
5
+ const transform_1 = require("@pgpmjs/transform");
6
+ exports.EXPORT_GRANULARITIES = ['atomic', 'object', 'consolidated'];
7
+ const isExportGranularity = (value) => typeof value === 'string' && exports.EXPORT_GRANULARITIES.includes(value);
8
+ exports.isExportGranularity = isExportGranularity;
9
+ /**
10
+ * Restructure exported migration rows to the target granularity.
11
+ *
12
+ * The rows' deploy SQL is flattened in export order, restructured, and
13
+ * re-sliced into per-object changes whose paths come from the naming spec and
14
+ * whose deps come from the statement graph. When two changes derive the same
15
+ * path (the same object altered again), later occurrences get the spec's
16
+ * alteration convention via `alterationPathFor` (monotonic per-parent
17
+ * counter), with the parent added to their deps.
18
+ *
19
+ * Revert/verify scripts are not carried through from the original rows (the
20
+ * restructured grouping no longer matches them one-to-one); instead each
21
+ * change gets scripts generated from its own statements via
22
+ * `revertFor`/`verifyFor` (drops in reverse topological order, one existence
23
+ * check per created object).
24
+ */
25
+ const restructureExportRows = async (rows, granularity) => {
26
+ await (0, transform_1.loadModule)();
27
+ const { changes, warnings } = (0, transform_1.restructureChanges)(rows.map(row => ({
28
+ name: row.deploy,
29
+ dependencies: row.deps ?? [],
30
+ deploy: row.content
31
+ })), { granularity });
32
+ const counters = new Map();
33
+ const taken = new Set();
34
+ const restructured = changes.map(change => {
35
+ let deploy = change.name;
36
+ const deps = [...change.dependencies];
37
+ if (taken.has(deploy)) {
38
+ let n = (counters.get(change.name) ?? 0) + 1;
39
+ while (taken.has((0, naming_spec_1.alterationPathFor)(change.name, n)))
40
+ n++;
41
+ counters.set(change.name, n);
42
+ deploy = (0, naming_spec_1.alterationPathFor)(change.name, n);
43
+ if (!deps.includes(change.name))
44
+ deps.push(change.name);
45
+ }
46
+ taken.add(deploy);
47
+ return {
48
+ name: deploy,
49
+ deploy,
50
+ deps,
51
+ content: change.deploy,
52
+ revert: change.revert,
53
+ verify: change.verify
54
+ };
55
+ });
56
+ return { rows: restructured, warnings };
57
+ };
58
+ exports.restructureExportRows = restructureExportRows;