@genesislcap/build-kit 14.142.1-alpha-2787e5d.0 → 14.143.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.
Files changed (42) hide show
  1. package/dist/utils/archive.d.ts +2 -0
  2. package/dist/utils/archive.d.ts.map +1 -0
  3. package/dist/utils/archive.js +20 -0
  4. package/dist/utils/index.d.ts +5 -1
  5. package/dist/utils/index.d.ts.map +1 -1
  6. package/dist/utils/index.js +5 -1
  7. package/dist/utils/npm.d.ts +1 -1
  8. package/dist/utils/npm.d.ts.map +1 -1
  9. package/dist/utils/npm.js +4 -2
  10. package/dist/utils/prompts.d.ts.map +1 -1
  11. package/dist/utils/prompts.js +7 -5
  12. package/dist/utils/seed.fetching.d.ts +36 -0
  13. package/dist/utils/seed.fetching.d.ts.map +1 -0
  14. package/dist/utils/seed.fetching.js +157 -0
  15. package/dist/utils/seed.meta.d.ts +10 -0
  16. package/dist/utils/seed.meta.d.ts.map +1 -0
  17. package/dist/utils/seed.meta.js +38 -0
  18. package/dist/utils/seed.processing.d.ts +4 -0
  19. package/dist/utils/seed.processing.d.ts.map +1 -0
  20. package/dist/utils/seed.processing.js +87 -0
  21. package/dist/utils/seed.setup.d.ts +3 -0
  22. package/dist/utils/seed.setup.d.ts.map +1 -0
  23. package/dist/utils/seed.setup.js +73 -0
  24. package/package.json +6 -3
  25. package/src/utils/archive.ts +18 -0
  26. package/src/utils/index.ts +5 -1
  27. package/src/utils/npm.ts +4 -2
  28. package/src/utils/prompts.ts +8 -5
  29. package/src/utils/seed.fetching.ts +256 -0
  30. package/src/utils/seed.meta.ts +34 -0
  31. package/src/utils/seed.processing.ts +100 -0
  32. package/src/utils/seed.setup.ts +98 -0
  33. package/test/fixtures/mock-seed/.genx/.genxrc.js +7 -0
  34. package/test/fixtures/mock-seed/.genx/configure.js +3 -0
  35. package/test/fixtures/mock-seed/.genx/package.json +17 -0
  36. package/test/fixtures/mock-seed/test.md +44 -0
  37. package/test/utils/seed.fetching.test.ts +145 -0
  38. package/test/utils/seed.meta.test.ts +33 -0
  39. package/dist/utils/seed.d.ts +0 -31
  40. package/dist/utils/seed.d.ts.map +0 -1
  41. package/dist/utils/seed.js +0 -264
  42. package/src/utils/seed.ts +0 -351
