@patternfly/patternfly-cli 1.0.2
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/.github/workflows/build.yml +21 -0
- package/.github/workflows/lint.yml +24 -0
- package/.github/workflows/release.yml +42 -0
- package/.github/workflows/test.yml +24 -0
- package/.releaserc.json +14 -0
- package/LICENSE +21 -0
- package/README.md +110 -0
- package/__mocks__/execa.js +5 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +272 -0
- package/dist/cli.js.map +1 -0
- package/dist/github.d.ts +33 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +180 -0
- package/dist/github.js.map +1 -0
- package/dist/load.d.ts +6 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +40 -0
- package/dist/load.js.map +1 -0
- package/dist/save.d.ts +6 -0
- package/dist/save.d.ts.map +1 -0
- package/dist/save.js +97 -0
- package/dist/save.js.map +1 -0
- package/dist/template-loader.d.ts +6 -0
- package/dist/template-loader.d.ts.map +1 -0
- package/dist/template-loader.js +83 -0
- package/dist/template-loader.js.map +1 -0
- package/dist/templates.d.ts +17 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +33 -0
- package/dist/templates.js.map +1 -0
- package/eslint.config.js +19 -0
- package/package.json +80 -0
- package/src/__tests__/cli.test.ts +171 -0
- package/src/__tests__/fixtures/invalid-template-bad-options.json +1 -0
- package/src/__tests__/fixtures/invalid-template-missing-name.json +1 -0
- package/src/__tests__/fixtures/not-array.json +1 -0
- package/src/__tests__/fixtures/valid-templates.json +14 -0
- package/src/__tests__/github.test.ts +214 -0
- package/src/__tests__/load.test.ts +106 -0
- package/src/__tests__/save.test.ts +272 -0
- package/src/cli.ts +307 -0
- package/src/github.ts +193 -0
- package/src/load.ts +38 -0
- package/src/save.ts +103 -0
- package/src/template-loader.ts +84 -0
- package/src/templates.ts +48 -0
- package/tsconfig.json +50 -0
package/dist/github.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
/**
|
|
6
|
+
* Sanitize a package name for use as a GitHub repository name (alphanumeric, hyphens, underscores)
|
|
7
|
+
*/
|
|
8
|
+
export function sanitizeRepoName(name) {
|
|
9
|
+
// Strip npm scope if present (e.g. @scope/package -> package)
|
|
10
|
+
const withoutScope = name.startsWith('@') ? name.slice(name.indexOf('/') + 1) : name;
|
|
11
|
+
// GitHub allows A-Za-z0-9_.- ; replace invalid chars with hyphen and collapse multiple hyphens
|
|
12
|
+
return withoutScope
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
.replace(/[^a-z0-9_.-]/g, '-')
|
|
15
|
+
.replace(/-+/g, '-')
|
|
16
|
+
.replace(/^-|-$/g, '') || 'my-project';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if GitHub CLI is installed and the user is authenticated
|
|
20
|
+
*/
|
|
21
|
+
export async function checkGhAuth() {
|
|
22
|
+
try {
|
|
23
|
+
await execa('gh', ['auth', 'status'], { reject: true });
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return { ok: false, message: 'GitHub CLI (gh) is not installed or you are not logged in. Install it from https://cli.github.com/ and run "gh auth login".' };
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const { stdout } = await execa('gh', ['api', 'user', '--jq', '.login'], { encoding: 'utf8' });
|
|
30
|
+
const username = stdout?.trim();
|
|
31
|
+
if (!username) {
|
|
32
|
+
return { ok: false, message: 'Could not determine your GitHub username.' };
|
|
33
|
+
}
|
|
34
|
+
return { ok: true, username };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return { ok: false, message: 'Could not fetch your GitHub username. Ensure "gh auth login" has been run.' };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if a repository already exists for the given owner and repo name
|
|
42
|
+
*/
|
|
43
|
+
export async function repoExists(owner, repoName) {
|
|
44
|
+
try {
|
|
45
|
+
await execa('gh', ['api', `repos/${owner}/${repoName}`], { reject: true });
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Ensure the project has at least one commit (for push). Idempotent.
|
|
54
|
+
*/
|
|
55
|
+
async function ensureInitialCommit(projectPath) {
|
|
56
|
+
try {
|
|
57
|
+
await execa('git', ['rev-parse', '--verify', 'HEAD'], {
|
|
58
|
+
cwd: projectPath,
|
|
59
|
+
reject: true,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
await execa('git', ['add', '.'], { stdio: 'inherit', cwd: projectPath });
|
|
64
|
+
await execa('git', ['commit', '-m', 'Initial commit'], {
|
|
65
|
+
stdio: 'inherit',
|
|
66
|
+
cwd: projectPath,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Create a new GitHub repository and return its URL. Does not push.
|
|
72
|
+
*/
|
|
73
|
+
export async function createRepo(options) {
|
|
74
|
+
const gitDir = path.join(options.projectPath, '.git');
|
|
75
|
+
if (!(await fs.pathExists(gitDir))) {
|
|
76
|
+
await execa('git', ['init'], { stdio: 'inherit', cwd: options.projectPath });
|
|
77
|
+
}
|
|
78
|
+
await ensureInitialCommit(options.projectPath);
|
|
79
|
+
const args = [
|
|
80
|
+
'repo',
|
|
81
|
+
'create',
|
|
82
|
+
options.repoName,
|
|
83
|
+
'--public',
|
|
84
|
+
`--source=${options.projectPath}`,
|
|
85
|
+
'--remote=origin',
|
|
86
|
+
'--push',
|
|
87
|
+
];
|
|
88
|
+
if (options.description) {
|
|
89
|
+
args.push(`--description=${options.description}`);
|
|
90
|
+
}
|
|
91
|
+
await execa('gh', args, { stdio: 'inherit', cwd: options.projectPath });
|
|
92
|
+
return `https://github.com/${options.username}/${options.repoName}.git`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Interactive flow: prompt to create a GitHub repo under the current user, then create it and set origin.
|
|
96
|
+
* Returns true if a repo was created (or already had origin), false if skipped or failed.
|
|
97
|
+
*/
|
|
98
|
+
export async function offerAndCreateGitHubRepo(projectPath) {
|
|
99
|
+
const pkgJsonPath = path.join(projectPath, 'package.json');
|
|
100
|
+
if (!(await fs.pathExists(pkgJsonPath))) {
|
|
101
|
+
console.log('\nℹ️ No package.json found; skipping GitHub repository creation.\n');
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const { createGitHub } = await inquirer.prompt([
|
|
105
|
+
{
|
|
106
|
+
type: 'confirm',
|
|
107
|
+
name: 'createGitHub',
|
|
108
|
+
message: 'Would you like to create a GitHub repository for this project?',
|
|
109
|
+
default: false,
|
|
110
|
+
},
|
|
111
|
+
]);
|
|
112
|
+
if (!createGitHub)
|
|
113
|
+
return false;
|
|
114
|
+
const auth = await checkGhAuth();
|
|
115
|
+
if (!auth.ok) {
|
|
116
|
+
console.log(`\n⚠️ ${auth.message}`);
|
|
117
|
+
console.log(' Skipping GitHub repository creation.\n');
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
const pkgJson = await fs.readJson(pkgJsonPath);
|
|
121
|
+
const projectName = pkgJson.name ?? 'my-project';
|
|
122
|
+
let repoName = sanitizeRepoName(projectName);
|
|
123
|
+
while (await repoExists(auth.username, repoName)) {
|
|
124
|
+
console.log(`\n⚠️ A repository named "${repoName}" already exists on GitHub under your account.\n`);
|
|
125
|
+
const { alternativeName } = await inquirer.prompt([
|
|
126
|
+
{
|
|
127
|
+
type: 'input',
|
|
128
|
+
name: 'alternativeName',
|
|
129
|
+
message: 'Enter an alternative repository name (or leave empty to skip creating a GitHub repository):',
|
|
130
|
+
default: '',
|
|
131
|
+
},
|
|
132
|
+
]);
|
|
133
|
+
if (!alternativeName?.trim()) {
|
|
134
|
+
repoName = '';
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
repoName = sanitizeRepoName(alternativeName.trim());
|
|
138
|
+
}
|
|
139
|
+
if (!repoName)
|
|
140
|
+
return false;
|
|
141
|
+
const repoUrl = `https://github.com/${auth.username}/${repoName}`;
|
|
142
|
+
console.log('\n📋 The following will happen:\n');
|
|
143
|
+
console.log(` • A new public repository will be created at: ${repoUrl}`);
|
|
144
|
+
console.log(` • The repository will be created under your GitHub account (${auth.username}).`);
|
|
145
|
+
console.log(` • The repository URL will be added to your package.json.`);
|
|
146
|
+
console.log(` • The remote "origin" will be set to this repository (you can push when ready).\n`);
|
|
147
|
+
const { confirmCreate } = await inquirer.prompt([
|
|
148
|
+
{
|
|
149
|
+
type: 'confirm',
|
|
150
|
+
name: 'confirmCreate',
|
|
151
|
+
message: 'Do you want to proceed with creating this repository?',
|
|
152
|
+
default: true,
|
|
153
|
+
},
|
|
154
|
+
]);
|
|
155
|
+
if (!confirmCreate) {
|
|
156
|
+
console.log('\n❌ GitHub repository was not created.\n');
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const createdUrl = await createRepo({
|
|
161
|
+
repoName,
|
|
162
|
+
projectPath,
|
|
163
|
+
username: auth.username,
|
|
164
|
+
...(pkgJson.description && { description: String(pkgJson.description) }),
|
|
165
|
+
});
|
|
166
|
+
pkgJson.repository = { type: 'git', url: createdUrl };
|
|
167
|
+
await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
|
|
168
|
+
console.log('\n✅ GitHub repository created successfully!');
|
|
169
|
+
console.log(` ${repoUrl}`);
|
|
170
|
+
console.log(' Repository URL has been added to your package.json.\n');
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
console.error('\n❌ Failed to create GitHub repository:');
|
|
175
|
+
if (err instanceof Error)
|
|
176
|
+
console.error(` ${err.message}\n`);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
package/dist/load.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the load flow: verify repo, then pull the latest updates from the remote.
|
|
3
|
+
* Throws on fatal errors (not a git repo, or git command failure). Caller should catch and process.exit(1).
|
|
4
|
+
*/
|
|
5
|
+
export declare function runLoad(cwd: string): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BxD"}
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
/**
|
|
5
|
+
* Runs the load flow: verify repo, then pull the latest updates from the remote.
|
|
6
|
+
* Throws on fatal errors (not a git repo, or git command failure). Caller should catch and process.exit(1).
|
|
7
|
+
*/
|
|
8
|
+
export async function runLoad(cwd) {
|
|
9
|
+
const gitDir = path.join(cwd, '.git');
|
|
10
|
+
if (!(await fs.pathExists(gitDir))) {
|
|
11
|
+
console.error('❌ This directory is not a git repository (.git not found).');
|
|
12
|
+
console.error(' Initialize with "git init" or create a project with "patternfly-cli create".\n');
|
|
13
|
+
throw new Error('Not a git repository');
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
console.log('📥 Pulling latest updates from GitHub...\n');
|
|
17
|
+
await execa('git', ['pull'], { cwd, stdio: 'inherit' });
|
|
18
|
+
console.log('\n✅ Latest updates loaded successfully.\n');
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err && typeof err === 'object' && 'exitCode' in err) {
|
|
22
|
+
const code = err.exitCode;
|
|
23
|
+
if (code === 128) {
|
|
24
|
+
console.error('\n❌ Pull failed. You may need to set a remote (e.g. "git remote add origin <url>") or run "gh auth login".\n');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
console.error('\n❌ Pull failed. See the output above for details.\n');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.error('\n❌ An error occurred:');
|
|
32
|
+
if (err instanceof Error)
|
|
33
|
+
console.error(` ${err.message}\n`);
|
|
34
|
+
else
|
|
35
|
+
console.error(` ${String(err)}\n`);
|
|
36
|
+
}
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=load.js.map
|
package/dist/load.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC5E,OAAO,CAAC,KAAK,CAAC,mFAAmF,CAAC,CAAC;QACnG,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;QAC1D,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;YACxD,MAAM,IAAI,GAAI,GAA6B,CAAC,QAAQ,CAAC;YACrD,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CACX,8GAA8G,CAC/G,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACxC,IAAI,GAAG,YAAY,KAAK;gBAAE,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;;gBAC1D,OAAO,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
package/dist/save.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the save flow: verify repo, check for changes, prompt to commit, then add/commit/push.
|
|
3
|
+
* Throws on fatal errors (not a git repo, or git command failure). Caller should catch and process.exit(1).
|
|
4
|
+
*/
|
|
5
|
+
export declare function runSave(cwd: string): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=save.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4FxD"}
|
package/dist/save.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import { offerAndCreateGitHubRepo } from './github.js';
|
|
6
|
+
/**
|
|
7
|
+
* Runs the save flow: verify repo, check for changes, prompt to commit, then add/commit/push.
|
|
8
|
+
* Throws on fatal errors (not a git repo, or git command failure). Caller should catch and process.exit(1).
|
|
9
|
+
*/
|
|
10
|
+
export async function runSave(cwd) {
|
|
11
|
+
const gitDir = path.join(cwd, '.git');
|
|
12
|
+
if (!(await fs.pathExists(gitDir))) {
|
|
13
|
+
console.error('❌ This directory is not a git repository (.git not found).');
|
|
14
|
+
console.error(' Initialize with "git init" or create a project with "patternfly-cli create".\n');
|
|
15
|
+
throw new Error('Not a git repository');
|
|
16
|
+
}
|
|
17
|
+
const { stdout: statusOut } = await execa('git', ['status', '--porcelain'], {
|
|
18
|
+
cwd,
|
|
19
|
+
encoding: 'utf8',
|
|
20
|
+
});
|
|
21
|
+
const hasChanges = statusOut.trim().length > 0;
|
|
22
|
+
if (!hasChanges) {
|
|
23
|
+
console.log('📭 No changes to save (working tree clean).\n');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const { saveChanges } = await inquirer.prompt([
|
|
27
|
+
{
|
|
28
|
+
type: 'confirm',
|
|
29
|
+
name: 'saveChanges',
|
|
30
|
+
message: 'You have uncommitted changes. Would you like to save them?',
|
|
31
|
+
default: true,
|
|
32
|
+
},
|
|
33
|
+
]);
|
|
34
|
+
if (!saveChanges) {
|
|
35
|
+
console.log('\n📭 Nothing has been saved.\n');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const { message } = await inquirer.prompt([
|
|
39
|
+
{
|
|
40
|
+
type: 'input',
|
|
41
|
+
name: 'message',
|
|
42
|
+
message: 'Describe your changes (commit message):',
|
|
43
|
+
validate: (input) => {
|
|
44
|
+
if (!input?.trim())
|
|
45
|
+
return 'A commit message is required to save.';
|
|
46
|
+
return true;
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
const commitMessage = message.trim();
|
|
51
|
+
if (!commitMessage) {
|
|
52
|
+
console.log('\n📭 No message provided; nothing has been saved.\n');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
await execa('git', ['add', '.'], { cwd, stdio: 'inherit' });
|
|
57
|
+
await execa('git', ['commit', '-m', commitMessage], { cwd, stdio: 'inherit' });
|
|
58
|
+
// If no remote origin, offer to create a GitHub repository before pushing
|
|
59
|
+
let hasOrigin = false;
|
|
60
|
+
try {
|
|
61
|
+
await execa('git', ['remote', 'get-url', 'origin'], { cwd, reject: true });
|
|
62
|
+
hasOrigin = true;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// no origin
|
|
66
|
+
}
|
|
67
|
+
if (!hasOrigin) {
|
|
68
|
+
const created = await offerAndCreateGitHubRepo(cwd);
|
|
69
|
+
if (!created) {
|
|
70
|
+
console.error('\n❌ Push skipped. Set a remote (e.g. "patternfly-cli init" or "git remote add origin <url>") then try save again.\n');
|
|
71
|
+
throw new Error('No remote origin');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
await execa('git', ['push'], { cwd, stdio: 'inherit' });
|
|
75
|
+
console.log('\n✅ Changes saved and pushed to GitHub successfully.\n');
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
if (err && typeof err === 'object' && 'exitCode' in err) {
|
|
79
|
+
const code = err.exitCode;
|
|
80
|
+
if (code === 128) {
|
|
81
|
+
console.error('\n❌ Push failed. You may need to set a remote (e.g. "git remote add origin <url>") or run "gh auth login".\n');
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.error('\n❌ Save or push failed. See the output above for details.\n');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else if (!(err instanceof Error && err.message === 'No remote origin')) {
|
|
88
|
+
console.error('\n❌ An error occurred:');
|
|
89
|
+
if (err instanceof Error)
|
|
90
|
+
console.error(` ${err.message}\n`);
|
|
91
|
+
else
|
|
92
|
+
console.error(` ${String(err)}\n`);
|
|
93
|
+
}
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=save.js.map
|
package/dist/save.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.js","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC5E,OAAO,CAAC,KAAK,CAAC,mFAAmF,CAAC,CAAC;QACnG,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE;QAC1E,GAAG;QACH,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAE/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QAC5C;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,4DAA4D;YACrE,OAAO,EAAE,IAAI;SACd;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACxC;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,yCAAyC;YAClD,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC1B,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;oBAAE,OAAO,uCAAuC,CAAC;gBACnE,OAAO,IAAI,CAAC;YACd,CAAC;SACF;KACF,CAAC,CAAC;IAEH,MAAM,aAAa,GAAI,OAAkB,CAAC,IAAI,EAAE,CAAC;IACjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5D,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAE/E,0EAA0E;QAC1E,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3E,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,YAAY;QACd,CAAC;QACD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,GAAG,CAAC,CAAC;YACpD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CACX,qHAAqH,CACtH,CAAC;gBACF,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAED,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,UAAU,IAAI,GAAG,EAAE,CAAC;YACxD,MAAM,IAAI,GAAI,GAA6B,CAAC,QAAQ,CAAC;YACrD,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CACX,8GAA8G,CAC/G,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,KAAK,kBAAkB,CAAC,EAAE,CAAC;YACzE,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACxC,IAAI,GAAG,YAAY,KAAK;gBAAE,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;;gBAC1D,OAAO,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Template } from './templates.js';
|
|
2
|
+
/** Function used to load custom templates from a JSON file */
|
|
3
|
+
export declare function loadCustomTemplates(filePath: string): Template[];
|
|
4
|
+
/** Function used to merge built-in templates with custom templates */
|
|
5
|
+
export declare function mergeTemplates(builtIn: Template[], customFilePath?: string): Template[];
|
|
6
|
+
//# sourceMappingURL=template-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-loader.d.ts","sourceRoot":"","sources":["../src/template-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,CAkEhE;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CASvF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/** Function used to load custom templates from a JSON file */
|
|
4
|
+
export function loadCustomTemplates(filePath) {
|
|
5
|
+
const resolved = path.resolve(filePath);
|
|
6
|
+
if (!fs.existsSync(resolved)) {
|
|
7
|
+
console.error(`❌ Template file not found: ${resolved}\n`);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
const raw = fs.readFileSync(resolved, 'utf-8');
|
|
11
|
+
let data;
|
|
12
|
+
try {
|
|
13
|
+
data = JSON.parse(raw);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
console.error(`❌ Invalid JSON in template file: ${resolved}\n`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
if (!Array.isArray(data)) {
|
|
20
|
+
console.error(`❌ Template file must be a JSON array of templates.\n`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
const result = [];
|
|
24
|
+
for (let i = 0; i < data.length; i++) {
|
|
25
|
+
const item = data[i];
|
|
26
|
+
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
27
|
+
console.error(`❌ Template at index ${i}: must be an object.\n`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const obj = item;
|
|
31
|
+
const name = obj['name'];
|
|
32
|
+
const description = obj['description'];
|
|
33
|
+
const repo = obj['repo'];
|
|
34
|
+
if (typeof name !== 'string' || !name.trim()) {
|
|
35
|
+
console.error(`❌ Template at index ${i}: "name" must be a non-empty string.\n`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
if (typeof description !== 'string') {
|
|
39
|
+
console.error(`❌ Template at index ${i}: "description" must be a string.\n`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
if (typeof repo !== 'string' || !repo.trim()) {
|
|
43
|
+
console.error(`❌ Template at index ${i}: "repo" must be a non-empty string.\n`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
const repoSSH = obj['repoSSH'];
|
|
47
|
+
const options = obj['options'];
|
|
48
|
+
const packageManager = obj['packageManager'];
|
|
49
|
+
if (typeof repoSSH !== 'undefined' && (typeof repoSSH !== 'string' || !repoSSH.trim())) {
|
|
50
|
+
console.error(`❌ Template at index ${i}: "repoSSH" must be a non-empty string.\n`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
if (options !== undefined && (!Array.isArray(options) || options.some((o) => typeof o !== 'string'))) {
|
|
54
|
+
console.error(`❌ Template at index ${i}: "options" must be an array of strings.\n`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
if (packageManager !== undefined && typeof packageManager !== 'string') {
|
|
58
|
+
console.error(`❌ Template at index ${i}: "packageManager" must be a string.\n`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
result.push({
|
|
62
|
+
name: name.trim(),
|
|
63
|
+
description: String(description),
|
|
64
|
+
repo: repo.trim(),
|
|
65
|
+
...(typeof repoSSH === 'string' && repoSSH.trim() && { repoSSH: repoSSH.trim() }),
|
|
66
|
+
...(Array.isArray(options) && options.length > 0 && { options: options }),
|
|
67
|
+
...(typeof packageManager === 'string' && packageManager.length > 0 && { packageManager }),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
/** Function used to merge built-in templates with custom templates */
|
|
73
|
+
export function mergeTemplates(builtIn, customFilePath) {
|
|
74
|
+
if (!customFilePath) {
|
|
75
|
+
return builtIn;
|
|
76
|
+
}
|
|
77
|
+
const custom = loadCustomTemplates(customFilePath);
|
|
78
|
+
const byName = new Map();
|
|
79
|
+
builtIn.forEach((t) => byName.set(t.name, t));
|
|
80
|
+
custom.forEach((t) => byName.set(t.name, t));
|
|
81
|
+
return [...byName.values()];
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=template-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-loader.js","sourceRoot":"","sources":["../src/template-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type Template = {
|
|
2
|
+
/** Template name */
|
|
3
|
+
name: string;
|
|
4
|
+
/** Template description */
|
|
5
|
+
description: string;
|
|
6
|
+
/** Template repository URL */
|
|
7
|
+
repo: string;
|
|
8
|
+
/** Template repository SSH URL (optional, falls back to repo if not provided) */
|
|
9
|
+
repoSSH?: string;
|
|
10
|
+
/** Template checkout options */
|
|
11
|
+
options?: string[];
|
|
12
|
+
/** Template package manager */
|
|
13
|
+
packageManager?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const defaultTemplates: Template[];
|
|
16
|
+
export default defaultTemplates;
|
|
17
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,EA8BtC,CAAA;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const defaultTemplates = [
|
|
2
|
+
{
|
|
3
|
+
name: "starter",
|
|
4
|
+
description: "A starter template for Patternfly react typescript project",
|
|
5
|
+
repo: "https://github.com/patternfly/patternfly-react-seed.git",
|
|
6
|
+
repoSSH: "git@github.com:patternfly/patternfly-react-seed.git",
|
|
7
|
+
packageManager: "yarn"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: "compass-starter",
|
|
11
|
+
description: "A starter template for Patternfly compass theme typescript project",
|
|
12
|
+
repo: "https://github.com/patternfly/patternfly-react-seed.git",
|
|
13
|
+
repoSSH: "git@github.com:patternfly/patternfly-react-seed.git",
|
|
14
|
+
options: ["--single-branch", "--branch", "compass_theme"],
|
|
15
|
+
packageManager: "yarn"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: "nextjs-starter",
|
|
19
|
+
description: "A starter template for Patternfly nextjs project",
|
|
20
|
+
repo: "https://github.com/patternfly/patternfly-nextjs-seed.git",
|
|
21
|
+
repoSSH: "git@github.com:patternfly/patternfly-nextjs-seed.git",
|
|
22
|
+
packageManager: "yarn"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "rhoai_enabled_starter",
|
|
26
|
+
description: "A starter template for Red Hat Open AI enabled project",
|
|
27
|
+
repo: "https://gitlab.cee.redhat.com/uxd/prototypes/rhoai",
|
|
28
|
+
repoSSH: "git@gitlab.cee.redhat.com:uxd/prototypes/rhoai.git",
|
|
29
|
+
options: ["--single-branch", "--branch", "3.2"]
|
|
30
|
+
}
|
|
31
|
+
];
|
|
32
|
+
export default defaultTemplates;
|
|
33
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,gBAAgB,GAAe;IACxC;QACI,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,4DAA4D;QACzE,IAAI,EAAE,yDAAyD;QAC/D,OAAO,EAAE,qDAAqD;QAC9D,cAAc,EAAE,MAAM;KACzB;IACD;QACI,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,oEAAoE;QACjF,IAAI,EAAE,yDAAyD;QAC/D,OAAO,EAAE,qDAAqD;QAC9D,OAAO,EAAE,CAAC,iBAAiB,EAAE,UAAU,EAAE,eAAe,CAAC;QACzD,cAAc,EAAE,MAAM;KACzB;IACD;QACI,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,kDAAkD;QAC/D,IAAI,EAAE,0DAA0D;QAChE,OAAO,EAAE,sDAAsD;QAC/D,cAAc,EAAE,MAAM;KACzB;IACD;QACI,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,wDAAwD;QACrE,IAAI,EAAE,oDAAoD;QAC1D,OAAO,EAAE,oDAAoD;QAC7D,OAAO,EAAE,CAAC,iBAAiB,EAAE,UAAU,EAAE,KAAK,CAAC;KAClD;CACJ,CAAA;AAED,eAAe,gBAAgB,CAAC"}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import tseslint from 'typescript-eslint';
|
|
3
|
+
|
|
4
|
+
export default tseslint.config(
|
|
5
|
+
eslint.configs.recommended,
|
|
6
|
+
...tseslint.configs.recommended,
|
|
7
|
+
{
|
|
8
|
+
languageOptions: {
|
|
9
|
+
parserOptions: {
|
|
10
|
+
projectService: true,
|
|
11
|
+
tsconfigRootDir: import.meta.dirname,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
files: ['**/__tests__/**/*.test.ts'],
|
|
17
|
+
extends: [tseslint.configs.disableTypeChecked],
|
|
18
|
+
}
|
|
19
|
+
);
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@patternfly/patternfly-cli",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Patternfly cli for scaffolding projects, performing code mods, and running project related tasks",
|
|
5
|
+
"author": "Red Hat",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/cli.js",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"bin": {
|
|
13
|
+
"patternfly-cli": "./dist/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"start": "node dist/cli.js",
|
|
18
|
+
"test": "jest",
|
|
19
|
+
"semantic-release": "semantic-release",
|
|
20
|
+
"lint": "eslint src",
|
|
21
|
+
"lint:fix": "eslint src --fix"
|
|
22
|
+
},
|
|
23
|
+
"jest": {
|
|
24
|
+
"preset": "ts-jest",
|
|
25
|
+
"testEnvironment": "node",
|
|
26
|
+
"testMatch": [
|
|
27
|
+
"**/__tests__/**/*.test.ts"
|
|
28
|
+
],
|
|
29
|
+
"moduleFileExtensions": [
|
|
30
|
+
"ts",
|
|
31
|
+
"js"
|
|
32
|
+
],
|
|
33
|
+
"transform": {
|
|
34
|
+
"^.+\\.tsx?$": [
|
|
35
|
+
"ts-jest",
|
|
36
|
+
{
|
|
37
|
+
"tsconfig": {
|
|
38
|
+
"module": "commonjs",
|
|
39
|
+
"moduleResolution": "node"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"moduleNameMapper": {
|
|
45
|
+
"^(\\.\\./.*)\\.js$": "$1",
|
|
46
|
+
"^(\\./.*)\\.js$": "$1"
|
|
47
|
+
},
|
|
48
|
+
"transformIgnorePatterns": [
|
|
49
|
+
"/node_modules/(?!inquirer)"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"0g": "^0.4.2",
|
|
54
|
+
"commander": "^12.1.0",
|
|
55
|
+
"execa": "^9.3.0",
|
|
56
|
+
"fs-extra": "^11.2.0",
|
|
57
|
+
"inquirer": "^9.3.5"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@eslint/js": "^10.0.1",
|
|
61
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
62
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
63
|
+
"@semantic-release/git": "^10.0.1",
|
|
64
|
+
"@semantic-release/github": "^12.0.6",
|
|
65
|
+
"@semantic-release/npm": "^13.1.5",
|
|
66
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
67
|
+
"@types/commander": "^2.12.0",
|
|
68
|
+
"@types/execa": "^0.9.0",
|
|
69
|
+
"@types/fs-extra": "^11.0.4",
|
|
70
|
+
"@types/inquirer": "^9.0.9",
|
|
71
|
+
"@types/jest": "^30.0.0",
|
|
72
|
+
"@types/node": "^24.10.1",
|
|
73
|
+
"eslint": "^10.0.2",
|
|
74
|
+
"jest": "^29.7.0",
|
|
75
|
+
"semantic-release": "^24.2.0",
|
|
76
|
+
"ts-jest": "^29.4.5",
|
|
77
|
+
"typescript": "^5.9.3",
|
|
78
|
+
"typescript-eslint": "^8.56.1"
|
|
79
|
+
}
|
|
80
|
+
}
|