@pgpmjs/core 3.2.3 → 4.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.
@@ -17,6 +17,8 @@ export interface InitModuleOptions {
17
17
  branch?: string;
18
18
  templateRepo?: string;
19
19
  templatePath?: string;
20
+ /** Override the base directory for template resolution (e.g., 'supabase', 'drizzle') */
21
+ dir?: string;
20
22
  cacheTtlMs?: number;
21
23
  noTty?: boolean;
22
24
  toolName?: string;
@@ -369,12 +369,11 @@ class PgpmPackage {
369
369
  extensions: options.extensions
370
370
  };
371
371
  await (0, template_scaffold_1.scaffoldTemplate)({
372
- type: 'module',
372
+ fromPath: options.templatePath ?? 'module',
373
373
  outputDir: targetPath,
374
374
  templateRepo: options.templateRepo ?? template_scaffold_1.DEFAULT_TEMPLATE_REPO,
375
375
  branch: options.branch,
376
- // Don't set default templatePath - let scaffoldTemplate use metadata-driven resolution
377
- templatePath: options.templatePath,
376
+ dir: options.dir,
378
377
  answers,
379
378
  noTty: options.noTty ?? false,
380
379
  cacheTtlMs: options.cacheTtlMs ?? template_scaffold_1.DEFAULT_TEMPLATE_TTL_MS,
@@ -1,19 +1,57 @@
1
- import { BoilerplateQuestion } from './boilerplate-types';
2
- export type TemplateKind = 'workspace' | 'module';
1
+ import { BoilerplateConfig } from 'create-gen-app';
2
+ import type { Inquirerer, Question } from 'inquirerer';
3
+ export interface InspectTemplateOptions {
4
+ fromPath: string;
5
+ templateRepo?: string;
6
+ branch?: string;
7
+ cacheTtlMs?: number;
8
+ toolName?: string;
9
+ cwd?: string;
10
+ cacheBaseDir?: string;
11
+ /**
12
+ * Override the base directory for template resolution.
13
+ * When provided, the effective path becomes `join(dir, fromPath)`.
14
+ * When not provided, create-gen-app uses .boilerplates.json's dir as the default.
15
+ */
16
+ dir?: string;
17
+ }
18
+ export interface InspectTemplateResult {
19
+ /** Path to the cached/cloned template directory (repository root) */
20
+ templateDir: string;
21
+ /** The resolved fromPath after .boilerplates.json resolution */
22
+ resolvedFromPath?: string;
23
+ /** Full path to the resolved template subdirectory */
24
+ resolvedTemplatePath: string;
25
+ /** Whether a cached template was used */
26
+ cacheUsed: boolean;
27
+ /** Whether the cache was expired and refreshed */
28
+ cacheExpired: boolean;
29
+ /** Configuration from .boilerplate.json (includes type, questions, etc.) */
30
+ config: BoilerplateConfig | null;
31
+ }
3
32
  export interface ScaffoldTemplateOptions {
4
- type: TemplateKind;
33
+ fromPath: string;
5
34
  outputDir: string;
6
35
  templateRepo?: string;
7
36
  branch?: string;
8
- templatePath?: string;
9
37
  answers: Record<string, any>;
10
38
  noTty?: boolean;
11
39
  cacheTtlMs?: number;
12
40
  toolName?: string;
13
41
  cwd?: string;
14
42
  cacheBaseDir?: string;
15
- /** Override the boilerplate directory (e.g., "default", "supabase") */
43
+ /**
44
+ * Override the base directory for template resolution.
45
+ * When provided, the effective path becomes `join(dir, fromPath)`.
46
+ * When not provided, create-gen-app uses .boilerplates.json's dir as the default.
47
+ */
16
48
  dir?: string;
49
+ /**
50
+ * Optional Inquirerer instance to reuse for prompting.
51
+ * If provided, the caller retains ownership and is responsible for closing it.
52
+ * If not provided, a new instance will be created and closed automatically.
53
+ */
54
+ prompter?: Inquirerer;
17
55
  }
18
56
  export interface ScaffoldTemplateResult {
19
57
  cacheUsed: boolean;
@@ -21,9 +59,10 @@ export interface ScaffoldTemplateResult {
21
59
  cachePath?: string;
22
60
  templateDir: string;
23
61
  /** Questions loaded from .boilerplate.json, if any */
24
- questions?: BoilerplateQuestion[];
62
+ questions?: Question[];
25
63
  }
26
64
  export declare const DEFAULT_TEMPLATE_REPO = "https://github.com/constructive-io/pgpm-boilerplates.git";
27
65
  export declare const DEFAULT_TEMPLATE_TTL_MS: number;
28
66
  export declare const DEFAULT_TEMPLATE_TOOL_NAME = "pgpm";
67
+ export declare function inspectTemplate(options: InspectTemplateOptions): InspectTemplateResult;
29
68
  export declare function scaffoldTemplate(options: ScaffoldTemplateOptions): Promise<ScaffoldTemplateResult>;
@@ -4,145 +4,84 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DEFAULT_TEMPLATE_TOOL_NAME = exports.DEFAULT_TEMPLATE_TTL_MS = exports.DEFAULT_TEMPLATE_REPO = void 0;
7
+ exports.inspectTemplate = inspectTemplate;
7
8
  exports.scaffoldTemplate = scaffoldTemplate;
8
- const fs_1 = __importDefault(require("fs"));
9
9
  const os_1 = __importDefault(require("os"));
10
10
  const path_1 = __importDefault(require("path"));
11
11
  const create_gen_app_1 = require("create-gen-app");
12
- const boilerplate_scanner_1 = require("./boilerplate-scanner");
13
12
  exports.DEFAULT_TEMPLATE_REPO = 'https://github.com/constructive-io/pgpm-boilerplates.git';
14
13
  exports.DEFAULT_TEMPLATE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 1 week
15
14
  exports.DEFAULT_TEMPLATE_TOOL_NAME = 'pgpm';
16
- const templatizer = new create_gen_app_1.Templatizer();
17
- const looksLikePath = (value) => {
18
- return (value.startsWith('.') || value.startsWith('/') || value.startsWith('~'));
19
- };
20
- /**
21
- * Resolve the template path using the new metadata-driven resolution.
22
- *
23
- * Resolution order:
24
- * 1. If explicit `templatePath` is provided, use it directly
25
- * 2. If `.boilerplates.json` exists, use its `dir` field to find the base directory
26
- * 3. Look for `{baseDir}/{type}` (e.g., "default/module")
27
- * 4. Fallback to legacy structure: `{type}` directly in root
28
- */
29
- const resolveFromPath = (templateDir, templatePath, type, dirOverride) => {
30
- // If explicit templatePath is provided, use it directly
31
- if (templatePath) {
32
- const candidateDir = path_1.default.isAbsolute(templatePath)
33
- ? templatePath
34
- : path_1.default.join(templateDir, templatePath);
35
- if (fs_1.default.existsSync(candidateDir) &&
36
- fs_1.default.statSync(candidateDir).isDirectory()) {
37
- return {
38
- fromPath: path_1.default.relative(templateDir, candidateDir) || '.',
39
- resolvedTemplatePath: candidateDir,
40
- };
41
- }
42
- return {
43
- fromPath: templatePath,
44
- resolvedTemplatePath: path_1.default.join(templateDir, templatePath),
45
- };
15
+ function resolveCacheBaseDir(cacheBaseDir) {
16
+ if (cacheBaseDir) {
17
+ return cacheBaseDir;
46
18
  }
47
- // Try new metadata-driven resolution
48
- const rootConfig = (0, boilerplate_scanner_1.readBoilerplatesConfig)(templateDir);
49
- const baseDir = dirOverride ?? rootConfig?.dir;
50
- if (baseDir) {
51
- // New structure: {templateDir}/{baseDir}/{type}
52
- const newStructurePath = path_1.default.join(templateDir, baseDir, type);
53
- if (fs_1.default.existsSync(newStructurePath) &&
54
- fs_1.default.statSync(newStructurePath).isDirectory()) {
55
- return {
56
- fromPath: path_1.default.join(baseDir, type),
57
- resolvedTemplatePath: newStructurePath,
58
- };
59
- }
19
+ if (process.env.PGPM_CACHE_BASE_DIR) {
20
+ return process.env.PGPM_CACHE_BASE_DIR;
60
21
  }
61
- // Fallback to legacy structure: {templateDir}/{type}
62
- const legacyPath = path_1.default.join(templateDir, type);
63
- if (fs_1.default.existsSync(legacyPath) && fs_1.default.statSync(legacyPath).isDirectory()) {
64
- return {
65
- fromPath: type,
66
- resolvedTemplatePath: legacyPath,
67
- };
22
+ if (process.env.JEST_WORKER_ID) {
23
+ return path_1.default.join(os_1.default.tmpdir(), `pgpm-cache-${process.env.JEST_WORKER_ID}`);
68
24
  }
69
- // Default fallback
25
+ return undefined;
26
+ }
27
+ function inspectTemplate(options) {
28
+ const { fromPath, templateRepo = exports.DEFAULT_TEMPLATE_REPO, branch, cacheTtlMs = exports.DEFAULT_TEMPLATE_TTL_MS, toolName = exports.DEFAULT_TEMPLATE_TOOL_NAME, cwd, cacheBaseDir, dir, } = options;
29
+ const scaffolder = new create_gen_app_1.TemplateScaffolder({
30
+ toolName,
31
+ ttlMs: cacheTtlMs,
32
+ cacheBaseDir: resolveCacheBaseDir(cacheBaseDir),
33
+ });
34
+ // If dir is provided, prefix fromPath with it
35
+ // Otherwise, let create-gen-app resolve via .boilerplates.json
36
+ const effectiveFromPath = dir ? path_1.default.join(dir, fromPath) : fromPath;
37
+ const template = templateRepo.startsWith('.') ||
38
+ templateRepo.startsWith('/') ||
39
+ templateRepo.startsWith('~')
40
+ ? path_1.default.resolve(cwd ?? process.cwd(), templateRepo)
41
+ : templateRepo;
42
+ const result = scaffolder.inspect({
43
+ template,
44
+ branch,
45
+ fromPath: effectiveFromPath,
46
+ });
70
47
  return {
71
- fromPath: type,
72
- resolvedTemplatePath: path_1.default.join(templateDir, type),
48
+ templateDir: result.templateDir,
49
+ resolvedFromPath: result.resolvedFromPath,
50
+ resolvedTemplatePath: result.resolvedTemplatePath,
51
+ cacheUsed: result.cacheUsed,
52
+ cacheExpired: result.cacheExpired,
53
+ config: result.config,
73
54
  };
74
- };
55
+ }
75
56
  async function scaffoldTemplate(options) {
76
- const { type, outputDir, templateRepo = exports.DEFAULT_TEMPLATE_REPO, branch, templatePath, answers, noTty = false, cacheTtlMs = exports.DEFAULT_TEMPLATE_TTL_MS, toolName = exports.DEFAULT_TEMPLATE_TOOL_NAME, cwd, cacheBaseDir, dir, } = options;
77
- const resolvedRepo = looksLikePath(templateRepo)
78
- ? path_1.default.resolve(cwd ?? process.cwd(), templateRepo)
79
- : templateRepo;
80
- // Handle local template directories without caching
81
- if (looksLikePath(templateRepo) &&
82
- fs_1.default.existsSync(resolvedRepo) &&
83
- fs_1.default.statSync(resolvedRepo).isDirectory()) {
84
- const { fromPath, resolvedTemplatePath } = resolveFromPath(resolvedRepo, templatePath, type, dir);
85
- // Read boilerplate config for questions (create-gen-app now handles .boilerplate.json natively)
86
- const boilerplateConfig = (0, boilerplate_scanner_1.readBoilerplateConfig)(resolvedTemplatePath);
87
- await templatizer.process(resolvedRepo, outputDir, {
88
- argv: answers,
89
- noTty,
90
- fromPath,
91
- });
92
- return {
93
- cacheUsed: false,
94
- cacheExpired: false,
95
- templateDir: resolvedRepo,
96
- questions: boilerplateConfig?.questions,
97
- };
98
- }
99
- // Remote repo with caching
100
- const cacheManager = new create_gen_app_1.CacheManager({
57
+ const { fromPath, outputDir, templateRepo = exports.DEFAULT_TEMPLATE_REPO, branch, answers, noTty = false, cacheTtlMs = exports.DEFAULT_TEMPLATE_TTL_MS, toolName = exports.DEFAULT_TEMPLATE_TOOL_NAME, cwd, cacheBaseDir, dir, prompter, } = options;
58
+ const scaffolder = new create_gen_app_1.TemplateScaffolder({
101
59
  toolName,
102
- ttl: cacheTtlMs,
103
- baseDir: cacheBaseDir ??
104
- process.env.PGPM_CACHE_BASE_DIR ??
105
- (process.env.JEST_WORKER_ID
106
- ? path_1.default.join(os_1.default.tmpdir(), `pgpm-cache-${process.env.JEST_WORKER_ID}`)
107
- : undefined),
60
+ ttlMs: cacheTtlMs,
61
+ cacheBaseDir: resolveCacheBaseDir(cacheBaseDir),
108
62
  });
109
- const gitCloner = new create_gen_app_1.GitCloner();
110
- const normalizedUrl = gitCloner.normalizeUrl(resolvedRepo);
111
- const cacheKey = cacheManager.createKey(normalizedUrl, branch);
112
- const expiredMetadata = cacheManager.checkExpiration(cacheKey);
113
- if (expiredMetadata) {
114
- cacheManager.clear(cacheKey);
115
- }
116
- let templateDir;
117
- let cacheUsed = false;
118
- const cachedPath = cacheManager.get(cacheKey);
119
- if (cachedPath && !expiredMetadata) {
120
- templateDir = cachedPath;
121
- cacheUsed = true;
122
- }
123
- else {
124
- const tempDest = path_1.default.join(cacheManager.getReposDir(), cacheKey);
125
- gitCloner.clone(normalizedUrl, tempDest, {
126
- branch,
127
- depth: 1,
128
- singleBranch: true,
129
- });
130
- cacheManager.set(cacheKey, tempDest);
131
- templateDir = tempDest;
132
- }
133
- const { fromPath, resolvedTemplatePath } = resolveFromPath(templateDir, templatePath, type, dir);
134
- // Read boilerplate config for questions (create-gen-app now handles .boilerplate.json natively)
135
- const boilerplateConfig = (0, boilerplate_scanner_1.readBoilerplateConfig)(resolvedTemplatePath);
136
- await templatizer.process(templateDir, outputDir, {
137
- argv: answers,
63
+ // If dir is provided, prefix fromPath with it
64
+ // Otherwise, let create-gen-app resolve via .boilerplates.json
65
+ const effectiveFromPath = dir ? path_1.default.join(dir, fromPath) : fromPath;
66
+ const template = templateRepo.startsWith('.') ||
67
+ templateRepo.startsWith('/') ||
68
+ templateRepo.startsWith('~')
69
+ ? path_1.default.resolve(cwd ?? process.cwd(), templateRepo)
70
+ : templateRepo;
71
+ const result = await scaffolder.scaffold({
72
+ template,
73
+ outputDir,
74
+ branch,
75
+ fromPath: effectiveFromPath,
76
+ answers,
138
77
  noTty,
139
- fromPath,
78
+ prompter,
140
79
  });
141
80
  return {
142
- cacheUsed,
143
- cacheExpired: Boolean(expiredMetadata),
144
- cachePath: templateDir,
145
- templateDir,
146
- questions: boilerplateConfig?.questions,
81
+ cacheUsed: result.cacheUsed,
82
+ cacheExpired: result.cacheExpired,
83
+ cachePath: result.templateDir,
84
+ templateDir: result.templateDir,
85
+ questions: result.questions,
147
86
  };
148
87
  }
@@ -330,12 +330,11 @@ export class PgpmPackage {
330
330
  extensions: options.extensions
331
331
  };
332
332
  await scaffoldTemplate({
333
- type: 'module',
333
+ fromPath: options.templatePath ?? 'module',
334
334
  outputDir: targetPath,
335
335
  templateRepo: options.templateRepo ?? DEFAULT_TEMPLATE_REPO,
336
336
  branch: options.branch,
337
- // Don't set default templatePath - let scaffoldTemplate use metadata-driven resolution
338
- templatePath: options.templatePath,
337
+ dir: options.dir,
339
338
  answers,
340
339
  noTty: options.noTty ?? false,
341
340
  cacheTtlMs: options.cacheTtlMs ?? DEFAULT_TEMPLATE_TTL_MS,
@@ -1,141 +1,79 @@
1
- import fs from 'fs';
2
1
  import os from 'os';
3
2
  import path from 'path';
4
- import { CacheManager, GitCloner, Templatizer } from 'create-gen-app';
5
- import { readBoilerplateConfig, readBoilerplatesConfig, } from './boilerplate-scanner';
3
+ import { TemplateScaffolder } from 'create-gen-app';
6
4
  export const DEFAULT_TEMPLATE_REPO = 'https://github.com/constructive-io/pgpm-boilerplates.git';
7
5
  export const DEFAULT_TEMPLATE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 1 week
8
6
  export const DEFAULT_TEMPLATE_TOOL_NAME = 'pgpm';
9
- const templatizer = new Templatizer();
10
- const looksLikePath = (value) => {
11
- return (value.startsWith('.') || value.startsWith('/') || value.startsWith('~'));
12
- };
13
- /**
14
- * Resolve the template path using the new metadata-driven resolution.
15
- *
16
- * Resolution order:
17
- * 1. If explicit `templatePath` is provided, use it directly
18
- * 2. If `.boilerplates.json` exists, use its `dir` field to find the base directory
19
- * 3. Look for `{baseDir}/{type}` (e.g., "default/module")
20
- * 4. Fallback to legacy structure: `{type}` directly in root
21
- */
22
- const resolveFromPath = (templateDir, templatePath, type, dirOverride) => {
23
- // If explicit templatePath is provided, use it directly
24
- if (templatePath) {
25
- const candidateDir = path.isAbsolute(templatePath)
26
- ? templatePath
27
- : path.join(templateDir, templatePath);
28
- if (fs.existsSync(candidateDir) &&
29
- fs.statSync(candidateDir).isDirectory()) {
30
- return {
31
- fromPath: path.relative(templateDir, candidateDir) || '.',
32
- resolvedTemplatePath: candidateDir,
33
- };
34
- }
35
- return {
36
- fromPath: templatePath,
37
- resolvedTemplatePath: path.join(templateDir, templatePath),
38
- };
7
+ function resolveCacheBaseDir(cacheBaseDir) {
8
+ if (cacheBaseDir) {
9
+ return cacheBaseDir;
39
10
  }
40
- // Try new metadata-driven resolution
41
- const rootConfig = readBoilerplatesConfig(templateDir);
42
- const baseDir = dirOverride ?? rootConfig?.dir;
43
- if (baseDir) {
44
- // New structure: {templateDir}/{baseDir}/{type}
45
- const newStructurePath = path.join(templateDir, baseDir, type);
46
- if (fs.existsSync(newStructurePath) &&
47
- fs.statSync(newStructurePath).isDirectory()) {
48
- return {
49
- fromPath: path.join(baseDir, type),
50
- resolvedTemplatePath: newStructurePath,
51
- };
52
- }
11
+ if (process.env.PGPM_CACHE_BASE_DIR) {
12
+ return process.env.PGPM_CACHE_BASE_DIR;
53
13
  }
54
- // Fallback to legacy structure: {templateDir}/{type}
55
- const legacyPath = path.join(templateDir, type);
56
- if (fs.existsSync(legacyPath) && fs.statSync(legacyPath).isDirectory()) {
57
- return {
58
- fromPath: type,
59
- resolvedTemplatePath: legacyPath,
60
- };
14
+ if (process.env.JEST_WORKER_ID) {
15
+ return path.join(os.tmpdir(), `pgpm-cache-${process.env.JEST_WORKER_ID}`);
61
16
  }
62
- // Default fallback
17
+ return undefined;
18
+ }
19
+ export function inspectTemplate(options) {
20
+ const { fromPath, templateRepo = DEFAULT_TEMPLATE_REPO, branch, cacheTtlMs = DEFAULT_TEMPLATE_TTL_MS, toolName = DEFAULT_TEMPLATE_TOOL_NAME, cwd, cacheBaseDir, dir, } = options;
21
+ const scaffolder = new TemplateScaffolder({
22
+ toolName,
23
+ ttlMs: cacheTtlMs,
24
+ cacheBaseDir: resolveCacheBaseDir(cacheBaseDir),
25
+ });
26
+ // If dir is provided, prefix fromPath with it
27
+ // Otherwise, let create-gen-app resolve via .boilerplates.json
28
+ const effectiveFromPath = dir ? path.join(dir, fromPath) : fromPath;
29
+ const template = templateRepo.startsWith('.') ||
30
+ templateRepo.startsWith('/') ||
31
+ templateRepo.startsWith('~')
32
+ ? path.resolve(cwd ?? process.cwd(), templateRepo)
33
+ : templateRepo;
34
+ const result = scaffolder.inspect({
35
+ template,
36
+ branch,
37
+ fromPath: effectiveFromPath,
38
+ });
63
39
  return {
64
- fromPath: type,
65
- resolvedTemplatePath: path.join(templateDir, type),
40
+ templateDir: result.templateDir,
41
+ resolvedFromPath: result.resolvedFromPath,
42
+ resolvedTemplatePath: result.resolvedTemplatePath,
43
+ cacheUsed: result.cacheUsed,
44
+ cacheExpired: result.cacheExpired,
45
+ config: result.config,
66
46
  };
67
- };
47
+ }
68
48
  export async function scaffoldTemplate(options) {
69
- const { type, outputDir, templateRepo = DEFAULT_TEMPLATE_REPO, branch, templatePath, answers, noTty = false, cacheTtlMs = DEFAULT_TEMPLATE_TTL_MS, toolName = DEFAULT_TEMPLATE_TOOL_NAME, cwd, cacheBaseDir, dir, } = options;
70
- const resolvedRepo = looksLikePath(templateRepo)
71
- ? path.resolve(cwd ?? process.cwd(), templateRepo)
72
- : templateRepo;
73
- // Handle local template directories without caching
74
- if (looksLikePath(templateRepo) &&
75
- fs.existsSync(resolvedRepo) &&
76
- fs.statSync(resolvedRepo).isDirectory()) {
77
- const { fromPath, resolvedTemplatePath } = resolveFromPath(resolvedRepo, templatePath, type, dir);
78
- // Read boilerplate config for questions (create-gen-app now handles .boilerplate.json natively)
79
- const boilerplateConfig = readBoilerplateConfig(resolvedTemplatePath);
80
- await templatizer.process(resolvedRepo, outputDir, {
81
- argv: answers,
82
- noTty,
83
- fromPath,
84
- });
85
- return {
86
- cacheUsed: false,
87
- cacheExpired: false,
88
- templateDir: resolvedRepo,
89
- questions: boilerplateConfig?.questions,
90
- };
91
- }
92
- // Remote repo with caching
93
- const cacheManager = new CacheManager({
49
+ const { fromPath, outputDir, templateRepo = DEFAULT_TEMPLATE_REPO, branch, answers, noTty = false, cacheTtlMs = DEFAULT_TEMPLATE_TTL_MS, toolName = DEFAULT_TEMPLATE_TOOL_NAME, cwd, cacheBaseDir, dir, prompter, } = options;
50
+ const scaffolder = new TemplateScaffolder({
94
51
  toolName,
95
- ttl: cacheTtlMs,
96
- baseDir: cacheBaseDir ??
97
- process.env.PGPM_CACHE_BASE_DIR ??
98
- (process.env.JEST_WORKER_ID
99
- ? path.join(os.tmpdir(), `pgpm-cache-${process.env.JEST_WORKER_ID}`)
100
- : undefined),
52
+ ttlMs: cacheTtlMs,
53
+ cacheBaseDir: resolveCacheBaseDir(cacheBaseDir),
101
54
  });
102
- const gitCloner = new GitCloner();
103
- const normalizedUrl = gitCloner.normalizeUrl(resolvedRepo);
104
- const cacheKey = cacheManager.createKey(normalizedUrl, branch);
105
- const expiredMetadata = cacheManager.checkExpiration(cacheKey);
106
- if (expiredMetadata) {
107
- cacheManager.clear(cacheKey);
108
- }
109
- let templateDir;
110
- let cacheUsed = false;
111
- const cachedPath = cacheManager.get(cacheKey);
112
- if (cachedPath && !expiredMetadata) {
113
- templateDir = cachedPath;
114
- cacheUsed = true;
115
- }
116
- else {
117
- const tempDest = path.join(cacheManager.getReposDir(), cacheKey);
118
- gitCloner.clone(normalizedUrl, tempDest, {
119
- branch,
120
- depth: 1,
121
- singleBranch: true,
122
- });
123
- cacheManager.set(cacheKey, tempDest);
124
- templateDir = tempDest;
125
- }
126
- const { fromPath, resolvedTemplatePath } = resolveFromPath(templateDir, templatePath, type, dir);
127
- // Read boilerplate config for questions (create-gen-app now handles .boilerplate.json natively)
128
- const boilerplateConfig = readBoilerplateConfig(resolvedTemplatePath);
129
- await templatizer.process(templateDir, outputDir, {
130
- argv: answers,
55
+ // If dir is provided, prefix fromPath with it
56
+ // Otherwise, let create-gen-app resolve via .boilerplates.json
57
+ const effectiveFromPath = dir ? path.join(dir, fromPath) : fromPath;
58
+ const template = templateRepo.startsWith('.') ||
59
+ templateRepo.startsWith('/') ||
60
+ templateRepo.startsWith('~')
61
+ ? path.resolve(cwd ?? process.cwd(), templateRepo)
62
+ : templateRepo;
63
+ const result = await scaffolder.scaffold({
64
+ template,
65
+ outputDir,
66
+ branch,
67
+ fromPath: effectiveFromPath,
68
+ answers,
131
69
  noTty,
132
- fromPath,
70
+ prompter,
133
71
  });
134
72
  return {
135
- cacheUsed,
136
- cacheExpired: Boolean(expiredMetadata),
137
- cachePath: templateDir,
138
- templateDir,
139
- questions: boilerplateConfig?.questions,
73
+ cacheUsed: result.cacheUsed,
74
+ cacheExpired: result.cacheExpired,
75
+ cachePath: result.templateDir,
76
+ templateDir: result.templateDir,
77
+ questions: result.questions,
140
78
  };
141
79
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/core",
3
- "version": "3.2.3",
3
+ "version": "4.0.0",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PGPM Package and Migration Tools",
6
6
  "main": "index.js",
@@ -44,6 +44,7 @@
44
44
  "@pgsql/types": "^17.6.2",
45
45
  "@types/pg": "^8.16.0",
46
46
  "copyfiles": "^2.4.1",
47
+ "inquirerer": "^2.4.0",
47
48
  "makage": "^0.1.9"
48
49
  },
49
50
  "dependencies": {
@@ -51,7 +52,7 @@
51
52
  "@pgpmjs/logger": "^1.3.5",
52
53
  "@pgpmjs/server-utils": "^2.8.9",
53
54
  "@pgpmjs/types": "^2.12.6",
54
- "create-gen-app": "^0.6.4",
55
+ "create-gen-app": "^0.8.1",
55
56
  "csv-to-pg": "^2.0.10",
56
57
  "glob": "^13.0.0",
57
58
  "komoji": "^0.7.11",
@@ -63,5 +64,5 @@
63
64
  "pgsql-parser": "^17.9.4",
64
65
  "yanse": "^0.1.8"
65
66
  },
66
- "gitHead": "9ffc005dd4668e97082d9254ce5c8ff934b757e1"
67
+ "gitHead": "b1d773f5215ad5ea1dca82b33b550728fdcd1ec0"
67
68
  }