@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,37 @@
1
+ /**
2
+ * Resolves SQL scripts for deployment or reversion.
3
+ *
4
+ * @param pkgDir - The package directory (defaults to the current working directory).
5
+ * @param scriptType - The type of script to resolve (`deploy` or `revert`).
6
+ * @returns A single concatenated SQL script as a string.
7
+ */
8
+ export declare const resolve: (pkgDir?: string, scriptType?: "deploy" | "revert") => string;
9
+ /**
10
+ * Resolves SQL scripts based on the `pgpm.plan` file.
11
+ *
12
+ * @param pkgDir - The package directory (defaults to the current working directory).
13
+ * @param scriptType - The type of script to resolve (`deploy` or `revert`).
14
+ * @returns A single concatenated SQL script as a string.
15
+ */
16
+ export declare const resolveWithPlan: (pkgDir?: string, scriptType?: "deploy" | "revert") => string;
17
+ /**
18
+ * Resolves a tag reference to its corresponding change name.
19
+ * Tags provide a way to reference specific points in a package's deployment history.
20
+ *
21
+ * @param planPath - Path to the plan file containing tag definitions
22
+ * @param tagReference - The tag reference to resolve (e.g., "package:@tagName" or "@tagName")
23
+ * @param currentPackage - The current package name (used when tag doesn't specify package)
24
+ * @returns The resolved change name
25
+ * @throws Error if tag format is invalid or tag is not found
26
+ *
27
+ * @example
28
+ * // Resolve a tag in the current package
29
+ * resolveTagToChangeName('/path/to/pgpm.plan', '@v1.0.0', 'mypackage')
30
+ * // Returns: 'schema/v1'
31
+ *
32
+ * @example
33
+ * // Resolve a tag from another package
34
+ * resolveTagToChangeName('/path/to/pgpm.plan', 'auth:@v2.0.0')
35
+ * // Returns: 'users/table'
36
+ */
37
+ export declare const resolveTagToChangeName: (planPath: string, tagReference: string, currentProject?: string) => string;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveTagToChangeName = exports.resolveWithPlan = exports.resolve = void 0;
4
+ const fs_1 = require("fs");
5
+ const files_1 = require("../files");
6
+ const parser_1 = require("../files/plan/parser");
7
+ const deps_1 = require("./deps");
8
+ const types_1 = require("@pgpmjs/types");
9
+ /**
10
+ * Resolves SQL scripts for deployment or reversion.
11
+ *
12
+ * @param pkgDir - The package directory (defaults to the current working directory).
13
+ * @param scriptType - The type of script to resolve (`deploy` or `revert`).
14
+ * @returns A single concatenated SQL script as a string.
15
+ */
16
+ const resolve = (pkgDir = process.cwd(), scriptType = 'deploy') => {
17
+ const sqlfile = [];
18
+ const name = (0, files_1.getExtensionName)(pkgDir);
19
+ const { resolved, external } = (0, deps_1.resolveDependencies)(pkgDir, name, { tagResolution: 'resolve' });
20
+ const scripts = scriptType === 'revert' ? [...resolved].reverse() : resolved;
21
+ for (const script of scripts) {
22
+ if (external.includes(script))
23
+ continue;
24
+ const file = `${pkgDir}/${scriptType}/${script}.sql`;
25
+ const dscript = (0, fs_1.readFileSync)(file, 'utf-8');
26
+ sqlfile.push(dscript);
27
+ }
28
+ return sqlfile.join('\n');
29
+ };
30
+ exports.resolve = resolve;
31
+ /**
32
+ * Resolves SQL scripts based on the `pgpm.plan` file.
33
+ *
34
+ * @param pkgDir - The package directory (defaults to the current working directory).
35
+ * @param scriptType - The type of script to resolve (`deploy` or `revert`).
36
+ * @returns A single concatenated SQL script as a string.
37
+ */
38
+ const resolveWithPlan = (pkgDir = process.cwd(), scriptType = 'deploy') => {
39
+ const sqlfile = [];
40
+ const planPath = `${pkgDir}/pgpm.plan`;
41
+ let resolved = (0, files_1.getChanges)(planPath);
42
+ if (scriptType === 'revert') {
43
+ resolved = resolved.reverse();
44
+ }
45
+ for (const script of resolved) {
46
+ const file = `${pkgDir}/${scriptType}/${script}.sql`;
47
+ const dscript = (0, fs_1.readFileSync)(file, 'utf-8');
48
+ sqlfile.push(dscript);
49
+ }
50
+ return sqlfile.join('\n');
51
+ };
52
+ exports.resolveWithPlan = resolveWithPlan;
53
+ /**
54
+ * Resolves a tag reference to its corresponding change name.
55
+ * Tags provide a way to reference specific points in a package's deployment history.
56
+ *
57
+ * @param planPath - Path to the plan file containing tag definitions
58
+ * @param tagReference - The tag reference to resolve (e.g., "package:@tagName" or "@tagName")
59
+ * @param currentPackage - The current package name (used when tag doesn't specify package)
60
+ * @returns The resolved change name
61
+ * @throws Error if tag format is invalid or tag is not found
62
+ *
63
+ * @example
64
+ * // Resolve a tag in the current package
65
+ * resolveTagToChangeName('/path/to/pgpm.plan', '@v1.0.0', 'mypackage')
66
+ * // Returns: 'schema/v1'
67
+ *
68
+ * @example
69
+ * // Resolve a tag from another package
70
+ * resolveTagToChangeName('/path/to/pgpm.plan', 'auth:@v2.0.0')
71
+ * // Returns: 'users/table'
72
+ */
73
+ const resolveTagToChangeName = (planPath, tagReference, currentProject) => {
74
+ // If not a tag reference, return as-is
75
+ if (!tagReference.includes('@')) {
76
+ return tagReference;
77
+ }
78
+ // Handle simple tag format (@tagName) by prepending current package
79
+ if (tagReference.startsWith('@') && !tagReference.includes(':')) {
80
+ if (!currentProject) {
81
+ const plan = (0, parser_1.parsePlanFile)(planPath);
82
+ if (!plan.data) {
83
+ throw types_1.errors.PLAN_PARSE_ERROR({ planPath, errors: 'Could not parse plan file' });
84
+ }
85
+ currentProject = plan.data.package;
86
+ }
87
+ tagReference = `${currentProject}:${tagReference}`;
88
+ }
89
+ // Parse package:@tagName format
90
+ const match = tagReference.match(/^([^:]+):@(.+)$/);
91
+ if (!match) {
92
+ throw types_1.errors.INVALID_NAME({ name: tagReference, type: 'tag', rules: 'Expected format: package:@tagName or @tagName' });
93
+ }
94
+ const [, projectName, tagName] = match;
95
+ // Parse plan file to find tag
96
+ const planResult = (0, parser_1.parsePlanFile)(planPath);
97
+ if (!planResult.data) {
98
+ throw types_1.errors.PLAN_PARSE_ERROR({ planPath, errors: 'Could not parse plan file' });
99
+ }
100
+ // Find the tag in the plan
101
+ const tag = planResult.data.tags?.find((t) => t.name === tagName);
102
+ if (!tag) {
103
+ throw types_1.errors.TAG_NOT_FOUND({ tag: tagName, project: projectName });
104
+ }
105
+ return tag.change;
106
+ };
107
+ exports.resolveTagToChangeName = resolveTagToChangeName;
@@ -0,0 +1,21 @@
1
+ export interface DebugOptions {
2
+ enabled: boolean;
3
+ logLevel?: 'info' | 'warn' | 'error' | 'debug';
4
+ showStackTrace?: boolean;
5
+ showQueryParams?: boolean;
6
+ showFullSQL?: boolean;
7
+ }
8
+ export declare class DebugHelper {
9
+ private options;
10
+ constructor(options?: DebugOptions);
11
+ isEnabled(): boolean;
12
+ logError(message: string, error?: any, context?: Record<string, any>): void;
13
+ logQuery(query: string, params?: any[], duration?: number): void;
14
+ logTransactionStart(): void;
15
+ logTransactionCommit(duration?: number): void;
16
+ logTransactionRollback(duration?: number): void;
17
+ static fromEnvironment(): DebugHelper;
18
+ }
19
+ export declare const debugHelper: DebugHelper;
20
+ export declare function enableDebugMode(): void;
21
+ export declare function createDebugSummary(error: any, context?: Record<string, any>): string;
package/utils/debug.js ADDED
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.debugHelper = exports.DebugHelper = void 0;
4
+ exports.enableDebugMode = enableDebugMode;
5
+ exports.createDebugSummary = createDebugSummary;
6
+ const logger_1 = require("@pgpmjs/logger");
7
+ const log = new logger_1.Logger('debug');
8
+ class DebugHelper {
9
+ options;
10
+ constructor(options = { enabled: false }) {
11
+ this.options = {
12
+ logLevel: 'debug',
13
+ showStackTrace: true,
14
+ showQueryParams: true,
15
+ showFullSQL: true,
16
+ ...options
17
+ };
18
+ }
19
+ isEnabled() {
20
+ return this.options.enabled;
21
+ }
22
+ logError(message, error, context) {
23
+ if (!this.options.enabled)
24
+ return;
25
+ log.error(message);
26
+ if (context) {
27
+ log.error('Context:', JSON.stringify(context, null, 2));
28
+ }
29
+ if (error) {
30
+ log.error('Error Details:', {
31
+ code: error.code,
32
+ message: error.message,
33
+ severity: error.severity,
34
+ detail: error.detail,
35
+ hint: error.hint,
36
+ position: error.position,
37
+ where: error.where,
38
+ schema: error.schema,
39
+ table: error.table,
40
+ column: error.column,
41
+ dataType: error.dataType,
42
+ constraint: error.constraint,
43
+ file: error.file,
44
+ line: error.line,
45
+ routine: error.routine
46
+ });
47
+ if (this.options.showStackTrace && error.stack) {
48
+ log.error('Stack Trace:', error.stack);
49
+ }
50
+ }
51
+ }
52
+ logQuery(query, params, duration) {
53
+ if (!this.options.enabled)
54
+ return;
55
+ log.debug(`Query executed in ${duration || 0}ms:`);
56
+ if (this.options.showFullSQL) {
57
+ log.debug('Full SQL:', query);
58
+ }
59
+ else {
60
+ log.debug('SQL Preview:', query.split('\n')[0].trim());
61
+ }
62
+ if (this.options.showQueryParams && params && params.length > 0) {
63
+ log.debug('Parameters:', JSON.stringify(params, null, 2));
64
+ }
65
+ }
66
+ logTransactionStart() {
67
+ if (!this.options.enabled)
68
+ return;
69
+ log.debug('🔄 Transaction started');
70
+ }
71
+ logTransactionCommit(duration) {
72
+ if (!this.options.enabled)
73
+ return;
74
+ log.debug(`✅ Transaction committed in ${duration || 0}ms`);
75
+ }
76
+ logTransactionRollback(duration) {
77
+ if (!this.options.enabled)
78
+ return;
79
+ log.debug(`❌ Transaction rolled back after ${duration || 0}ms`);
80
+ }
81
+ static fromEnvironment() {
82
+ const enabled = process.env.LAUNCHQL_DEBUG === 'true' || process.env.DEBUG === 'launchql*';
83
+ const logLevel = process.env.LAUNCHQL_DEBUG_LEVEL || 'debug';
84
+ const showStackTrace = process.env.LAUNCHQL_DEBUG_STACK !== 'false';
85
+ const showQueryParams = process.env.LAUNCHQL_DEBUG_PARAMS !== 'false';
86
+ const showFullSQL = process.env.LAUNCHQL_DEBUG_SQL !== 'false';
87
+ return new DebugHelper({
88
+ enabled,
89
+ logLevel,
90
+ showStackTrace,
91
+ showQueryParams,
92
+ showFullSQL
93
+ });
94
+ }
95
+ }
96
+ exports.DebugHelper = DebugHelper;
97
+ // Global debug instance
98
+ exports.debugHelper = DebugHelper.fromEnvironment();
99
+ // Utility functions
100
+ function enableDebugMode() {
101
+ process.env.LAUNCHQL_DEBUG = 'true';
102
+ process.env.LOG_LEVEL = 'debug';
103
+ log.info('🔍 Debug mode enabled');
104
+ log.info(' Set LAUNCHQL_DEBUG=false to disable');
105
+ log.info(' Set LAUNCHQL_DEBUG_LEVEL=info|warn|error|debug to change log level');
106
+ log.info(' Set LAUNCHQL_DEBUG_STACK=false to hide stack traces');
107
+ log.info(' Set LAUNCHQL_DEBUG_PARAMS=false to hide query parameters');
108
+ log.info(' Set LAUNCHQL_DEBUG_SQL=false to hide full SQL scripts');
109
+ }
110
+ function createDebugSummary(error, context) {
111
+ const summary = [];
112
+ summary.push('=== LaunchQL Debug Summary ===');
113
+ summary.push('');
114
+ if (error) {
115
+ summary.push('Error Information:');
116
+ summary.push(` Code: ${error.code || 'N/A'}`);
117
+ summary.push(` Message: ${error.message || 'N/A'}`);
118
+ summary.push(` Severity: ${error.severity || 'N/A'}`);
119
+ if (error.detail)
120
+ summary.push(` Detail: ${error.detail}`);
121
+ if (error.hint)
122
+ summary.push(` Hint: ${error.hint}`);
123
+ if (error.position)
124
+ summary.push(` Position: ${error.position}`);
125
+ if (error.where)
126
+ summary.push(` Where: ${error.where}`);
127
+ if (error.schema)
128
+ summary.push(` Schema: ${error.schema}`);
129
+ if (error.table)
130
+ summary.push(` Table: ${error.table}`);
131
+ if (error.column)
132
+ summary.push(` Column: ${error.column}`);
133
+ if (error.constraint)
134
+ summary.push(` Constraint: ${error.constraint}`);
135
+ summary.push('');
136
+ }
137
+ if (context) {
138
+ summary.push('Context:');
139
+ Object.entries(context).forEach(([key, value]) => {
140
+ summary.push(` ${key}: ${JSON.stringify(value)}`);
141
+ });
142
+ summary.push('');
143
+ }
144
+ summary.push('Debugging Tips:');
145
+ summary.push(' 1. Run with LAUNCHQL_DEBUG=true for more details');
146
+ summary.push(' 2. Check the transaction query history above');
147
+ summary.push(' 3. Verify your SQL scripts for syntax errors');
148
+ summary.push(' 4. Ensure dependencies are applied in correct order');
149
+ summary.push(' 5. Check database permissions and schema existence');
150
+ summary.push('');
151
+ summary.push('=== End Debug Summary ===');
152
+ return summary.join('\n');
153
+ }
@@ -0,0 +1,5 @@
1
+ export interface ParsedTarget {
2
+ packageName: string;
3
+ toChange?: string;
4
+ }
5
+ export declare function parseTarget(target: string): ParsedTarget;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTarget = parseTarget;
4
+ const types_1 = require("@pgpmjs/types");
5
+ function parseTarget(target) {
6
+ if (!target) {
7
+ throw new Error('Target parameter is required');
8
+ }
9
+ if (target.includes(':@')) {
10
+ const atIndex = target.indexOf(':@');
11
+ const beforeAt = target.substring(0, atIndex);
12
+ const afterAt = target.substring(atIndex + 2);
13
+ if (!afterAt) {
14
+ throw types_1.errors.INVALID_NAME({ name: target, type: 'tag', rules: 'Expected format: package:@tagName' });
15
+ }
16
+ // Check if this is a simple package:@tag format
17
+ if (!beforeAt.includes(':')) {
18
+ if (!beforeAt) {
19
+ throw types_1.errors.INVALID_NAME({ name: target, type: 'tag', rules: 'Expected format: package:@tagName' });
20
+ }
21
+ return { packageName: beforeAt, toChange: `@${afterAt}` };
22
+ }
23
+ throw types_1.errors.INVALID_NAME({ name: target, type: 'change', rules: 'Expected formats: package, package:changeName, or package:@tagName' });
24
+ }
25
+ if (target.includes(':') && !target.includes('@')) {
26
+ const parts = target.split(':');
27
+ if (parts.length > 2) {
28
+ throw types_1.errors.INVALID_NAME({ name: target, type: 'change', rules: 'Expected formats: package, package:changeName, or package:@tagName' });
29
+ }
30
+ const [packageName, changeName] = parts;
31
+ if (!packageName || !changeName) {
32
+ throw types_1.errors.INVALID_NAME({ name: target, type: 'change', rules: 'Expected format: package:changeName' });
33
+ }
34
+ return { packageName, toChange: changeName };
35
+ }
36
+ if (!target.includes(':')) {
37
+ return { packageName: target, toChange: undefined };
38
+ }
39
+ throw types_1.errors.INVALID_NAME({ name: target, type: 'change', rules: 'Expected formats: package, package:changeName, or package:@tagName' });
40
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Finds the module path by looking for pgpm.plan.
3
+ * @param cwd - Current working directory.
4
+ * @returns A promise that resolves to the directory path containing `pgpm.plan`.
5
+ */
6
+ export declare const modulePath: (cwd?: string) => string;
7
+ /**
8
+ * Finds the LaunchQL project path.
9
+ * @param cwd - Current working directory.
10
+ * @returns A promise that resolves to the directory path containing `pgpm.json`.
11
+ */
12
+ export declare const launchqlPath: (cwd?: string) => string;
13
+ export declare const getWorkspacePath: (cwd: string) => string;
14
+ export declare const getModulePath: (cwd: string) => string;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getModulePath = exports.getWorkspacePath = exports.launchqlPath = exports.modulePath = void 0;
4
+ const utils_1 = require("./utils");
5
+ const PROJECT_FILES = {
6
+ PLAN: 'pgpm.plan',
7
+ LAUNCHQL: 'pgpm.json',
8
+ };
9
+ /**
10
+ * Finds the module path by looking for pgpm.plan.
11
+ * @param cwd - Current working directory.
12
+ * @returns A promise that resolves to the directory path containing `pgpm.plan`.
13
+ */
14
+ const modulePath = (cwd = process.cwd()) => {
15
+ return (0, utils_1.walkUp)(cwd, PROJECT_FILES.PLAN);
16
+ };
17
+ exports.modulePath = modulePath;
18
+ /**
19
+ * Finds the LaunchQL project path.
20
+ * @param cwd - Current working directory.
21
+ * @returns A promise that resolves to the directory path containing `pgpm.json`.
22
+ */
23
+ const launchqlPath = (cwd = process.cwd()) => {
24
+ return (0, utils_1.walkUp)(cwd, PROJECT_FILES.LAUNCHQL);
25
+ };
26
+ exports.launchqlPath = launchqlPath;
27
+ const getWorkspacePath = (cwd) => {
28
+ let workspacePath;
29
+ try {
30
+ workspacePath = (0, exports.launchqlPath)(cwd);
31
+ }
32
+ catch (err) {
33
+ console.error('Error: You must be in a LaunchQL workspace. You can initialize one with `lql init workspace` (or `pgpm init workspace`).');
34
+ process.exit(1);
35
+ }
36
+ return workspacePath;
37
+ };
38
+ exports.getWorkspacePath = getWorkspacePath;
39
+ const getModulePath = (cwd) => {
40
+ let pkgPath;
41
+ try {
42
+ pkgPath = (0, exports.modulePath)(cwd);
43
+ }
44
+ catch (err) {
45
+ console.error('Error: You must be in a LaunchQL module. You can initialize one with the `init` command.');
46
+ process.exit(1);
47
+ }
48
+ return pkgPath;
49
+ };
50
+ exports.getModulePath = getModulePath;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Recursively walks up directories to find a specific file (sync version).
3
+ * @param startDir - Starting directory.
4
+ * @param filename - The target file to search for.
5
+ * @returns The directory path containing the file.
6
+ */
7
+ export declare const walkUp: (startDir: string, filename: string) => string;
8
+ export declare const sluggify: (text: string) => string;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sluggify = exports.walkUp = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const types_1 = require("@pgpmjs/types");
7
+ /**
8
+ * Recursively walks up directories to find a specific file (sync version).
9
+ * @param startDir - Starting directory.
10
+ * @param filename - The target file to search for.
11
+ * @returns The directory path containing the file.
12
+ */
13
+ const walkUp = (startDir, filename) => {
14
+ let currentDir = (0, path_1.resolve)(startDir);
15
+ while (currentDir) {
16
+ const targetPath = (0, path_1.resolve)(currentDir, filename);
17
+ if ((0, fs_1.existsSync)(targetPath)) {
18
+ return currentDir;
19
+ }
20
+ const parentDir = (0, path_1.dirname)(currentDir);
21
+ if (parentDir === currentDir) {
22
+ break;
23
+ }
24
+ currentDir = parentDir;
25
+ }
26
+ throw types_1.errors.FILE_NOT_FOUND({ filePath: filename, type: 'configuration' });
27
+ };
28
+ exports.walkUp = walkUp;
29
+ const sluggify = (text) => {
30
+ return text.toString().toLowerCase().trim()
31
+ .replace(/\s+/g, '-') // Replace spaces with -
32
+ .replace(/&/g, '-and-') // Replace & with 'and'
33
+ .replace(/[^\w\-]+/g, '') // Remove all non-word chars
34
+ .replace(/\-\-+/g, '-'); // Replace multiple - with single -
35
+ };
36
+ exports.sluggify = sluggify;