package/src/utils/seed.ts DELETED
@@ -1,351 +0,0 @@
1
- import { cpSync, existsSync, mkdirSync, renameSync } from 'node:fs';
2
- import { relative, resolve } from 'node:path';
3
- import { consola } from 'consola';
4
- import { downloadTemplate } from 'giget';
5
- import type { PackageJson } from 'pkg-types';
6
- import { runAsync } from './child-process';
7
- import { bold } from './console';
8
- import { listAllFiles, rename, rm } from './fs';
9
- import type { fsEntry } from './fs';
10
- import { render, renderFile } from './handlebars';
11
- import { editJSONFile, writeJSON } from './json';
12
- import { replaceObjectKeys } from './object';
13
- import { getData, getPromptDefaults, getPromptValidators, validateSeedData } from './prompts';
14
-
15
- const PROMPT_DATA_FILE = 'answers.json';
16
-
17
- export type LocalFetchResult = {
18
- local: boolean;
19
- genxDir: string;
20
- seed: string;
21
- subdir: string; // seed subdir within seed repo (if set)
22
- pkg: PackageJson;
23
- dir: string; // app directory e.g. myapp
24
- extractedSeedDir: string; // directory to extract seed: for init operation same as dir, for add operaion dir/.genx/tmp
25
- extractedSeedGenxDir: string;
26
- };
27
-
28
- export type RemoteFetchResult = LocalFetchResult & {
29
- repo: string;
30
- user: string;
31
- ref: string;
32
- provider: string;
33
- id: string;
34
- };
35
-
36
- export type FetchResult = LocalFetchResult | RemoteFetchResult;
37
-
38
- // map repo to Giget-compatible template ID
39
- const resolveSeed = (seed = '', ref = 'main', subdir = '', provider = 'gh') => {
40
- const parts = seed.split('/');
41
- const repo = parts.pop() || 'blank-app-seed';
42
- const user = parts.pop() || 'genesiscommunitysuccess';
43
- const dir = subdir ? `/${subdir}` : '';
44
- return {
45
- repo,
46
- user,
47
- ref,
48
- provider,
49
- id: `${provider}:${user}/${repo}${dir}#${ref}`,
50
- };
51
- };
52
-
53
- export const installSeedDeps = async (dir, isLogLevelVerbose) => {
54
- let dependencies = {};
55
- try {
56
- const packageJSONPath = resolve(dir, 'package.json');
57
- const packageJSON = require(packageJSONPath);
58
- dependencies = packageJSON.dependencies || {};
59
- } catch (e) {}
60
-
61
- consola.debug('Seed NPM dependencies', {
62
- targetInstallDir: dir,
63
- dependencyCount: Object.keys(dependencies).length,
64
- });
65
-
66
- if (Object.keys(dependencies).length !== 0) {
67
- const start2 = Date.now();
68
- consola.info('Installing seed NPM dependencies...');
69
- await runAsync(dir, 'npm install', {
70
- prefixCommandWithNode: false,
71
- exitOnError: false,
72
- verbose: isLogLevelVerbose,
73
- env: {
74
- ...process.env,
75
- NODE_ENV: 'production', // only install production NPM dependencies
76
- },
77
- }).catch((err) => {
78
- consola.error(
79
- 'Unexpected error installing seed dependencies. Try re-runing with --log-level verbose',
80
- );
81
- if (err) {
82
- consola.error(err);
83
- }
84
- process.exit(1);
85
- });
86
- consola.success(`Installed in ${Date.now() - start2}ms`);
87
- }
88
- };
89
-
90
- // load seed details including prompt question defaults and validators
91
- export const loadSeed = async (dir) => {
92
- const GENX_RC = '.genxrc.js';
93
- const genxConfigPath = resolve(dir, GENX_RC);
94
- const { prompts, configure, details } = require(genxConfigPath);
95
-
96
- const defaults = await getPromptDefaults(prompts());
97
- const validators = await getPromptValidators(prompts());
98
- const validate = (data) => validateSeedData(data, validators);
99
- return {
100
- prompts: prompts(),
101
- configure: configure(),
102
- details: details(),
103
- defaults,
104
- validators,
105
- validate,
106
- };
107
- };
108
-
109
- const loadGenxModule = (genxDir: string, module = 'package.json', warnIfMissing = true) => {
110
- const path = resolve(genxDir, module);
111
- try {
112
- return require(path);
113
- } catch (e) {
114
- if (warnIfMissing) {
115
- consola.warn(`Could not load ${module} from ${genxDir}`);
116
- }
117
- return {};
118
- }
119
- };
120
-
121
- // download remote or copy local seed
122
- export const fetchSeed = async (
123
- seed: string,
124
- dir: string,
125
- remote: boolean,
126
- ref: string,
127
- insecure: boolean,
128
- subdir: string,
129
- isInit: boolean,
130
- ): Promise<FetchResult> => {
131
- // disable SSL cert verification
132
- if (insecure) {
133
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
134
- }
135
-
136
- const GENX_DIR = '/.genx';
137
- const TMP_DIR = '/tmp';
138
- const start = Date.now();
139
- const localPath = subdir ? `${seed}/${subdir}` : seed;
140
- const isLocalSeed = !remote && existsSync(localPath);
141
- const genxDir = relative(process.cwd(), `${dir}${GENX_DIR}`);
142
- const extractedSeedDir = isInit ? dir : relative(process.cwd(), `${dir}${GENX_DIR}${TMP_DIR}`);
143
- const extractedSeedGenxDir = isInit
144
- ? genxDir
145
- : relative(process.cwd(), `${extractedSeedDir}${GENX_DIR}`);
146
-
147
- if (!isInit) {
148
- await rm(extractedSeedDir);
149
- mkdirSync(extractedSeedDir);
150
- }
151
-
152
- let result: FetchResult;
153
- if (isLocalSeed) {
154
- consola.info(`Copying local seed ${bold(localPath)}`);
155
- try {
156
- if (ref) {
157
- consola.warn(`${bold('ref')} has no effect when used with a local seed`);
158
- }
159
- cpSync(localPath, extractedSeedDir, { recursive: true });
160
- consola.success(`Seed copied in ${Date.now() - start}ms`);
161
- result = {
162
- local: true,
163
- genxDir,
164
- seed: localPath,
165
- subdir,
166
- pkg: loadGenxModule(extractedSeedGenxDir),
167
- dir,
168
- extractedSeedDir,
169
- extractedSeedGenxDir,
170
- };
171
- } catch (e) {
172
- consola.error(`Error copying ${localPath} to ${bold(dir)}`, e);
173
- process.exit(1);
174
- }
175
- } else {
176
- const data = resolveSeed(seed, ref, subdir);
177
- const subDirMessage = subdir ? `, subdir ${bold(subdir)}` : '';
178
- consola.info(
179
- `Downloading ${bold(data.user)} seed ${bold(data.repo)} (Git ref ${bold(
180
- data.ref,
181
- )}${subDirMessage}) to ${bold(dir)} directory...`,
182
- );
183
- try {
184
- await downloadTemplate(data.id, {
185
- dir: extractedSeedDir, // destination directory to clone to
186
- // auth?: string; // custom Authorization token to use for downloading template
187
- registry: false, // disable built-in Giget registry
188
- });
189
- consola.success(`Seed downloaded in ${Date.now() - start}ms`);
190
- result = {
191
- local: false,
192
- genxDir,
193
- seed,
194
- subdir,
195
- pkg: loadGenxModule(extractedSeedGenxDir),
196
- dir,
197
- extractedSeedDir,
198
- extractedSeedGenxDir,
199
- ...data,
200
- };
201
- } catch (err) {
202
- const error = process.env.DEBUG ? err : err.message;
203
- consola.error(error);
204
- process.exit(1);
205
- }
206
- }
207
-
208
- await removeExclusions(extractedSeedDir, result.pkg.genxSeedConfig?.exclude);
209
-
210
- return result;
211
- };
212
-
213
- const removeExclusions = async (dir, exclusions: string[]) => {
214
- try {
215
- const exclude = (exclusions ?? []).map((x) => resolve(dir, x));
216
- await Promise.all(
217
- exclude.map(async (exclusion) => {
218
- if (existsSync(exclusion)) {
219
- await rm(exclusion);
220
- consola.debug(`Excluded: ${exclusion}`);
221
- } else {
222
- consola.debug(`Ignored invalid exclusion: ${exclusion}`);
223
- }
224
- }),
225
- );
226
- } catch (err) {
227
- const error = process.env.DEBUG ? err : err.message;
228
- consola.error(error);
229
- process.exit(1);
230
- }
231
- };
232
-
233
- const processItem = (
234
- { base, dir: itemDir, path, isDir, ext, stats }: fsEntry,
235
- data,
236
- renamingEnabled: boolean,
237
- interpolationEnabled: boolean,
238
- interpolationWhitelist: string[],
239
- ) => {
240
- const baseNew = render(base, data);
241
- const needsRenaming = renamingEnabled && baseNew !== base;
242
- const pathNew = needsRenaming ? resolve(itemDir, baseNew) : path;
243
-
244
- if (needsRenaming) {
245
- try {
246
- renameSync(resolve(itemDir, base), resolve(itemDir, baseNew));
247
- consola.debug(`Renamed ${bold(base)} to ${bold(baseNew)}`);
248
- } catch (e) {
249
- consola.error(`Error renaming ${bold(base)} to ${bold(baseNew)}`);
250
- }
251
- }
252
-
253
- // Handlebars rendering
254
- if (interpolationEnabled && !isDir && interpolationWhitelist.some((i) => baseNew.includes(i))) {
255
- try {
256
- renderFile(pathNew, data, pathNew);
257
- consola.debug(`Interpolated variables in ${pathNew}`);
258
- } catch (e) {
259
- consola.error(`Error interpolating variables in ${pathNew}`);
260
- }
261
- }
262
-
263
- return { isDir, ext, dir: itemDir, base: baseNew, path: pathNew, stats };
264
- };
265
-
266
- const processOptions = (fetchSeedResult, dir, data, isInit, persistedAnswers) => {
267
- const options = fetchSeedResult.pkg?.genxSeedConfig || {};
268
- consola.debug('Seed options', JSON.stringify(options));
269
-
270
- if (options.processFiles) {
271
- const ignoreDirs = options.processFiles?.exclude || [
272
- '.git',
273
- '.genx',
274
- '.github',
275
- 'node_modules',
276
- '.gradle',
277
- 'gradle',
278
- ];
279
-
280
- const filter = (entry: fsEntry) => !ignoreDirs.includes(entry.base);
281
- const mapper = (entry: fsEntry) =>
282
- processItem(
283
- entry,
284
- data,
285
- !!options.processFiles?.rename,
286
- !!options.processFiles?.interpolateVariables?.enabled,
287
- options.processFiles?.interpolateVariables?.include,
288
- );
289
-
290
- listAllFiles(dir, filter, mapper);
291
- }
292
-
293
- if (options.persistAnswers) {
294
- const jsonPath = resolve(fetchSeedResult.genxDir, PROMPT_DATA_FILE);
295
- const additions = persistedAnswers.additions || [];
296
- const json = isInit
297
- ? data
298
- : { ...data, appSeed: persistedAnswers.appSeed, additions: [...additions, data.appSeed] };
299
- writeJSON(jsonPath, json);
300
- }
301
- };
302
-
303
- // run seed configure script
304
- export const configureSeedApp = async (
305
- seedInfo,
306
- fetchSeedResult,
307
- params,
308
- dir,
309
- skipOptionalPrompts,
310
- isInit: boolean,
311
- ) => {
312
- const { configure, prompts, details, defaults, validate } = seedInfo;
313
-
314
- // load persisted answers if available
315
- const persistedAnswers = loadGenxModule(fetchSeedResult.genxDir, PROMPT_DATA_FILE, false);
316
-
317
- // get prompt answers
318
- const data = await getData(
319
- persistedAnswers,
320
- prompts,
321
- details,
322
- defaults,
323
- validate,
324
- params,
325
- dir,
326
- skipOptionalPrompts,
327
- fetchSeedResult,
328
- );
329
- consola.debug('Loaded seed data', data);
330
-
331
- const utils = {
332
- writeFileWithData: renderFile,
333
- editJSONFile,
334
- replaceObjectKeys,
335
- listAllFiles,
336
- rename,
337
- };
338
-
339
- // run seed configure script
340
- await configure(data, utils).catch((e) => consola.error(e));
341
-
342
- // process seed exclusions, render templates, rename files/folders
343
- processOptions(fetchSeedResult, fetchSeedResult.extractedSeedDir, data, isInit, persistedAnswers);
344
-
345
- // when adding seed, copy result from temp folder to the app root (omitting .genx folder of the seed)
346
- if (!isInit) {
347
- await rm(fetchSeedResult.extractedSeedGenxDir);
348
- cpSync(fetchSeedResult.extractedSeedDir, dir, { recursive: true });
349
- await rm(fetchSeedResult.extractedSeedDir);
350
- }
351
- };