frontpl 0.3.0 → 0.3.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/README.md +12 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +6 -1
- package/dist/index.mjs +2 -2
- package/dist/{init-CQKT_mPD.mjs → init-oJwslpqP.mjs} +96 -15
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ Follow the prompts to choose:
|
|
|
30
30
|
- Optional tooling: `oxlint`, `oxfmt`, `vitest`, `tsdown`
|
|
31
31
|
|
|
32
32
|
When `oxlint` is enabled, generated projects use `@kingsword/lint-config` via `oxlint.config.ts`.
|
|
33
|
+
Generated lint-related dependencies (`oxlint`, `oxlint-tsgolint`, `oxfmt`, `@kingsword/lint-config`) default to `latest` in scaffolded `package.json`.
|
|
33
34
|
|
|
34
35
|
- Git init
|
|
35
36
|
- GitHub Actions workflows:
|
|
@@ -61,10 +62,11 @@ What it does:
|
|
|
61
62
|
- Detects Node.js major version from `.nvmrc`, `.node-version`, or `package.json#engines.node` (defaults to `22`)
|
|
62
63
|
- Generates `.github/workflows/ci.yml`
|
|
63
64
|
- Optionally generates `.github/workflows/release.yml` (tag/commit/both)
|
|
65
|
+
- Optionally generates `.github/dependabot.yml` with grouped updates (`dependencies`, `github-actions`)
|
|
64
66
|
|
|
65
67
|
## GitHub Actions (CI + Release)
|
|
66
68
|
|
|
67
|
-
frontpl generates workflows that call reusable workflows from `kingsword09/workflows` (pinned to
|
|
69
|
+
frontpl generates workflows that call reusable workflows from `kingsword09/workflows` (pinned to commit SHA + `# vX.Y.Z` comment by default):
|
|
68
70
|
|
|
69
71
|
- CI: `cli-ci.yml`
|
|
70
72
|
- Release (tag, recommended): `cli-release-tag.yml`
|
|
@@ -81,6 +83,15 @@ frontpl generates workflows that call reusable workflows from `kingsword09/workf
|
|
|
81
83
|
- **Trusted publishing (OIDC)**: enable `trustedPublishing: true` (no `NPM_TOKEN` required). Your repo must be configured on npm as a trusted publisher for the calling workflow.
|
|
82
84
|
- **NPM token**: set `trustedPublishing: false` and provide `NPM_TOKEN` in GitHub secrets.
|
|
83
85
|
|
|
86
|
+
## Dependabot (optional)
|
|
87
|
+
|
|
88
|
+
When CI workflows are enabled, frontpl can also generate `.github/dependabot.yml`:
|
|
89
|
+
|
|
90
|
+
- Keeps `github-actions` updates enabled
|
|
91
|
+
- Adds grouped dependencies updates (`groups.dependencies`)
|
|
92
|
+
- Uses the selected `workingDirectory` (`.` -> `/`, monorepo package -> `/packages/<name>`)
|
|
93
|
+
- Maps JavaScript package managers (`npm`/`pnpm`/`yarn`/`bun`) to Dependabot `package-ecosystem: "npm"`
|
|
94
|
+
|
|
84
95
|
## Development
|
|
85
96
|
|
|
86
97
|
```sh
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -41,6 +41,11 @@ declare function githubCliCiWorkflowTemplate(opts: {
|
|
|
41
41
|
formatCheckCommand?: string;
|
|
42
42
|
testCommand?: string;
|
|
43
43
|
workflowsRef?: string;
|
|
44
|
+
workflowsVersion?: string;
|
|
45
|
+
}): string;
|
|
46
|
+
declare function githubDependabotTemplate(opts: {
|
|
47
|
+
packageManager: "npm" | "pnpm" | "yarn" | "bun" | "deno";
|
|
48
|
+
workingDirectory: string;
|
|
44
49
|
}): string;
|
|
45
50
|
//#endregion
|
|
46
|
-
export { githubCliCiWorkflowTemplate, oxlintConfigTemplate, packageJsonTemplate, runCi, runInit };
|
|
51
|
+
export { githubCliCiWorkflowTemplate, githubDependabotTemplate, oxlintConfigTemplate, packageJsonTemplate, runCi, runInit };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as oxlintConfigTemplate, i as githubDependabotTemplate, n as runCi, o as packageJsonTemplate, r as githubCliCiWorkflowTemplate, t as runInit } from "./init-oJwslpqP.mjs";
|
|
2
2
|
|
|
3
|
-
export { githubCliCiWorkflowTemplate, oxlintConfigTemplate, packageJsonTemplate, runCi, runInit };
|
|
3
|
+
export { githubCliCiWorkflowTemplate, githubDependabotTemplate, oxlintConfigTemplate, packageJsonTemplate, runCi, runInit };
|
|
@@ -144,8 +144,18 @@ function packageJsonTemplate(opts) {
|
|
|
144
144
|
packageManager: opts.packageManager
|
|
145
145
|
}, null, 2) + "\n";
|
|
146
146
|
}
|
|
147
|
+
const DEFAULT_WORKFLOWS_REF = "7320d30bcd47cee17cc2d8d28250ba1ab1f742b8";
|
|
148
|
+
const DEFAULT_WORKFLOWS_VERSION = "v1.0.3";
|
|
149
|
+
function resolveWorkflowsPin(opts) {
|
|
150
|
+
const ref = opts.workflowsRef?.trim() || DEFAULT_WORKFLOWS_REF;
|
|
151
|
+
const version = opts.workflowsVersion?.trim() || (opts.workflowsRef ? void 0 : DEFAULT_WORKFLOWS_VERSION);
|
|
152
|
+
return {
|
|
153
|
+
ref,
|
|
154
|
+
versionComment: version ? ` # ${version}` : ""
|
|
155
|
+
};
|
|
156
|
+
}
|
|
147
157
|
function githubCliCiWorkflowTemplate(opts) {
|
|
148
|
-
const ref = opts
|
|
158
|
+
const { ref, versionComment } = resolveWorkflowsPin(opts);
|
|
149
159
|
const installCommand = opts.installCommand?.trim();
|
|
150
160
|
const lintCommand = opts.lintCommand?.trim();
|
|
151
161
|
const formatCheckCommand = opts.formatCheckCommand?.trim();
|
|
@@ -161,7 +171,7 @@ function githubCliCiWorkflowTemplate(opts) {
|
|
|
161
171
|
"",
|
|
162
172
|
"jobs:",
|
|
163
173
|
" ci:",
|
|
164
|
-
` uses: kingsword09/workflows/.github/workflows/cli-ci.yml@${ref}`,
|
|
174
|
+
` uses: kingsword09/workflows/.github/workflows/cli-ci.yml@${ref}${versionComment}`,
|
|
165
175
|
" with:",
|
|
166
176
|
` packageManager: ${opts.packageManager}`,
|
|
167
177
|
` nodeVersion: ${opts.nodeVersion}`,
|
|
@@ -177,7 +187,7 @@ function githubCliCiWorkflowTemplate(opts) {
|
|
|
177
187
|
].join("\n");
|
|
178
188
|
}
|
|
179
189
|
function githubCliReleaseWorkflowTemplate(opts) {
|
|
180
|
-
const ref = opts
|
|
190
|
+
const { ref, versionComment } = resolveWorkflowsPin(opts);
|
|
181
191
|
const trustedPublishing = opts.trustedPublishing;
|
|
182
192
|
const needsNpmToken = opts.packageManager !== "deno" && trustedPublishing === false;
|
|
183
193
|
return [
|
|
@@ -192,7 +202,7 @@ function githubCliReleaseWorkflowTemplate(opts) {
|
|
|
192
202
|
" permissions:",
|
|
193
203
|
" contents: write",
|
|
194
204
|
" id-token: write",
|
|
195
|
-
` uses: kingsword09/workflows/.github/workflows/cli-release.yml@${ref}`,
|
|
205
|
+
` uses: kingsword09/workflows/.github/workflows/cli-release.yml@${ref}${versionComment}`,
|
|
196
206
|
" with:",
|
|
197
207
|
` packageManager: ${opts.packageManager}`,
|
|
198
208
|
` nodeVersion: ${opts.nodeVersion}`,
|
|
@@ -203,7 +213,7 @@ function githubCliReleaseWorkflowTemplate(opts) {
|
|
|
203
213
|
].join("\n");
|
|
204
214
|
}
|
|
205
215
|
function githubCliReleaseTagWorkflowTemplate(opts) {
|
|
206
|
-
const ref = opts
|
|
216
|
+
const { ref, versionComment } = resolveWorkflowsPin(opts);
|
|
207
217
|
const trustedPublishing = opts.trustedPublishing;
|
|
208
218
|
const needsNpmToken = opts.packageManager !== "deno" && trustedPublishing === false;
|
|
209
219
|
return [
|
|
@@ -218,7 +228,7 @@ function githubCliReleaseTagWorkflowTemplate(opts) {
|
|
|
218
228
|
" permissions:",
|
|
219
229
|
" contents: write",
|
|
220
230
|
" id-token: write",
|
|
221
|
-
` uses: kingsword09/workflows/.github/workflows/cli-release-tag.yml@${ref}`,
|
|
231
|
+
` uses: kingsword09/workflows/.github/workflows/cli-release-tag.yml@${ref}${versionComment}`,
|
|
222
232
|
" with:",
|
|
223
233
|
` packageManager: ${opts.packageManager}`,
|
|
224
234
|
` nodeVersion: ${opts.nodeVersion}`,
|
|
@@ -229,7 +239,7 @@ function githubCliReleaseTagWorkflowTemplate(opts) {
|
|
|
229
239
|
].join("\n");
|
|
230
240
|
}
|
|
231
241
|
function githubCliReleaseBothWorkflowTemplate(opts) {
|
|
232
|
-
const ref = opts
|
|
242
|
+
const { ref, versionComment } = resolveWorkflowsPin(opts);
|
|
233
243
|
const trustedPublishing = opts.trustedPublishing;
|
|
234
244
|
const needsNpmToken = opts.packageManager !== "deno" && trustedPublishing === false;
|
|
235
245
|
return [
|
|
@@ -246,7 +256,7 @@ function githubCliReleaseBothWorkflowTemplate(opts) {
|
|
|
246
256
|
" permissions:",
|
|
247
257
|
" contents: write",
|
|
248
258
|
" id-token: write",
|
|
249
|
-
` uses: kingsword09/workflows/.github/workflows/cli-release-tag.yml@${ref}`,
|
|
259
|
+
` uses: kingsword09/workflows/.github/workflows/cli-release-tag.yml@${ref}${versionComment}`,
|
|
250
260
|
" with:",
|
|
251
261
|
` packageManager: ${opts.packageManager}`,
|
|
252
262
|
` nodeVersion: ${opts.nodeVersion}`,
|
|
@@ -259,7 +269,7 @@ function githubCliReleaseBothWorkflowTemplate(opts) {
|
|
|
259
269
|
" permissions:",
|
|
260
270
|
" contents: write",
|
|
261
271
|
" id-token: write",
|
|
262
|
-
` uses: kingsword09/workflows/.github/workflows/cli-release.yml@${ref}`,
|
|
272
|
+
` uses: kingsword09/workflows/.github/workflows/cli-release.yml@${ref}${versionComment}`,
|
|
263
273
|
" with:",
|
|
264
274
|
` packageManager: ${opts.packageManager}`,
|
|
265
275
|
` nodeVersion: ${opts.nodeVersion}`,
|
|
@@ -269,6 +279,56 @@ function githubCliReleaseBothWorkflowTemplate(opts) {
|
|
|
269
279
|
""
|
|
270
280
|
].join("\n");
|
|
271
281
|
}
|
|
282
|
+
function toDependabotDirectory(workingDirectory) {
|
|
283
|
+
const normalized = workingDirectory.trim();
|
|
284
|
+
if (!normalized || normalized === ".") return "/";
|
|
285
|
+
return normalized.startsWith("/") ? normalized : `/${normalized}`;
|
|
286
|
+
}
|
|
287
|
+
function resolveDependabotPackageEcosystem(packageManager) {
|
|
288
|
+
if (packageManager === "deno") return;
|
|
289
|
+
return "npm";
|
|
290
|
+
}
|
|
291
|
+
function githubDependabotTemplate(opts) {
|
|
292
|
+
const packageEcosystem = resolveDependabotPackageEcosystem(opts.packageManager);
|
|
293
|
+
const directory = toDependabotDirectory(opts.workingDirectory);
|
|
294
|
+
return [
|
|
295
|
+
"version: 2",
|
|
296
|
+
"updates:",
|
|
297
|
+
...packageEcosystem ? [
|
|
298
|
+
` - package-ecosystem: "${packageEcosystem}"`,
|
|
299
|
+
` directory: "${directory}"`,
|
|
300
|
+
" schedule:",
|
|
301
|
+
" interval: \"weekly\"",
|
|
302
|
+
" day: \"monday\"",
|
|
303
|
+
" time: \"03:00\"",
|
|
304
|
+
" timezone: \"America/Los_Angeles\"",
|
|
305
|
+
" open-pull-requests-limit: 10",
|
|
306
|
+
" groups:",
|
|
307
|
+
" dependencies:",
|
|
308
|
+
" patterns:",
|
|
309
|
+
" - \"*\"",
|
|
310
|
+
" labels:",
|
|
311
|
+
" - \"dependencies\"",
|
|
312
|
+
""
|
|
313
|
+
] : [],
|
|
314
|
+
" - package-ecosystem: \"github-actions\"",
|
|
315
|
+
" directory: \"/\"",
|
|
316
|
+
" schedule:",
|
|
317
|
+
" interval: \"weekly\"",
|
|
318
|
+
" day: \"monday\"",
|
|
319
|
+
" time: \"03:00\"",
|
|
320
|
+
" timezone: \"America/Los_Angeles\"",
|
|
321
|
+
" open-pull-requests-limit: 10",
|
|
322
|
+
" groups:",
|
|
323
|
+
" github-actions:",
|
|
324
|
+
" patterns:",
|
|
325
|
+
" - \"*\"",
|
|
326
|
+
" labels:",
|
|
327
|
+
" - \"dependencies\"",
|
|
328
|
+
" - \"github-actions\"",
|
|
329
|
+
""
|
|
330
|
+
].join("\n");
|
|
331
|
+
}
|
|
272
332
|
function yamlString(value) {
|
|
273
333
|
return JSON.stringify(value);
|
|
274
334
|
}
|
|
@@ -338,7 +398,7 @@ async function runCi() {
|
|
|
338
398
|
const nodeVersionText = await text({
|
|
339
399
|
message: "Node.js major version (for GitHub Actions)",
|
|
340
400
|
initialValue: String(nodeVersionDefault),
|
|
341
|
-
validate: (value) => {
|
|
401
|
+
validate: (value = "") => {
|
|
342
402
|
const major = Number.parseInt(value.trim(), 10);
|
|
343
403
|
if (!Number.isFinite(major) || major <= 0) return "Enter a valid major version (e.g. 22)";
|
|
344
404
|
}
|
|
@@ -375,8 +435,14 @@ async function runCi() {
|
|
|
375
435
|
initialValue: true
|
|
376
436
|
}) : void 0;
|
|
377
437
|
if (isCancel(trustedPublishing)) return abort();
|
|
438
|
+
const addDependabot = await pathExists(path.join(rootDir, ".git")) ? await confirm({
|
|
439
|
+
message: "Add/update Dependabot config (.github/dependabot.yml)?",
|
|
440
|
+
initialValue: true
|
|
441
|
+
}) : false;
|
|
442
|
+
if (isCancel(addDependabot)) return abort();
|
|
378
443
|
const ciWorkflowPath = path.join(rootDir, ".github/workflows/ci.yml");
|
|
379
444
|
const releaseWorkflowPath = path.join(rootDir, ".github/workflows/release.yml");
|
|
445
|
+
const dependabotPath = path.join(rootDir, ".github/dependabot.yml");
|
|
380
446
|
if (!await confirmOverwriteIfExists(ciWorkflowPath, ".github/workflows/ci.yml")) {
|
|
381
447
|
cancel("Skipped CI workflow");
|
|
382
448
|
process.exitCode = 0;
|
|
@@ -401,7 +467,13 @@ async function runCi() {
|
|
|
401
467
|
trustedPublishing
|
|
402
468
|
}));
|
|
403
469
|
}
|
|
404
|
-
|
|
470
|
+
if (addDependabot) {
|
|
471
|
+
if (await confirmOverwriteIfExists(dependabotPath, ".github/dependabot.yml")) await writeText(dependabotPath, githubDependabotTemplate({
|
|
472
|
+
packageManager,
|
|
473
|
+
workingDirectory
|
|
474
|
+
}));
|
|
475
|
+
}
|
|
476
|
+
outro(addRelease ? "Done. Generated CI + release workflows (and optional Dependabot)." : "Done. Generated CI workflow (and optional Dependabot).");
|
|
405
477
|
} catch (err) {
|
|
406
478
|
if (err instanceof CancelledError) return;
|
|
407
479
|
throw err;
|
|
@@ -532,7 +604,7 @@ async function promptCommand(message, initialValue) {
|
|
|
532
604
|
const value = await text({
|
|
533
605
|
message,
|
|
534
606
|
initialValue,
|
|
535
|
-
validate: (v) => !v.trim() ? "Command is required" : void 0
|
|
607
|
+
validate: (v = "") => !v.trim() ? "Command is required" : void 0
|
|
536
608
|
});
|
|
537
609
|
if (isCancel(value)) return abort();
|
|
538
610
|
return String(value).trim();
|
|
@@ -737,6 +809,11 @@ async function runInit({ nameArg }) {
|
|
|
737
809
|
]
|
|
738
810
|
}) : void 0;
|
|
739
811
|
if (isCancel(releaseMode)) return onCancel();
|
|
812
|
+
const addDependabot = initGit && githubActions !== "none" ? await confirm({
|
|
813
|
+
message: "Add Dependabot config (.github/dependabot.yml)?",
|
|
814
|
+
initialValue: true
|
|
815
|
+
}) : false;
|
|
816
|
+
if (isCancel(addDependabot)) return onCancel();
|
|
740
817
|
const trustedPublishing = githubActions === "ci+release" && packageManager !== "deno" ? await confirm({
|
|
741
818
|
message: "Release: npm trusted publishing (OIDC)?",
|
|
742
819
|
initialValue: true
|
|
@@ -780,7 +857,7 @@ async function runInit({ nameArg }) {
|
|
|
780
857
|
useOxlint,
|
|
781
858
|
oxlintVersion: "latest",
|
|
782
859
|
oxlintTsgolintVersion: "latest",
|
|
783
|
-
kingswordLintConfigVersion: "
|
|
860
|
+
kingswordLintConfigVersion: "latest",
|
|
784
861
|
useOxfmt,
|
|
785
862
|
oxfmtVersion: "latest",
|
|
786
863
|
useVitest,
|
|
@@ -810,6 +887,10 @@ async function runInit({ nameArg }) {
|
|
|
810
887
|
formatCheckCommand,
|
|
811
888
|
testCommand
|
|
812
889
|
}));
|
|
890
|
+
if (addDependabot) await writeText(path.join(rootDir, ".github/dependabot.yml"), githubDependabotTemplate({
|
|
891
|
+
packageManager,
|
|
892
|
+
workingDirectory
|
|
893
|
+
}));
|
|
813
894
|
}
|
|
814
895
|
if (githubActions === "ci+release") {
|
|
815
896
|
const workingDirectory = pnpmWorkspace ? path.posix.join("packages", projectName) : ".";
|
|
@@ -832,7 +913,7 @@ async function runInit({ nameArg }) {
|
|
|
832
913
|
outro(`Done. Next:\n cd ${projectName}${!canInstall ? `\n (${packageManager} not found, run install manually)` : !installOk ? `\n (${packageManager} install failed, run install manually)` : ""}\n ${nextStepHint(packageManager)}`);
|
|
833
914
|
}
|
|
834
915
|
function validateProjectName(value) {
|
|
835
|
-
const name = value.trim();
|
|
916
|
+
const name = (value ?? "").trim();
|
|
836
917
|
if (!name) return "Project name is required";
|
|
837
918
|
if (name.length > 214) return "Project name is too long";
|
|
838
919
|
if (name.startsWith(".")) return "Project name cannot start with '.'";
|
|
@@ -855,4 +936,4 @@ function nextStepHint(pm) {
|
|
|
855
936
|
}
|
|
856
937
|
|
|
857
938
|
//#endregion
|
|
858
|
-
export {
|
|
939
|
+
export { oxlintConfigTemplate as a, githubDependabotTemplate as i, runCi as n, packageJsonTemplate as o, githubCliCiWorkflowTemplate as r, runInit as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontpl",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Interactive CLI to scaffold standardized frontend project templates.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
"prepublishOnly": "pnpm run build"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@clack/prompts": "^0.
|
|
53
|
-
"tiny-bin": "^
|
|
52
|
+
"@clack/prompts": "^1.0.0",
|
|
53
|
+
"tiny-bin": "^2.0.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@kingsword/lint-config": "^0.1.1",
|
|
57
57
|
"@types/node": "^25.0.10",
|
|
58
|
-
"oxfmt": "^0.
|
|
59
|
-
"oxlint": "^1.
|
|
60
|
-
"oxlint-tsgolint": "^0.11.
|
|
58
|
+
"oxfmt": "^0.31.0",
|
|
59
|
+
"oxlint": "^1.46.0",
|
|
60
|
+
"oxlint-tsgolint": "^0.11.5",
|
|
61
61
|
"tsdown": "^0.20.1",
|
|
62
62
|
"typescript": "^5.9.3"
|
|
63
63
|
},
|