@valbuild/init 0.53.0 → 0.55.0
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/main/dist/valbuild-init-main.cjs.dev.js +220 -182
- package/main/dist/valbuild-init-main.cjs.prod.js +220 -182
- package/main/dist/valbuild-init-main.esm.js +220 -182
- package/package.json +2 -1
- package/src/init.ts +95 -71
- package/src/templates.ts +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valbuild/init",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.0",
|
|
4
4
|
"description": "Initialize a new val.build project",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./main": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"./package.json": "./package.json"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
13
14
|
"test": "jest"
|
|
14
15
|
},
|
|
15
16
|
"bin": {
|
package/src/init.ts
CHANGED
|
@@ -51,7 +51,7 @@ function walk(dir: string, skip: RegExp = /node_modules|.git/): string[] {
|
|
|
51
51
|
maxResetLength = Math.max(maxResetLength, m.length);
|
|
52
52
|
process.stdout.write(m + " ".repeat(maxResetLength - m.length));
|
|
53
53
|
return fs.readdirSync(dir).reduce((files, fileOrDirName) => {
|
|
54
|
-
const fileOrDirPath = [dir, fileOrDirName].join("/"); // always use / as path separator - should work on windows as well?
|
|
54
|
+
const fileOrDirPath = [dir, fileOrDirName].join("/"); // always use / as path separator since we are doing .endsWith("/foo/bar.ts") when checking for files and we thought this would make it easier (if you are reading this and wondering wtf, then maybe not :) - should work on windows as well?
|
|
55
55
|
if (fs.statSync(fileOrDirPath).isDirectory() && !skip.test(fileOrDirName)) {
|
|
56
56
|
return files.concat(walk(fileOrDirPath));
|
|
57
57
|
}
|
|
@@ -65,8 +65,8 @@ type Analysis = Partial<{
|
|
|
65
65
|
srcDir: string;
|
|
66
66
|
packageJsonDir: string;
|
|
67
67
|
valConfigPath: string;
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
isTypeScript: boolean;
|
|
69
|
+
isJavaScript: boolean;
|
|
70
70
|
|
|
71
71
|
// Val package:
|
|
72
72
|
isValInstalled: boolean;
|
|
@@ -179,8 +179,8 @@ const analyze = async (root: string, files: string[]): Promise<Analysis> => {
|
|
|
179
179
|
files.find((file) => file.endsWith("/pages/_app.jsx"));
|
|
180
180
|
analysis.pagesRouter = !!pagesRouterAppPath;
|
|
181
181
|
if (pagesRouterAppPath) {
|
|
182
|
-
analysis.
|
|
183
|
-
analysis.
|
|
182
|
+
analysis.isTypeScript = !!pagesRouterAppPath.endsWith(".tsx");
|
|
183
|
+
analysis.isJavaScript = !!pagesRouterAppPath.endsWith(".jsx");
|
|
184
184
|
analysis.srcDir = path.dirname(path.dirname(pagesRouterAppPath));
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -192,8 +192,8 @@ const analyze = async (root: string, files: string[]): Promise<Analysis> => {
|
|
|
192
192
|
analysis.appRouter = true;
|
|
193
193
|
analysis.appRouterLayoutPath = appRouterLayoutPath;
|
|
194
194
|
analysis.appRouterLayoutFile = fs.readFileSync(appRouterLayoutPath, "utf8");
|
|
195
|
-
analysis.
|
|
196
|
-
analysis.
|
|
195
|
+
analysis.isTypeScript = !!appRouterLayoutPath.endsWith(".tsx");
|
|
196
|
+
analysis.isJavaScript = !!appRouterLayoutPath.endsWith(".jsx");
|
|
197
197
|
analysis.appRouterPath = path.dirname(appRouterLayoutPath);
|
|
198
198
|
analysis.srcDir = path.dirname(analysis.appRouterPath);
|
|
199
199
|
}
|
|
@@ -267,10 +267,28 @@ async function plan(
|
|
|
267
267
|
logger.error("Install @valbuild/next first");
|
|
268
268
|
return { abort: true };
|
|
269
269
|
} else {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
270
|
+
if (!analysis.valVersionIsSatisfied) {
|
|
271
|
+
logger.warn(
|
|
272
|
+
` This init script expects @valbuild/next >= ${MIN_VAL_VERSION}. Found: ${analysis.valVersion}`
|
|
273
|
+
);
|
|
274
|
+
const answer = !defaultAnswers
|
|
275
|
+
? await confirm({
|
|
276
|
+
message: "Continue?",
|
|
277
|
+
default: false,
|
|
278
|
+
})
|
|
279
|
+
: false;
|
|
280
|
+
if (!answer) {
|
|
281
|
+
logger.error(
|
|
282
|
+
`Aborted: val version is not satisfied.\n\nInstall the @valbuild/next@${MIN_VAL_VERSION} package with your favorite package manager.\n\nExample:\n\n npm install -D @valbuild/next@${MIN_VAL_VERSION}\n`
|
|
283
|
+
);
|
|
284
|
+
return { abort: true };
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
logger.info(
|
|
288
|
+
` Val version: found ${analysis.valVersion} >= ${MIN_VAL_VERSION}`,
|
|
289
|
+
{ isGood: true }
|
|
290
|
+
);
|
|
291
|
+
}
|
|
274
292
|
}
|
|
275
293
|
if (!analysis.nextVersionIsSatisfied) {
|
|
276
294
|
logger.error(
|
|
@@ -283,17 +301,17 @@ async function plan(
|
|
|
283
301
|
{ isGood: true }
|
|
284
302
|
);
|
|
285
303
|
}
|
|
286
|
-
if (analysis.
|
|
304
|
+
if (analysis.isTypeScript) {
|
|
287
305
|
logger.info(" Use: TypeScript", { isGood: true });
|
|
288
306
|
plan.useTypescript = true;
|
|
289
307
|
}
|
|
290
|
-
if (analysis.
|
|
308
|
+
if (analysis.isJavaScript) {
|
|
291
309
|
logger.info(" Use: JavaScript", { isGood: true });
|
|
292
310
|
if (!plan.useTypescript) {
|
|
293
311
|
plan.useJavascript = true;
|
|
294
312
|
}
|
|
295
313
|
}
|
|
296
|
-
if (analysis.
|
|
314
|
+
if (analysis.isTypeScript) {
|
|
297
315
|
const tsconfigJsonPath = path.join(analysis.root, "tsconfig.json");
|
|
298
316
|
if (fs.statSync(tsconfigJsonPath).isFile()) {
|
|
299
317
|
logger.info(" tsconfig.json: found", { isGood: true });
|
|
@@ -341,51 +359,6 @@ async function plan(
|
|
|
341
359
|
logger.warn(" Git state: dirty");
|
|
342
360
|
}
|
|
343
361
|
|
|
344
|
-
if (analysis.valEslintVersion) {
|
|
345
|
-
if (analysis.isValEslintRulesConfigured) {
|
|
346
|
-
logger.info(" @valbuild/eslint-plugin rules configured", {
|
|
347
|
-
isGood: true,
|
|
348
|
-
});
|
|
349
|
-
} else {
|
|
350
|
-
if (analysis.eslintRcJsPath) {
|
|
351
|
-
logger.warn(
|
|
352
|
-
'Cannot patch eslint: found .eslintrc.js but can only patch JSON files (at the moment).\nAdd the following to your eslint config:\n\n "extends": ["plugin:@valbuild/recommended"]\n'
|
|
353
|
-
);
|
|
354
|
-
} else if (analysis.eslintRcJsonPath) {
|
|
355
|
-
const answer = !defaultAnswers
|
|
356
|
-
? await confirm({
|
|
357
|
-
message:
|
|
358
|
-
"Patch eslintrc.json to use the recommended Val eslint rules?",
|
|
359
|
-
default: true,
|
|
360
|
-
})
|
|
361
|
-
: true;
|
|
362
|
-
if (answer) {
|
|
363
|
-
const currentEslintRc = fs.readFileSync(
|
|
364
|
-
analysis.eslintRcJsonPath,
|
|
365
|
-
"utf-8"
|
|
366
|
-
);
|
|
367
|
-
const parsedEslint = JSON.parse(currentEslintRc);
|
|
368
|
-
if (typeof parsedEslint !== "object") {
|
|
369
|
-
logger.error(
|
|
370
|
-
`Could not patch eslint: ${analysis.eslintRcJsonPath} was not an object`
|
|
371
|
-
);
|
|
372
|
-
return { abort: true };
|
|
373
|
-
}
|
|
374
|
-
if (typeof parsedEslint.extends === "string") {
|
|
375
|
-
parsedEslint.extends = [parsedEslint.extends];
|
|
376
|
-
}
|
|
377
|
-
parsedEslint.extends = parsedEslint.extends || [];
|
|
378
|
-
parsedEslint.extends.push("plugin:@valbuild/recommended");
|
|
379
|
-
plan.updateEslint = {
|
|
380
|
-
path: analysis.eslintRcJsonPath,
|
|
381
|
-
source: JSON.stringify(parsedEslint, null, 2) + "\n",
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
} else {
|
|
385
|
-
logger.warn("Cannot patch eslint: failed to find eslint config file");
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
362
|
if (!analysis.isGitClean) {
|
|
390
363
|
while (plan.ignoreGitDirty === undefined) {
|
|
391
364
|
const answer = !defaultAnswers
|
|
@@ -397,17 +370,26 @@ async function plan(
|
|
|
397
370
|
plan.ignoreGitDirty = answer;
|
|
398
371
|
if (!answer) {
|
|
399
372
|
logger.error("Aborted: git state dirty");
|
|
400
|
-
return { abort: true
|
|
373
|
+
return { abort: true };
|
|
401
374
|
}
|
|
402
375
|
}
|
|
403
376
|
}
|
|
404
377
|
|
|
405
378
|
// New required files:
|
|
406
|
-
const valConfigPath = path.join(
|
|
379
|
+
const valConfigPath = path.join(
|
|
380
|
+
analysis.root,
|
|
381
|
+
analysis.isTypeScript ? "val.config.ts" : "val.config.js"
|
|
382
|
+
);
|
|
383
|
+
if (fs.existsSync(valConfigPath)) {
|
|
384
|
+
logger.error(
|
|
385
|
+
`Aborted: a Val config file: ${valConfigPath} already exists.`
|
|
386
|
+
);
|
|
387
|
+
return { abort: true };
|
|
388
|
+
}
|
|
407
389
|
|
|
408
390
|
plan.createConfigFile = {
|
|
409
391
|
path: valConfigPath,
|
|
410
|
-
source: VAL_CONFIG({}),
|
|
392
|
+
source: VAL_CONFIG(!!analysis.isTypeScript, {}),
|
|
411
393
|
};
|
|
412
394
|
|
|
413
395
|
const valUtilsDir = path.join(analysis.srcDir, "val");
|
|
@@ -418,7 +400,7 @@ async function plan(
|
|
|
418
400
|
|
|
419
401
|
const valServerPath = path.join(
|
|
420
402
|
valUtilsDir,
|
|
421
|
-
analysis.
|
|
403
|
+
analysis.isTypeScript ? "val.server.ts" : "val.server.js"
|
|
422
404
|
);
|
|
423
405
|
plan.createValServer = {
|
|
424
406
|
path: valServerPath,
|
|
@@ -433,7 +415,8 @@ async function plan(
|
|
|
433
415
|
analysis.appRouterPath || path.join(analysis.srcDir, "app"),
|
|
434
416
|
"(val)",
|
|
435
417
|
"val",
|
|
436
|
-
|
|
418
|
+
"[[...val]]",
|
|
419
|
+
analysis.isTypeScript ? "page.tsx" : "page.jsx"
|
|
437
420
|
);
|
|
438
421
|
const valPageImportPath = path
|
|
439
422
|
.relative(path.dirname(valAppPagePath), valConfigPath)
|
|
@@ -449,7 +432,8 @@ async function plan(
|
|
|
449
432
|
"(val)",
|
|
450
433
|
"api",
|
|
451
434
|
"val",
|
|
452
|
-
|
|
435
|
+
"[[...val]]",
|
|
436
|
+
analysis.isTypeScript ? "router.tsx" : "router.jsx"
|
|
453
437
|
);
|
|
454
438
|
const valRouterImportPath = path
|
|
455
439
|
.relative(path.dirname(valRouterPath), valServerPath)
|
|
@@ -473,7 +457,7 @@ async function plan(
|
|
|
473
457
|
plan.createValClient = {
|
|
474
458
|
path: path.join(
|
|
475
459
|
valUtilsDir,
|
|
476
|
-
analysis.
|
|
460
|
+
analysis.isTypeScript ? "val.client.ts" : "val.client.js"
|
|
477
461
|
),
|
|
478
462
|
source: VAL_CLIENT(valUtilsImportPath),
|
|
479
463
|
};
|
|
@@ -492,7 +476,7 @@ async function plan(
|
|
|
492
476
|
plan.createValRsc = {
|
|
493
477
|
path: path.join(
|
|
494
478
|
valUtilsDir,
|
|
495
|
-
analysis.
|
|
479
|
+
analysis.isTypeScript ? "val.rsc.ts" : "val.rsc.js"
|
|
496
480
|
),
|
|
497
481
|
source: VAL_SERVER(valUtilsImportPath),
|
|
498
482
|
};
|
|
@@ -501,10 +485,6 @@ async function plan(
|
|
|
501
485
|
}
|
|
502
486
|
}
|
|
503
487
|
|
|
504
|
-
if (analysis.eslintRcJsPath) {
|
|
505
|
-
logger.warn("ESLint config found: " + analysis.eslintRcJsPath);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
488
|
// Patches:
|
|
509
489
|
|
|
510
490
|
const NO_PATCH_WARNING =
|
|
@@ -576,6 +556,50 @@ async function plan(
|
|
|
576
556
|
logger.warn(NO_PATCH_WARNING);
|
|
577
557
|
}
|
|
578
558
|
|
|
559
|
+
if (analysis.valEslintVersion) {
|
|
560
|
+
if (analysis.isValEslintRulesConfigured) {
|
|
561
|
+
logger.warn(" @valbuild/eslint-plugin rules: already configured");
|
|
562
|
+
} else {
|
|
563
|
+
if (analysis.eslintRcJsPath) {
|
|
564
|
+
logger.warn(
|
|
565
|
+
'Cannot patch eslint: found .eslintrc.js but can only patch JSON files (at the moment).\nAdd the following to your eslint config:\n\n "extends": ["plugin:@valbuild/recommended"]\n'
|
|
566
|
+
);
|
|
567
|
+
} else if (analysis.eslintRcJsonPath) {
|
|
568
|
+
const answer = !defaultAnswers
|
|
569
|
+
? await confirm({
|
|
570
|
+
message:
|
|
571
|
+
"Patch eslintrc.json to use the recommended Val eslint rules?",
|
|
572
|
+
default: true,
|
|
573
|
+
})
|
|
574
|
+
: true;
|
|
575
|
+
if (answer) {
|
|
576
|
+
const currentEslintRc = fs.readFileSync(
|
|
577
|
+
analysis.eslintRcJsonPath,
|
|
578
|
+
"utf-8"
|
|
579
|
+
);
|
|
580
|
+
const parsedEslint = JSON.parse(currentEslintRc);
|
|
581
|
+
if (typeof parsedEslint !== "object") {
|
|
582
|
+
logger.error(
|
|
583
|
+
`Could not patch eslint: ${analysis.eslintRcJsonPath} was not an object`
|
|
584
|
+
);
|
|
585
|
+
return { abort: true };
|
|
586
|
+
}
|
|
587
|
+
if (typeof parsedEslint.extends === "string") {
|
|
588
|
+
parsedEslint.extends = [parsedEslint.extends];
|
|
589
|
+
}
|
|
590
|
+
parsedEslint.extends = parsedEslint.extends || [];
|
|
591
|
+
parsedEslint.extends.push("plugin:@valbuild/recommended");
|
|
592
|
+
plan.updateEslint = {
|
|
593
|
+
path: analysis.eslintRcJsonPath,
|
|
594
|
+
source: JSON.stringify(parsedEslint, null, 2) + "\n",
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
} else {
|
|
598
|
+
logger.warn("Cannot patch eslint: failed to find eslint config file");
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
579
603
|
return plan;
|
|
580
604
|
}
|
|
581
605
|
|
package/src/templates.ts
CHANGED
|
@@ -44,12 +44,14 @@ type ValConfig = {
|
|
|
44
44
|
valConfigPath?: string;
|
|
45
45
|
};
|
|
46
46
|
export const VAL_CONFIG = (
|
|
47
|
+
isTypeScript: boolean,
|
|
47
48
|
options: ValConfig
|
|
48
49
|
) => `import { initVal } from "@valbuild/next";
|
|
49
50
|
|
|
50
|
-
const { s, val, config } = initVal(${JSON.stringify(options, null, 2)});
|
|
51
|
+
const { s, c, val, config } = initVal(${JSON.stringify(options, null, 2)});
|
|
51
52
|
|
|
52
|
-
export {
|
|
53
|
+
${isTypeScript ? 'export type { t } from "@valbuild/next";' : ""};
|
|
54
|
+
export { s, c, val, config };
|
|
53
55
|
`;
|
|
54
56
|
|
|
55
57
|
export const VAL_API_ROUTER = (
|