@genesislcap/build-kit 14.162.4 → 14.162.5
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/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/prompts.js +2 -2
- package/dist/utils/seed.commands.d.ts +19 -0
- package/dist/utils/seed.commands.d.ts.map +1 -0
- package/dist/utils/seed.commands.js +58 -0
- package/dist/utils/seed.processing.d.ts.map +1 -1
- package/dist/utils/seed.processing.js +4 -3
- package/package.json +3 -3
- package/src/index.ts +0 -2
- package/src/types/build-context.ts +0 -57
- package/src/types/config.ts +0 -269
- package/src/types/index.ts +0 -3
- package/src/types/pwa.ts +0 -67
- package/src/utils/archive.ts +0 -18
- package/src/utils/args.ts +0 -7
- package/src/utils/build-context.ts +0 -42
- package/src/utils/child-process.ts +0 -115
- package/src/utils/config.ts +0 -45
- package/src/utils/console.ts +0 -1
- package/src/utils/env.ts +0 -71
- package/src/utils/federation.ts +0 -40
- package/src/utils/fs.ts +0 -53
- package/src/utils/handlebars.ts +0 -61
- package/src/utils/https.ts +0 -29
- package/src/utils/index.ts +0 -21
- package/src/utils/json.ts +0 -12
- package/src/utils/npm.ts +0 -155
- package/src/utils/object.ts +0 -21
- package/src/utils/prompts.ts +0 -160
- package/src/utils/proxy.ts +0 -139
- package/src/utils/seed.fetching.ts +0 -257
- package/src/utils/seed.meta.ts +0 -34
- package/src/utils/seed.processing.ts +0 -100
- package/src/utils/seed.setup.ts +0 -101
- package/src/utils/time.ts +0 -1
- package/test/utils/args.test.ts +0 -17
- package/test/utils/build-context.test.ts +0 -68
- package/test/utils/env.test.ts +0 -212
- package/test/utils/handlebars.test.ts +0 -277
- package/test/utils/https.test.ts +0 -14
- package/test/utils/proxy.test.ts +0 -96
- package/test/utils/seed.fetching.test.ts +0 -145
- package/test/utils/seed.meta.test.ts +0 -33
- package/tsconfig.json +0 -18
package/src/utils/prompts.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { basename } from 'node:path';
|
|
2
|
-
import consola from 'consola';
|
|
3
|
-
import inquirer from 'inquirer';
|
|
4
|
-
import type { Question } from 'inquirer';
|
|
5
|
-
import { bold } from './console';
|
|
6
|
-
|
|
7
|
-
export const runPrompts = async (prompts: any, prevAns: any = {}) => prompts(inquirer, prevAns);
|
|
8
|
-
|
|
9
|
-
export const validateSeedData = (data, validators) => {
|
|
10
|
-
const errors = [];
|
|
11
|
-
|
|
12
|
-
Object.keys(data).forEach((key) => {
|
|
13
|
-
const value = data[key];
|
|
14
|
-
if (typeof value === 'undefined') {
|
|
15
|
-
errors.push({ message: `${key} is undefined` });
|
|
16
|
-
} else if (value === '') {
|
|
17
|
-
errors.push({ message: `${key} is empty` });
|
|
18
|
-
} else if (validators[key]) {
|
|
19
|
-
const isValid = validators[key](value);
|
|
20
|
-
if (isValid !== true) {
|
|
21
|
-
errors.push({ message: `${key} is invalid: ${bold(value)} ${isValid}` });
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return errors;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const getPromptInputs = async (prompts): Promise<Question[]> => {
|
|
30
|
-
// disable any prompt messages
|
|
31
|
-
const _log = console.log;
|
|
32
|
-
console.log = () => {};
|
|
33
|
-
|
|
34
|
-
const inputs = [];
|
|
35
|
-
|
|
36
|
-
const mockInquirer = {
|
|
37
|
-
prompt: async (promptInputs) => {
|
|
38
|
-
inputs.push(...promptInputs);
|
|
39
|
-
return {};
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
await prompts(mockInquirer);
|
|
44
|
-
|
|
45
|
-
// re-enable prompt messages
|
|
46
|
-
console.log = _log;
|
|
47
|
-
|
|
48
|
-
return inputs;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const getPromptDefaults = async (prompts) => {
|
|
52
|
-
const inputs = await getPromptInputs(prompts);
|
|
53
|
-
|
|
54
|
-
const defaults = inputs.reduce((acc, value) => {
|
|
55
|
-
let addDefault;
|
|
56
|
-
if (typeof value.when === 'function') {
|
|
57
|
-
addDefault = value.when(acc);
|
|
58
|
-
} else if (typeof value.when === 'undefined') {
|
|
59
|
-
addDefault = true;
|
|
60
|
-
} else {
|
|
61
|
-
addDefault = value.when;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (addDefault) {
|
|
65
|
-
acc[value.name] = value.default;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return acc;
|
|
69
|
-
}, {});
|
|
70
|
-
|
|
71
|
-
return defaults;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export const getPromptValidators = async (prompts) => {
|
|
75
|
-
const inputs = await getPromptInputs(prompts);
|
|
76
|
-
|
|
77
|
-
const validators = inputs.reduce((acc, value) => {
|
|
78
|
-
acc[value.name] = value.validate;
|
|
79
|
-
return acc;
|
|
80
|
-
}, {});
|
|
81
|
-
|
|
82
|
-
return validators;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// process CLI prompt params
|
|
86
|
-
const getCLIParams = (
|
|
87
|
-
persistedAnswers,
|
|
88
|
-
params,
|
|
89
|
-
defaults,
|
|
90
|
-
dir,
|
|
91
|
-
subdir,
|
|
92
|
-
skipOptionalPrompts,
|
|
93
|
-
seedMeta,
|
|
94
|
-
details,
|
|
95
|
-
validate,
|
|
96
|
-
) => {
|
|
97
|
-
const base = skipOptionalPrompts ? defaults : {};
|
|
98
|
-
|
|
99
|
-
const cliParams = {
|
|
100
|
-
...base,
|
|
101
|
-
...persistedAnswers,
|
|
102
|
-
...params,
|
|
103
|
-
appName: basename(dir),
|
|
104
|
-
pkgName: basename(dir),
|
|
105
|
-
directory: basename(dir),
|
|
106
|
-
appSeed: {
|
|
107
|
-
type: seedMeta.local ? 'local' : 'remote',
|
|
108
|
-
name: seedMeta.seed,
|
|
109
|
-
description: details.description,
|
|
110
|
-
version: details.version,
|
|
111
|
-
repo: seedMeta.repo,
|
|
112
|
-
artifact: seedMeta.artifact,
|
|
113
|
-
ref: seedMeta.ref,
|
|
114
|
-
subdir: seedMeta.subdir,
|
|
115
|
-
date: new Date(),
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
const validationErrors = validate(cliParams);
|
|
119
|
-
if (validationErrors.length) {
|
|
120
|
-
consola.error('Validation errors detected:');
|
|
121
|
-
validationErrors.forEach((error) => consola.log(` * ${error.message}`));
|
|
122
|
-
process.exit(1);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return cliParams;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// get combined prompt answers (CLI params / defaults / user interaction)
|
|
129
|
-
export const getData = async (
|
|
130
|
-
persistedAnswers,
|
|
131
|
-
prompts,
|
|
132
|
-
details,
|
|
133
|
-
defaults,
|
|
134
|
-
validate,
|
|
135
|
-
params,
|
|
136
|
-
dir,
|
|
137
|
-
skipOptionalPrompts,
|
|
138
|
-
seedMeta,
|
|
139
|
-
) => {
|
|
140
|
-
// process CLI params
|
|
141
|
-
const cliParams = getCLIParams(
|
|
142
|
-
persistedAnswers,
|
|
143
|
-
params,
|
|
144
|
-
defaults,
|
|
145
|
-
dir,
|
|
146
|
-
seedMeta.subdir,
|
|
147
|
-
skipOptionalPrompts,
|
|
148
|
-
seedMeta,
|
|
149
|
-
details,
|
|
150
|
-
validate,
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
const data = await runPrompts(prompts, cliParams);
|
|
154
|
-
|
|
155
|
-
const combined = {
|
|
156
|
-
...cliParams,
|
|
157
|
-
...data,
|
|
158
|
-
};
|
|
159
|
-
return combined;
|
|
160
|
-
};
|
package/src/utils/proxy.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import consola from 'consola';
|
|
2
|
-
import type { ServerOptions } from 'http-proxy';
|
|
3
|
-
import portfinderSync from 'portfinder-sync';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @public
|
|
7
|
-
*/
|
|
8
|
-
export const getPort = (packageJson): number =>
|
|
9
|
-
portfinderSync.getPort(packageJson.config?.PORT || process.env.PORT || 9000);
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @public
|
|
13
|
-
*/
|
|
14
|
-
export const convertWsEndpointToHTTP = (endpoint = '', socketExt = '') => {
|
|
15
|
-
const protocolUpdate = endpoint.replace(/^ws(s)?:\/\//, 'http$1://');
|
|
16
|
-
return socketExt ? protocolUpdate.replace(`/${socketExt}`, '') : protocolUpdate;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Config to create a development proxy for a specific path.
|
|
21
|
-
*
|
|
22
|
-
* @public
|
|
23
|
-
*/
|
|
24
|
-
export type DevProxyConfig = {
|
|
25
|
-
target?: string;
|
|
26
|
-
path?: string;
|
|
27
|
-
options?: ServerOptions;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Config to create development proxies for an array of paths.
|
|
32
|
-
*
|
|
33
|
-
* @public
|
|
34
|
-
*/
|
|
35
|
-
export type DevProxiesConfig = Omit<DevProxyConfig, 'path'> & {
|
|
36
|
-
paths?: string[];
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Object containing entries for each proxy keyed by path.
|
|
41
|
-
*
|
|
42
|
-
* @public
|
|
43
|
-
*/
|
|
44
|
-
export type DevProxies = Record<string, ServerOptions> & {};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Create development proxy for a specific path.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```ts
|
|
51
|
-
* const proxy = createDevProxy({ path: '/sm', target: process.env.API_HOST, options: {...} });
|
|
52
|
-
* ```
|
|
53
|
-
*
|
|
54
|
-
* @remarks
|
|
55
|
-
* Applicable when running in dev mode and a valid target and path is set.
|
|
56
|
-
*
|
|
57
|
-
* @privateRemarks
|
|
58
|
-
* It is important to guard for the case where neither target nor path is set by returning undefined.
|
|
59
|
-
* Proxies with empty string targets will cause blow ups in vite, whereas webpack seems to tolerate them.
|
|
60
|
-
*
|
|
61
|
-
* @param config - A {@link DevProxyConfig}.
|
|
62
|
-
* @returns A {@link DevProxies} object or undefined.
|
|
63
|
-
*
|
|
64
|
-
* @public
|
|
65
|
-
*/
|
|
66
|
-
export const createDevProxy = (config: DevProxyConfig): DevProxies | undefined => {
|
|
67
|
-
if (!config.target || !config.path) {
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
const { options, path, target } = config;
|
|
71
|
-
return {
|
|
72
|
-
[path]: {
|
|
73
|
-
target,
|
|
74
|
-
secure: false,
|
|
75
|
-
changeOrigin: true,
|
|
76
|
-
cookieDomainRewrite: 'localhost',
|
|
77
|
-
ws: true,
|
|
78
|
-
...(options ?? {}),
|
|
79
|
-
headers: {
|
|
80
|
-
origin: target,
|
|
81
|
-
...(options?.headers ?? {}),
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Create development proxies for an array of paths.
|
|
89
|
-
*
|
|
90
|
-
* @example Create default development proxies
|
|
91
|
-
* ```ts
|
|
92
|
-
* const proxy = createDevProxies();
|
|
93
|
-
* ```
|
|
94
|
-
*
|
|
95
|
-
* @example Create custom development proxies
|
|
96
|
-
* ```ts
|
|
97
|
-
* const proxy = createDevProxies({ paths: ['/foo', '/bar'], target: 'http://mydomain.com' });
|
|
98
|
-
* ```
|
|
99
|
-
*
|
|
100
|
-
* @remarks
|
|
101
|
-
* `process.env.API_HOST` will be used as the target if `config.target` is not set. Undefined will be returned if
|
|
102
|
-
* neither are available.
|
|
103
|
-
*
|
|
104
|
-
* @privateRemarks
|
|
105
|
-
* It is important to guard for the case where neither target nor API_HOST are set by returning undefined.
|
|
106
|
-
* Proxies with empty string targets will cause blow ups in vite, whereas webpack seems to tolerate them.
|
|
107
|
-
*
|
|
108
|
-
* @param config - An optional {@link DevProxiesConfig}.
|
|
109
|
-
* @returns A {@link DevProxies} object or undefined.
|
|
110
|
-
*
|
|
111
|
-
* @public
|
|
112
|
-
*/
|
|
113
|
-
export const createDevProxies = (config: DevProxiesConfig = {}): DevProxies | undefined => {
|
|
114
|
-
if (!config.target && !process.env.API_HOST) {
|
|
115
|
-
return undefined;
|
|
116
|
-
}
|
|
117
|
-
const socketExt = process.env.SOCKET_EXT || 'gwf';
|
|
118
|
-
const paths = Array.isArray(config.paths) ? config.paths : ['/sm', '/sso', `/${socketExt}`];
|
|
119
|
-
const target = config.target ?? convertWsEndpointToHTTP(process.env.API_HOST, socketExt);
|
|
120
|
-
const defaultConfig: DevProxyConfig = {
|
|
121
|
-
...config,
|
|
122
|
-
target,
|
|
123
|
-
};
|
|
124
|
-
const proxies = paths.reduce(
|
|
125
|
-
(prev, curr) => ({
|
|
126
|
-
...prev,
|
|
127
|
-
...createDevProxy({
|
|
128
|
-
...defaultConfig,
|
|
129
|
-
path: curr,
|
|
130
|
-
}),
|
|
131
|
-
}),
|
|
132
|
-
{},
|
|
133
|
-
);
|
|
134
|
-
if (Object.keys(proxies).length) {
|
|
135
|
-
consola.info('Dev Proxies:');
|
|
136
|
-
console.table(proxies);
|
|
137
|
-
}
|
|
138
|
-
return proxies;
|
|
139
|
-
};
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
import { cpSync, existsSync, mkdirSync } from 'node:fs';
|
|
2
|
-
import { relative, sep } from 'node:path';
|
|
3
|
-
import { consola } from 'consola';
|
|
4
|
-
import getNpmTarballUrl from 'get-npm-tarball-url';
|
|
5
|
-
import { downloadTemplate } from 'giget';
|
|
6
|
-
import type { PackageJson } from 'pkg-types';
|
|
7
|
-
import { downloadTarball } from './archive';
|
|
8
|
-
import { bold } from './console';
|
|
9
|
-
import { rm } from './fs';
|
|
10
|
-
import { getLatestVersion } from './npm';
|
|
11
|
-
import { loadGenxModule } from './seed.meta';
|
|
12
|
-
import { removeExclusions } from './seed.processing';
|
|
13
|
-
|
|
14
|
-
export type LocalFetchResult = {
|
|
15
|
-
local: boolean;
|
|
16
|
-
genxDir: string;
|
|
17
|
-
seed: string;
|
|
18
|
-
subdir: string; // seed subdir within seed repo (if set)
|
|
19
|
-
pkg: PackageJson;
|
|
20
|
-
dir: string; // app directory e.g. myapp
|
|
21
|
-
extractedSeedDir: string; // directory to extract seed: for init operation same as dir, for add operaion dir/.genx/tmp
|
|
22
|
-
extractedSeedGenxDir: string;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export type RemoteGitFetchResult = {
|
|
26
|
-
repo: string;
|
|
27
|
-
ref: string;
|
|
28
|
-
id: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type RemoteNPMFetchResult = {
|
|
32
|
-
artifact: string;
|
|
33
|
-
ref: string;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type RemoteFetchResult = RemoteGitFetchResult | RemoteNPMFetchResult;
|
|
37
|
-
|
|
38
|
-
export type FetchResult = LocalFetchResult | (LocalFetchResult & RemoteFetchResult);
|
|
39
|
-
|
|
40
|
-
export const resolveGitSeed = (
|
|
41
|
-
seed = '',
|
|
42
|
-
ref = 'main',
|
|
43
|
-
subdir = '',
|
|
44
|
-
provider = 'gh',
|
|
45
|
-
): RemoteGitFetchResult => {
|
|
46
|
-
const parts = seed.split('/');
|
|
47
|
-
const repo = parts.pop() || 'blank-app-seed';
|
|
48
|
-
const user = parts.pop() || 'genesiscommunitysuccess';
|
|
49
|
-
const dir = subdir ? `/${subdir}` : '';
|
|
50
|
-
return {
|
|
51
|
-
repo: `${user}/${repo}`,
|
|
52
|
-
ref,
|
|
53
|
-
// Giget-compatible template ID
|
|
54
|
-
id: `${provider}:${user}/${repo}${dir}#${ref}`,
|
|
55
|
-
};
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export const resolveNPMSeed = (
|
|
59
|
-
seed = '',
|
|
60
|
-
ref = 'latest',
|
|
61
|
-
useDefaultNPMScope = true,
|
|
62
|
-
): RemoteNPMFetchResult => {
|
|
63
|
-
const parts = seed.split('/');
|
|
64
|
-
const moduleName = parts.pop() || 'blank-app-seed';
|
|
65
|
-
const scope = parts.pop() || (useDefaultNPMScope ? 'genesislcap' : '');
|
|
66
|
-
const scopeFormatted = scope ? `@${scope}/` : '';
|
|
67
|
-
const artifact = `${scopeFormatted}${moduleName}`;
|
|
68
|
-
return {
|
|
69
|
-
artifact,
|
|
70
|
-
ref,
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export type SeedDirs = {
|
|
75
|
-
isLocalSeed: boolean;
|
|
76
|
-
dir: string;
|
|
77
|
-
subdir: string;
|
|
78
|
-
localPath: string;
|
|
79
|
-
genxDir: string;
|
|
80
|
-
extractedSeedDir: string;
|
|
81
|
-
extractedSeedGenxDir: string;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const getSeedDirs = (
|
|
85
|
-
seed: string,
|
|
86
|
-
dir: string,
|
|
87
|
-
subdir: string,
|
|
88
|
-
isInit: boolean,
|
|
89
|
-
remote: boolean,
|
|
90
|
-
): SeedDirs => {
|
|
91
|
-
const GENX_DIR = '/.genx';
|
|
92
|
-
const TMP_DIR = '/tmp';
|
|
93
|
-
const localPath = subdir ? `${seed}/${subdir}` : seed;
|
|
94
|
-
const isLocalSeed = !remote && existsSync(localPath);
|
|
95
|
-
const genxDir = relative(process.cwd(), `${dir}${GENX_DIR}`);
|
|
96
|
-
const extractedSeedDir = isInit ? dir : relative(process.cwd(), `${dir}${GENX_DIR}${TMP_DIR}`);
|
|
97
|
-
const extractedSeedGenxDir = isInit
|
|
98
|
-
? genxDir
|
|
99
|
-
: relative(process.cwd(), `${extractedSeedDir}${GENX_DIR}`);
|
|
100
|
-
return {
|
|
101
|
-
localPath,
|
|
102
|
-
dir,
|
|
103
|
-
subdir,
|
|
104
|
-
isLocalSeed,
|
|
105
|
-
genxDir,
|
|
106
|
-
extractedSeedDir,
|
|
107
|
-
extractedSeedGenxDir,
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const copyLocalSeed = (dirs: SeedDirs, ref: string, start: number): LocalFetchResult => {
|
|
112
|
-
const { dir, subdir, localPath, extractedSeedDir, genxDir, extractedSeedGenxDir } = dirs;
|
|
113
|
-
consola.info(`Copying local seed ${bold(localPath)}`);
|
|
114
|
-
try {
|
|
115
|
-
if (ref) {
|
|
116
|
-
consola.warn(`${bold('ref')} has no effect when used with a local seed`);
|
|
117
|
-
}
|
|
118
|
-
cpSync(localPath, extractedSeedDir, { recursive: true });
|
|
119
|
-
consola.success(`Seed copied in ${Date.now() - start}ms`);
|
|
120
|
-
return {
|
|
121
|
-
local: true,
|
|
122
|
-
genxDir,
|
|
123
|
-
seed: localPath,
|
|
124
|
-
subdir,
|
|
125
|
-
pkg: loadGenxModule(extractedSeedGenxDir),
|
|
126
|
-
dir,
|
|
127
|
-
extractedSeedDir,
|
|
128
|
-
extractedSeedGenxDir,
|
|
129
|
-
};
|
|
130
|
-
} catch (e) {
|
|
131
|
-
consola.error(`Error copying ${localPath} to ${bold(dir)}`, e);
|
|
132
|
-
process.exit(1);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const fetchNPMSeed = async (
|
|
137
|
-
seed: string,
|
|
138
|
-
ref: string,
|
|
139
|
-
dirs: SeedDirs,
|
|
140
|
-
useDefaultNPMScope: boolean,
|
|
141
|
-
start: number,
|
|
142
|
-
) => {
|
|
143
|
-
let success = true;
|
|
144
|
-
const data = resolveNPMSeed(seed, ref, useDefaultNPMScope);
|
|
145
|
-
|
|
146
|
-
consola.info(
|
|
147
|
-
`Downloading NPM seed ${bold(data.artifact)} (dist tag ${bold(data.ref)}, subdir: ${bold(
|
|
148
|
-
dirs.subdir || 'N/A',
|
|
149
|
-
)}) to ${bold(dirs.dir)} directory...`,
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
const version = getLatestVersion(data.artifact, data.ref, false);
|
|
154
|
-
const url = getNpmTarballUrl(data.artifact, version);
|
|
155
|
-
// NPM tarballs contains top-level directory called package
|
|
156
|
-
const path = dirs.subdir ? `${sep}package/${dirs.subdir}` : `${sep}package`;
|
|
157
|
-
await downloadTarball(url, dirs.extractedSeedDir, path).catch((err) => {
|
|
158
|
-
consola.warn('Error downloading module', err);
|
|
159
|
-
success = false;
|
|
160
|
-
});
|
|
161
|
-
} catch (err) {
|
|
162
|
-
success = false;
|
|
163
|
-
consola.warn('Error fetching version information from the registry');
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// If NPM download successful return result, otherwise fall back to Git download
|
|
167
|
-
if (success) {
|
|
168
|
-
consola.success(`Seed downloaded in ${Date.now() - start}ms`);
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
local: false,
|
|
172
|
-
genxDir: dirs.genxDir,
|
|
173
|
-
seed,
|
|
174
|
-
subdir: dirs.subdir,
|
|
175
|
-
pkg: loadGenxModule(dirs.extractedSeedGenxDir),
|
|
176
|
-
dir: dirs.dir,
|
|
177
|
-
extractedSeedDir: dirs.extractedSeedDir,
|
|
178
|
-
extractedSeedGenxDir: dirs.extractedSeedGenxDir,
|
|
179
|
-
...data,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const fetchGitSeed = async (seed: string, ref: string, dirs: SeedDirs, start: number) => {
|
|
185
|
-
const data = resolveGitSeed(seed, ref, dirs.subdir);
|
|
186
|
-
consola.info(
|
|
187
|
-
`Downloading Git seed ${bold(data.repo)} (Ref ${bold(data.ref)}, subdir: ${bold(
|
|
188
|
-
dirs.subdir || 'N/A',
|
|
189
|
-
)}) to ${bold(dirs.dir)} directory...`,
|
|
190
|
-
);
|
|
191
|
-
try {
|
|
192
|
-
await downloadTemplate(data.id, {
|
|
193
|
-
dir: dirs.extractedSeedDir, // destination directory to clone to
|
|
194
|
-
// auth?: string; // custom Authorization token to use for downloading template
|
|
195
|
-
registry: false, // disable built-in Giget registry
|
|
196
|
-
});
|
|
197
|
-
consola.success(`Seed downloaded in ${Date.now() - start}ms`);
|
|
198
|
-
return {
|
|
199
|
-
local: false,
|
|
200
|
-
genxDir: dirs.genxDir,
|
|
201
|
-
seed,
|
|
202
|
-
subdir: dirs.subdir,
|
|
203
|
-
pkg: loadGenxModule(dirs.extractedSeedGenxDir),
|
|
204
|
-
dir: dirs.dir,
|
|
205
|
-
extractedSeedDir: dirs.extractedSeedDir,
|
|
206
|
-
extractedSeedGenxDir: dirs.extractedSeedGenxDir,
|
|
207
|
-
...data,
|
|
208
|
-
};
|
|
209
|
-
} catch (err) {
|
|
210
|
-
const error = process.env.DEBUG ? err : err.message;
|
|
211
|
-
consola.error(error);
|
|
212
|
-
process.exit(1);
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
// download remote or copy local seed
|
|
217
|
-
export const fetchSeed = async (
|
|
218
|
-
seed: string,
|
|
219
|
-
dir: string,
|
|
220
|
-
remote: boolean,
|
|
221
|
-
ref: string,
|
|
222
|
-
insecure: boolean,
|
|
223
|
-
subdir: string,
|
|
224
|
-
isInit: boolean,
|
|
225
|
-
lookupInNPM: boolean,
|
|
226
|
-
useDefaultNPMScope: boolean,
|
|
227
|
-
): Promise<FetchResult> => {
|
|
228
|
-
// disable SSL cert verification
|
|
229
|
-
if (insecure) {
|
|
230
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const start = Date.now();
|
|
234
|
-
const dirs = getSeedDirs(seed, dir, subdir, isInit, remote);
|
|
235
|
-
|
|
236
|
-
if (!isInit) {
|
|
237
|
-
await rm(dirs.extractedSeedDir);
|
|
238
|
-
mkdirSync(dirs.extractedSeedDir);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
let result: FetchResult;
|
|
242
|
-
if (dirs.isLocalSeed) {
|
|
243
|
-
result = copyLocalSeed(dirs, ref, start);
|
|
244
|
-
} else {
|
|
245
|
-
if (lookupInNPM) {
|
|
246
|
-
result = await fetchNPMSeed(seed, ref, dirs, useDefaultNPMScope, start);
|
|
247
|
-
}
|
|
248
|
-
// if NPM lookup disabled or if it's enabled & failed, fall back to Git
|
|
249
|
-
if (!lookupInNPM || !result) {
|
|
250
|
-
result = await fetchGitSeed(seed, ref, dirs, start);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
await removeExclusions(dirs.extractedSeedDir, result.pkg.genxSeedConfig?.exclude);
|
|
255
|
-
|
|
256
|
-
return result;
|
|
257
|
-
};
|
package/src/utils/seed.meta.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
import { consola } from 'consola';
|
|
3
|
-
import { getPromptDefaults, getPromptValidators, validateSeedData } from './prompts';
|
|
4
|
-
|
|
5
|
-
// load seed details including prompt question defaults and validators
|
|
6
|
-
export const loadSeed = async (dir) => {
|
|
7
|
-
const GENX_RC = '.genxrc.js';
|
|
8
|
-
const genxConfigPath = resolve(dir, GENX_RC);
|
|
9
|
-
const { prompts, configure, details } = require(genxConfigPath);
|
|
10
|
-
|
|
11
|
-
const defaults = await getPromptDefaults(prompts());
|
|
12
|
-
const validators = await getPromptValidators(prompts());
|
|
13
|
-
const validate = (data) => validateSeedData(data, validators);
|
|
14
|
-
return {
|
|
15
|
-
prompts: prompts(),
|
|
16
|
-
configure: configure(),
|
|
17
|
-
details: details(),
|
|
18
|
-
defaults,
|
|
19
|
-
validators,
|
|
20
|
-
validate,
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export const loadGenxModule = (genxDir: string, module = 'package.json', warnIfMissing = true) => {
|
|
25
|
-
const path = resolve(genxDir, module);
|
|
26
|
-
try {
|
|
27
|
-
return require(path);
|
|
28
|
-
} catch (e) {
|
|
29
|
-
if (warnIfMissing) {
|
|
30
|
-
consola.warn(`Could not load ${module} from ${genxDir}`);
|
|
31
|
-
}
|
|
32
|
-
return {};
|
|
33
|
-
}
|
|
34
|
-
};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { existsSync, renameSync } from 'node:fs';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
import { consola } from 'consola';
|
|
4
|
-
import { bold } from './console';
|
|
5
|
-
import { listAllFiles, rm } from './fs';
|
|
6
|
-
import type { fsEntry } from './fs';
|
|
7
|
-
import { render, renderFile } from './handlebars';
|
|
8
|
-
import { writeJSON } from './json';
|
|
9
|
-
|
|
10
|
-
export const PROMPT_DATA_FILE = 'answers.json';
|
|
11
|
-
|
|
12
|
-
export const removeExclusions = async (dir, exclusions: string[]) => {
|
|
13
|
-
try {
|
|
14
|
-
const exclude = (exclusions ?? []).map((x) => resolve(dir, x));
|
|
15
|
-
await Promise.all(
|
|
16
|
-
exclude.map(async (exclusion) => {
|
|
17
|
-
if (existsSync(exclusion)) {
|
|
18
|
-
await rm(exclusion);
|
|
19
|
-
consola.debug(`Excluded: ${exclusion}`);
|
|
20
|
-
} else {
|
|
21
|
-
consola.debug(`Ignored invalid exclusion: ${exclusion}`);
|
|
22
|
-
}
|
|
23
|
-
}),
|
|
24
|
-
);
|
|
25
|
-
} catch (err) {
|
|
26
|
-
const error = process.env.DEBUG ? err : err.message;
|
|
27
|
-
consola.error(error);
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const processItem = (
|
|
33
|
-
{ base, dir: itemDir, path, isDir, ext, stats }: fsEntry,
|
|
34
|
-
data,
|
|
35
|
-
renamingEnabled: boolean,
|
|
36
|
-
interpolationEnabled: boolean,
|
|
37
|
-
interpolationWhitelist: string[],
|
|
38
|
-
) => {
|
|
39
|
-
const baseNew = render(base, data);
|
|
40
|
-
const needsRenaming = renamingEnabled && baseNew !== base;
|
|
41
|
-
const pathNew = needsRenaming ? resolve(itemDir, baseNew) : path;
|
|
42
|
-
|
|
43
|
-
if (needsRenaming) {
|
|
44
|
-
try {
|
|
45
|
-
renameSync(resolve(itemDir, base), resolve(itemDir, baseNew));
|
|
46
|
-
consola.debug(`Renamed ${bold(base)} to ${bold(baseNew)}`);
|
|
47
|
-
} catch (e) {
|
|
48
|
-
consola.error(`Error renaming ${bold(base)} to ${bold(baseNew)}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Handlebars rendering
|
|
53
|
-
if (interpolationEnabled && !isDir && interpolationWhitelist.some((i) => baseNew.includes(i))) {
|
|
54
|
-
try {
|
|
55
|
-
renderFile(pathNew, data, pathNew);
|
|
56
|
-
consola.debug(`Interpolated variables in ${pathNew}`);
|
|
57
|
-
} catch (e) {
|
|
58
|
-
consola.error(`Error interpolating variables in ${pathNew}`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return { isDir, ext, dir: itemDir, base: baseNew, path: pathNew, stats };
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const processOptions = (fetchSeedResult, dir, data, isInit, persistedAnswers) => {
|
|
66
|
-
const options = fetchSeedResult.pkg?.genxSeedConfig || {};
|
|
67
|
-
consola.debug('Seed options', JSON.stringify(options));
|
|
68
|
-
|
|
69
|
-
if (options.processFiles) {
|
|
70
|
-
const ignoreDirs = options.processFiles?.exclude || [
|
|
71
|
-
'.git',
|
|
72
|
-
'.genx',
|
|
73
|
-
'.github',
|
|
74
|
-
'node_modules',
|
|
75
|
-
'.gradle',
|
|
76
|
-
'gradle',
|
|
77
|
-
];
|
|
78
|
-
|
|
79
|
-
const filter = (entry: fsEntry) => !ignoreDirs.includes(entry.base);
|
|
80
|
-
const mapper = (entry: fsEntry) =>
|
|
81
|
-
processItem(
|
|
82
|
-
entry,
|
|
83
|
-
data,
|
|
84
|
-
!!options.processFiles?.rename,
|
|
85
|
-
!!options.processFiles?.interpolateVariables?.enabled,
|
|
86
|
-
options.processFiles?.interpolateVariables?.include,
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
listAllFiles(dir, filter, mapper);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (options.persistAnswers) {
|
|
93
|
-
const jsonPath = resolve(fetchSeedResult.genxDir, PROMPT_DATA_FILE);
|
|
94
|
-
const additions = persistedAnswers.additions || [];
|
|
95
|
-
const json = isInit
|
|
96
|
-
? data
|
|
97
|
-
: { ...data, appSeed: persistedAnswers.appSeed, additions: [...additions, data.appSeed] };
|
|
98
|
-
writeJSON(jsonPath, json);
|
|
99
|
-
}
|
|
100
|
-
};
|