@pgpmjs/core 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -94,14 +94,6 @@ const config = {
94
94
  hash: 'uuid'
95
95
  }
96
96
  },
97
- database_extension: {
98
- schema: 'metaschema_public',
99
- table: 'database_extension',
100
- fields: {
101
- name: 'text',
102
- database_id: 'uuid'
103
- }
104
- },
105
97
  schema: {
106
98
  schema: 'metaschema_public',
107
99
  table: 'schema',
@@ -432,16 +424,6 @@ const config = {
432
424
  data: 'jsonb'
433
425
  }
434
426
  },
435
- api_extensions: {
436
- schema: 'services_public',
437
- table: 'api_extensions',
438
- fields: {
439
- id: 'uuid',
440
- database_id: 'uuid',
441
- api_id: 'uuid',
442
- schema_name: 'text'
443
- }
444
- },
445
427
  api_schemas: {
446
428
  schema: 'services_public',
447
429
  table: 'api_schemas',
@@ -218,7 +218,6 @@ SET session_replication_role TO DEFAULT;`;
218
218
  // Tables that depend on 'database' being inserted first
219
219
  const tableOrder = [
220
220
  'database',
221
- 'database_extension',
222
221
  'schema',
223
222
  'table',
224
223
  'field',
@@ -244,7 +243,6 @@ SET session_replication_role TO DEFAULT;`;
244
243
  'site_themes',
245
244
  'site_metadata',
246
245
  'api_modules',
247
- 'api_extensions',
248
246
  'api_schemas',
249
247
  'rls_module',
250
248
  'user_auth_module',
package/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './core/class/pgpm';
2
2
  export * from './export/export-meta';
3
3
  export * from './export/export-migrations';
4
+ export * from './slice';
4
5
  export * from './extensions/extensions';
5
6
  export * from './modules/modules';
6
7
  export * from './packaging/package';
package/index.js CHANGED
@@ -18,6 +18,7 @@ exports.withTransaction = exports.executeQuery = exports.hashString = exports.ha
18
18
  __exportStar(require("./core/class/pgpm"), exports);
19
19
  __exportStar(require("./export/export-meta"), exports);
20
20
  __exportStar(require("./export/export-migrations"), exports);
21
+ __exportStar(require("./slice"), exports);
21
22
  __exportStar(require("./extensions/extensions"), exports);
22
23
  __exportStar(require("./modules/modules"), exports);
23
24
  __exportStar(require("./packaging/package"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/core",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PGPM Package and Migration Tools",
6
6
  "main": "index.js",
@@ -56,6 +56,7 @@
56
56
  "genomic": "^5.3.0",
57
57
  "glob": "^13.0.0",
58
58
  "komoji": "^0.8.0",
59
+ "minimatch": "^10.1.1",
59
60
  "parse-package-name": "^1.0.0",
60
61
  "pg": "^8.17.1",
61
62
  "pg-cache": "^2.0.0",
@@ -64,5 +65,5 @@
64
65
  "pgsql-parser": "^17.9.11",
65
66
  "yanse": "^0.2.0"
66
67
  },
67
- "gitHead": "390f4dd57fc158554518ec454bf2a4856d550552"
68
+ "gitHead": "20d7e992348542531e73f20c0fd084decec86325"
68
69
  }
@@ -0,0 +1,3 @@
1
+ export * from './types';
2
+ export * from './slice';
3
+ export * from './output';
package/slice/index.js ADDED
@@ -0,0 +1,19 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./slice"), exports);
19
+ __exportStar(require("./output"), exports);
@@ -0,0 +1,22 @@
1
+ import { SliceResult } from './types';
2
+ /**
3
+ * Options for writing sliced packages to disk
4
+ */
5
+ export interface WriteSliceOptions {
6
+ /** Base output directory */
7
+ outputDir: string;
8
+ /** Whether to overwrite existing packages */
9
+ overwrite?: boolean;
10
+ /** Whether to copy SQL files from source */
11
+ copySourceFiles?: boolean;
12
+ /** Source directory containing deploy/revert/verify folders */
13
+ sourceDir?: string;
14
+ }
15
+ /**
16
+ * Write sliced packages to disk
17
+ */
18
+ export declare function writeSliceResult(result: SliceResult, options: WriteSliceOptions): void;
19
+ /**
20
+ * Generate a dry-run report of what would be created
21
+ */
22
+ export declare function generateDryRunReport(result: SliceResult): string;
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeSliceResult = writeSliceResult;
7
+ exports.generateDryRunReport = generateDryRunReport;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ /**
11
+ * Write sliced packages to disk
12
+ */
13
+ function writeSliceResult(result, options) {
14
+ const { outputDir, overwrite = false, copySourceFiles = false, sourceDir } = options;
15
+ // Create output directory
16
+ fs_1.default.mkdirSync(outputDir, { recursive: true });
17
+ // Write each package
18
+ for (const pkg of result.packages) {
19
+ writePackage(pkg, outputDir, overwrite, copySourceFiles, sourceDir);
20
+ }
21
+ // Write workspace manifest
22
+ const manifestPath = path_1.default.join(outputDir, 'pgpm-workspace.json');
23
+ const manifestContent = JSON.stringify({
24
+ packages: result.workspace.packages.map(p => `packages/${p}`),
25
+ slicing: {
26
+ deployOrder: result.workspace.deployOrder,
27
+ dependencies: result.workspace.dependencies
28
+ },
29
+ stats: result.stats
30
+ }, null, 2);
31
+ fs_1.default.writeFileSync(manifestPath, manifestContent);
32
+ }
33
+ /**
34
+ * Write a single package to disk
35
+ */
36
+ function writePackage(pkg, outputDir, overwrite, copySourceFiles, sourceDir) {
37
+ const pkgDir = path_1.default.join(outputDir, 'packages', pkg.name);
38
+ // Check if package already exists
39
+ if (fs_1.default.existsSync(pkgDir) && !overwrite) {
40
+ throw new Error(`Package directory already exists: ${pkgDir}. Use --overwrite to replace.`);
41
+ }
42
+ // Create package directory structure
43
+ fs_1.default.mkdirSync(pkgDir, { recursive: true });
44
+ fs_1.default.mkdirSync(path_1.default.join(pkgDir, 'deploy'), { recursive: true });
45
+ fs_1.default.mkdirSync(path_1.default.join(pkgDir, 'revert'), { recursive: true });
46
+ fs_1.default.mkdirSync(path_1.default.join(pkgDir, 'verify'), { recursive: true });
47
+ // Write plan file
48
+ fs_1.default.writeFileSync(path_1.default.join(pkgDir, 'pgpm.plan'), pkg.planContent);
49
+ // Write control file
50
+ fs_1.default.writeFileSync(path_1.default.join(pkgDir, `${pkg.name}.control`), pkg.controlContent);
51
+ // Copy SQL files if requested
52
+ if (copySourceFiles && sourceDir) {
53
+ for (const change of pkg.changes) {
54
+ copyChangeFiles(change.name, sourceDir, pkgDir);
55
+ }
56
+ }
57
+ }
58
+ /**
59
+ * Copy deploy/revert/verify SQL files for a change
60
+ */
61
+ function copyChangeFiles(changeName, sourceDir, targetDir) {
62
+ const types = ['deploy', 'revert', 'verify'];
63
+ for (const type of types) {
64
+ const sourceFile = path_1.default.join(sourceDir, type, `${changeName}.sql`);
65
+ const targetFile = path_1.default.join(targetDir, type, `${changeName}.sql`);
66
+ if (fs_1.default.existsSync(sourceFile)) {
67
+ // Create target directory if needed
68
+ const targetSubDir = path_1.default.dirname(targetFile);
69
+ fs_1.default.mkdirSync(targetSubDir, { recursive: true });
70
+ // Copy file
71
+ fs_1.default.copyFileSync(sourceFile, targetFile);
72
+ }
73
+ }
74
+ }
75
+ /**
76
+ * Generate a dry-run report of what would be created
77
+ */
78
+ function generateDryRunReport(result) {
79
+ const lines = [];
80
+ lines.push('=== PGPM Slice Dry Run Report ===\n');
81
+ // Statistics
82
+ lines.push('Statistics:');
83
+ lines.push(` Total changes: ${result.stats.totalChanges}`);
84
+ lines.push(` Packages to create: ${result.stats.packagesCreated}`);
85
+ lines.push(` Internal edges: ${result.stats.internalEdges}`);
86
+ lines.push(` Cross-package edges: ${result.stats.crossPackageEdges}`);
87
+ lines.push(` Cross-package ratio: ${(result.stats.crossPackageRatio * 100).toFixed(1)}%`);
88
+ lines.push('');
89
+ // Warnings
90
+ if (result.warnings.length > 0) {
91
+ lines.push('Warnings:');
92
+ for (const warning of result.warnings) {
93
+ lines.push(` [${warning.type}] ${warning.message}`);
94
+ if (warning.suggestedAction) {
95
+ lines.push(` Suggestion: ${warning.suggestedAction}`);
96
+ }
97
+ }
98
+ lines.push('');
99
+ }
100
+ // Deploy order
101
+ lines.push('Deploy Order:');
102
+ for (let i = 0; i < result.workspace.deployOrder.length; i++) {
103
+ const pkg = result.workspace.deployOrder[i];
104
+ const deps = result.workspace.dependencies[pkg] || [];
105
+ const depStr = deps.length > 0 ? ` (depends on: ${deps.join(', ')})` : '';
106
+ lines.push(` ${i + 1}. ${pkg}${depStr}`);
107
+ }
108
+ lines.push('');
109
+ // Package details
110
+ lines.push('Packages:');
111
+ for (const pkg of result.packages) {
112
+ lines.push(`\n ${pkg.name}/`);
113
+ lines.push(` Changes: ${pkg.changes.length}`);
114
+ lines.push(` Dependencies: ${pkg.packageDependencies.join(', ') || 'none'}`);
115
+ lines.push(' Contents:');
116
+ for (const change of pkg.changes.slice(0, 5)) {
117
+ lines.push(` - ${change.name}`);
118
+ }
119
+ if (pkg.changes.length > 5) {
120
+ lines.push(` ... and ${pkg.changes.length - 5} more`);
121
+ }
122
+ }
123
+ return lines.join('\n');
124
+ }
@@ -0,0 +1,59 @@
1
+ import { Change, Tag, ExtendedPlanFile } from '../files/types';
2
+ import { SliceConfig, SliceResult, DependencyGraph, PackageOutput, GroupingStrategy, PatternStrategy } from './types';
3
+ /**
4
+ * Build a dependency graph from a parsed plan file
5
+ */
6
+ export declare function buildDependencyGraph(plan: ExtendedPlanFile): DependencyGraph;
7
+ /**
8
+ * Validate that the dependency graph is a DAG (no cycles)
9
+ */
10
+ export declare function validateDAG(graph: DependencyGraph): void;
11
+ /**
12
+ * Extract package name from a change path using folder-based strategy
13
+ */
14
+ export declare function extractPackageFromPath(changeName: string, depth?: number, prefixToStrip?: string): string;
15
+ /**
16
+ * Find the matching package for a change using pattern-based strategy.
17
+ * Returns the first matching slice's package name, or undefined if no match.
18
+ */
19
+ export declare function findMatchingPattern(changeName: string, strategy: PatternStrategy): string | undefined;
20
+ /**
21
+ * Assign changes to packages based on grouping strategy
22
+ */
23
+ export declare function assignChangesToPackages(graph: DependencyGraph, strategy: GroupingStrategy, defaultPackage?: string): Map<string, Set<string>>;
24
+ /**
25
+ * Merge small packages into larger ones
26
+ */
27
+ export declare function mergeSmallPackages(assignments: Map<string, Set<string>>, minChanges: number, defaultPackage?: string): Map<string, Set<string>>;
28
+ /**
29
+ * Build package-level dependency graph
30
+ */
31
+ export declare function buildPackageDependencies(graph: DependencyGraph, assignments: Map<string, Set<string>>): Map<string, Set<string>>;
32
+ /**
33
+ * Detect cycles in package dependency graph
34
+ */
35
+ export declare function detectPackageCycle(deps: Map<string, Set<string>>): string[] | null;
36
+ /**
37
+ * Compute deployment order for packages (topological sort)
38
+ */
39
+ export declare function computeDeployOrder(packageDeps: Map<string, Set<string>>): string[];
40
+ /**
41
+ * Topological sort of changes within a package
42
+ */
43
+ export declare function topologicalSortWithinPackage(changes: Set<string>, graph: DependencyGraph): string[];
44
+ /**
45
+ * Generate plan file content for a package
46
+ */
47
+ export declare function generatePlanContent(pkgName: string, entries: Change[], tags?: Tag[]): string;
48
+ /**
49
+ * Generate control file content for a package
50
+ */
51
+ export declare function generateControlContent(pkgName: string, deps: Set<string>): string;
52
+ /**
53
+ * Generate a single package output
54
+ */
55
+ export declare function generateSinglePackage(pkgName: string, changes: Set<string>, graph: DependencyGraph, changeToPackage: Map<string, string>, pkgDeps: Set<string>, useTagsForCrossPackageDeps?: boolean): PackageOutput;
56
+ /**
57
+ * Main slicing function
58
+ */
59
+ export declare function slicePlan(config: SliceConfig): SliceResult;