@pgpmjs/core 5.0.1 → 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.
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;