@rshono/create 1.0.0-rc.1 → 1.0.0-rc.11
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 +97 -59
- package/bin/create-rshono.mjs +5 -3
- package/dist/api.mjs +324 -202
- package/dist/cli.mjs +409 -298
- package/package.json +11 -12
- package/templates/base/AGENTS.md +5 -0
- package/templates/base/CLAUDE.md +1 -0
- package/templates/base/README.md +8 -10
- package/templates/base/_env +2 -5
- package/templates/base/public/favicon.svg +2 -1
- package/templates/base/rshono.config.ts +1 -31
- package/templates/base/src/components/404.tsx +0 -1
- package/templates/base/src/components/500.tsx +0 -6
- package/templates/base/src/components/home.tsx +6 -23
- package/templates/base/src/components/layout.tsx +4 -11
- package/templates/base/src/routes.ts +1 -26
- package/templates/base/src/server.ts +20 -35
- package/templates/base/src/styles.css +1 -64
- package/templates/biome/biome.json +2 -1
- package/templates/biome-tailwind/biome.json +1 -1
- package/templates/eslint/eslint.config.mjs +0 -15
- package/templates/oxfmt/_oxfmtrc.json +1 -1
- package/templates/oxlint/_oxlintrc.json +1 -1
- package/templates/prettier/_prettierignore +6 -1
- package/templates/tailwind/postcss.config.mjs +0 -4
- package/templates/tailwind/rshono.config.ts +2 -38
- package/templates/tailwind/src/components/home.tsx +6 -23
- package/templates/tailwind/src/components/layout.tsx +4 -11
- package/templates/tailwind/src/styles.css +0 -25
- package/templates/base/src/actions.ts +0 -22
- package/templates/base/src/components/greet-form.tsx +0 -27
- package/templates/base/src/lib/env.ts +0 -26
package/dist/api.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {fileURLToPath as __rspack_fileURLToPath} from "node:url";
|
|
3
3
|
import {dirname as __rspack_dirname} from "node:path";
|
|
4
4
|
var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
5
|
-
import {
|
|
5
|
+
import { mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { dirname, join, posix, sep } from "node:path";
|
|
7
7
|
import "node:child_process";
|
|
8
8
|
// The require scope
|
|
@@ -32,16 +32,16 @@ var __webpack_exports__ = {};
|
|
|
32
32
|
__webpack_require__.d(__webpack_exports__, {
|
|
33
33
|
bp: () => (/* reexport */ DEPLOY_TARGET_NAMES),
|
|
34
34
|
ml: () => (/* reexport */ (/* inlined export .ESLINT_TYPESCRIPT */"~6.0.3")),
|
|
35
|
+
wC: () => (/* reexport */ FORMATTER_NAMES),
|
|
35
36
|
e7: () => (/* reexport */ FRAMEWORK_DEPS),
|
|
37
|
+
At: () => (/* reexport */ LINTER_NAMES),
|
|
36
38
|
Ab: () => (/* reexport */ PACKAGE_MANAGERS),
|
|
37
39
|
pm: () => (/* reexport */ QUALITY_PRESETS),
|
|
38
40
|
s_: () => (/* reexport */ RSHONO_RANGE),
|
|
39
41
|
RM: () => (/* reexport */ TOOL_VERSIONS),
|
|
40
|
-
|
|
42
|
+
dh: () => (/* reexport */ conflictingEntries),
|
|
41
43
|
P8: () => (/* reexport */ deployHint),
|
|
42
44
|
Lv: () => (/* reexport */ detectPackageManager),
|
|
43
|
-
WL: () => (/* reexport */ inspectTarget),
|
|
44
|
-
p1: () => (/* reexport */ isDeployTarget),
|
|
45
45
|
eW: () => (/* reexport */ isValidPackageName),
|
|
46
46
|
VZ: () => (/* reexport */ packageManager),
|
|
47
47
|
et: () => (/* reexport */ plan_plan),
|
|
@@ -77,9 +77,88 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
77
77
|
] : [];
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
;// CONCATENATED MODULE: ./src/scripts.ts
|
|
81
|
+
// `features/types.js` rather than `features/index.js`: the deploy feature imports `invoke` from here, and
|
|
82
|
+
// going through the barrel would make that a cycle — types.ts imports nothing.
|
|
83
|
+
/**
|
|
84
|
+
* The scripts every app gets, whatever it targets.
|
|
85
|
+
*
|
|
86
|
+
* `start`, `preview` and `deploy` are deliberately not here: each one means something different per
|
|
87
|
+
* platform, so the deploy target contributes its own. The three names are a contract the targets keep,
|
|
88
|
+
* and the reason the README can describe an app it was not written for:
|
|
89
|
+
*
|
|
90
|
+
* - **`start`** runs a build that already exists and never makes one — what a host's own start command
|
|
91
|
+
* calls. Only the target whose build is a server has one.
|
|
92
|
+
* - **`preview`** builds, then runs the result here — for the targets where that is not the same two
|
|
93
|
+
* commands, because otherwise the production build is unanswerable without deploying it.
|
|
94
|
+
* - **`deploy`** builds, then ships it — where the platform has one command that does the shipping.
|
|
95
|
+
*/ const BASE_SCRIPTS = {
|
|
96
|
+
dev: 'rshono dev',
|
|
97
|
+
build: 'rshono build',
|
|
98
|
+
typecheck: 'tsc --noEmit'
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Every script the app gets, in the order they are written: the base ones, then each feature's, in the order
|
|
102
|
+
* the features were selected. The manifest and the README's command table are both this, so neither can
|
|
103
|
+
* document a script the other does not have.
|
|
104
|
+
*/ function buildScripts(features) {
|
|
105
|
+
const scripts = {
|
|
106
|
+
...BASE_SCRIPTS
|
|
107
|
+
};
|
|
108
|
+
for (const feature of features)Object.assign(scripts, feature.scripts);
|
|
109
|
+
return scripts;
|
|
110
|
+
}
|
|
111
|
+
/** The gloss for each base script, in the README's command table. `build` names the target it is for. */ function baseScriptHelp(deploy) {
|
|
112
|
+
return {
|
|
113
|
+
dev: 'dev server with HMR, http://localhost:3000',
|
|
114
|
+
build: `production build for ${deploy}`,
|
|
115
|
+
typecheck: 'tsc --noEmit'
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Script names a package manager has a command of its own for. `pnpm deploy` runs pnpm's workspace-deploy
|
|
120
|
+
* command and never looks at the manifest, so printing it would hand somebody a line that quietly does
|
|
121
|
+
* something else. The explicit `run` form is what all four managers accept, so those names get it.
|
|
122
|
+
*/ const SHADOWED = new Set([
|
|
123
|
+
'deploy'
|
|
124
|
+
]);
|
|
125
|
+
/** How to type one of the app's scripts with this package manager — `pnpm dev`, but `npm run dev`. */ function invoke(pm, script) {
|
|
126
|
+
return `${SHADOWED.has(script) ? `${pm.name} run` : pm.run} ${script}`;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The README's command table: one line per script, with the command to type and a one-line gloss.
|
|
130
|
+
*
|
|
131
|
+
* A script whose feature supplies no `scriptHelp` is left out and covered by the "package.json has the
|
|
132
|
+
* rest" line — that is how a formatter's `format:check` stays out of a table about running the app.
|
|
133
|
+
*/ function scriptTable(answers, features, pm) {
|
|
134
|
+
const help = baseScriptHelp(answers.deploy);
|
|
135
|
+
for (const feature of features)Object.assign(help, feature.scriptHelp);
|
|
136
|
+
const documented = Object.keys(buildScripts(features)).filter((name)=>help[name]);
|
|
137
|
+
const width = Math.max(...documented.map((name)=>invoke(pm, name).length));
|
|
138
|
+
return documented.map((name)=>`${invoke(pm, name).padEnd(width)} # ${help[name]}`).join('\n');
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The command that gets this app into production, as a sentence — the README's deploy step, and the same
|
|
142
|
+
* choice the closing summary makes, so the two cannot name different commands.
|
|
143
|
+
*
|
|
144
|
+
* Read off the scripts rather than the target, so a target that gains a `deploy` gains the sentence with it.
|
|
145
|
+
* `start` is the answer where there is no `deploy`: it ships nothing itself, but it is what the host runs.
|
|
146
|
+
*/ function deployStep(features, pm) {
|
|
147
|
+
const scripts = buildScripts(features);
|
|
148
|
+
if (scripts.deploy) return `\`${invoke(pm, 'deploy')}\` does the build and the upload in one step.`;
|
|
149
|
+
if (scripts.start) return `\`${invoke(pm, 'start')}\` runs that build wherever you host it, and never makes one.`;
|
|
150
|
+
// Every branch names a script the app has, so a target that contributes none of the three still reads true.
|
|
151
|
+
if (scripts.preview) return `\`${invoke(pm, 'preview')}\` runs the build here, so you can check it first.`;
|
|
152
|
+
return `\`${invoke(pm, 'build')}\` produces it; getting it there is yours to script.`;
|
|
153
|
+
}
|
|
154
|
+
|
|
80
155
|
;// CONCATENATED MODULE: ./src/generated/framework.ts
|
|
81
156
|
// GENERATED by scripts/codegen.mjs from packages/core — do not edit. Run `pnpm --filter @rshono/create codegen`.
|
|
82
|
-
/** The framework release a scaffolded app is pinned to: this package and rshono ship together. */ const RSHONO_VERSION = '1.0.0-rc.
|
|
157
|
+
/** The framework release a scaffolded app is pinned to: this package and rshono ship together. */ const RSHONO_VERSION = '1.0.0-rc.11';
|
|
158
|
+
/**
|
|
159
|
+
* The Node range rshono itself declares, restated in every scaffolded app's `engines` — so a CI image
|
|
160
|
+
* or a contributor on an older Node hears it from their package manager rather than from a stack trace.
|
|
161
|
+
*/ const NODE_ENGINE = '>=22.18.0';
|
|
83
162
|
/**
|
|
84
163
|
* The dependency versions rshono is tested against, copied from its own manifest. Exact where it is
|
|
85
164
|
* exact — React's RSC internals are coupled across builds, and a generated app has no workspace
|
|
@@ -101,22 +180,10 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
101
180
|
name: 'cloudflare',
|
|
102
181
|
hint: 'deploy with `wrangler deploy`'
|
|
103
182
|
},
|
|
104
|
-
{
|
|
105
|
-
name: 'bun',
|
|
106
|
-
hint: 'run `bun dist/server/main.mjs`'
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
name: 'deno',
|
|
110
|
-
hint: 'run `deno serve -A dist/server/main.mjs`'
|
|
111
|
-
},
|
|
112
183
|
{
|
|
113
184
|
name: 'vercel',
|
|
114
185
|
hint: 'deploy with `vercel deploy --prebuilt`'
|
|
115
186
|
},
|
|
116
|
-
{
|
|
117
|
-
name: 'netlify',
|
|
118
|
-
hint: 'deploy with `netlify deploy --build=false --dir=.netlify/publish`'
|
|
119
|
-
},
|
|
120
187
|
{
|
|
121
188
|
name: 'aws-lambda',
|
|
122
189
|
hint: 'zip dist/ with the handler at dist/server/main.mjs'
|
|
@@ -125,7 +192,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
125
192
|
|
|
126
193
|
;// CONCATENATED MODULE: ./src/versions.ts
|
|
127
194
|
|
|
128
|
-
|
|
195
|
+
/** Passed straight through, so everything generated from the framework reaches the rest of the package here. */
|
|
129
196
|
/** The framework range a scaffolded app gets. The two packages are released together, so this is ours. */ const RSHONO_RANGE = `^${RSHONO_VERSION}`;
|
|
130
197
|
/**
|
|
131
198
|
* Versions for the optional tooling the features can add — the one place in this package where a
|
|
@@ -156,12 +223,11 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
156
223
|
};
|
|
157
224
|
/**
|
|
158
225
|
* The TypeScript an ESLint app pins, in place of the framework's own — the one deliberate exception to
|
|
159
|
-
* {@link FRAMEWORK_DEPS}
|
|
226
|
+
* {@link FRAMEWORK_DEPS}.
|
|
160
227
|
*
|
|
161
|
-
* typescript-eslint reads TypeScript's compiler API directly rather than through a stable interface,
|
|
162
|
-
* it accepts `typescript >=4.8.4 <6.1.0` and nothing above
|
|
163
|
-
*
|
|
164
|
-
* rshono's declarations compile the same under either, which is what makes this pin an app's business
|
|
228
|
+
* typescript-eslint reads TypeScript's compiler API directly rather than through a stable interface,
|
|
229
|
+
* so it accepts `typescript >=4.8.4 <6.1.0` and nothing above; `~6.0.3` is the newest that satisfies
|
|
230
|
+
* it. rshono's declarations compile the same under either, which is what makes this an app's business
|
|
165
231
|
* and not the framework's.
|
|
166
232
|
*
|
|
167
233
|
* When upstream widens the range, this constant and the ESLint feature's use of it are what to delete.
|
|
@@ -169,88 +235,128 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
169
235
|
|
|
170
236
|
;// CONCATENATED MODULE: ./src/features/deploy.ts
|
|
171
237
|
|
|
238
|
+
|
|
172
239
|
/**
|
|
173
|
-
* What a deploy target adds beyond the `deploy` line in `rshono.config.ts
|
|
174
|
-
* to read, and the template's to carry.
|
|
240
|
+
* What a deploy target adds beyond the `deploy` line in `rshono.config.ts`, which the template carries.
|
|
175
241
|
*
|
|
176
|
-
* Deliberately thin
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
},
|
|
209
|
-
// wrangler brings workerd, whose install script only picks the platform binary out of the optional
|
|
210
|
-
// dependency that already carries it — `workerd --version` answers without it having run.
|
|
211
|
-
allowBuilds: {
|
|
212
|
-
workerd: false
|
|
213
|
-
},
|
|
214
|
-
scripts: {
|
|
215
|
-
deploy: 'rshono build && wrangler deploy'
|
|
242
|
+
* Deliberately thin: the framework arranges its own output for every platform, and `rshono build`
|
|
243
|
+
* writes the one platform config that has to exist (`wrangler.jsonc`) if the project has none — a second
|
|
244
|
+
* copy generated here would only go stale. So a target contributes the commands that run and ship the
|
|
245
|
+
* build, the CLI they need, the directories to gitignore, and a note for the step no command covers.
|
|
246
|
+
*
|
|
247
|
+
* What the three script names promise is documented once, above `BASE_SCRIPTS` in `scripts.ts`. Only `node`
|
|
248
|
+
* has a `start`, because `rshono start` refuses a bundle built for anywhere else, and it needs no `preview`:
|
|
249
|
+
* `build` then `start` already is one.
|
|
250
|
+
*
|
|
251
|
+
* `pm` is here because two things have to be spelled for the app's package manager — the runner that fetches
|
|
252
|
+
* the uninstalled Vercel CLI ({@link PackageManager.dlx}), and every command in {@link Feature.platformSetup}.
|
|
253
|
+
*/ function deployFeatures(pm) {
|
|
254
|
+
const build = invoke(pm, 'build');
|
|
255
|
+
return {
|
|
256
|
+
// Where a Node build goes from here is a Dockerfile or a process manager, neither of which this can
|
|
257
|
+
// guess — so the target contributes only the command that runs what was built.
|
|
258
|
+
node: {
|
|
259
|
+
id: 'deploy-node',
|
|
260
|
+
scripts: {
|
|
261
|
+
start: 'rshono start'
|
|
262
|
+
},
|
|
263
|
+
scriptHelp: {
|
|
264
|
+
start: 'run the build that exists — what your host calls'
|
|
265
|
+
},
|
|
266
|
+
platformSetup: [
|
|
267
|
+
'The two commands a host asks for:',
|
|
268
|
+
'',
|
|
269
|
+
`- **Build** — \`${pm.name} install && ${build}\``,
|
|
270
|
+
`- **Start** — \`${invoke(pm, 'start')}\``,
|
|
271
|
+
'',
|
|
272
|
+
`In a Dockerfile, the same pair: \`RUN ${build}\`, then \`CMD ["${pm.name}", "start"]\`.`
|
|
273
|
+
].join('\n')
|
|
216
274
|
},
|
|
217
|
-
|
|
218
|
-
'
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
275
|
+
cloudflare: {
|
|
276
|
+
id: 'deploy-cloudflare',
|
|
277
|
+
devDependencies: {
|
|
278
|
+
wrangler: TOOL_VERSIONS.wrangler
|
|
279
|
+
},
|
|
280
|
+
// The only two install scripts a scaffolded app can end up with, and wrangler brings both. Each
|
|
281
|
+
// one merely picks the platform binary out of the optional dependency that already carries it, so
|
|
282
|
+
// neither needs to run — `workerd --version` and `esbuild --version` both answer without it.
|
|
283
|
+
allowBuilds: {
|
|
284
|
+
esbuild: false,
|
|
285
|
+
workerd: false
|
|
286
|
+
},
|
|
287
|
+
// `wrangler dev` is the one preview that runs the code in the runtime it will actually run in:
|
|
288
|
+
// workerd, not Node, serving the assets the build assembled. Both scripts read the wrangler.jsonc the
|
|
289
|
+
// build wrote, so nothing here has to know where the bundle or the assets went.
|
|
290
|
+
scripts: {
|
|
291
|
+
preview: 'rshono build && wrangler dev',
|
|
292
|
+
deploy: 'rshono build && wrangler deploy'
|
|
293
|
+
},
|
|
294
|
+
scriptHelp: {
|
|
295
|
+
preview: 'build, then run it in workerd — port 8787',
|
|
296
|
+
deploy: 'build, then ship it to Cloudflare'
|
|
297
|
+
},
|
|
298
|
+
gitignore: [
|
|
299
|
+
'.wrangler/'
|
|
300
|
+
],
|
|
301
|
+
notes: [
|
|
302
|
+
'The first build writes wrangler.jsonc — yours to edit after that.'
|
|
303
|
+
],
|
|
304
|
+
platformSetup: [
|
|
305
|
+
`Building from a git repo instead: set Workers Builds' **Build command** to \`${build}\`.`,
|
|
306
|
+
'Its deploy command already defaults to `npx wrangler deploy`, and it installs dependencies itself.'
|
|
307
|
+
].join('\n')
|
|
228
308
|
},
|
|
229
|
-
|
|
230
|
-
'
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
309
|
+
vercel: {
|
|
310
|
+
id: 'deploy-vercel',
|
|
311
|
+
// `--prod` because the script is called `deploy`: without it the CLI uploads to a throwaway preview
|
|
312
|
+
// URL, which is a useful thing to have but not what the word means. The local `preview` is a Node
|
|
313
|
+
// build run here — the platform has no way to run its own prebuilt output on your machine.
|
|
314
|
+
scripts: {
|
|
315
|
+
preview: 'rshono build --deploy node && rshono start',
|
|
316
|
+
deploy: `rshono build && ${pm.dlx} vercel deploy --prebuilt --prod`
|
|
317
|
+
},
|
|
318
|
+
scriptHelp: {
|
|
319
|
+
preview: 'build for Node and run that here',
|
|
320
|
+
deploy: 'build, then upload it to production'
|
|
321
|
+
},
|
|
322
|
+
gitignore: [
|
|
323
|
+
'.vercel/'
|
|
324
|
+
],
|
|
325
|
+
notes: [
|
|
326
|
+
'--prebuilt uploads what rshono build assembled; the platform must not rebuild it.',
|
|
327
|
+
'Drop --prod from the deploy script for a preview URL instead.'
|
|
328
|
+
],
|
|
329
|
+
platformSetup: [
|
|
330
|
+
`Deploying from CI instead: the same \`${invoke(pm, 'deploy')}\`, with \`VERCEL_ORG_ID\`, \`VERCEL_PROJECT_ID\``,
|
|
331
|
+
'and a CLI token in the environment.',
|
|
332
|
+
'',
|
|
333
|
+
`If you let Vercel build the repo itself, set **Framework Preset** to Other — \`hono\` is otherwise`,
|
|
334
|
+
`detected as the Hono preset — and **Build Command** to \`${build}\`.`
|
|
335
|
+
].join('\n')
|
|
240
336
|
},
|
|
241
|
-
|
|
242
|
-
'
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
337
|
+
'aws-lambda': {
|
|
338
|
+
id: 'deploy-aws-lambda',
|
|
339
|
+
// No CLI to wrap, and no upload this could guess at. `preview` still applies — the bundle is a Node
|
|
340
|
+
// handler, so it runs here.
|
|
341
|
+
scripts: {
|
|
342
|
+
preview: 'rshono build --deploy node && rshono start'
|
|
343
|
+
},
|
|
344
|
+
scriptHelp: {
|
|
345
|
+
preview: 'build for Node and run that here'
|
|
346
|
+
},
|
|
347
|
+
notes: [
|
|
348
|
+
'Use a Function URL in RESPONSE_STREAM mode — a buffered invoke mode drops the streaming.'
|
|
349
|
+
],
|
|
350
|
+
platformSetup: [
|
|
351
|
+
`There is no settings page here; the upload is yours to script. A job needs \`${pm.name} install && ${build}\`,`,
|
|
352
|
+
'then the function package: `dist/`, plus `node_modules` for any dependency of your own, which the server',
|
|
353
|
+
'bundle leaves external.'
|
|
354
|
+
].join('\n')
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function deployFeature(target, pm) {
|
|
359
|
+
return deployFeatures(pm)[target];
|
|
254
360
|
}
|
|
255
361
|
|
|
256
362
|
;// CONCATENATED MODULE: ./src/features/quality.ts
|
|
@@ -260,8 +366,10 @@ function deployFeature(target) {
|
|
|
260
366
|
* deduplicates by `id`, so `formatter: 'biome', linter: 'biome'` contributes one set of files, one
|
|
261
367
|
* dependency and one pair of scripts.
|
|
262
368
|
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
369
|
+
* A formatter brings `format:check` beside `format`, because the writing half and the CI half want
|
|
370
|
+
* different exit-code behaviour: `format` rewrites files, `format:check` fails instead. A linter brings
|
|
371
|
+
* `lint:fix` beside `lint`, for the same reason in the other direction — `lint` is already the failing
|
|
372
|
+
* one. Biome adds a `check` of its own, which is the pair of them in a single pass.
|
|
265
373
|
*/ const PRETTIER = {
|
|
266
374
|
id: 'prettier',
|
|
267
375
|
overlays: [
|
|
@@ -302,12 +410,11 @@ const OXLINT = {
|
|
|
302
410
|
}
|
|
303
411
|
};
|
|
304
412
|
/**
|
|
305
|
-
* The one feature that changes a dependency the framework otherwise decides: typescript-eslint cannot
|
|
306
|
-
* installed alongside the TypeScript rshono is tested against, so an ESLint app pins the newest one
|
|
307
|
-
* peer range accepts (see {@link ESLINT_TYPESCRIPT}).
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
* so the config it ships hands the whole program to the parser rather than linting file by file.
|
|
413
|
+
* The one feature that changes a dependency the framework otherwise decides: typescript-eslint cannot
|
|
414
|
+
* be installed alongside the TypeScript rshono is tested against, so an ESLint app pins the newest one
|
|
415
|
+
* its peer range accepts (see {@link ESLINT_TYPESCRIPT}). Its rules are type-aware — the reason to
|
|
416
|
+
* reach for ESLint over a syntax-only linter — so the config it ships hands the parser the whole
|
|
417
|
+
* program rather than linting file by file.
|
|
311
418
|
*/ const ESLINT = {
|
|
312
419
|
id: 'eslint',
|
|
313
420
|
overlays: [
|
|
@@ -363,14 +470,13 @@ function linterFeature(linter) {
|
|
|
363
470
|
;// CONCATENATED MODULE: ./src/features/styling.ts
|
|
364
471
|
|
|
365
472
|
/**
|
|
366
|
-
* Tailwind is a PostCSS plugin and nothing more, which is the whole of this feature: four packages,
|
|
367
|
-
* an overlay carrying
|
|
368
|
-
*
|
|
369
|
-
*
|
|
473
|
+
* Tailwind is a PostCSS plugin and nothing more, which is the whole of this feature: four packages,
|
|
474
|
+
* plus an overlay carrying `postcss.config.mjs`, an `rshono.config.ts` whose `rspack` hook puts
|
|
475
|
+
* postcss-loader in front of the CSS parser, a Tailwind entry stylesheet, and the two views rewritten
|
|
476
|
+
* in utilities.
|
|
370
477
|
*
|
|
371
478
|
* `postcss` and `postcss-loader` are the app's dependencies rather than the framework's — rshono
|
|
372
|
-
* compiles CSS natively
|
|
373
|
-
* install one.
|
|
479
|
+
* compiles CSS natively, so an app that does not want a plugin chain does not install one.
|
|
374
480
|
*/ const TAILWIND = {
|
|
375
481
|
id: 'tailwind',
|
|
376
482
|
overlays: [
|
|
@@ -396,9 +502,12 @@ function stylingFeature(styling) {
|
|
|
396
502
|
* The features a set of answers selects, in application order — so an overlay listed later wins a file
|
|
397
503
|
* both of them ship. Deduplicated by `id`, which is what lets one feature answer two questions (Biome
|
|
398
504
|
* is both the formatter and the linter) without contributing twice.
|
|
399
|
-
|
|
505
|
+
*
|
|
506
|
+
* `pm` reaches the deploy target because one script has to name the runner that fetches an uninstalled
|
|
507
|
+
* CLI; nothing else here depends on which package manager the app is for.
|
|
508
|
+
*/ function selectFeatures(answers, pm) {
|
|
400
509
|
const selected = [
|
|
401
|
-
deployFeature(answers.deploy),
|
|
510
|
+
deployFeature(answers.deploy, pm),
|
|
402
511
|
stylingFeature(answers.styling),
|
|
403
512
|
formatterFeature(answers.formatter),
|
|
404
513
|
linterFeature(answers.linter),
|
|
@@ -416,6 +525,22 @@ function stylingFeature(styling) {
|
|
|
416
525
|
|
|
417
526
|
;// CONCATENATED MODULE: ./src/options.ts
|
|
418
527
|
|
|
528
|
+
/*
|
|
529
|
+
* The names each option accepts, spelled once. The types below are derived from them, the CLI validates
|
|
530
|
+
* its flags against them and prints them in `--help`, and `pm.ts` recognises a package manager by them
|
|
531
|
+
* — so a name added here reaches all three without a second list to remember.
|
|
532
|
+
*/ const FORMATTER_NAMES = [
|
|
533
|
+
'prettier',
|
|
534
|
+
'biome',
|
|
535
|
+
'oxfmt',
|
|
536
|
+
'none'
|
|
537
|
+
];
|
|
538
|
+
const LINTER_NAMES = [
|
|
539
|
+
'oxlint',
|
|
540
|
+
'eslint',
|
|
541
|
+
'biome',
|
|
542
|
+
'none'
|
|
543
|
+
];
|
|
419
544
|
const PACKAGE_MANAGERS = [
|
|
420
545
|
'npm',
|
|
421
546
|
'pnpm',
|
|
@@ -426,9 +551,6 @@ const DEPLOY_TARGET_NAMES = DEPLOY_TARGETS.map((target)=>target.name);
|
|
|
426
551
|
function deployHint(name) {
|
|
427
552
|
return DEPLOY_TARGETS.find((target)=>target.name === name)?.hint ?? '';
|
|
428
553
|
}
|
|
429
|
-
function isDeployTarget(value) {
|
|
430
|
-
return DEPLOY_TARGET_NAMES.includes(value);
|
|
431
|
-
}
|
|
432
554
|
const QUALITY_PRESETS = [
|
|
433
555
|
{
|
|
434
556
|
id: 'prettier-oxlint',
|
|
@@ -486,16 +608,13 @@ const QUALITY_PRESETS = [
|
|
|
486
608
|
return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(name) && name.length <= 214;
|
|
487
609
|
}
|
|
488
610
|
|
|
611
|
+
;// CONCATENATED MODULE: external "node:fs"
|
|
612
|
+
|
|
613
|
+
;// CONCATENATED MODULE: external "node:path"
|
|
614
|
+
|
|
489
615
|
;// CONCATENATED MODULE: ./src/pkg.ts
|
|
490
616
|
|
|
491
|
-
|
|
492
|
-
* The scripts every app gets. `start` is not among them: it is the *Node* launcher, and the deploy
|
|
493
|
-
* features each contribute the command their own platform runs what was built with.
|
|
494
|
-
*/ const BASE_SCRIPTS = {
|
|
495
|
-
dev: 'rshono dev',
|
|
496
|
-
build: 'rshono build',
|
|
497
|
-
typecheck: 'tsc --noEmit'
|
|
498
|
-
};
|
|
617
|
+
|
|
499
618
|
/** Field order in the emitted file — the conventional reading order, and stable so snapshots are too. */ const FIELD_ORDER = [
|
|
500
619
|
'name',
|
|
501
620
|
'version',
|
|
@@ -511,48 +630,35 @@ function sorted(record) {
|
|
|
511
630
|
return Object.fromEntries(Object.entries(record).sort(([a], [b])=>a < b ? -1 : 1));
|
|
512
631
|
}
|
|
513
632
|
/**
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
* the optional dependency that already carries it — rshono's own repo denies it for the same reason.
|
|
517
|
-
*/ const BASE_ALLOW_BUILDS = {
|
|
518
|
-
esbuild: false
|
|
519
|
-
};
|
|
520
|
-
/**
|
|
521
|
-
* pnpm's settings for the new app — written for pnpm and for nobody else.
|
|
633
|
+
* pnpm's settings for the new app, written only when a feature has something to put in them. `null`
|
|
634
|
+
* means there is nothing to say, so no file is written.
|
|
522
635
|
*
|
|
523
|
-
* It exists for one field
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
* `pnpm approve-builds` before it has rendered a page once.
|
|
636
|
+
* It exists for one field, `allowBuilds`. pnpm fails an install — and every `pnpm dev` after it —
|
|
637
|
+
* until the project has said whether a dependency's install script should run. Nothing rshono itself
|
|
638
|
+
* installs has one, so most apps get no file; the packages that do (wrangler's esbuild and workerd)
|
|
639
|
+
* declare their answer on the feature that brings them.
|
|
528
640
|
*
|
|
529
|
-
*
|
|
530
|
-
* package projects included. What lands here is a decision about *this* app: a scaffolded file the app
|
|
531
|
-
* owns from then on, not something the framework reaches back into.
|
|
641
|
+
* A file rather than a `pnpm` key in `package.json`, which pnpm 11 no longer reads.
|
|
532
642
|
*/ function buildPnpmSettings(features) {
|
|
533
|
-
const allowBuilds = {
|
|
534
|
-
...BASE_ALLOW_BUILDS
|
|
535
|
-
};
|
|
643
|
+
const allowBuilds = {};
|
|
536
644
|
for (const feature of features)Object.assign(allowBuilds, feature.allowBuilds);
|
|
645
|
+
const entries = Object.entries(sorted(allowBuilds));
|
|
646
|
+
if (entries.length === 0) return null;
|
|
537
647
|
return [
|
|
538
648
|
'# Which dependencies may run an install script. pnpm runs none it has not been told about, and',
|
|
539
649
|
'# fails the install rather than skip one quietly — so anything added later belongs here too.',
|
|
540
650
|
'# `false` means the script was looked at: these ship their real binary as an optional dependency.',
|
|
541
651
|
'allowBuilds:',
|
|
542
|
-
...
|
|
652
|
+
...entries.map(([name, allowed])=>` ${name}: ${allowed}`),
|
|
543
653
|
''
|
|
544
654
|
].join('\n');
|
|
545
655
|
}
|
|
546
656
|
/**
|
|
547
657
|
* Assembles `package.json` from the answers and whatever the selected features contribute.
|
|
548
658
|
*
|
|
549
|
-
* Dependencies are sorted by name and scripts
|
|
550
|
-
*
|
|
551
|
-
* identical output, which is what makes the generated manifest snapshot-testable.
|
|
659
|
+
* Dependencies are sorted by name and scripts keep the order {@link buildScripts} gives them — so two runs
|
|
660
|
+
* with the same answers produce byte-identical output, which is what makes the manifest snapshot-testable.
|
|
552
661
|
*/ function buildPackageJson(answers, features, pm) {
|
|
553
|
-
const scripts = {
|
|
554
|
-
...BASE_SCRIPTS
|
|
555
|
-
};
|
|
556
662
|
const dependencies = {
|
|
557
663
|
'@rshono/core': RSHONO_RANGE,
|
|
558
664
|
hono: FRAMEWORK_DEPS.hono,
|
|
@@ -565,7 +671,6 @@ function sorted(record) {
|
|
|
565
671
|
typescript: FRAMEWORK_DEPS.typescript
|
|
566
672
|
};
|
|
567
673
|
for (const feature of features){
|
|
568
|
-
Object.assign(scripts, feature.scripts);
|
|
569
674
|
Object.assign(dependencies, feature.dependencies);
|
|
570
675
|
Object.assign(devDependencies, feature.devDependencies);
|
|
571
676
|
}
|
|
@@ -574,12 +679,11 @@ function sorted(record) {
|
|
|
574
679
|
version: '0.1.0',
|
|
575
680
|
private: true,
|
|
576
681
|
type: 'module',
|
|
577
|
-
//
|
|
578
|
-
// Node finds out from their package manager rather than from a stack trace.
|
|
682
|
+
// Generated from the framework's own manifest, so the app's floor cannot drift below rshono's.
|
|
579
683
|
engines: {
|
|
580
|
-
node:
|
|
684
|
+
node: NODE_ENGINE
|
|
581
685
|
},
|
|
582
|
-
scripts,
|
|
686
|
+
scripts: buildScripts(features),
|
|
583
687
|
dependencies: sorted(dependencies),
|
|
584
688
|
devDependencies: sorted(devDependencies)
|
|
585
689
|
};
|
|
@@ -593,25 +697,27 @@ function sorted(record) {
|
|
|
593
697
|
return `${JSON.stringify(ordered, null, 2)}\n`;
|
|
594
698
|
}
|
|
595
699
|
|
|
596
|
-
;// CONCATENATED MODULE: external "node:fs"
|
|
597
|
-
|
|
598
|
-
;// CONCATENATED MODULE: external "node:path"
|
|
599
|
-
|
|
600
700
|
;// CONCATENATED MODULE: ./src/render.ts
|
|
601
701
|
|
|
602
|
-
|
|
603
|
-
|
|
702
|
+
/**
|
|
703
|
+
* `{{NAME}}`, deliberately not `__NAME__`: templates are real files that real tools run over, and in
|
|
704
|
+
* markdown `__NAME__` *is* strong emphasis — Prettier rewrites it to `**NAME**` and the token stops
|
|
705
|
+
* matching. `{{…}}` means nothing to any format these templates are written in.
|
|
706
|
+
*/ const TOKEN_PATTERN = /\{\{[A-Z][A-Z\d_]*\}\}/g;
|
|
707
|
+
function tokensFor(answers, features, pm) {
|
|
604
708
|
return {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
709
|
+
'{{PROJECT_NAME}}': answers.packageName,
|
|
710
|
+
'{{DEPLOY_TARGET}}': answers.deploy,
|
|
711
|
+
// Derived from the features rather than the answers, because all three are about the scripts the app
|
|
712
|
+
// actually got: its command table, the one command that ships it, and what its platform asks for.
|
|
713
|
+
'{{SCRIPT_TABLE}}': scriptTable(answers, features, pm),
|
|
714
|
+
'{{DEPLOY_STEP}}': deployStep(features, pm),
|
|
715
|
+
'{{PLATFORM_SETUP}}': features.map((feature)=>feature.platformSetup ?? '').join('')
|
|
610
716
|
};
|
|
611
717
|
}
|
|
612
718
|
/**
|
|
613
719
|
* Substitutes tokens, and throws on one it doesn't know — a typo in a template would otherwise ship a
|
|
614
|
-
* literal `
|
|
720
|
+
* literal `{{PORJECT_NAME}}` into somebody's new app, which no test of the generator's logic would
|
|
615
721
|
* catch.
|
|
616
722
|
*/ function render(contents, tokens, source) {
|
|
617
723
|
return contents.replace(TOKEN_PATTERN, (token)=>{
|
|
@@ -644,10 +750,9 @@ function readTemplateDir(dir) {
|
|
|
644
750
|
/**
|
|
645
751
|
* `_gitignore` → `.gitignore`, and so on for every dotfile.
|
|
646
752
|
*
|
|
647
|
-
* npm strips a literal `.gitignore` out of a published tarball, so a template cannot
|
|
648
|
-
*
|
|
649
|
-
*
|
|
650
|
-
* fix. It applies to the basename only, so `src/lib/_x.ts` is a dotfile but `templates/_x/y.ts` is not.
|
|
753
|
+
* npm strips a literal `.gitignore` out of a published tarball, so a template cannot contain one — it
|
|
754
|
+
* would exist in the repo, pass every local test, and be missing from the package everybody installs.
|
|
755
|
+
* Applies to the basename only, so `src/lib/_x.ts` is a dotfile but `templates/_x/y.ts` is not.
|
|
651
756
|
*/ function undotted(path) {
|
|
652
757
|
const segments = path.split(posix.sep);
|
|
653
758
|
const name = segments.pop();
|
|
@@ -670,8 +775,8 @@ function readTemplateDir(dir) {
|
|
|
670
775
|
* decisions and the I/O are separated so the whole matrix of answers can be asserted on in a test, and
|
|
671
776
|
* so `--dry-run` is the same code path minus the last step.
|
|
672
777
|
*/ function plan_plan(answers, pm) {
|
|
673
|
-
const features = selectFeatures(answers);
|
|
674
|
-
const tokens = tokensFor(answers, pm);
|
|
778
|
+
const features = selectFeatures(answers, pm);
|
|
779
|
+
const tokens = tokensFor(answers, features, pm);
|
|
675
780
|
const raw = readTemplateDir(join(TEMPLATES_DIR, 'base'));
|
|
676
781
|
for (const feature of features){
|
|
677
782
|
for (const overlay of feature.overlays ?? []){
|
|
@@ -687,7 +792,9 @@ function readTemplateDir(dir) {
|
|
|
687
792
|
const gitignore = files.get('.gitignore');
|
|
688
793
|
if (gitignore) files.set('.gitignore', appendGitignore(gitignore, features));
|
|
689
794
|
files.set('package.json', buildPackageJson(answers, features, pm));
|
|
690
|
-
|
|
795
|
+
// Only for pnpm, and only when a feature brought an install script to answer for — see `buildPnpmSettings`.
|
|
796
|
+
const pnpmSettings = pm.name === 'pnpm' ? buildPnpmSettings(features) : null;
|
|
797
|
+
if (pnpmSettings) files.set('pnpm-workspace.yaml', pnpmSettings);
|
|
691
798
|
return {
|
|
692
799
|
// Sorted, so both the write order and a test's snapshot are stable.
|
|
693
800
|
files: new Map([
|
|
@@ -702,6 +809,7 @@ function readTemplateDir(dir) {
|
|
|
702
809
|
|
|
703
810
|
;// CONCATENATED MODULE: ./src/pm.ts
|
|
704
811
|
|
|
812
|
+
|
|
705
813
|
const INSTALL = {
|
|
706
814
|
npm: [
|
|
707
815
|
'install'
|
|
@@ -720,20 +828,27 @@ const RUN = {
|
|
|
720
828
|
yarn: 'yarn',
|
|
721
829
|
bun: 'bun'
|
|
722
830
|
};
|
|
831
|
+
const DLX = {
|
|
832
|
+
npm: 'npx',
|
|
833
|
+
pnpm: 'pnpm dlx',
|
|
834
|
+
yarn: 'yarn dlx',
|
|
835
|
+
bun: 'bunx'
|
|
836
|
+
};
|
|
723
837
|
function isKnown(name) {
|
|
724
|
-
return name
|
|
838
|
+
return PACKAGE_MANAGERS.includes(name);
|
|
725
839
|
}
|
|
726
840
|
function packageManager(name, version) {
|
|
727
841
|
return {
|
|
728
842
|
name,
|
|
729
843
|
version,
|
|
730
844
|
install: INSTALL[name],
|
|
731
|
-
run: RUN[name]
|
|
845
|
+
run: RUN[name],
|
|
846
|
+
dlx: DLX[name]
|
|
732
847
|
};
|
|
733
848
|
}
|
|
734
849
|
/**
|
|
735
|
-
* Which package manager invoked us. Every one of them sets `npm_config_user_agent`
|
|
736
|
-
* spawns — `pnpm/11.9.0 npm/? node/v22.14.0 darwin arm64` — so `
|
|
850
|
+
* Which package manager invoked us. Every one of them sets `npm_config_user_agent` on the process it
|
|
851
|
+
* spawns — `pnpm/11.9.0 npm/? node/v22.14.0 darwin arm64` — so `pnx @rshono/create` scaffolds a pnpm
|
|
737
852
|
* project without asking, and the exact version comes along for the `packageManager` field.
|
|
738
853
|
*
|
|
739
854
|
* Falls back to npm, which is also what a bare `node bin/create-rshono.mjs` gets.
|
|
@@ -750,12 +865,6 @@ function packageManager(name, version) {
|
|
|
750
865
|
*/ function runInstall(pm, cwd) {
|
|
751
866
|
return run(pm, pm.install, cwd);
|
|
752
867
|
}
|
|
753
|
-
/** `<pm> run <script>` — the one form every package manager accepts, Yarn v1 included. */ function runScript(pm, script, cwd) {
|
|
754
|
-
return run(pm, [
|
|
755
|
-
'run',
|
|
756
|
-
script
|
|
757
|
-
], cwd);
|
|
758
|
-
}
|
|
759
868
|
function run(pm, args, cwd) {
|
|
760
869
|
const result = spawnSync(pm.name, args, {
|
|
761
870
|
cwd,
|
|
@@ -778,15 +887,20 @@ function run(pm, args, cwd) {
|
|
|
778
887
|
'.vscode',
|
|
779
888
|
'Thumbs.db'
|
|
780
889
|
]);
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
890
|
+
/**
|
|
891
|
+
* What is already at the target path, ignoring the entries a fresh clone or an editor leaves behind —
|
|
892
|
+
* which is what decides whether scaffolding into it is safe.
|
|
893
|
+
*
|
|
894
|
+
* A path that does not exist yet is no conflict. A path that exists and is *not* a directory throws
|
|
895
|
+
* rather than reporting an empty list, since `--force` should not write into one either — otherwise
|
|
896
|
+
* `create-rshono README.md` gets as far as `mkdir` before failing on a raw ENOTDIR.
|
|
897
|
+
*/ function conflictingEntries(dir) {
|
|
898
|
+
const stats = statSync(dir, {
|
|
899
|
+
throwIfNoEntry: false
|
|
900
|
+
});
|
|
901
|
+
if (!stats) return [];
|
|
902
|
+
if (!stats.isDirectory()) throw new Error(`${dir} already exists and is not a directory.`);
|
|
903
|
+
return readdirSync(dir).filter((entry)=>!IGNORED_ENTRIES.has(entry));
|
|
790
904
|
}
|
|
791
905
|
/**
|
|
792
906
|
* Writes the plan. Directories are created as needed, and files are written with the plan's own
|
|
@@ -808,7 +922,16 @@ function inspectTarget(dir) {
|
|
|
808
922
|
/**
|
|
809
923
|
* The generator without the CLI around it: answers in, the exact set of files out. This is what the
|
|
810
924
|
* test suite asserts on — the whole matrix of options, in memory, with no directory to clean up — and
|
|
811
|
-
* what another tool would call to scaffold an app itself
|
|
925
|
+
* what another tool would call to scaffold an app itself:
|
|
926
|
+
*
|
|
927
|
+
* ```ts
|
|
928
|
+
* import { packageManager, plan, writePlan } from '@rshono/create';
|
|
929
|
+
*
|
|
930
|
+
* const answers = { packageName: 'my-app', deploy: 'node', styling: 'css', formatter: 'prettier', linter: 'oxlint' };
|
|
931
|
+
* writePlan(plan(answers, packageManager('npm')), './my-app');
|
|
932
|
+
* ```
|
|
933
|
+
*
|
|
934
|
+
* `package.json` is assembled inside `plan`, so nothing here needs to be composed by hand.
|
|
812
935
|
*
|
|
813
936
|
* @packageDocumentation
|
|
814
937
|
*/
|
|
@@ -818,23 +941,22 @@ function inspectTarget(dir) {
|
|
|
818
941
|
|
|
819
942
|
|
|
820
943
|
|
|
821
|
-
|
|
822
944
|
var __webpack_exports__DEPLOY_TARGET_NAMES = __webpack_exports__.bp;
|
|
823
945
|
var __webpack_exports__ESLINT_TYPESCRIPT = __webpack_exports__.ml;
|
|
946
|
+
var __webpack_exports__FORMATTER_NAMES = __webpack_exports__.wC;
|
|
824
947
|
var __webpack_exports__FRAMEWORK_DEPS = __webpack_exports__.e7;
|
|
948
|
+
var __webpack_exports__LINTER_NAMES = __webpack_exports__.At;
|
|
825
949
|
var __webpack_exports__PACKAGE_MANAGERS = __webpack_exports__.Ab;
|
|
826
950
|
var __webpack_exports__QUALITY_PRESETS = __webpack_exports__.pm;
|
|
827
951
|
var __webpack_exports__RSHONO_RANGE = __webpack_exports__.s_;
|
|
828
952
|
var __webpack_exports__TOOL_VERSIONS = __webpack_exports__.RM;
|
|
829
|
-
var
|
|
953
|
+
var __webpack_exports__conflictingEntries = __webpack_exports__.dh;
|
|
830
954
|
var __webpack_exports__deployHint = __webpack_exports__.P8;
|
|
831
955
|
var __webpack_exports__detectPackageManager = __webpack_exports__.Lv;
|
|
832
|
-
var __webpack_exports__inspectTarget = __webpack_exports__.WL;
|
|
833
|
-
var __webpack_exports__isDeployTarget = __webpack_exports__.p1;
|
|
834
956
|
var __webpack_exports__isValidPackageName = __webpack_exports__.eW;
|
|
835
957
|
var __webpack_exports__packageManager = __webpack_exports__.VZ;
|
|
836
958
|
var __webpack_exports__plan = __webpack_exports__.et;
|
|
837
959
|
var __webpack_exports__selectFeatures = __webpack_exports__.N7;
|
|
838
960
|
var __webpack_exports__toPackageName = __webpack_exports__.PQ;
|
|
839
961
|
var __webpack_exports__writePlan = __webpack_exports__.pD;
|
|
840
|
-
export { __webpack_exports__DEPLOY_TARGET_NAMES as DEPLOY_TARGET_NAMES, __webpack_exports__ESLINT_TYPESCRIPT as ESLINT_TYPESCRIPT, __webpack_exports__FRAMEWORK_DEPS as FRAMEWORK_DEPS, __webpack_exports__PACKAGE_MANAGERS as PACKAGE_MANAGERS, __webpack_exports__QUALITY_PRESETS as QUALITY_PRESETS, __webpack_exports__RSHONO_RANGE as RSHONO_RANGE, __webpack_exports__TOOL_VERSIONS as TOOL_VERSIONS,
|
|
962
|
+
export { __webpack_exports__DEPLOY_TARGET_NAMES as DEPLOY_TARGET_NAMES, __webpack_exports__ESLINT_TYPESCRIPT as ESLINT_TYPESCRIPT, __webpack_exports__FORMATTER_NAMES as FORMATTER_NAMES, __webpack_exports__FRAMEWORK_DEPS as FRAMEWORK_DEPS, __webpack_exports__LINTER_NAMES as LINTER_NAMES, __webpack_exports__PACKAGE_MANAGERS as PACKAGE_MANAGERS, __webpack_exports__QUALITY_PRESETS as QUALITY_PRESETS, __webpack_exports__RSHONO_RANGE as RSHONO_RANGE, __webpack_exports__TOOL_VERSIONS as TOOL_VERSIONS, __webpack_exports__conflictingEntries as conflictingEntries, __webpack_exports__deployHint as deployHint, __webpack_exports__detectPackageManager as detectPackageManager, __webpack_exports__isValidPackageName as isValidPackageName, __webpack_exports__packageManager as packageManager, __webpack_exports__plan as plan, __webpack_exports__selectFeatures as selectFeatures, __webpack_exports__toPackageName as toPackageName, __webpack_exports__writePlan as writePlan };
|