@pgpmjs/core 7.14.0 → 7.15.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.
@@ -6,16 +6,10 @@ import * as path from 'path';
6
6
  import { getPgPool } from 'pg-cache';
7
7
  import { resolveEffectiveModulePath } from '../apply/materialize';
8
8
  import { hasApplySpec } from '../apply/apply-spec';
9
+ import { deployModuleFast, isBundledDeployResult } from '../bundle/deploy-bundled';
9
10
  import { PgpmPackage } from '../core/class/pgpm';
10
11
  import { PgpmMigrate } from '../migrate/client';
11
- import { packageModule } from '../packaging/package';
12
12
  import { resolveExtensionDependencies } from '../resolution/deps';
13
- // Cache for fast deployment
14
- const deployFastCache = {};
15
- const getCacheKey = (pg, name, database) => {
16
- const { host, port, user } = pg ?? {};
17
- return `${host}:${port}:${user}:${database}:${name}`;
18
- };
19
13
  const log = new Logger('deploy');
20
14
  export const deployProject = async (opts, name, database, pkg, toChange) => {
21
15
  const mergedOpts = getEnvOptions(opts);
@@ -50,56 +44,25 @@ export const deployProject = async (opts, name, database, pkg, toChange) => {
50
44
  if (modulePath !== sourcePath) {
51
45
  log.info(`🔁 Applying transpiled module (spec in ${sourcePath})`);
52
46
  }
53
- if (mergedOpts.deployment.fast) {
54
- // Use fast deployment strategy
55
- const localProject = new PgpmPackage(modulePath, { extensionsDir: pkg.extensionsDir });
56
- const cacheKey = getCacheKey(mergedOpts.pg, extension, database);
57
- if (mergedOpts.deployment.cache && deployFastCache[cacheKey]) {
58
- log.warn(`⚡ Using cached package for ${extension}.`);
59
- await pgPool.query(deployFastCache[cacheKey].sql);
47
+ // The fast strategy is opt-in; everything else uses the per-change path.
48
+ if (mergedOpts.deployment.fast || mergedOpts.deployment.bundled) {
49
+ // Fast strategy: execute the module in one shot AND record the
50
+ // migration ledger, from the pre-built bundle artifact when one
51
+ // verifies and from `deploy/` otherwise. If the semantics cannot be
52
+ // honoured, fall through to the per-change migration path rather than
53
+ // deploying without a ledger.
54
+ const outcome = await deployModuleFast(modulePath, {
55
+ config: { ...mergedOpts.pg, database },
56
+ logOnly: mergedOpts.deployment.logOnly,
57
+ useTransaction: mergedOpts.deployment.useTx,
58
+ hashMethod: mergedOpts.deployment.hashMethod
59
+ });
60
+ if (isBundledDeployResult(outcome)) {
60
61
  continue;
61
62
  }
62
- let modulePackage;
63
- try {
64
- modulePackage = await packageModule(localProject.modulePath, {
65
- usePlan: mergedOpts.deployment.usePlan,
66
- extension: false
67
- });
68
- }
69
- catch (err) {
70
- // Build comprehensive error message
71
- const errorLines = [];
72
- errorLines.push(`❌ Failed to package module "${extension}" at path: ${modulePath}`);
73
- errorLines.push(` Module Path: ${modulePath}`);
74
- errorLines.push(` Workspace Path: ${pkg.workspacePath}`);
75
- errorLines.push(` Error Code: ${err.code || 'N/A'}`);
76
- errorLines.push(` Error Message: ${err.message || 'Unknown error'}`);
77
- // Provide debugging hints
78
- if (err.code === 'ENOENT') {
79
- errorLines.push('💡 Hint: File or directory not found. Check if the module path is correct.');
80
- }
81
- else if (err.code === 'EACCES') {
82
- errorLines.push('💡 Hint: Permission denied. Check file permissions.');
83
- }
84
- else if (err.message && err.message.includes('pgpm.plan')) {
85
- errorLines.push('💡 Hint: pgpm.plan file issue. Check if the plan file exists and is valid.');
86
- }
87
- // Log the consolidated error message
88
- log.error(errorLines.join('\n'));
89
- console.error(err); // Preserve full stack trace
90
- throw errors.DEPLOYMENT_FAILED({
91
- type: 'Deployment',
92
- module: extension
93
- });
94
- }
95
- log.debug(`→ Command: sqitch deploy db:pg:${database}`);
96
- log.debug(`> ${modulePackage.sql}`);
97
- await pgPool.query(modulePackage.sql);
98
- if (mergedOpts.deployment.cache) {
99
- deployFastCache[cacheKey] = modulePackage;
100
- }
63
+ log.info(`â†Šī¸ Fast deploy unavailable for ${extension} (${outcome}); using per-change path.`);
101
64
  }
102
- else {
65
+ {
103
66
  // Use new migration system
104
67
  log.debug(`→ Command: constructive migrate deploy db:pg:${database}`);
105
68
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/core",
3
- "version": "7.14.0",
3
+ "version": "7.15.0",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PGPM Package and Migration Tools",
6
6
  "main": "index.js",
@@ -48,24 +48,24 @@
48
48
  "makage": "^0.3.0"
49
49
  },
50
50
  "dependencies": {
51
- "@pgpmjs/ast": "^0.9.1",
52
- "@pgpmjs/bundle": "^0.11.0",
53
- "@pgpmjs/env": "^2.37.0",
51
+ "@pgpmjs/ast": "^0.9.2",
52
+ "@pgpmjs/bundle": "^0.12.0",
53
+ "@pgpmjs/env": "^2.38.0",
54
54
  "@pgpmjs/logger": "^2.22.0",
55
- "@pgpmjs/server-utils": "^3.23.0",
56
- "@pgpmjs/slice": "^0.10.0",
57
- "@pgpmjs/transform": "^0.10.0",
58
- "@pgpmjs/types": "^2.45.0",
55
+ "@pgpmjs/server-utils": "^3.23.1",
56
+ "@pgpmjs/slice": "^0.10.1",
57
+ "@pgpmjs/transform": "^0.11.0",
58
+ "@pgpmjs/types": "^2.46.0",
59
59
  "csv-to-pg": "^4.8.0",
60
60
  "genomic": "^5.6.2",
61
61
  "glob": "^13.0.6",
62
62
  "parse-package-name": "^1.0.0",
63
63
  "pg": "^8.21.0",
64
- "pg-cache": "^3.23.0",
64
+ "pg-cache": "^3.23.1",
65
65
  "pg-env": "^1.26.0",
66
66
  "pgsql-deparser": "^18.1.1",
67
67
  "pgsql-parser": "^18.1.1",
68
68
  "yanse": "^0.2.1"
69
69
  },
70
- "gitHead": "d85911699e8a50a9fdfeb7506195442525c1f238"
70
+ "gitHead": "5ef8341033a8fbd85841b770e996e468dd15333b"
71
71
  }
@@ -9,6 +9,12 @@ interface PackageModuleOptions {
9
9
  interface WritePackageOptions extends PackageModuleOptions {
10
10
  version: string;
11
11
  packageDir: string;
12
+ /**
13
+ * Also emit the content-addressed bundle artifact
14
+ * `sql/<name>--<version>.bundle.tar.gz` (default true). It is what
15
+ * `deploy --bundled` consumes.
16
+ */
17
+ bundle?: boolean;
12
18
  }
13
19
  export interface MergeSqlOptions {
14
20
  /** Strip `TransactionStmt`/`CreateExtensionStmt` before deparsing (extension mode) */
@@ -38,5 +44,5 @@ export declare const packageModule: (packageDir: string, { usePlan, extension, p
38
44
  tree1?: string;
39
45
  tree2?: string;
40
46
  }>;
41
- export declare const writePackage: ({ version, extension, usePlan, packageDir, outputDiff, }: WritePackageOptions) => Promise<void>;
47
+ export declare const writePackage: ({ version, extension, usePlan, packageDir, outputDiff, bundle, }: WritePackageOptions) => Promise<void>;
42
48
  export {};
@@ -7,6 +7,7 @@ const path_1 = require("path");
7
7
  const pgsql_deparser_1 = require("pgsql-deparser");
8
8
  const pgsql_parser_1 = require("pgsql-parser");
9
9
  const files_1 = require("@pgpmjs/ast/files");
10
+ const artifact_1 = require("../bundle/artifact");
10
11
  const resolve_1 = require("../resolution/resolve");
11
12
  const transform_1 = require("./transform");
12
13
  const log = new logger_1.Logger('package');
@@ -84,7 +85,7 @@ const packageModule = async (packageDir, { usePlan = true, extension = true, pre
84
85
  }
85
86
  };
86
87
  exports.packageModule = packageModule;
87
- const writePackage = async ({ version, extension = true, usePlan = true, packageDir, outputDiff = false, }) => {
88
+ const writePackage = async ({ version, extension = true, usePlan = true, packageDir, outputDiff = false, bundle = true, }) => {
88
89
  const pkgPath = `${packageDir}/package.json`;
89
90
  const pkg = require(pkgPath);
90
91
  const extname = await (0, files_1.getExtensionName)(packageDir);
@@ -121,5 +122,11 @@ const writePackage = async ({ version, extension = true, usePlan = true, package
121
122
  const writePath = `${outPath}/${sqlFileName}`;
122
123
  (0, fs_1.writeFileSync)(writePath, sql);
123
124
  log.success(`${(0, path_1.relative)(packageDir, writePath)} written`);
125
+ if (bundle) {
126
+ const bundlePath = await (0, artifact_1.writeBundleArtifact)(packageDir, version, {
127
+ createdWith: '@pgpmjs/core'
128
+ });
129
+ log.success(`${(0, path_1.relative)(packageDir, bundlePath)} written`);
130
+ }
124
131
  };
125
132
  exports.writePackage = writePackage;
@@ -42,16 +42,10 @@ const path = __importStar(require("path"));
42
42
  const pg_cache_1 = require("pg-cache");
43
43
  const materialize_1 = require("../apply/materialize");
44
44
  const apply_spec_1 = require("../apply/apply-spec");
45
+ const deploy_bundled_1 = require("../bundle/deploy-bundled");
45
46
  const pgpm_1 = require("../core/class/pgpm");
46
47
  const client_1 = require("../migrate/client");
47
- const package_1 = require("../packaging/package");
48
48
  const deps_1 = require("../resolution/deps");
49
- // Cache for fast deployment
50
- const deployFastCache = {};
51
- const getCacheKey = (pg, name, database) => {
52
- const { host, port, user } = pg ?? {};
53
- return `${host}:${port}:${user}:${database}:${name}`;
54
- };
55
49
  const log = new logger_1.Logger('deploy');
56
50
  const deployProject = async (opts, name, database, pkg, toChange) => {
57
51
  const mergedOpts = (0, env_1.getEnvOptions)(opts);
@@ -86,56 +80,25 @@ const deployProject = async (opts, name, database, pkg, toChange) => {
86
80
  if (modulePath !== sourcePath) {
87
81
  log.info(`🔁 Applying transpiled module (spec in ${sourcePath})`);
88
82
  }
89
- if (mergedOpts.deployment.fast) {
90
- // Use fast deployment strategy
91
- const localProject = new pgpm_1.PgpmPackage(modulePath, { extensionsDir: pkg.extensionsDir });
92
- const cacheKey = getCacheKey(mergedOpts.pg, extension, database);
93
- if (mergedOpts.deployment.cache && deployFastCache[cacheKey]) {
94
- log.warn(`⚡ Using cached package for ${extension}.`);
95
- await pgPool.query(deployFastCache[cacheKey].sql);
83
+ // The fast strategy is opt-in; everything else uses the per-change path.
84
+ if (mergedOpts.deployment.fast || mergedOpts.deployment.bundled) {
85
+ // Fast strategy: execute the module in one shot AND record the
86
+ // migration ledger, from the pre-built bundle artifact when one
87
+ // verifies and from `deploy/` otherwise. If the semantics cannot be
88
+ // honoured, fall through to the per-change migration path rather than
89
+ // deploying without a ledger.
90
+ const outcome = await (0, deploy_bundled_1.deployModuleFast)(modulePath, {
91
+ config: { ...mergedOpts.pg, database },
92
+ logOnly: mergedOpts.deployment.logOnly,
93
+ useTransaction: mergedOpts.deployment.useTx,
94
+ hashMethod: mergedOpts.deployment.hashMethod
95
+ });
96
+ if ((0, deploy_bundled_1.isBundledDeployResult)(outcome)) {
96
97
  continue;
97
98
  }
98
- let modulePackage;
99
- try {
100
- modulePackage = await (0, package_1.packageModule)(localProject.modulePath, {
101
- usePlan: mergedOpts.deployment.usePlan,
102
- extension: false
103
- });
104
- }
105
- catch (err) {
106
- // Build comprehensive error message
107
- const errorLines = [];
108
- errorLines.push(`❌ Failed to package module "${extension}" at path: ${modulePath}`);
109
- errorLines.push(` Module Path: ${modulePath}`);
110
- errorLines.push(` Workspace Path: ${pkg.workspacePath}`);
111
- errorLines.push(` Error Code: ${err.code || 'N/A'}`);
112
- errorLines.push(` Error Message: ${err.message || 'Unknown error'}`);
113
- // Provide debugging hints
114
- if (err.code === 'ENOENT') {
115
- errorLines.push('💡 Hint: File or directory not found. Check if the module path is correct.');
116
- }
117
- else if (err.code === 'EACCES') {
118
- errorLines.push('💡 Hint: Permission denied. Check file permissions.');
119
- }
120
- else if (err.message && err.message.includes('pgpm.plan')) {
121
- errorLines.push('💡 Hint: pgpm.plan file issue. Check if the plan file exists and is valid.');
122
- }
123
- // Log the consolidated error message
124
- log.error(errorLines.join('\n'));
125
- console.error(err); // Preserve full stack trace
126
- throw types_1.errors.DEPLOYMENT_FAILED({
127
- type: 'Deployment',
128
- module: extension
129
- });
130
- }
131
- log.debug(`→ Command: sqitch deploy db:pg:${database}`);
132
- log.debug(`> ${modulePackage.sql}`);
133
- await pgPool.query(modulePackage.sql);
134
- if (mergedOpts.deployment.cache) {
135
- deployFastCache[cacheKey] = modulePackage;
136
- }
99
+ log.info(`â†Šī¸ Fast deploy unavailable for ${extension} (${outcome}); using per-change path.`);
137
100
  }
138
- else {
101
+ {
139
102
  // Use new migration system
140
103
  log.debug(`→ Command: constructive migrate deploy db:pg:${database}`);
141
104
  try {