@pgpmjs/core 3.2.3 → 4.0.1
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.
- package/core/class/pgpm.d.ts +2 -0
- package/core/class/pgpm.js +2 -3
- package/core/template-scaffold.d.ts +49 -6
- package/core/template-scaffold.js +70 -122
- package/esm/core/class/pgpm.js +2 -3
- package/esm/core/template-scaffold.js +70 -123
- package/package.json +4 -3
package/core/class/pgpm.d.ts
CHANGED
|
@@ -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;
|
package/core/class/pgpm.js
CHANGED
|
@@ -369,12 +369,11 @@ class PgpmPackage {
|
|
|
369
369
|
extensions: options.extensions
|
|
370
370
|
};
|
|
371
371
|
await (0, template_scaffold_1.scaffoldTemplate)({
|
|
372
|
-
|
|
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
|
-
|
|
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,61 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { BoilerplateConfig } from 'create-gen-app';
|
|
2
|
+
import type { Inquirerer, Question } from 'inquirerer';
|
|
3
|
+
export interface InspectTemplateOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The boilerplate path to inspect. When omitted, inspects the template
|
|
6
|
+
* repository root and returns the templateDir for scanning available boilerplates.
|
|
7
|
+
*/
|
|
8
|
+
fromPath?: string;
|
|
9
|
+
templateRepo?: string;
|
|
10
|
+
branch?: string;
|
|
11
|
+
cacheTtlMs?: number;
|
|
12
|
+
toolName?: string;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
cacheBaseDir?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Override the base directory for template resolution.
|
|
17
|
+
* When provided, the effective path becomes `join(dir, fromPath)`.
|
|
18
|
+
* When not provided, create-gen-app uses .boilerplates.json's dir as the default.
|
|
19
|
+
*/
|
|
20
|
+
dir?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface InspectTemplateResult {
|
|
23
|
+
/** Path to the cached/cloned template directory (repository root) */
|
|
24
|
+
templateDir: string;
|
|
25
|
+
/** The resolved fromPath after .boilerplates.json resolution */
|
|
26
|
+
resolvedFromPath?: string;
|
|
27
|
+
/** Full path to the resolved template subdirectory */
|
|
28
|
+
resolvedTemplatePath: string;
|
|
29
|
+
/** Whether a cached template was used */
|
|
30
|
+
cacheUsed: boolean;
|
|
31
|
+
/** Whether the cache was expired and refreshed */
|
|
32
|
+
cacheExpired: boolean;
|
|
33
|
+
/** Configuration from .boilerplate.json (includes type, questions, etc.) */
|
|
34
|
+
config: BoilerplateConfig | null;
|
|
35
|
+
}
|
|
3
36
|
export interface ScaffoldTemplateOptions {
|
|
4
|
-
|
|
37
|
+
fromPath: string;
|
|
5
38
|
outputDir: string;
|
|
6
39
|
templateRepo?: string;
|
|
7
40
|
branch?: string;
|
|
8
|
-
templatePath?: string;
|
|
9
41
|
answers: Record<string, any>;
|
|
10
42
|
noTty?: boolean;
|
|
11
43
|
cacheTtlMs?: number;
|
|
12
44
|
toolName?: string;
|
|
13
45
|
cwd?: string;
|
|
14
46
|
cacheBaseDir?: string;
|
|
15
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Override the base directory for template resolution.
|
|
49
|
+
* When provided, the effective path becomes `join(dir, fromPath)`.
|
|
50
|
+
* When not provided, create-gen-app uses .boilerplates.json's dir as the default.
|
|
51
|
+
*/
|
|
16
52
|
dir?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Optional Inquirerer instance to reuse for prompting.
|
|
55
|
+
* If provided, the caller retains ownership and is responsible for closing it.
|
|
56
|
+
* If not provided, a new instance will be created and closed automatically.
|
|
57
|
+
*/
|
|
58
|
+
prompter?: Inquirerer;
|
|
17
59
|
}
|
|
18
60
|
export interface ScaffoldTemplateResult {
|
|
19
61
|
cacheUsed: boolean;
|
|
@@ -21,9 +63,10 @@ export interface ScaffoldTemplateResult {
|
|
|
21
63
|
cachePath?: string;
|
|
22
64
|
templateDir: string;
|
|
23
65
|
/** Questions loaded from .boilerplate.json, if any */
|
|
24
|
-
questions?:
|
|
66
|
+
questions?: Question[];
|
|
25
67
|
}
|
|
26
68
|
export declare const DEFAULT_TEMPLATE_REPO = "https://github.com/constructive-io/pgpm-boilerplates.git";
|
|
27
69
|
export declare const DEFAULT_TEMPLATE_TTL_MS: number;
|
|
28
70
|
export declare const DEFAULT_TEMPLATE_TOOL_NAME = "pgpm";
|
|
71
|
+
export declare function inspectTemplate(options: InspectTemplateOptions): InspectTemplateResult;
|
|
29
72
|
export declare function scaffoldTemplate(options: ScaffoldTemplateOptions): Promise<ScaffoldTemplateResult>;
|
|
@@ -4,145 +4,93 @@ 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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
+
// Compute effective fromPath:
|
|
35
|
+
// - If dir is provided, join it with fromPath and bypass .boilerplates.json
|
|
36
|
+
// - If dir is NOT provided, let create-gen-app use .boilerplates.json
|
|
37
|
+
const effectiveFromPath = dir
|
|
38
|
+
? fromPath
|
|
39
|
+
? path_1.default.join(dir, fromPath)
|
|
40
|
+
: dir
|
|
41
|
+
: fromPath;
|
|
42
|
+
const template = templateRepo.startsWith('.') ||
|
|
43
|
+
templateRepo.startsWith('/') ||
|
|
44
|
+
templateRepo.startsWith('~')
|
|
45
|
+
? path_1.default.resolve(cwd ?? process.cwd(), templateRepo)
|
|
46
|
+
: templateRepo;
|
|
47
|
+
const result = scaffolder.inspect({
|
|
48
|
+
template,
|
|
49
|
+
branch,
|
|
50
|
+
fromPath: effectiveFromPath,
|
|
51
|
+
// When dir is specified, bypass .boilerplates.json resolution entirely
|
|
52
|
+
useBoilerplatesConfig: !dir,
|
|
53
|
+
});
|
|
70
54
|
return {
|
|
71
|
-
|
|
72
|
-
|
|
55
|
+
templateDir: result.templateDir,
|
|
56
|
+
resolvedFromPath: result.resolvedFromPath,
|
|
57
|
+
resolvedTemplatePath: result.resolvedTemplatePath,
|
|
58
|
+
cacheUsed: result.cacheUsed,
|
|
59
|
+
cacheExpired: result.cacheExpired,
|
|
60
|
+
config: result.config,
|
|
73
61
|
};
|
|
74
|
-
}
|
|
62
|
+
}
|
|
75
63
|
async function scaffoldTemplate(options) {
|
|
76
|
-
const {
|
|
77
|
-
const
|
|
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({
|
|
64
|
+
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;
|
|
65
|
+
const scaffolder = new create_gen_app_1.TemplateScaffolder({
|
|
101
66
|
toolName,
|
|
102
|
-
|
|
103
|
-
|
|
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),
|
|
67
|
+
ttlMs: cacheTtlMs,
|
|
68
|
+
cacheBaseDir: resolveCacheBaseDir(cacheBaseDir),
|
|
108
69
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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,
|
|
70
|
+
// If dir is provided, join it with fromPath and bypass .boilerplates.json
|
|
71
|
+
// Otherwise, let create-gen-app resolve via .boilerplates.json
|
|
72
|
+
const effectiveFromPath = dir ? path_1.default.join(dir, fromPath) : fromPath;
|
|
73
|
+
const template = templateRepo.startsWith('.') ||
|
|
74
|
+
templateRepo.startsWith('/') ||
|
|
75
|
+
templateRepo.startsWith('~')
|
|
76
|
+
? path_1.default.resolve(cwd ?? process.cwd(), templateRepo)
|
|
77
|
+
: templateRepo;
|
|
78
|
+
const result = await scaffolder.scaffold({
|
|
79
|
+
template,
|
|
80
|
+
outputDir,
|
|
81
|
+
branch,
|
|
82
|
+
fromPath: effectiveFromPath,
|
|
83
|
+
answers,
|
|
138
84
|
noTty,
|
|
139
|
-
|
|
85
|
+
prompter,
|
|
86
|
+
// When dir is specified, bypass .boilerplates.json resolution entirely
|
|
87
|
+
useBoilerplatesConfig: !dir,
|
|
140
88
|
});
|
|
141
89
|
return {
|
|
142
|
-
cacheUsed,
|
|
143
|
-
cacheExpired:
|
|
144
|
-
cachePath: templateDir,
|
|
145
|
-
templateDir,
|
|
146
|
-
questions:
|
|
90
|
+
cacheUsed: result.cacheUsed,
|
|
91
|
+
cacheExpired: result.cacheExpired,
|
|
92
|
+
cachePath: result.templateDir,
|
|
93
|
+
templateDir: result.templateDir,
|
|
94
|
+
questions: result.questions,
|
|
147
95
|
};
|
|
148
96
|
}
|
package/esm/core/class/pgpm.js
CHANGED
|
@@ -330,12 +330,11 @@ export class PgpmPackage {
|
|
|
330
330
|
extensions: options.extensions
|
|
331
331
|
};
|
|
332
332
|
await scaffoldTemplate({
|
|
333
|
-
|
|
333
|
+
fromPath: options.templatePath ?? 'module',
|
|
334
334
|
outputDir: targetPath,
|
|
335
335
|
templateRepo: options.templateRepo ?? DEFAULT_TEMPLATE_REPO,
|
|
336
336
|
branch: options.branch,
|
|
337
|
-
|
|
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,88 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
1
|
import os from 'os';
|
|
3
2
|
import path from 'path';
|
|
4
|
-
import {
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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
|
+
// Compute effective fromPath:
|
|
27
|
+
// - If dir is provided, join it with fromPath and bypass .boilerplates.json
|
|
28
|
+
// - If dir is NOT provided, let create-gen-app use .boilerplates.json
|
|
29
|
+
const effectiveFromPath = dir
|
|
30
|
+
? fromPath
|
|
31
|
+
? path.join(dir, fromPath)
|
|
32
|
+
: dir
|
|
33
|
+
: fromPath;
|
|
34
|
+
const template = templateRepo.startsWith('.') ||
|
|
35
|
+
templateRepo.startsWith('/') ||
|
|
36
|
+
templateRepo.startsWith('~')
|
|
37
|
+
? path.resolve(cwd ?? process.cwd(), templateRepo)
|
|
38
|
+
: templateRepo;
|
|
39
|
+
const result = scaffolder.inspect({
|
|
40
|
+
template,
|
|
41
|
+
branch,
|
|
42
|
+
fromPath: effectiveFromPath,
|
|
43
|
+
// When dir is specified, bypass .boilerplates.json resolution entirely
|
|
44
|
+
useBoilerplatesConfig: !dir,
|
|
45
|
+
});
|
|
63
46
|
return {
|
|
64
|
-
|
|
65
|
-
|
|
47
|
+
templateDir: result.templateDir,
|
|
48
|
+
resolvedFromPath: result.resolvedFromPath,
|
|
49
|
+
resolvedTemplatePath: result.resolvedTemplatePath,
|
|
50
|
+
cacheUsed: result.cacheUsed,
|
|
51
|
+
cacheExpired: result.cacheExpired,
|
|
52
|
+
config: result.config,
|
|
66
53
|
};
|
|
67
|
-
}
|
|
54
|
+
}
|
|
68
55
|
export async function scaffoldTemplate(options) {
|
|
69
|
-
const {
|
|
70
|
-
const
|
|
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({
|
|
56
|
+
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;
|
|
57
|
+
const scaffolder = new TemplateScaffolder({
|
|
94
58
|
toolName,
|
|
95
|
-
|
|
96
|
-
|
|
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),
|
|
59
|
+
ttlMs: cacheTtlMs,
|
|
60
|
+
cacheBaseDir: resolveCacheBaseDir(cacheBaseDir),
|
|
101
61
|
});
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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,
|
|
62
|
+
// If dir is provided, join it with fromPath and bypass .boilerplates.json
|
|
63
|
+
// Otherwise, let create-gen-app resolve via .boilerplates.json
|
|
64
|
+
const effectiveFromPath = dir ? path.join(dir, fromPath) : fromPath;
|
|
65
|
+
const template = templateRepo.startsWith('.') ||
|
|
66
|
+
templateRepo.startsWith('/') ||
|
|
67
|
+
templateRepo.startsWith('~')
|
|
68
|
+
? path.resolve(cwd ?? process.cwd(), templateRepo)
|
|
69
|
+
: templateRepo;
|
|
70
|
+
const result = await scaffolder.scaffold({
|
|
71
|
+
template,
|
|
72
|
+
outputDir,
|
|
73
|
+
branch,
|
|
74
|
+
fromPath: effectiveFromPath,
|
|
75
|
+
answers,
|
|
131
76
|
noTty,
|
|
132
|
-
|
|
77
|
+
prompter,
|
|
78
|
+
// When dir is specified, bypass .boilerplates.json resolution entirely
|
|
79
|
+
useBoilerplatesConfig: !dir,
|
|
133
80
|
});
|
|
134
81
|
return {
|
|
135
|
-
cacheUsed,
|
|
136
|
-
cacheExpired:
|
|
137
|
-
cachePath: templateDir,
|
|
138
|
-
templateDir,
|
|
139
|
-
questions:
|
|
82
|
+
cacheUsed: result.cacheUsed,
|
|
83
|
+
cacheExpired: result.cacheExpired,
|
|
84
|
+
cachePath: result.templateDir,
|
|
85
|
+
templateDir: result.templateDir,
|
|
86
|
+
questions: result.questions,
|
|
140
87
|
};
|
|
141
88
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pgpmjs/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
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.
|
|
55
|
+
"create-gen-app": "^0.9.0",
|
|
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": "
|
|
67
|
+
"gitHead": "b4dd6e24bd84d79f3057d8555b850481b7d4e19a"
|
|
67
68
|
}
|