@pgpmjs/core 4.9.0 → 4.10.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.
@@ -70,10 +70,31 @@ function scanBoilerplates(baseDir) {
70
70
  const boilerplatePath = path_1.default.join(baseDir, entry.name);
71
71
  const config = readBoilerplateConfig(boilerplatePath);
72
72
  if (config) {
73
+ // Validate and normalize the type field
74
+ const validTypes = ['workspace', 'module', 'generic'];
75
+ const configType = config.type;
76
+ const type = validTypes.includes(configType)
77
+ ? configType
78
+ : 'module';
79
+ // Validate and normalize requiresWorkspace field
80
+ const validWorkspaceTypes = ['pgpm', 'pnpm', 'lerna', 'npm'];
81
+ let requiresWorkspace;
82
+ if (config.requiresWorkspace === false) {
83
+ requiresWorkspace = false;
84
+ }
85
+ else if (typeof config.requiresWorkspace === 'string' &&
86
+ validWorkspaceTypes.includes(config.requiresWorkspace)) {
87
+ requiresWorkspace = config.requiresWorkspace;
88
+ }
89
+ else {
90
+ // Default: 'pgpm' for module type (backward compatibility), undefined for others
91
+ requiresWorkspace = type === 'module' ? 'pgpm' : undefined;
92
+ }
73
93
  boilerplates.push({
74
94
  name: entry.name,
75
95
  path: boilerplatePath,
76
- type: config.type ?? 'module',
96
+ type,
97
+ requiresWorkspace,
77
98
  questions: config.questions
78
99
  });
79
100
  }
@@ -2,6 +2,7 @@
2
2
  * Boilerplate metadata types for the new metadata-driven resolution system.
3
3
  * These types support the `.boilerplate.json` and `.boilerplates.json` configuration files.
4
4
  */
5
+ export type { BoilerplateConfig, WorkspaceType } from './template-scaffold';
5
6
  /**
6
7
  * A question to prompt the user during template scaffolding.
7
8
  */
@@ -23,16 +24,6 @@ export interface BoilerplateQuestion {
23
24
  /** Auto-set value from resolver, skipping the prompt entirely */
24
25
  setFrom?: string;
25
26
  }
26
- /**
27
- * Configuration for a single boilerplate template.
28
- * Stored in `.boilerplate.json` within each template directory.
29
- */
30
- export interface BoilerplateConfig {
31
- /** The type of boilerplate: workspace or module */
32
- type: 'workspace' | 'module';
33
- /** Questions to prompt the user during scaffolding */
34
- questions?: BoilerplateQuestion[];
35
- }
36
27
  /**
37
28
  * Root configuration for a boilerplates repository.
38
29
  * Stored in `.boilerplates.json` at the repository root.
@@ -50,7 +41,12 @@ export interface ScannedBoilerplate {
50
41
  /** The full path to the boilerplate directory */
51
42
  path: string;
52
43
  /** The type of boilerplate */
53
- type: 'workspace' | 'module';
44
+ type: 'workspace' | 'module' | 'generic';
45
+ /**
46
+ * What type of workspace this template requires.
47
+ * 'pgpm' also indicates pgpm files should be created.
48
+ */
49
+ requiresWorkspace?: 'pgpm' | 'pnpm' | 'lerna' | 'npm' | false;
54
50
  /** Questions from the boilerplate config */
55
51
  questions?: BoilerplateQuestion[];
56
52
  }
@@ -29,6 +29,11 @@ export interface InitModuleOptions {
29
29
  * Must be an absolute path or relative to workspace root.
30
30
  */
31
31
  outputDir?: string;
32
+ /**
33
+ * Whether this is a pgpm-managed module that should create pgpm.plan and .control files.
34
+ * Defaults to true for backward compatibility.
35
+ */
36
+ pgpm?: boolean;
32
37
  }
