@pgpmjs/core 3.0.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.
Files changed (140) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +99 -0
  3. package/core/boilerplate-scanner.d.ts +41 -0
  4. package/core/boilerplate-scanner.js +106 -0
  5. package/core/boilerplate-types.d.ts +52 -0
  6. package/core/boilerplate-types.js +6 -0
  7. package/core/class/pgpm.d.ts +150 -0
  8. package/core/class/pgpm.js +1470 -0
  9. package/core/template-scaffold.d.ts +29 -0
  10. package/core/template-scaffold.js +168 -0
  11. package/esm/core/boilerplate-scanner.js +96 -0
  12. package/esm/core/boilerplate-types.js +5 -0
  13. package/esm/core/class/pgpm.js +1430 -0
  14. package/esm/core/template-scaffold.js +161 -0
  15. package/esm/export/export-meta.js +240 -0
  16. package/esm/export/export-migrations.js +180 -0
  17. package/esm/extensions/extensions.js +31 -0
  18. package/esm/files/extension/index.js +3 -0
  19. package/esm/files/extension/reader.js +79 -0
  20. package/esm/files/extension/writer.js +63 -0
  21. package/esm/files/index.js +6 -0
  22. package/esm/files/plan/generator.js +49 -0
  23. package/esm/files/plan/index.js +5 -0
  24. package/esm/files/plan/parser.js +296 -0
  25. package/esm/files/plan/validators.js +181 -0
  26. package/esm/files/plan/writer.js +114 -0
  27. package/esm/files/sql/index.js +1 -0
  28. package/esm/files/sql/writer.js +107 -0
  29. package/esm/files/sql-scripts/index.js +2 -0
  30. package/esm/files/sql-scripts/reader.js +19 -0
  31. package/esm/files/types/index.js +1 -0
  32. package/esm/files/types/package.js +1 -0
  33. package/esm/index.js +21 -0
  34. package/esm/init/client.js +144 -0
  35. package/esm/init/sql/bootstrap-roles.sql +55 -0
  36. package/esm/init/sql/bootstrap-test-roles.sql +72 -0
  37. package/esm/migrate/clean.js +23 -0
  38. package/esm/migrate/client.js +551 -0
  39. package/esm/migrate/index.js +5 -0
  40. package/esm/migrate/sql/procedures.sql +258 -0
  41. package/esm/migrate/sql/schema.sql +37 -0
  42. package/esm/migrate/types.js +1 -0
  43. package/esm/migrate/utils/event-logger.js +28 -0
  44. package/esm/migrate/utils/hash.js +27 -0
  45. package/esm/migrate/utils/transaction.js +125 -0
  46. package/esm/modules/modules.js +49 -0
  47. package/esm/packaging/package.js +96 -0
  48. package/esm/packaging/transform.js +70 -0
  49. package/esm/projects/deploy.js +123 -0
  50. package/esm/projects/revert.js +75 -0
  51. package/esm/projects/verify.js +61 -0
  52. package/esm/resolution/deps.js +526 -0
  53. package/esm/resolution/resolve.js +101 -0
  54. package/esm/utils/debug.js +147 -0
  55. package/esm/utils/target-utils.js +37 -0
  56. package/esm/workspace/paths.js +43 -0
  57. package/esm/workspace/utils.js +31 -0
  58. package/export/export-meta.d.ts +8 -0
  59. package/export/export-meta.js +244 -0
  60. package/export/export-migrations.d.ts +17 -0
  61. package/export/export-migrations.js +187 -0
  62. package/extensions/extensions.d.ts +5 -0
  63. package/extensions/extensions.js +35 -0
  64. package/files/extension/index.d.ts +2 -0
  65. package/files/extension/index.js +19 -0
  66. package/files/extension/reader.d.ts +24 -0
  67. package/files/extension/reader.js +86 -0
  68. package/files/extension/writer.d.ts +39 -0
  69. package/files/extension/writer.js +70 -0
  70. package/files/index.d.ts +5 -0
  71. package/files/index.js +22 -0
  72. package/files/plan/generator.d.ts +22 -0
  73. package/files/plan/generator.js +57 -0
  74. package/files/plan/index.d.ts +4 -0
  75. package/files/plan/index.js +21 -0
  76. package/files/plan/parser.d.ts +27 -0
  77. package/files/plan/parser.js +303 -0
  78. package/files/plan/validators.d.ts +52 -0
  79. package/files/plan/validators.js +187 -0
  80. package/files/plan/writer.d.ts +27 -0
  81. package/files/plan/writer.js +124 -0
  82. package/files/sql/index.d.ts +1 -0
  83. package/files/sql/index.js +17 -0
  84. package/files/sql/writer.d.ts +12 -0
  85. package/files/sql/writer.js +114 -0
  86. package/files/sql-scripts/index.d.ts +1 -0
  87. package/files/sql-scripts/index.js +18 -0
  88. package/files/sql-scripts/reader.d.ts +8 -0
  89. package/files/sql-scripts/reader.js +23 -0
  90. package/files/types/index.d.ts +46 -0
  91. package/files/types/index.js +17 -0
  92. package/files/types/package.d.ts +20 -0
  93. package/files/types/package.js +2 -0
  94. package/index.d.ts +21 -0
  95. package/index.js +45 -0
  96. package/init/client.d.ts +26 -0
  97. package/init/client.js +148 -0
  98. package/init/sql/bootstrap-roles.sql +55 -0
  99. package/init/sql/bootstrap-test-roles.sql +72 -0
  100. package/migrate/clean.d.ts +1 -0
  101. package/migrate/clean.js +27 -0
  102. package/migrate/client.d.ts +80 -0
  103. package/migrate/client.js +555 -0
  104. package/migrate/index.d.ts +5 -0
  105. package/migrate/index.js +21 -0
  106. package/migrate/sql/procedures.sql +258 -0
  107. package/migrate/sql/schema.sql +37 -0
  108. package/migrate/types.d.ts +67 -0
  109. package/migrate/types.js +2 -0
  110. package/migrate/utils/event-logger.d.ts +13 -0
  111. package/migrate/utils/event-logger.js +32 -0
  112. package/migrate/utils/hash.d.ts +12 -0
  113. package/migrate/utils/hash.js +32 -0
  114. package/migrate/utils/transaction.d.ts +27 -0
  115. package/migrate/utils/transaction.js +129 -0
  116. package/modules/modules.d.ts +31 -0
  117. package/modules/modules.js +56 -0
  118. package/package.json +70 -0
  119. package/packaging/package.d.ts +19 -0
  120. package/packaging/package.js +102 -0
  121. package/packaging/transform.d.ts +22 -0
  122. package/packaging/transform.js +75 -0
  123. package/projects/deploy.d.ts +8 -0
  124. package/projects/deploy.js +160 -0
  125. package/projects/revert.d.ts +15 -0
  126. package/projects/revert.js +112 -0
  127. package/projects/verify.d.ts +8 -0
  128. package/projects/verify.js +98 -0
  129. package/resolution/deps.d.ts +57 -0
  130. package/resolution/deps.js +531 -0
  131. package/resolution/resolve.d.ts +37 -0
  132. package/resolution/resolve.js +107 -0
  133. package/utils/debug.d.ts +21 -0
  134. package/utils/debug.js +153 -0
  135. package/utils/target-utils.d.ts +5 -0
  136. package/utils/target-utils.js +40 -0
  137. package/workspace/paths.d.ts +14 -0
  138. package/workspace/paths.js +50 -0
  139. package/workspace/utils.d.ts +8 -0
  140. package/workspace/utils.js +36 -0
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getExtensionsAndModulesChanges = exports.getExtensionsAndModules = exports.latestChangeAndVersion = exports.latestChange = void 0;
4
+ const files_1 = require("../files");
5
+ const types_1 = require("@pgpmjs/types");
6
+ /**
7
+ * Get the latest change from the pgpm.plan file for a specific module.
8
+ */
9
+ const latestChange = (sqlmodule, modules, basePath) => {
10
+ const module = modules[sqlmodule];
11
+ if (!module) {
12
+ throw types_1.errors.MODULE_NOT_FOUND({ name: sqlmodule });
13
+ }
14
+ const planPath = `${basePath}/${module.path}/pgpm.plan`;
15
+ return (0, files_1.getLatestChange)(planPath);
16
+ };
17
+ exports.latestChange = latestChange;
18
+ /**
19
+ * Get the latest change and version for a specific module.
20
+ */
21
+ const latestChangeAndVersion = (sqlmodule, modules, basePath) => {
22
+ const module = modules[sqlmodule];
23
+ if (!module) {
24
+ throw types_1.errors.MODULE_NOT_FOUND({ name: sqlmodule });
25
+ }
26
+ const planPath = `${basePath}/${module.path}/pgpm.plan`;
27
+ const change = (0, files_1.getLatestChange)(planPath);
28
+ const pkg = require(`${basePath}/${module.path}/package.json`);
29
+ return { change, version: pkg.version };
30
+ };
31
+ exports.latestChangeAndVersion = latestChangeAndVersion;
32
+ /**
33
+ * Get extensions and modules required by a specific module.
34
+ */
35
+ const getExtensionsAndModules = (sqlmodule, modules) => {
36
+ const module = modules[sqlmodule];
37
+ if (!module) {
38
+ throw types_1.errors.MODULE_NOT_FOUND({ name: sqlmodule });
39
+ }
40
+ const native = module.requires.filter((req) => !Object.keys(modules).includes(req));
41
+ const sqitch = module.requires.filter((req) => Object.keys(modules).includes(req));
42
+ return { native, sqitch };
43
+ };
44
+ exports.getExtensionsAndModules = getExtensionsAndModules;
45
+ /**
46
+ * Get extensions and modules with their latest changes and versions.
47
+ */
48
+ const getExtensionsAndModulesChanges = (sqlmodule, modules, basePath) => {
49
+ const { native, sqitch } = (0, exports.getExtensionsAndModules)(sqlmodule, modules);
50
+ const sqitchWithDetails = sqitch.map((mod) => {
51
+ const { change, version } = (0, exports.latestChangeAndVersion)(mod, modules, basePath);
52
+ return { name: mod, latest: change, version };
53
+ });
54
+ return { native, sqitch: sqitchWithDetails };
55
+ };
56
+ exports.getExtensionsAndModulesChanges = getExtensionsAndModulesChanges;
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@pgpmjs/core",
3
+ "version": "3.0.0",
4
+ "author": "Constructive <developers@constructive.io>",
5
+ "description": "PGPM Package and Migration Tools",
6
+ "main": "index.js",
7
+ "module": "esm/index.js",
8
+ "types": "index.d.ts",
9
+ "homepage": "https://github.com/constructive-io/constructive",
10
+ "license": "MIT",
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "directory": "dist"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/constructive-io/constructive"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/constructive-io/constructive/issues"
21
+ },
22
+ "scripts": {
23
+ "copy": "npm run copy:pkg; npm run copy:sql",
24
+ "copy:pkg": "makage assets",
25
+ "copy:sql": "copyfiles -f src/migrate/sql/* dist/migrate/sql && copyfiles -f src/migrate/sql/* dist/esm/migrate/sql && copyfiles -f src/init/sql/* dist/init/sql && copyfiles -f src/init/sql/* dist/esm/init/sql",
26
+ "clean": "makage clean",
27
+ "prepack": "npm run build",
28
+ "build": "makage build && npm run copy",
29
+ "build:dev": "makage build --dev",
30
+ "lint": "eslint . --fix",
31
+ "test": "jest",
32
+ "test:watch": "jest --watch"
33
+ },
34
+ "keywords": [
35
+ "database",
36
+ "migration",
37
+ "postgresql",
38
+ "pgpm",
39
+ "pgpmjs",
40
+ "schema",
41
+ "sqitch"
42
+ ],
43
+ "devDependencies": {
44
+ "@types/pg": "^8.16.0",
45
+ "copyfiles": "^2.4.1",
46
+ "makage": "^0.1.8"
47
+ },
48
+ "dependencies": {
49
+ "@pgpmjs/env": "^2.7.0",
50
+ "@pgpmjs/logger": "^1.3.0",
51
+ "@pgpmjs/server-utils": "^2.8.0",
52
+ "@pgpmjs/types": "^2.11.0",
53
+ "@pgsql/types": "^17.6.2",
54
+ "create-gen-app": "^0.3.3",
55
+ "csv-to-pg": "^2.0.10",
56
+ "glob": "^13.0.0",
57
+ "komoji": "^0.7.8",
58
+ "parse-package-name": "^1.0.0",
59
+ "pg": "^8.16.3",
60
+ "pg-cache": "^1.6.0",
61
+ "pg-env": "^1.2.1",
62
+ "pgsql-deparser": "^17.12.2",
63
+ "pgsql-parser": "^17.9.2",
64
+ "yanse": "^0.1.5"
65
+ },
66
+ "peerDependencies": {
67
+ "@pgsql/types": "^17.6.1"
68
+ },
69
+ "gitHead": "e4d5396a5d9154f4886176bb00c2b460b0f320e5"
70
+ }
@@ -0,0 +1,19 @@
1
+ export declare const cleanTree: (tree: any) => any;
2
+ interface PackageModuleOptions {
3
+ usePlan?: boolean;
4
+ extension?: boolean;
5
+ pretty?: boolean;
6
+ functionDelimiter?: string;
7
+ }
8
+ interface WritePackageOptions extends PackageModuleOptions {
9
+ version: string;
10
+ packageDir: string;
11
+ }
12
+ export declare const packageModule: (packageDir: string, { usePlan, extension, pretty, functionDelimiter }?: PackageModuleOptions) => Promise<{
13
+ sql: string;
14
+ diff?: boolean;
15
+ tree1?: string;
16
+ tree2?: string;
17
+ }>;
18
+ export declare const writePackage: ({ version, extension, usePlan, packageDir, }: WritePackageOptions) => Promise<void>;
19
+ export {};
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writePackage = exports.packageModule = exports.cleanTree = void 0;
4
+ const logger_1 = require("@pgpmjs/logger");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const pgsql_deparser_1 = require("pgsql-deparser");
8
+ const pgsql_parser_1 = require("pgsql-parser");
9
+ const files_1 = require("../files");
10
+ const resolve_1 = require("../resolution/resolve");
11
+ const transform_1 = require("./transform");
12
+ const log = new logger_1.Logger('package');
13
+ const noop = () => undefined;
14
+ const cleanTree = (tree) => {
15
+ return (0, transform_1.transformProps)(tree, {
16
+ stmt_len: noop,
17
+ stmt_location: noop,
18
+ location: noop,
19
+ });
20
+ };
21
+ exports.cleanTree = cleanTree;
22
+ const filterStatements = (stmts, extension) => {
23
+ if (!extension)
24
+ return stmts;
25
+ return stmts.filter(node => {
26
+ const stmt = node.stmt;
27
+ return !stmt.hasOwnProperty('TransactionStmt') &&
28
+ !stmt.hasOwnProperty('CreateExtensionStmt');
29
+ });
30
+ };
31
+ const packageModule = async (packageDir, { usePlan = true, extension = true, pretty = true, functionDelimiter = '$EOFCODE$' } = {}) => {
32
+ const resolveFn = usePlan ? resolve_1.resolveWithPlan : resolve_1.resolve;
33
+ const sql = resolveFn(packageDir);
34
+ if (!sql?.trim()) {
35
+ log.warn(`โš ๏ธ No SQL generated for module at ${packageDir}. Skipping.`);
36
+ return { sql: '' };
37
+ }
38
+ const extname = (0, files_1.getExtensionName)(packageDir);
39
+ try {
40
+ const parsed = await (0, pgsql_parser_1.parse)(sql);
41
+ parsed.stmts = filterStatements(parsed.stmts, extension);
42
+ const topLine = extension
43
+ ? `\\echo Use "CREATE EXTENSION ${extname}" to load this file. \\quit\n`
44
+ : '';
45
+ const finalSql = await (0, pgsql_deparser_1.deparse)(parsed, {
46
+ pretty,
47
+ functionDelimiter
48
+ });
49
+ const tree1 = parsed.stmts;
50
+ const tree2 = await (0, pgsql_parser_1.parse)(finalSql);
51
+ const results = {
52
+ sql: `${topLine}${finalSql}`,
53
+ };
54
+ const diff = JSON.stringify((0, exports.cleanTree)(tree1)) !== JSON.stringify((0, exports.cleanTree)(tree2));
55
+ if (diff) {
56
+ results.diff = true;
57
+ results.tree1 = JSON.stringify((0, exports.cleanTree)(tree1), null, 2);
58
+ results.tree2 = JSON.stringify((0, exports.cleanTree)(tree2), null, 2);
59
+ }
60
+ return results;
61
+ }
62
+ catch (e) {
63
+ log.error(`โŒ Failed to parse SQL for ${packageDir}`);
64
+ console.error(e);
65
+ throw e;
66
+ }
67
+ };
68
+ exports.packageModule = packageModule;
69
+ const writePackage = async ({ version, extension = true, usePlan = true, packageDir, }) => {
70
+ const pkgPath = `${packageDir}/package.json`;
71
+ const pkg = require(pkgPath);
72
+ const extname = await (0, files_1.getExtensionName)(packageDir);
73
+ const makePath = `${packageDir}/Makefile`;
74
+ const controlPath = `${packageDir}/${extname}.control`;
75
+ const sqlFileName = `${extname}--${version}.sql`;
76
+ const Makefile = (0, fs_1.readFileSync)(makePath, 'utf-8');
77
+ const control = (0, fs_1.readFileSync)(controlPath, 'utf-8');
78
+ const { sql, diff, tree1, tree2 } = await (0, exports.packageModule)(packageDir, {
79
+ extension,
80
+ usePlan,
81
+ });
82
+ const outPath = extension ? `${packageDir}/sql` : `${packageDir}/out`;
83
+ (0, fs_1.rmSync)(outPath, { recursive: true, force: true });
84
+ (0, fs_1.mkdirSync)(outPath, { recursive: true });
85
+ if (extension) {
86
+ (0, fs_1.writeFileSync)(controlPath, control.replace(/default_version = '[0-9\.]+'/, `default_version = '${version}'`));
87
+ pkg.version = version;
88
+ (0, fs_1.writeFileSync)(pkgPath, JSON.stringify(pkg, null, 2));
89
+ const regex = new RegExp(`${extname}--[0-9.]+.sql`);
90
+ (0, fs_1.writeFileSync)(makePath, Makefile.replace(regex, sqlFileName));
91
+ }
92
+ if (diff) {
93
+ log.warn(`โš ๏ธ SQL diff exists! Review the ${(0, path_1.relative)(packageDir, outPath)}/ folder.`);
94
+ // Uncomment if needed:
95
+ // writeFileSync(`${outPath}/orig.${sqlFileName}.tree.json`, tree1);
96
+ // writeFileSync(`${outPath}/parsed.${sqlFileName}.tree.json`, tree2);
97
+ }
98
+ const writePath = `${outPath}/${sqlFileName}`;
99
+ (0, fs_1.writeFileSync)(writePath, sql);
100
+ log.success(`${(0, path_1.relative)(packageDir, writePath)} written`);
101
+ };
102
+ exports.writePackage = writePackage;
@@ -0,0 +1,22 @@
1
+ type TransformProps = {
2
+ [key: string]: ((value: any) => any) | {
3
+ [key: string]: any;
4
+ };
5
+ };
6
+ /**
7
+ * Recursively transforms the properties of an object based on a transformation map.
8
+ *
9
+ * @param obj - The object to transform.
10
+ * @param props - A map of properties and their transformation rules.
11
+ * @returns A new object with transformed properties.
12
+ */
13
+ export declare const transformProps: (obj: any, props: TransformProps) => any;
14
+ /**
15
+ * Parses a SQL statement, transforms its properties, and regenerates the SQL.
16
+ *
17
+ * @param statement - The SQL statement to transform.
18
+ * @param props - A map of properties and their transformation rules.
19
+ * @returns The transformed SQL statement.
20
+ */
21
+ export declare const transform: (statement: string, props: TransformProps) => Promise<string>;
22
+ export {};
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transform = exports.transformProps = void 0;
4
+ const pgsql_deparser_1 = require("pgsql-deparser");
5
+ const pgsql_parser_1 = require("pgsql-parser");
6
+ /**
7
+ * Recursively transforms the properties of an object based on a transformation map.
8
+ *
9
+ * @param obj - The object to transform.
10
+ * @param props - A map of properties and their transformation rules.
11
+ * @returns A new object with transformed properties.
12
+ */
13
+ const transformProps = (obj, props) => {
14
+ let copy;
15
+ // Handle primitive types, null, or undefined
16
+ if (obj === null || typeof obj !== 'object')
17
+ return obj;
18
+ // Handle Date
19
+ if (obj instanceof Date) {
20
+ copy = new Date();
21
+ copy.setTime(obj.getTime());
22
+ return copy;
23
+ }
24
+ // Handle Array
25
+ if (Array.isArray(obj)) {
26
+ copy = [];
27
+ for (let i = 0, len = obj.length; i < len; i++) {
28
+ copy[i] = (0, exports.transformProps)(obj[i], props);
29
+ }
30
+ return copy;
31
+ }
32
+ // Handle Object
33
+ if (obj instanceof Object || typeof obj === 'object') {
34
+ copy = {};
35
+ for (const attr in obj) {
36
+ if (Object.prototype.hasOwnProperty.call(obj, attr)) {
37
+ if (props.hasOwnProperty(attr)) {
38
+ const propRule = props[attr];
39
+ if (typeof propRule === 'function') {
40
+ // Apply function transformation
41
+ copy[attr] = propRule(obj[attr]);
42
+ }
43
+ else if (typeof propRule === 'object' && propRule !== null) {
44
+ // Apply value-based transformation
45
+ if (propRule.hasOwnProperty(obj[attr])) {
46
+ copy[attr] = propRule[obj[attr]];
47
+ }
48
+ else {
49
+ copy[attr] = (0, exports.transformProps)(obj[attr], props);
50
+ }
51
+ }
52
+ }
53
+ else {
54
+ copy[attr] = (0, exports.transformProps)(obj[attr], props);
55
+ }
56
+ }
57
+ }
58
+ return copy;
59
+ }
60
+ throw new Error("Unable to copy obj! Its type isn't supported.");
61
+ };
62
+ exports.transformProps = transformProps;
63
+ /**
64
+ * Parses a SQL statement, transforms its properties, and regenerates the SQL.
65
+ *
66
+ * @param statement - The SQL statement to transform.
67
+ * @param props - A map of properties and their transformation rules.
68
+ * @returns The transformed SQL statement.
69
+ */
70
+ const transform = async (statement, props) => {
71
+ let tree = await (0, pgsql_parser_1.parse)(statement);
72
+ tree = (0, exports.transformProps)(tree, props);
73
+ return await (0, pgsql_deparser_1.deparse)(tree);
74
+ };
75
+ exports.transform = transform;
@@ -0,0 +1,8 @@
1
+ import { PgpmOptions } from '@pgpmjs/types';
2
+ import { PgpmPackage } from '../core/class/pgpm';
3
+ interface Extensions {
4
+ resolved: string[];
5
+ external: string[];
6
+ }
7
+ export declare const deployProject: (opts: PgpmOptions, name: string, database: string, pkg: PgpmPackage, toChange?: string) => Promise<Extensions>;
8
+ export {};
@@ -0,0 +1,160 @@
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.deployProject = void 0;
37
+ const env_1 = require("@pgpmjs/env");
38
+ const logger_1 = require("@pgpmjs/logger");
39
+ const types_1 = require("@pgpmjs/types");
40
+ const path_1 = require("path");
41
+ const path = __importStar(require("path"));
42
+ const pg_cache_1 = require("pg-cache");
43
+ const pgpm_1 = require("../core/class/pgpm");
44
+ const client_1 = require("../migrate/client");
45
+ const package_1 = require("../packaging/package");
46
+ // Cache for fast deployment
47
+ const deployFastCache = {};
48
+ const getCacheKey = (pg, name, database) => {
49
+ const { host, port, user } = pg ?? {};
50
+ return `${host}:${port}:${user}:${database}:${name}`;
51
+ };
52
+ const log = new logger_1.Logger('deploy');
53
+ const deployProject = async (opts, name, database, pkg, toChange) => {
54
+ const mergedOpts = (0, env_1.getEnvOptions)(opts);
55
+ log.info(`๐Ÿ” Gathering modules from ${pkg.workspacePath}...`);
56
+ const modules = pkg.getModuleMap();
57
+ if (!modules[name]) {
58
+ log.error(`โŒ Module "${name}" not found in modules list.`);
59
+ throw types_1.errors.MODULE_NOT_FOUND({ name });
60
+ }
61
+ const modulePath = path.resolve(pkg.workspacePath, modules[name].path);
62
+ const moduleProject = new pgpm_1.PgpmPackage(modulePath);
63
+ log.info(`๐Ÿ“ฆ Resolving dependencies for ${name}...`);
64
+ const extensions = moduleProject.getModuleExtensions();
65
+ const pgPool = (0, pg_cache_1.getPgPool)({ ...opts.pg, database });
66
+ log.success(`๐Ÿš€ Starting deployment to database ${database}...`);
67
+ for (const extension of extensions.resolved) {
68
+ try {
69
+ if (extensions.external.includes(extension)) {
70
+ const msg = `CREATE EXTENSION IF NOT EXISTS "${extension}" CASCADE;`;
71
+ log.info(`๐Ÿ“ฅ Installing external extension: ${extension}`);
72
+ log.debug(`> ${msg}`);
73
+ await pgPool.query(msg);
74
+ }
75
+ else {
76
+ const modulePath = (0, path_1.resolve)(pkg.workspacePath, modules[extension].path);
77
+ log.info(`๐Ÿ“‚ Deploying local module: ${extension}`);
78
+ log.debug(`โ†’ Path: ${modulePath}`);
79
+ if (mergedOpts.deployment.fast) {
80
+ // Use fast deployment strategy
81
+ const localProject = new pgpm_1.PgpmPackage(modulePath);
82
+ const cacheKey = getCacheKey(mergedOpts.pg, extension, database);
83
+ if (mergedOpts.deployment.cache && deployFastCache[cacheKey]) {
84
+ log.warn(`โšก Using cached package for ${extension}.`);
85
+ await pgPool.query(deployFastCache[cacheKey].sql);
86
+ continue;
87
+ }
88
+ let modulePackage;
89
+ try {
90
+ modulePackage = await (0, package_1.packageModule)(localProject.modulePath, {
91
+ usePlan: mergedOpts.deployment.usePlan,
92
+ extension: false
93
+ });
94
+ }
95
+ catch (err) {
96
+ // Build comprehensive error message
97
+ const errorLines = [];
98
+ errorLines.push(`โŒ Failed to package module "${extension}" at path: ${modulePath}`);
99
+ errorLines.push(` Module Path: ${modulePath}`);
100
+ errorLines.push(` Workspace Path: ${pkg.workspacePath}`);
101
+ errorLines.push(` Error Code: ${err.code || 'N/A'}`);
102
+ errorLines.push(` Error Message: ${err.message || 'Unknown error'}`);
103
+ // Provide debugging hints
104
+ if (err.code === 'ENOENT') {
105
+ errorLines.push('๐Ÿ’ก Hint: File or directory not found. Check if the module path is correct.');
106
+ }
107
+ else if (err.code === 'EACCES') {
108
+ errorLines.push('๐Ÿ’ก Hint: Permission denied. Check file permissions.');
109
+ }
110
+ else if (err.message && err.message.includes('pgpm.plan')) {
111
+ errorLines.push('๐Ÿ’ก Hint: pgpm.plan file issue. Check if the plan file exists and is valid.');
112
+ }
113
+ // Log the consolidated error message
114
+ log.error(errorLines.join('\n'));
115
+ console.error(err); // Preserve full stack trace
116
+ throw types_1.errors.DEPLOYMENT_FAILED({
117
+ type: 'Deployment',
118
+ module: extension
119
+ });
120
+ }
121
+ log.debug(`โ†’ Command: sqitch deploy db:pg:${database}`);
122
+ log.debug(`> ${modulePackage.sql}`);
123
+ await pgPool.query(modulePackage.sql);
124
+ if (mergedOpts.deployment.cache) {
125
+ deployFastCache[cacheKey] = modulePackage;
126
+ }
127
+ }
128
+ else {
129
+ // Use new migration system
130
+ log.debug(`โ†’ Command: launchql migrate deploy db:pg:${database}`);
131
+ try {
132
+ const client = new client_1.PgpmMigrate(mergedOpts.pg);
133
+ const result = await client.deploy({
134
+ modulePath,
135
+ toChange,
136
+ useTransaction: mergedOpts.deployment.useTx,
137
+ logOnly: mergedOpts.deployment.logOnly
138
+ });
139
+ if (result.failed) {
140
+ throw types_1.errors.OPERATION_FAILED({ operation: 'Deployment', target: result.failed });
141
+ }
142
+ }
143
+ catch (deployError) {
144
+ log.error(`โŒ Deployment failed for module ${extension}`);
145
+ console.error(deployError);
146
+ throw types_1.errors.DEPLOYMENT_FAILED({ type: 'Deployment', module: extension });
147
+ }
148
+ }
149
+ }
150
+ }
151
+ catch (err) {
152
+ log.error(`๐Ÿ›‘ Error during deployment: ${err instanceof Error ? err.message : err}`);
153
+ console.error(err); // Keep raw error output for stack traces
154
+ throw types_1.errors.DEPLOYMENT_FAILED({ type: 'Deployment', module: extension });
155
+ }
156
+ }
157
+ log.success(`โœ… Deployment complete for ${name}.`);
158
+ return extensions;
159
+ };
160
+ exports.deployProject = deployProject;
@@ -0,0 +1,15 @@
1
+ import { PgpmOptions } from '@pgpmjs/types';
2
+ import { PgpmPackage } from '../core/class/pgpm';
3
+ interface Extensions {
4
+ resolved: string[];
5
+ external: string[];
6
+ }
7
+ export declare const revertProject: (opts: PgpmOptions, name: string, database: string, pkg: PgpmPackage, options?: {
8
+ useTransaction?: boolean;
9
+ /**
10
+ * Revert to a specific change (exclusive - this change will NOT be reverted)
11
+ * Can be a change name or a tag reference (e.g., '@v1.0.0')
12
+ */
13
+ toChange?: string;
14
+ }) => Promise<Extensions>;
15
+ export {};
@@ -0,0 +1,112 @@
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.revertProject = void 0;
37
+ const logger_1 = require("@pgpmjs/logger");
38
+ const types_1 = require("@pgpmjs/types");
39
+ const path_1 = require("path");
40
+ const path = __importStar(require("path"));
41
+ const pg_cache_1 = require("pg-cache");
42
+ const pgpm_1 = require("../core/class/pgpm");
43
+ const client_1 = require("../migrate/client");
44
+ const log = new logger_1.Logger('revert');
45
+ const revertProject = async (opts, name, database, pkg, options) => {
46
+ log.info(`๐Ÿ” Gathering modules from ${pkg.workspacePath}...`);
47
+ const modules = pkg.getModuleMap();
48
+ if (!modules[name]) {
49
+ log.error(`โŒ Module "${name}" not found in modules list.`);
50
+ throw types_1.errors.MODULE_NOT_FOUND({ name });
51
+ }
52
+ const modulePath = path.resolve(pkg.workspacePath, modules[name].path);
53
+ const moduleProject = new pgpm_1.PgpmPackage(modulePath);
54
+ log.info(`๐Ÿ“ฆ Resolving dependencies for ${name}...`);
55
+ const extensions = moduleProject.getModuleExtensions();
56
+ const pgPool = (0, pg_cache_1.getPgPool)({
57
+ ...opts.pg,
58
+ database
59
+ });
60
+ log.success(`๐Ÿงน Starting revert process on database ${database}...`);
61
+ const reversedExtensions = [...extensions.resolved].reverse();
62
+ for (const extension of reversedExtensions) {
63
+ try {
64
+ if (extensions.external.includes(extension)) {
65
+ const msg = `DROP EXTENSION IF EXISTS "${extension}" RESTRICT;`;
66
+ log.warn(`โš ๏ธ Dropping external extension: ${extension}`);
67
+ log.debug(`> ${msg}`);
68
+ try {
69
+ await pgPool.query(msg);
70
+ }
71
+ catch (err) {
72
+ if (err.code === '2BP01') { // dependent_objects_still_exist
73
+ log.warn(`โš ๏ธ Cannot drop extension ${extension} due to dependencies, skipping`);
74
+ }
75
+ else {
76
+ throw err;
77
+ }
78
+ }
79
+ }
80
+ else {
81
+ const modulePath = (0, path_1.resolve)(pkg.workspacePath, modules[extension].path);
82
+ log.info(`๐Ÿ“‚ Reverting local module: ${extension}`);
83
+ log.debug(`โ†’ Path: ${modulePath}`);
84
+ // Use new migration system
85
+ log.debug(`โ†’ Command: launchql migrate revert db:pg:${database}`);
86
+ try {
87
+ const client = new client_1.PgpmMigrate(opts.pg);
88
+ const result = await client.revert({
89
+ modulePath,
90
+ toChange: options?.toChange,
91
+ useTransaction: options?.useTransaction
92
+ });
93
+ if (result.failed) {
94
+ throw types_1.errors.OPERATION_FAILED({ operation: 'Revert', target: result.failed });
95
+ }
96
+ }
97
+ catch (revertError) {
98
+ log.error(`โŒ Revert failed for module ${extension}`);
99
+ throw types_1.errors.DEPLOYMENT_FAILED({ type: 'Revert', module: extension });
100
+ }
101
+ }
102
+ }
103
+ catch (e) {
104
+ log.error(`๐Ÿ›‘ Error during revert: ${e instanceof Error ? e.message : e}`);
105
+ console.error(e); // optional raw stack trace
106
+ throw types_1.errors.DEPLOYMENT_FAILED({ type: 'Revert', module: extension });
107
+ }
108
+ }
109
+ log.success(`โœ… Revert complete for ${name}.`);
110
+ return extensions;
111
+ };
112
+ exports.revertProject = revertProject;
@@ -0,0 +1,8 @@
1
+ import { PgpmOptions } from '@pgpmjs/types';
2
+ import { PgpmPackage } from '../core/class/pgpm';
3
+ interface Extensions {
4
+ resolved: string[];
5
+ external: string[];
6
+ }
7
+ export declare const verifyProject: (opts: PgpmOptions, name: string, database: string, pkg: PgpmPackage, options?: {}) => Promise<Extensions>;
8
+ export {};