33
38
  export declare class PgpmPackage {
34
39
  cwd: string;
@@ -364,6 +364,8 @@ class PgpmPackage {
364
364
  }
365
365
  async initModule(options) {
366
366
  this.ensureWorkspace();
367
+ // Determine if this is a pgpm-managed module (defaults to true for backward compatibility)
368
+ const isPgpmModule = options.pgpm ?? true;
367
369
  // If outputDir is provided, use it directly instead of createModuleDirectory
368
370
  let targetPath;
369
371
  if (options.outputDir) {
@@ -397,8 +399,11 @@ class PgpmPackage {
397
399
  toolName: options.toolName ?? template_scaffold_1.DEFAULT_TEMPLATE_TOOL_NAME,
398
400
  cwd: this.cwd
399
401
  });
400
- this.initModuleSqitch(options.name, targetPath);
401
- (0, files_2.writeExtensions)(targetPath, options.extensions);
402
+ // Only create pgpm files (pgpm.plan, .control, deploy/revert/verify dirs) for pgpm-managed modules
403
+ if (isPgpmModule) {
404
+ this.initModuleSqitch(options.name, targetPath);
405
+ (0, files_2.writeExtensions)(targetPath, options.extensions);
406
+ }
402
407
  }
403
408
  // ──────────────── Dependency Analysis ────────────────
404
409
  getLatestChange(moduleName) {
@@ -1,5 +1,31 @@
1
- import { BoilerplateConfig } from 'genomic';
1
+ import { BoilerplateConfig as GenomicBoilerplateConfig } from 'genomic';
2
2
  import type { Inquirerer, Question } from 'inquirerer';
3
+ /**
4
+ * Supported workspace types for template requirements.
5
+ * - 'pgpm': Requires pgpm workspace (pgpm.json/pgpm.config.js) and creates pgpm.plan/.control files
6
+ * - 'pnpm': Requires pnpm workspace (pnpm-workspace.yaml)
7
+ * - 'lerna': Requires lerna workspace (lerna.json)
8
+ * - 'npm': Requires npm workspace (package.json with workspaces field)
9
+ * - false: No workspace required, can be scaffolded anywhere
10
+ */
11
+ export type WorkspaceType = 'pgpm' | 'pnpm' | 'lerna' | 'npm' | false;
12
+ /**
13
+ * Extended BoilerplateConfig that adds workspace requirement field.
14
+ * This field controls both workspace detection and whether pgpm-specific files are created.
15
+ */
16
+ export interface BoilerplateConfig extends GenomicBoilerplateConfig {
17
+ /**
18
+ * Specifies what type of workspace this template requires.
19
+ * - 'pgpm': Requires pgpm workspace AND creates pgpm.plan/.control files
20
+ * - 'pnpm': Requires pnpm workspace (pnpm-workspace.yaml), no pgpm files
21
+ * - 'lerna': Requires lerna workspace (lerna.json), no pgpm files
22
+ * - 'npm': Requires npm workspace (package.json with workspaces), no pgpm files
23
+ * - false: No workspace required, no pgpm files
24
+ *
25
+ * Defaults to 'pgpm' for 'module' type (backward compatibility), false for others.
26
+ */
27
+ requiresWorkspace?: WorkspaceType;
28
+ }
3
29
  export interface InspectTemplateOptions {
4
30
  /**
5
31
  * The boilerplate path to inspect. When omitted, inspects the template
@@ -60,10 +60,31 @@ export function scanBoilerplates(baseDir) {
60
60
  const boilerplatePath = path.join(baseDir, entry.name);
61
61
  const config = readBoilerplateConfig(boilerplatePath);
62
62
  if (config) {
63
+ // Validate and normalize the type field
64
+ const validTypes = ['workspace', 'module', 'generic'];
65
+ const configType = config.type;
66
+ const type = validTypes.includes(configType)
67
+ ? configType
68
+ : 'module';
69
+ // Validate and normalize requiresWorkspace field
70
+ const validWorkspaceTypes = ['pgpm', 'pnpm', 'lerna', 'npm'];
71
+ let requiresWorkspace;
72
+ if (config.requiresWorkspace === false) {
73
+ requiresWorkspace = false;
74
+ }
75
+ else if (typeof config.requiresWorkspace === 'string' &&
76
+ validWorkspaceTypes.includes(config.requiresWorkspace)) {
77
+ requiresWorkspace = config.requiresWorkspace;
78
+ }
79
+ else {
80
+ // Default: 'pgpm' for module type (backward compatibility), undefined for others
81
+ requiresWorkspace = type === 'module' ? 'pgpm' : undefined;
82
+ }
63
83
  boilerplates.push({
64
84
  name: entry.name,
65
85
  path: boilerplatePath,
66
- type: config.type ?? 'module',
86
+ type,
87
+ requiresWorkspace,
67
88
  questions: config.questions
68
89
  });
69
90
  }
@@ -325,6 +325,8 @@ export class PgpmPackage {
325
325
  }
326
326
  async initModule(options) {
327
327
  this.ensureWorkspace();
328
+ // Determine if this is a pgpm-managed module (defaults to true for backward compatibility)
329
+ const isPgpmModule = options.pgpm ?? true;
328
330
  // If outputDir is provided, use it directly instead of createModuleDirectory
329
331
  let targetPath;
330
332
  if (options.outputDir) {
@@ -358,8 +360,11 @@ export class PgpmPackage {
358
360
  toolName: options.toolName ?? DEFAULT_TEMPLATE_TOOL_NAME,
359
361
  cwd: this.cwd
360
362
  });
361
- this.initModuleSqitch(options.name, targetPath);
362
- writeExtensions(targetPath, options.extensions);
363
+ // Only create pgpm files (pgpm.plan, .control, deploy/revert/verify dirs) for pgpm-managed modules
364
+ if (isPgpmModule) {
365
+ this.initModuleSqitch(options.name, targetPath);
366
+ writeExtensions(targetPath, options.extensions);
367
+ }
363
368
  }
364
369
  // ──────────────── Dependency Analysis ────────────────
365
370
  getLatestChange(moduleName) {
@@ -38,7 +38,8 @@ const DB_REQUIRED_EXTENSIONS = [
38
38
  const SERVICE_REQUIRED_EXTENSIONS = [
39
39
  'plpgsql',
40
40
  'metaschema-schema',
41
- 'metaschema-modules'
41
+ 'metaschema-modules',
42
+ 'services'
42
43
  ];
43
44
  /**
44
45
  * Checks which pgpm modules from the extensions list are missing from the workspace
@@ -201,7 +202,7 @@ GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public to public;
201
202
  DO $LQLMIGRATION$
202
203
  DECLARE
203
204
  BEGIN
204
-
205
+
205
206
  EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), 'app_user');
206
207
  EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), 'app_admin');
207
208
 
@@ -10,6 +10,7 @@ export const PGPM_MODULE_MAP = {
10
10
  'pgpm-database-jobs': '@pgpm/database-jobs',
11
11
  'metaschema-modules': '@pgpm/metaschema-modules',
12
12
  'metaschema-schema': '@pgpm/metaschema-schema',
13
+ 'services': '@pgpm/services',
13
14
  'pgpm-inflection': '@pgpm/inflection',
14
15
  'pgpm-jwt-claims': '@pgpm/jwt-claims',
15
16
  'pgpm-stamps': '@pgpm/stamps',
@@ -44,7 +44,8 @@ const DB_REQUIRED_EXTENSIONS = [
44
44
  const SERVICE_REQUIRED_EXTENSIONS = [
45
45
  'plpgsql',
46
46
  'metaschema-schema',
47
- 'metaschema-modules'
47
+ 'metaschema-modules',
48
+ 'services'
48
49
  ];
49
50
  /**
50
51
  * Checks which pgpm modules from the extensions list are missing from the workspace
@@ -207,7 +208,7 @@ GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public to public;
207
208
  DO $LQLMIGRATION$
208
209
  DECLARE
209
210
  BEGIN
210
-
211
+
211
212
  EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), 'app_user');
212
213
  EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), 'app_admin');
213
214
 
@@ -13,6 +13,7 @@ exports.PGPM_MODULE_MAP = {
13
13
  'pgpm-database-jobs': '@pgpm/database-jobs',
14
14
  'metaschema-modules': '@pgpm/metaschema-modules',
15
15
  'metaschema-schema': '@pgpm/metaschema-schema',
16
+ 'services': '@pgpm/services',
16
17
  'pgpm-inflection': '@pgpm/inflection',
17
18
  'pgpm-jwt-claims': '@pgpm/jwt-claims',
18
19
  'pgpm-stamps': '@pgpm/stamps',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/core",
3
- "version": "4.9.0",
3
+ "version": "4.10.0",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PGPM Package and Migration Tools",
6
6
  "main": "index.js",
@@ -48,11 +48,11 @@
48
48
  "makage": "^0.1.10"
49
49
  },
50
50
  "dependencies": {
51
- "@pgpmjs/env": "^2.9.2",
51
+ "@pgpmjs/env": "^2.9.3",
52
52
  "@pgpmjs/logger": "^1.3.7",
53
53
  "@pgpmjs/server-utils": "^2.8.14",
54
54
  "@pgpmjs/types": "^2.14.0",
55
- "csv-to-pg": "^3.3.2",
55
+ "csv-to-pg": "^3.3.3",
56
56
  "genomic": "^5.2.0",
57
57
  "glob": "^13.0.0",
58
58
  "komoji": "^0.7.14",
@@ -64,5 +64,5 @@
64
64
  "pgsql-parser": "^17.9.9",
65
65
  "yanse": "^0.1.11"
66
66
  },
67
- "gitHead": "e6171117d5498f38f456dfaf7e8a497dd7d2a30b"
67
+ "gitHead": "ba5bbacf7ccc1980cba10bf3f45ebb0ca639fb79"
68
68
  }