create-newt-app 0.27.0 → 0.30.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/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +332 -128
- package/dist/index.js.map +1 -1
- package/dist/static/anti-slop/static/LICENSE +21 -0
- package/dist/static/anti-slop/static/index.ts +41 -0
- package/dist/static/anti-slop/static/rules/no-chained-type-assertions.ts +77 -0
- package/dist/static/anti-slop/static/rules/no-conditional-empty-object-spread.ts +49 -0
- package/dist/static/anti-slop/static/rules/no-known-value-widening.ts +247 -0
- package/dist/static/anti-slop/static/rules/no-module-mocking.ts +91 -0
- package/dist/static/anti-slop/static/rules/no-object-parameters.ts +126 -0
- package/dist/static/anti-slop/static/rules/no-reflect-apply.ts +28 -0
- package/dist/static/anti-slop/static/rules/no-reflect-get.ts +28 -0
- package/dist/static/anti-slop/static/rules/no-runtime-typeof.ts +67 -0
- package/dist/static/anti-slop/static/rules/no-shape-in-symbol-names.ts +39 -0
- package/dist/static/anti-slop/static/rules/no-unknown-parameters.ts +83 -0
- package/dist/static/anti-slop/static/rules/no-unknown-returns.ts +115 -0
- package/dist/static/anti-slop/static/rules/no-unknown-type-aliases.ts +70 -0
- package/dist/static/anti-slop/static/rules/no-unsafe-dictionary-type.ts +134 -0
- package/dist/static/anti-slop/static/rules/no-widen-then-assert.ts +366 -0
- package/dist/static/anti-slop/static/rules/require-safety-comment-for-type-assertion.ts +62 -0
- package/dist/static/anti-slop/static/shared/dictionary-types.ts +502 -0
- package/dist/static/anti-slop/static/shared/lexical-type-parameters.ts +61 -0
- package/dist/static/anti-slop/static/shared/reflect-method.ts +35 -0
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import ejs from "ejs";
|
|
|
10
10
|
import { existsSync, promises } from "fs";
|
|
11
11
|
import path from "path";
|
|
12
12
|
//#region package.json
|
|
13
|
-
var version = "0.
|
|
13
|
+
var version = "0.30.0";
|
|
14
14
|
var engines = { "node": ">=24.0.0" };
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/templates/root/index.ts
|
|
@@ -34,7 +34,10 @@ const root$2 = { templates: [
|
|
|
34
34
|
"turbo": "<%= versions.turbo %>",
|
|
35
35
|
"typescript": "<%= versions.typescript %>"
|
|
36
36
|
},
|
|
37
|
-
"
|
|
37
|
+
"pnpm": {
|
|
38
|
+
"onlyBuiltDependencies": ["better-sqlite3", "esbuild", "sharp", "unrs-resolver"]
|
|
39
|
+
},
|
|
40
|
+
"packageManager": "pnpm@10.34.5",
|
|
38
41
|
"engines": {
|
|
39
42
|
"node": ">=24.0.0"
|
|
40
43
|
}
|
|
@@ -110,10 +113,16 @@ dist
|
|
|
110
113
|
"inputs": ["$TURBO_DEFAULT$", ".env*"],
|
|
111
114
|
"outputs": [".next/**", "!.next/cache/**"]
|
|
112
115
|
},
|
|
113
|
-
"
|
|
116
|
+
<% if (linter === "oxc") { %> "typecheck": {
|
|
117
|
+
"dependsOn": ["^build"]
|
|
118
|
+
},<% } else { %> "lint": {
|
|
114
119
|
"dependsOn": ["^lint"],
|
|
115
120
|
"env": ["NODE_ENV"]
|
|
116
121
|
},
|
|
122
|
+
"lint:check": {
|
|
123
|
+
"dependsOn": ["^lint:check"],
|
|
124
|
+
"env": ["NODE_ENV"]
|
|
125
|
+
},<% } %>
|
|
117
126
|
"test": {
|
|
118
127
|
"dependsOn": ["^build"],
|
|
119
128
|
"outputs": ["coverage/**"]
|
|
@@ -737,7 +746,7 @@ export const authClient: ReturnType<typeof createAuthClient> = createAuthClient(
|
|
|
737
746
|
};
|
|
738
747
|
//#endregion
|
|
739
748
|
//#region src/templates/api/index.ts
|
|
740
|
-
const api$
|
|
749
|
+
const api$1 = { templates: [
|
|
741
750
|
{
|
|
742
751
|
when: (s) => !s.nestDiOnly && s.deployment !== "spa" && s.deployment !== "custom-server",
|
|
743
752
|
filename: "apps/api/package.json",
|
|
@@ -1246,7 +1255,7 @@ const dbPostgres = { templates: [
|
|
|
1246
1255
|
] };
|
|
1247
1256
|
//#endregion
|
|
1248
1257
|
//#region src/templates/ui/index.ts
|
|
1249
|
-
const ui$
|
|
1258
|
+
const ui$1 = { templates: [
|
|
1250
1259
|
{
|
|
1251
1260
|
filename: "packages/ui/package.json",
|
|
1252
1261
|
template: `{
|
|
@@ -1499,6 +1508,7 @@ const versions = {
|
|
|
1499
1508
|
"@nestjs/serve-static": "^5.0.0",
|
|
1500
1509
|
"@nestjs/testing": "^11.0.1",
|
|
1501
1510
|
"@next/eslint-plugin-next": "^16.3.0",
|
|
1511
|
+
"@oxlint/plugins": "^1.74.0",
|
|
1502
1512
|
"@shadcn/react": "^0.2.1",
|
|
1503
1513
|
"@swc/core": "^1.10.0",
|
|
1504
1514
|
"@tailwindcss/postcss": "^4.2.1",
|
|
@@ -1514,57 +1524,57 @@ const versions = {
|
|
|
1514
1524
|
"@types/react-dom": "19.2.3",
|
|
1515
1525
|
"@types/supertest": "^6.0.2",
|
|
1516
1526
|
"@vitest/coverage-v8": "^4.1.10",
|
|
1517
|
-
|
|
1527
|
+
auth: "^1.5.5",
|
|
1518
1528
|
"better-auth": "^1.2.8",
|
|
1519
1529
|
"better-sqlite3": "^12.11.1",
|
|
1520
1530
|
"class-variance-authority": "^0.7.1",
|
|
1521
|
-
|
|
1522
|
-
|
|
1531
|
+
clsx: "^2.1.1",
|
|
1532
|
+
cmdk: "^1.1.1",
|
|
1523
1533
|
"date-fns": "^4.2.1",
|
|
1524
|
-
|
|
1534
|
+
dotenv: "^17.3.1",
|
|
1525
1535
|
"dotenv-cli": "^11.0.0",
|
|
1526
1536
|
"embla-carousel-react": "^8.6.0",
|
|
1527
|
-
|
|
1537
|
+
eslint: "^9.39.1",
|
|
1528
1538
|
"eslint-config-prettier": "^10.1.1",
|
|
1529
1539
|
"eslint-plugin-only-warn": "^1.1.0",
|
|
1530
1540
|
"eslint-plugin-react": "^7.37.5",
|
|
1531
1541
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
1532
1542
|
"eslint-plugin-turbo": "^2.7.1",
|
|
1533
|
-
|
|
1543
|
+
globals: "^16.5.0",
|
|
1534
1544
|
"input-otp": "^1.4.2",
|
|
1535
|
-
|
|
1536
|
-
|
|
1545
|
+
jest: "^30.0.0",
|
|
1546
|
+
kysely: "^0.28.2",
|
|
1537
1547
|
"lucide-react": "^1.16.0",
|
|
1538
|
-
|
|
1548
|
+
next: "16.3.0",
|
|
1539
1549
|
"next-themes": "^0.4.6",
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1550
|
+
oxfmt: "^0.59.0",
|
|
1551
|
+
oxlint: "^1.74.0",
|
|
1552
|
+
pg: "^8.14.1",
|
|
1553
|
+
prettier: "^3.7.4",
|
|
1554
|
+
react: "^19.2.4",
|
|
1545
1555
|
"react-day-picker": "^10.0.1",
|
|
1546
1556
|
"react-dom": "^19.2.4",
|
|
1547
1557
|
"react-resizable-panels": "^4.11.1",
|
|
1548
|
-
|
|
1558
|
+
recharts: "^3.8.0",
|
|
1549
1559
|
"reflect-metadata": "^0.2.2",
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1560
|
+
rxjs: "^7.8.1",
|
|
1561
|
+
shadcn: "^4.7.0",
|
|
1562
|
+
sonner: "^2.0.7",
|
|
1553
1563
|
"source-map-support": "^0.5.21",
|
|
1554
|
-
|
|
1564
|
+
supertest: "^7.0.0",
|
|
1555
1565
|
"tailwind-merge": "^3.6.0",
|
|
1556
|
-
|
|
1566
|
+
tailwindcss: "^4.2.1",
|
|
1557
1567
|
"ts-jest": "^29.2.5",
|
|
1558
1568
|
"ts-loader": "^9.5.2",
|
|
1559
1569
|
"ts-node": "^10.9.2",
|
|
1560
1570
|
"tsconfig-paths": "^4.2.0",
|
|
1561
|
-
|
|
1562
|
-
|
|
1571
|
+
tsx: "^4.19.4",
|
|
1572
|
+
turbo: "^2.8.16",
|
|
1563
1573
|
"tw-animate-css": "^1.4.0",
|
|
1564
|
-
|
|
1574
|
+
typescript: "6.0.2",
|
|
1565
1575
|
"typescript-eslint": "^8.50.0",
|
|
1566
1576
|
"unplugin-swc": "^1.5.9",
|
|
1567
|
-
|
|
1577
|
+
vitest: "^4.1.10"
|
|
1568
1578
|
};
|
|
1569
1579
|
//#endregion
|
|
1570
1580
|
//#region src/templates/shadcn-ui/index.ts
|
|
@@ -3048,7 +3058,6 @@ function Calendar({
|
|
|
3048
3058
|
...classNames,
|
|
3049
3059
|
}}
|
|
3050
3060
|
components={{
|
|
3051
|
-
// eslint-disable-next-line react/prop-types
|
|
3052
3061
|
Root: ({ className, rootRef, ...props }) => {
|
|
3053
3062
|
return (
|
|
3054
3063
|
<div
|
|
@@ -3059,7 +3068,6 @@ function Calendar({
|
|
|
3059
3068
|
/>
|
|
3060
3069
|
)
|
|
3061
3070
|
},
|
|
3062
|
-
// eslint-disable-next-line react/prop-types
|
|
3063
3071
|
Chevron: ({ className, orientation, ...props }) => {
|
|
3064
3072
|
if (orientation === "left") {
|
|
3065
3073
|
return (
|
|
@@ -3881,7 +3889,7 @@ function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {
|
|
|
3881
3889
|
<CheckboxPrimitive.Root
|
|
3882
3890
|
data-slot="checkbox"
|
|
3883
3891
|
className={cn(
|
|
3884
|
-
"peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
|
|
3892
|
+
"peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary",
|
|
3885
3893
|
className
|
|
3886
3894
|
)}
|
|
3887
3895
|
{...props}
|
|
@@ -5597,7 +5605,7 @@ function FieldLabel({
|
|
|
5597
5605
|
<Label
|
|
5598
5606
|
data-slot="field-label"
|
|
5599
5607
|
className={cn(
|
|
5600
|
-
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border *:data-[slot=field]:p-2.5 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10",
|
|
5608
|
+
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-muted/50 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-3 has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/50 *:data-[slot=field]:p-2.5 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10",
|
|
5601
5609
|
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
|
|
5602
5610
|
className
|
|
5603
5611
|
)}
|
|
@@ -7285,7 +7293,7 @@ function RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {
|
|
|
7285
7293
|
<RadioPrimitive.Root
|
|
7286
7294
|
data-slot="radio-group-item"
|
|
7287
7295
|
className={cn(
|
|
7288
|
-
"group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
|
|
7296
|
+
"group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary",
|
|
7289
7297
|
className
|
|
7290
7298
|
)}
|
|
7291
7299
|
{...props}
|
|
@@ -8665,7 +8673,7 @@ function Switch({
|
|
|
8665
8673
|
data-slot="switch"
|
|
8666
8674
|
data-size={size}
|
|
8667
8675
|
className={cn(
|
|
8668
|
-
"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
8676
|
+
"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
8669
8677
|
className
|
|
8670
8678
|
)}
|
|
8671
8679
|
{...props}
|
|
@@ -10027,6 +10035,7 @@ export const config = [
|
|
|
10027
10035
|
...pluginReactHooks.configs.recommended.rules,
|
|
10028
10036
|
// React scope no longer necessary with new JSX transform.
|
|
10029
10037
|
"react/react-in-jsx-scope": "off",
|
|
10038
|
+
"react/prop-types": "off",
|
|
10030
10039
|
},
|
|
10031
10040
|
},
|
|
10032
10041
|
];`
|
|
@@ -10092,16 +10101,13 @@ export default config;`
|
|
|
10092
10101
|
//#region src/templates/root/templates/prettierrc.ts
|
|
10093
10102
|
var prettierrc_default = {
|
|
10094
10103
|
filename: ".prettierrc",
|
|
10095
|
-
template: `{
|
|
10096
|
-
"singleQuote": true,
|
|
10097
|
-
"trailingComma": "all"
|
|
10098
|
-
}`
|
|
10104
|
+
template: `{}`
|
|
10099
10105
|
};
|
|
10100
10106
|
//#endregion
|
|
10101
10107
|
//#region src/templates/eslint-config/index.ts
|
|
10102
10108
|
const web$1 = "apps/web";
|
|
10103
|
-
const api
|
|
10104
|
-
const ui
|
|
10109
|
+
const api = "apps/api";
|
|
10110
|
+
const ui = "packages/ui";
|
|
10105
10111
|
const root$1 = "";
|
|
10106
10112
|
const eslintConfig = {
|
|
10107
10113
|
templates: [
|
|
@@ -10129,49 +10135,49 @@ const eslintConfig = {
|
|
|
10129
10135
|
},
|
|
10130
10136
|
{
|
|
10131
10137
|
package: "@eslint/eslintrc",
|
|
10132
|
-
module: api
|
|
10138
|
+
module: api,
|
|
10133
10139
|
version: versions["@eslint/eslintrc"],
|
|
10134
10140
|
dev: true
|
|
10135
10141
|
},
|
|
10136
10142
|
{
|
|
10137
10143
|
package: "@eslint/js",
|
|
10138
|
-
module: api
|
|
10144
|
+
module: api,
|
|
10139
10145
|
version: versions["@eslint/js"],
|
|
10140
10146
|
dev: true
|
|
10141
10147
|
},
|
|
10142
10148
|
{
|
|
10143
10149
|
package: "eslint",
|
|
10144
|
-
module: api
|
|
10150
|
+
module: api,
|
|
10145
10151
|
version: versions.eslint,
|
|
10146
10152
|
dev: true
|
|
10147
10153
|
},
|
|
10148
10154
|
{
|
|
10149
10155
|
package: "eslint-config-prettier",
|
|
10150
|
-
module: api
|
|
10156
|
+
module: api,
|
|
10151
10157
|
version: versions["eslint-config-prettier"],
|
|
10152
10158
|
dev: true
|
|
10153
10159
|
},
|
|
10154
10160
|
{
|
|
10155
10161
|
package: "globals",
|
|
10156
|
-
module: api
|
|
10162
|
+
module: api,
|
|
10157
10163
|
version: versions.globals,
|
|
10158
10164
|
dev: true
|
|
10159
10165
|
},
|
|
10160
10166
|
{
|
|
10161
10167
|
package: "typescript-eslint",
|
|
10162
|
-
module: api
|
|
10168
|
+
module: api,
|
|
10163
10169
|
version: versions["typescript-eslint"],
|
|
10164
10170
|
dev: true
|
|
10165
10171
|
},
|
|
10166
10172
|
{
|
|
10167
10173
|
package: "eslint",
|
|
10168
|
-
module: ui
|
|
10174
|
+
module: ui,
|
|
10169
10175
|
version: versions.eslint,
|
|
10170
10176
|
dev: true
|
|
10171
10177
|
},
|
|
10172
10178
|
{
|
|
10173
10179
|
package: "@<%= projectName %>/eslint-config",
|
|
10174
|
-
module: ui
|
|
10180
|
+
module: ui,
|
|
10175
10181
|
version: "workspace:*",
|
|
10176
10182
|
dev: true
|
|
10177
10183
|
},
|
|
@@ -10194,25 +10200,30 @@ const eslintConfig = {
|
|
|
10194
10200
|
script: "eslint --max-warnings 0 && next typegen && tsc --noEmit"
|
|
10195
10201
|
},
|
|
10196
10202
|
{
|
|
10197
|
-
module: api
|
|
10203
|
+
module: api,
|
|
10198
10204
|
name: "lint",
|
|
10199
10205
|
script: `eslint "src/**/*.ts" --fix`
|
|
10200
10206
|
},
|
|
10201
10207
|
{
|
|
10202
|
-
module: api
|
|
10208
|
+
module: api,
|
|
10203
10209
|
name: "lint:check",
|
|
10204
|
-
script: `eslint "src/**/*.ts"`
|
|
10210
|
+
script: `eslint "src/**/*.ts" --max-warnings 0`
|
|
10205
10211
|
},
|
|
10206
10212
|
{
|
|
10207
|
-
module: ui
|
|
10213
|
+
module: ui,
|
|
10208
10214
|
name: "lint",
|
|
10209
10215
|
script: "eslint . --fix"
|
|
10210
10216
|
},
|
|
10211
10217
|
{
|
|
10212
|
-
module: ui
|
|
10218
|
+
module: ui,
|
|
10213
10219
|
name: "lint:check",
|
|
10214
10220
|
script: "eslint . --max-warnings 0"
|
|
10215
10221
|
},
|
|
10222
|
+
{
|
|
10223
|
+
module: root$1,
|
|
10224
|
+
name: "lint:check",
|
|
10225
|
+
script: "turbo run lint:check"
|
|
10226
|
+
},
|
|
10216
10227
|
{
|
|
10217
10228
|
module: root$1,
|
|
10218
10229
|
name: "format",
|
|
@@ -10233,7 +10244,48 @@ var oxlintrc_default = {
|
|
|
10233
10244
|
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
|
|
10234
10245
|
"categories": {
|
|
10235
10246
|
"correctness": "error"
|
|
10236
|
-
}
|
|
10247
|
+
}<% if (antiSlop) { %>,
|
|
10248
|
+
"ignorePatterns": ["tools/oxlint/anti-slop/**"],
|
|
10249
|
+
"jsPlugins": [{ "name": "anti-slop", "specifier": "./tools/oxlint/anti-slop/index.ts" }],
|
|
10250
|
+
"rules": {
|
|
10251
|
+
"anti-slop/no-chained-type-assertions": "error",
|
|
10252
|
+
"anti-slop/no-conditional-empty-object-spread": "error",
|
|
10253
|
+
"anti-slop/no-known-value-widening": "error",
|
|
10254
|
+
"anti-slop/no-module-mocking": "error",
|
|
10255
|
+
"anti-slop/no-object-parameters": "error",
|
|
10256
|
+
"anti-slop/no-reflect-apply": "error",
|
|
10257
|
+
"anti-slop/no-reflect-get": "error",
|
|
10258
|
+
"anti-slop/no-runtime-typeof": "error",
|
|
10259
|
+
"anti-slop/no-shape-in-symbol-names": "error",
|
|
10260
|
+
"anti-slop/no-unknown-parameters": "error",
|
|
10261
|
+
"anti-slop/no-unknown-returns": "error",
|
|
10262
|
+
"anti-slop/no-unknown-type-aliases": "error",
|
|
10263
|
+
"anti-slop/no-unsafe-dictionary-type": "error",
|
|
10264
|
+
"anti-slop/no-widen-then-assert": "error",
|
|
10265
|
+
"anti-slop/require-safety-comment-for-type-assertion": "error"
|
|
10266
|
+
}<% if (shadcn) { %>,
|
|
10267
|
+
"overrides": [
|
|
10268
|
+
{
|
|
10269
|
+
"files": ["packages/ui/src/components/**"],
|
|
10270
|
+
"rules": {
|
|
10271
|
+
"anti-slop/no-chained-type-assertions": "off",
|
|
10272
|
+
"anti-slop/no-conditional-empty-object-spread": "off",
|
|
10273
|
+
"anti-slop/no-known-value-widening": "off",
|
|
10274
|
+
"anti-slop/no-module-mocking": "off",
|
|
10275
|
+
"anti-slop/no-object-parameters": "off",
|
|
10276
|
+
"anti-slop/no-reflect-apply": "off",
|
|
10277
|
+
"anti-slop/no-reflect-get": "off",
|
|
10278
|
+
"anti-slop/no-runtime-typeof": "off",
|
|
10279
|
+
"anti-slop/no-shape-in-symbol-names": "off",
|
|
10280
|
+
"anti-slop/no-unknown-parameters": "off",
|
|
10281
|
+
"anti-slop/no-unknown-returns": "off",
|
|
10282
|
+
"anti-slop/no-unknown-type-aliases": "off",
|
|
10283
|
+
"anti-slop/no-unsafe-dictionary-type": "off",
|
|
10284
|
+
"anti-slop/no-widen-then-assert": "off",
|
|
10285
|
+
"anti-slop/require-safety-comment-for-type-assertion": "off"
|
|
10286
|
+
}
|
|
10287
|
+
}
|
|
10288
|
+
]<% } %><% } %>
|
|
10237
10289
|
}`
|
|
10238
10290
|
};
|
|
10239
10291
|
//#endregion
|
|
@@ -10242,85 +10294,187 @@ var oxfmtrc_default = {
|
|
|
10242
10294
|
filename: ".oxfmtrc.json",
|
|
10243
10295
|
template: `{
|
|
10244
10296
|
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
|
10245
|
-
"ignorePatterns": []
|
|
10297
|
+
"ignorePatterns": [<% if (antiSlop) { %>"tools/oxlint/anti-slop/"<% } %>]
|
|
10246
10298
|
}`
|
|
10247
10299
|
};
|
|
10248
10300
|
//#endregion
|
|
10249
10301
|
//#region src/templates/oxc/index.ts
|
|
10250
10302
|
const web = "apps/web";
|
|
10251
|
-
const api = "apps/api";
|
|
10252
|
-
const ui = "packages/ui";
|
|
10253
10303
|
const root = "";
|
|
10254
10304
|
const oxc = {
|
|
10255
10305
|
templates: [oxlintrc_default, oxfmtrc_default],
|
|
10256
|
-
packages: [
|
|
10306
|
+
packages: [{
|
|
10307
|
+
package: "oxlint",
|
|
10308
|
+
module: root,
|
|
10309
|
+
version: versions.oxlint,
|
|
10310
|
+
dev: true
|
|
10311
|
+
}, {
|
|
10312
|
+
package: "oxfmt",
|
|
10313
|
+
module: root,
|
|
10314
|
+
version: versions.oxfmt,
|
|
10315
|
+
dev: true
|
|
10316
|
+
}],
|
|
10317
|
+
scripts: [
|
|
10257
10318
|
{
|
|
10258
|
-
package: "oxlint",
|
|
10259
10319
|
module: web,
|
|
10260
|
-
|
|
10261
|
-
|
|
10320
|
+
name: "typecheck",
|
|
10321
|
+
script: "next typegen && tsc --noEmit"
|
|
10262
10322
|
},
|
|
10263
10323
|
{
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
dev: true
|
|
10324
|
+
module: root,
|
|
10325
|
+
name: "lint",
|
|
10326
|
+
script: "oxlint --fix"
|
|
10268
10327
|
},
|
|
10269
10328
|
{
|
|
10270
|
-
|
|
10271
|
-
|
|
10272
|
-
|
|
10273
|
-
dev: true
|
|
10329
|
+
module: root,
|
|
10330
|
+
name: "typecheck",
|
|
10331
|
+
script: "turbo run typecheck"
|
|
10274
10332
|
},
|
|
10275
10333
|
{
|
|
10276
|
-
package: "oxfmt",
|
|
10277
10334
|
module: root,
|
|
10278
|
-
|
|
10279
|
-
|
|
10335
|
+
name: "lint:check",
|
|
10336
|
+
script: "oxlint"
|
|
10337
|
+
},
|
|
10338
|
+
{
|
|
10339
|
+
module: root,
|
|
10340
|
+
name: "format",
|
|
10341
|
+
script: "oxfmt"
|
|
10342
|
+
},
|
|
10343
|
+
{
|
|
10344
|
+
module: root,
|
|
10345
|
+
name: "format:check",
|
|
10346
|
+
script: "oxfmt --check"
|
|
10280
10347
|
}
|
|
10281
|
-
]
|
|
10282
|
-
|
|
10348
|
+
]
|
|
10349
|
+
};
|
|
10350
|
+
//#endregion
|
|
10351
|
+
//#region src/templates/anti-slop/templates/plugin-package-json.ts
|
|
10352
|
+
var plugin_package_json_default = {
|
|
10353
|
+
filename: "tools/oxlint/anti-slop/package.json",
|
|
10354
|
+
template: `{
|
|
10355
|
+
"type": "module"
|
|
10356
|
+
}`
|
|
10357
|
+
};
|
|
10358
|
+
//#endregion
|
|
10359
|
+
//#region src/templates/anti-slop/templates/plugin-readme.ts
|
|
10360
|
+
var plugin_readme_default = {
|
|
10361
|
+
filename: "tools/oxlint/anti-slop/README.md",
|
|
10362
|
+
template: `# anti-slop
|
|
10363
|
+
|
|
10364
|
+
Oxlint rules that reject low-evidence TypeScript patterns, vendored from
|
|
10365
|
+
[dmmulroy/anti-slop](https://github.com/dmmulroy/anti-slop) at \`6d538555cb15\` (MIT, see LICENSE).
|
|
10366
|
+
|
|
10367
|
+
Upstream ships these to be vendored rather than depended on, so these files are
|
|
10368
|
+
yours: read them, change the messages, delete the rules you disagree with.
|
|
10369
|
+
|
|
10370
|
+
\`.oxlintrc.json\` registers the plugin and turns every rule on as an error.
|
|
10371
|
+
Turn one off there:
|
|
10372
|
+
|
|
10373
|
+
\`\`\`json
|
|
10374
|
+
{
|
|
10375
|
+
"rules": {
|
|
10376
|
+
"anti-slop/no-runtime-typeof": "off"
|
|
10377
|
+
}
|
|
10378
|
+
}
|
|
10379
|
+
\`\`\`
|
|
10380
|
+
|
|
10381
|
+
Vendored shadcn components under \`packages/ui/src/components\` are exempt, since
|
|
10382
|
+
they are upstream code you re-pull rather than write.
|
|
10383
|
+
`
|
|
10384
|
+
};
|
|
10385
|
+
//#endregion
|
|
10386
|
+
//#region src/templates/anti-slop/index.ts
|
|
10387
|
+
const plugin = "tools/oxlint/anti-slop";
|
|
10388
|
+
const antiSlop = {
|
|
10389
|
+
templates: [plugin_package_json_default, plugin_readme_default],
|
|
10390
|
+
staticFiles: [
|
|
10283
10391
|
{
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
script: "oxlint --fix && next typegen && tsc --noEmit"
|
|
10392
|
+
src: "anti-slop/static/LICENSE",
|
|
10393
|
+
filename: `${plugin}/LICENSE`
|
|
10287
10394
|
},
|
|
10288
10395
|
{
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
script: "oxlint && next typegen && tsc --noEmit"
|
|
10396
|
+
src: "anti-slop/static/index.ts",
|
|
10397
|
+
filename: `${plugin}/index.ts`
|
|
10292
10398
|
},
|
|
10293
10399
|
{
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
script: "oxlint src --fix"
|
|
10400
|
+
src: "anti-slop/static/rules/no-chained-type-assertions.ts",
|
|
10401
|
+
filename: `${plugin}/rules/no-chained-type-assertions.ts`
|
|
10297
10402
|
},
|
|
10298
10403
|
{
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
script: "oxlint src"
|
|
10404
|
+
src: "anti-slop/static/rules/no-conditional-empty-object-spread.ts",
|
|
10405
|
+
filename: `${plugin}/rules/no-conditional-empty-object-spread.ts`
|
|
10302
10406
|
},
|
|
10303
10407
|
{
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
script: "oxlint --fix"
|
|
10408
|
+
src: "anti-slop/static/rules/no-known-value-widening.ts",
|
|
10409
|
+
filename: `${plugin}/rules/no-known-value-widening.ts`
|
|
10307
10410
|
},
|
|
10308
10411
|
{
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
script: "oxlint"
|
|
10412
|
+
src: "anti-slop/static/rules/no-module-mocking.ts",
|
|
10413
|
+
filename: `${plugin}/rules/no-module-mocking.ts`
|
|
10312
10414
|
},
|
|
10313
10415
|
{
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
script: "oxfmt"
|
|
10416
|
+
src: "anti-slop/static/rules/no-object-parameters.ts",
|
|
10417
|
+
filename: `${plugin}/rules/no-object-parameters.ts`
|
|
10317
10418
|
},
|
|
10318
10419
|
{
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10420
|
+
src: "anti-slop/static/rules/no-reflect-apply.ts",
|
|
10421
|
+
filename: `${plugin}/rules/no-reflect-apply.ts`
|
|
10422
|
+
},
|
|
10423
|
+
{
|
|
10424
|
+
src: "anti-slop/static/rules/no-reflect-get.ts",
|
|
10425
|
+
filename: `${plugin}/rules/no-reflect-get.ts`
|
|
10426
|
+
},
|
|
10427
|
+
{
|
|
10428
|
+
src: "anti-slop/static/rules/no-runtime-typeof.ts",
|
|
10429
|
+
filename: `${plugin}/rules/no-runtime-typeof.ts`
|
|
10430
|
+
},
|
|
10431
|
+
{
|
|
10432
|
+
src: "anti-slop/static/rules/no-shape-in-symbol-names.ts",
|
|
10433
|
+
filename: `${plugin}/rules/no-shape-in-symbol-names.ts`
|
|
10434
|
+
},
|
|
10435
|
+
{
|
|
10436
|
+
src: "anti-slop/static/rules/no-unknown-parameters.ts",
|
|
10437
|
+
filename: `${plugin}/rules/no-unknown-parameters.ts`
|
|
10438
|
+
},
|
|
10439
|
+
{
|
|
10440
|
+
src: "anti-slop/static/rules/no-unknown-returns.ts",
|
|
10441
|
+
filename: `${plugin}/rules/no-unknown-returns.ts`
|
|
10442
|
+
},
|
|
10443
|
+
{
|
|
10444
|
+
src: "anti-slop/static/rules/no-unknown-type-aliases.ts",
|
|
10445
|
+
filename: `${plugin}/rules/no-unknown-type-aliases.ts`
|
|
10446
|
+
},
|
|
10447
|
+
{
|
|
10448
|
+
src: "anti-slop/static/rules/no-unsafe-dictionary-type.ts",
|
|
10449
|
+
filename: `${plugin}/rules/no-unsafe-dictionary-type.ts`
|
|
10450
|
+
},
|
|
10451
|
+
{
|
|
10452
|
+
src: "anti-slop/static/rules/no-widen-then-assert.ts",
|
|
10453
|
+
filename: `${plugin}/rules/no-widen-then-assert.ts`
|
|
10454
|
+
},
|
|
10455
|
+
{
|
|
10456
|
+
src: "anti-slop/static/rules/require-safety-comment-for-type-assertion.ts",
|
|
10457
|
+
filename: `${plugin}/rules/require-safety-comment-for-type-assertion.ts`
|
|
10458
|
+
},
|
|
10459
|
+
{
|
|
10460
|
+
src: "anti-slop/static/shared/dictionary-types.ts",
|
|
10461
|
+
filename: `${plugin}/shared/dictionary-types.ts`
|
|
10462
|
+
},
|
|
10463
|
+
{
|
|
10464
|
+
src: "anti-slop/static/shared/lexical-type-parameters.ts",
|
|
10465
|
+
filename: `${plugin}/shared/lexical-type-parameters.ts`
|
|
10466
|
+
},
|
|
10467
|
+
{
|
|
10468
|
+
src: "anti-slop/static/shared/reflect-method.ts",
|
|
10469
|
+
filename: `${plugin}/shared/reflect-method.ts`
|
|
10322
10470
|
}
|
|
10323
|
-
]
|
|
10471
|
+
],
|
|
10472
|
+
packages: [{
|
|
10473
|
+
package: "@oxlint/plugins",
|
|
10474
|
+
module: "",
|
|
10475
|
+
version: versions["@oxlint/plugins"],
|
|
10476
|
+
dev: true
|
|
10477
|
+
}]
|
|
10324
10478
|
};
|
|
10325
10479
|
//#endregion
|
|
10326
10480
|
//#region src/templates/typescript-config/index.ts
|
|
@@ -10396,9 +10550,9 @@ const testingJest = {
|
|
|
10396
10550
|
export default {
|
|
10397
10551
|
moduleFileExtensions: ['js', 'json', 'ts'],
|
|
10398
10552
|
rootDir: 'src',
|
|
10399
|
-
testRegex: '
|
|
10553
|
+
testRegex: '.*\\\\.spec\\\\.ts$',
|
|
10400
10554
|
transform: {
|
|
10401
|
-
'
|
|
10555
|
+
'^.+\\\\.(t|j)s$': 'ts-jest',
|
|
10402
10556
|
},
|
|
10403
10557
|
collectCoverageFrom: ['**/*.(t|j)s'],
|
|
10404
10558
|
coverageDirectory: '../coverage',
|
|
@@ -10790,10 +10944,16 @@ export default nextConfig;`
|
|
|
10790
10944
|
"env": ["API_HOST", "DATABASE_URL"],
|
|
10791
10945
|
"outputs": [".next/**", "!.next/cache/**"]
|
|
10792
10946
|
},
|
|
10793
|
-
"
|
|
10947
|
+
<% if (linter === "oxc") { %> "typecheck": {
|
|
10948
|
+
"dependsOn": ["^build"]
|
|
10949
|
+
},<% } else { %> "lint": {
|
|
10794
10950
|
"dependsOn": ["^lint"],
|
|
10795
10951
|
"env": ["NODE_ENV"]
|
|
10796
10952
|
},
|
|
10953
|
+
"lint:check": {
|
|
10954
|
+
"dependsOn": ["^lint:check"],
|
|
10955
|
+
"env": ["NODE_ENV"]
|
|
10956
|
+
},<% } %>
|
|
10797
10957
|
"test": {
|
|
10798
10958
|
"dependsOn": ["^build"],
|
|
10799
10959
|
"outputs": ["coverage/**"]
|
|
@@ -10880,7 +11040,7 @@ dotenv.config({ path: resolve(process.cwd(), '.env') });
|
|
|
10880
11040
|
import { NestFactory } from '@nestjs/core';
|
|
10881
11041
|
import { AppModule } from '@<%= projectName %>/api';
|
|
10882
11042
|
import next from 'next';
|
|
10883
|
-
import { createServer } from 'node:http';
|
|
11043
|
+
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
|
|
10884
11044
|
|
|
10885
11045
|
const dev = process.env.NODE_ENV !== 'production';
|
|
10886
11046
|
const port = parseInt(process.env.PORT ?? '3000', 10);
|
|
@@ -10898,7 +11058,7 @@ async function main() {
|
|
|
10898
11058
|
|
|
10899
11059
|
const nestListener = nestApp
|
|
10900
11060
|
.getHttpServer()
|
|
10901
|
-
.listeners('request')[0] as (req:
|
|
11061
|
+
.listeners('request')[0] as (req: IncomingMessage, res: ServerResponse) => void;
|
|
10902
11062
|
|
|
10903
11063
|
const server = createServer((req, res) => {
|
|
10904
11064
|
if (req.url?.startsWith('/api/')) {
|
|
@@ -11023,21 +11183,27 @@ export default nextConfig;`
|
|
|
11023
11183
|
"ui": "tui",
|
|
11024
11184
|
"tasks": {
|
|
11025
11185
|
"build": {
|
|
11026
|
-
"env": ["DATABASE_URL"],
|
|
11186
|
+
"env": ["DATABASE_URL", "PORT"],
|
|
11027
11187
|
"dependsOn": ["^build"],
|
|
11028
11188
|
"inputs": ["$TURBO_DEFAULT$", ".env*"],
|
|
11029
11189
|
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
|
|
11030
11190
|
},
|
|
11031
|
-
"
|
|
11191
|
+
<% if (linter === "oxc") { %> "typecheck": {
|
|
11192
|
+
"dependsOn": ["^build"]
|
|
11193
|
+
},<% } else { %> "lint": {
|
|
11032
11194
|
"dependsOn": ["^lint"],
|
|
11033
11195
|
"env": ["NODE_ENV"]
|
|
11034
11196
|
},
|
|
11197
|
+
"lint:check": {
|
|
11198
|
+
"dependsOn": ["^lint:check"],
|
|
11199
|
+
"env": ["NODE_ENV"]
|
|
11200
|
+
},<% } %>
|
|
11035
11201
|
"test": {
|
|
11036
11202
|
"dependsOn": ["^build"],
|
|
11037
11203
|
"outputs": ["coverage/**"]
|
|
11038
11204
|
},
|
|
11039
11205
|
"dev": {
|
|
11040
|
-
"env": ["DATABASE_URL"],
|
|
11206
|
+
"env": ["DATABASE_URL", "PORT"],
|
|
11041
11207
|
"dependsOn": ["^migrate", "^build"],
|
|
11042
11208
|
"cache": false,
|
|
11043
11209
|
"persistent": true
|
|
@@ -12445,7 +12611,7 @@ function getStaticFilePath(name) {
|
|
|
12445
12611
|
return fileURLToPath(new URL(`./static/${name}`, import.meta.url));
|
|
12446
12612
|
}
|
|
12447
12613
|
function selectModules(selection) {
|
|
12448
|
-
const { deployment, nestDiOnly: nestDiOnly$1, todoExample, shadcn, database, linter, testing } = selection;
|
|
12614
|
+
const { deployment, nestDiOnly: nestDiOnly$1, todoExample, shadcn, database, linter, testing, extras } = selection;
|
|
12449
12615
|
const deploymentModule = deployment === "standalone" ? deploymentStandalone : deployment === "custom-server" ? singleProcessCustomServer : deployment === "spa" ? singleProcessStaticExport : null;
|
|
12450
12616
|
const webModule = deployment === "spa" ? {
|
|
12451
12617
|
...web$2,
|
|
@@ -12454,11 +12620,12 @@ function selectModules(selection) {
|
|
|
12454
12620
|
return [
|
|
12455
12621
|
root$2,
|
|
12456
12622
|
webModule,
|
|
12457
|
-
api$
|
|
12623
|
+
api$1,
|
|
12458
12624
|
database === "postgres" ? dbPostgres : dbSqlite,
|
|
12459
12625
|
auth,
|
|
12460
|
-
shadcn ? shadcnUi : ui$
|
|
12626
|
+
shadcn ? shadcnUi : ui$1,
|
|
12461
12627
|
linter === "oxc" ? oxc : eslintConfig,
|
|
12628
|
+
...extras.includes("anti-slop") ? [antiSlop] : [],
|
|
12462
12629
|
typescriptConfig,
|
|
12463
12630
|
testing === "vitest" ? testingVitest : testingJest,
|
|
12464
12631
|
...deploymentModule ? [deploymentModule] : [],
|
|
@@ -12473,6 +12640,9 @@ function selectModules(selection) {
|
|
|
12473
12640
|
}
|
|
12474
12641
|
//#endregion
|
|
12475
12642
|
//#region src/utils.ts
|
|
12643
|
+
function isMissingFile(cause) {
|
|
12644
|
+
return cause instanceof Error && "code" in cause && cause.code === "ENOENT";
|
|
12645
|
+
}
|
|
12476
12646
|
async function updatePackageJson(destDir, packages, templateData) {
|
|
12477
12647
|
for (const pkg of packages) {
|
|
12478
12648
|
const renderedPackage = ejs.render(pkg.package, templateData);
|
|
@@ -12481,7 +12651,7 @@ async function updatePackageJson(destDir, packages, templateData) {
|
|
|
12481
12651
|
try {
|
|
12482
12652
|
packageJsonContent = await promises.readFile(packageJsonPath, "utf8");
|
|
12483
12653
|
} catch (err) {
|
|
12484
|
-
if (
|
|
12654
|
+
if (isMissingFile(err)) continue;
|
|
12485
12655
|
throw err;
|
|
12486
12656
|
}
|
|
12487
12657
|
const packageJson = JSON.parse(packageJsonContent);
|
|
@@ -12499,7 +12669,7 @@ async function updateScripts(destDir, scripts, templateData) {
|
|
|
12499
12669
|
try {
|
|
12500
12670
|
packageJsonContent = await promises.readFile(packageJsonPath, "utf8");
|
|
12501
12671
|
} catch (err) {
|
|
12502
|
-
if (
|
|
12672
|
+
if (isMissingFile(err)) continue;
|
|
12503
12673
|
throw err;
|
|
12504
12674
|
}
|
|
12505
12675
|
const packageJson = JSON.parse(packageJsonContent);
|
|
@@ -12564,6 +12734,13 @@ function validateFlagValue(flag, value, allowed) {
|
|
|
12564
12734
|
error: `Invalid value "${value}" for ${flag}. Valid choices: ${allowed.join(", ")}.`
|
|
12565
12735
|
};
|
|
12566
12736
|
}
|
|
12737
|
+
function validateExtrasCombo(extras, linter) {
|
|
12738
|
+
if (extras.includes("anti-slop") && linter !== "oxc") return {
|
|
12739
|
+
valid: false,
|
|
12740
|
+
error: "--extras anti-slop needs --linter oxc.\nanti-slop is a set of oxlint rules, and the eslint option installs neither oxlint\nnor a config to register them in. Add --linter oxc, or drop the extra."
|
|
12741
|
+
};
|
|
12742
|
+
return { valid: true };
|
|
12743
|
+
}
|
|
12567
12744
|
function validateDeploymentCombo(deployment, nestDiOnly) {
|
|
12568
12745
|
if (deployment === "spa" && nestDiOnly) return {
|
|
12569
12746
|
valid: false,
|
|
@@ -12635,6 +12812,9 @@ async function scaffold(modules, options) {
|
|
|
12635
12812
|
testing: options.testing,
|
|
12636
12813
|
database: options.database,
|
|
12637
12814
|
deployment: options.deployment,
|
|
12815
|
+
linter: options.linter,
|
|
12816
|
+
antiSlop: options.antiSlop,
|
|
12817
|
+
shadcn: options.selection.shadcn,
|
|
12638
12818
|
authSecret: randomBytes(32).toString("base64url"),
|
|
12639
12819
|
versions
|
|
12640
12820
|
};
|
|
@@ -12679,6 +12859,7 @@ const DEPLOYMENT_CHOICES = [
|
|
|
12679
12859
|
"custom-server",
|
|
12680
12860
|
"spa"
|
|
12681
12861
|
];
|
|
12862
|
+
const EXTRAS_CHOICES = ["anti-slop"];
|
|
12682
12863
|
var TaskBuilder = class {
|
|
12683
12864
|
tasks = [];
|
|
12684
12865
|
add(task) {
|
|
@@ -12734,6 +12915,15 @@ async function doInit(options) {
|
|
|
12734
12915
|
}],
|
|
12735
12916
|
initialValue: "eslint"
|
|
12736
12917
|
}),
|
|
12918
|
+
extras: ({ results }) => results.linter === "oxc" ? p.multiselect({
|
|
12919
|
+
message: "Extras?",
|
|
12920
|
+
options: [{
|
|
12921
|
+
value: "anti-slop",
|
|
12922
|
+
label: "anti-slop",
|
|
12923
|
+
hint: "oxlint rules that reject low-evidence TypeScript"
|
|
12924
|
+
}],
|
|
12925
|
+
required: false
|
|
12926
|
+
}) : void 0,
|
|
12737
12927
|
nestDiOnly: () => p.confirm({
|
|
12738
12928
|
message: "Use NestJS for dependency injection only?",
|
|
12739
12929
|
initialValue: false
|
|
@@ -12743,7 +12933,7 @@ async function doInit(options) {
|
|
|
12743
12933
|
initialValue: true
|
|
12744
12934
|
}),
|
|
12745
12935
|
deployment: ({ results }) => p.select({
|
|
12746
|
-
message: "Deployment
|
|
12936
|
+
message: "Deployment?",
|
|
12747
12937
|
options: [
|
|
12748
12938
|
{
|
|
12749
12939
|
value: "none",
|
|
@@ -12775,19 +12965,22 @@ async function doInit(options) {
|
|
|
12775
12965
|
git: options.git
|
|
12776
12966
|
}, hasCommand)].find((result) => !result.valid);
|
|
12777
12967
|
if (preflight) throw new Error(preflight.error);
|
|
12778
|
-
const
|
|
12968
|
+
const answers = await p.group(groupOpts, { onCancel: () => {
|
|
12779
12969
|
console.log("Exiting.");
|
|
12780
12970
|
process.exit(0);
|
|
12781
12971
|
} });
|
|
12782
|
-
const useShadcn = options.nonInteractive ? options.shadcn :
|
|
12783
|
-
const testing = options.nonInteractive ? options.testing :
|
|
12784
|
-
const database = options.nonInteractive ? options.database :
|
|
12785
|
-
const linter = options.nonInteractive ? options.linter :
|
|
12786
|
-
const deployment = options.nonInteractive ? options.deployment :
|
|
12787
|
-
const nestDiOnly = options.nonInteractive ? options.nestDiOnly :
|
|
12788
|
-
const todoExample = options.nonInteractive ?
|
|
12972
|
+
const useShadcn = options.nonInteractive ? options.shadcn : answers.shadcn ?? true;
|
|
12973
|
+
const testing = options.nonInteractive ? options.testing : answers.testing ?? "jest";
|
|
12974
|
+
const database = options.nonInteractive ? options.database : answers.database ?? "sqlite";
|
|
12975
|
+
const linter = options.nonInteractive ? options.linter : answers.linter ?? "eslint";
|
|
12976
|
+
const deployment = options.nonInteractive ? options.deployment : answers.deployment ?? "none";
|
|
12977
|
+
const nestDiOnly = options.nonInteractive ? options.nestDiOnly : answers.nestDiOnly ?? false;
|
|
12978
|
+
const todoExample = options.nonInteractive ? options.includeExample : answers.todoExample ?? true;
|
|
12979
|
+
const extras = options.nonInteractive ? options.extras : answers.extras ?? [];
|
|
12789
12980
|
const deploymentCombo = validateDeploymentCombo(deployment, nestDiOnly);
|
|
12790
12981
|
if (!deploymentCombo.valid) throw new Error(deploymentCombo.error);
|
|
12982
|
+
const extrasCombo = validateExtrasCombo(extras, linter);
|
|
12983
|
+
if (!extrasCombo.valid) throw new Error(extrasCombo.error);
|
|
12791
12984
|
const selection = {
|
|
12792
12985
|
deployment,
|
|
12793
12986
|
nestDiOnly,
|
|
@@ -12795,10 +12988,11 @@ async function doInit(options) {
|
|
|
12795
12988
|
shadcn: useShadcn,
|
|
12796
12989
|
database,
|
|
12797
12990
|
linter,
|
|
12798
|
-
testing
|
|
12991
|
+
testing,
|
|
12992
|
+
extras
|
|
12799
12993
|
};
|
|
12800
12994
|
const allModules = selectModules(selection);
|
|
12801
|
-
const name =
|
|
12995
|
+
const name = answers.name ?? options.name ?? "";
|
|
12802
12996
|
const taskBuilder = new TaskBuilder();
|
|
12803
12997
|
taskBuilder.add({
|
|
12804
12998
|
title: "Scaffolding project",
|
|
@@ -12808,6 +13002,8 @@ async function doInit(options) {
|
|
|
12808
13002
|
testing,
|
|
12809
13003
|
database,
|
|
12810
13004
|
deployment,
|
|
13005
|
+
linter,
|
|
13006
|
+
antiSlop: extras.includes("anti-slop"),
|
|
12811
13007
|
selection
|
|
12812
13008
|
});
|
|
12813
13009
|
return "Scaffolded.";
|
|
@@ -12849,7 +13045,7 @@ async function doInit(options) {
|
|
|
12849
13045
|
}
|
|
12850
13046
|
}
|
|
12851
13047
|
const program = new Command();
|
|
12852
|
-
program.name("create-newt-app").version(version).description("Create a new newt-app monorepo").argument("[name]").option("-ni, --no-install", "Skip pnpm install", true).option("-ng, --no-git", "Skip git initialization", true).option("--shadcn", "Include shadcn/ui", false).option("--testing <framework>", "Testing framework: vitest or jest", "jest").option("--database <database>", "Database: sqlite or postgres", "sqlite").option("--linter <linter>", "Linter: eslint or oxc", "eslint").option("--deployment <strategy>", "Deployment
|
|
13048
|
+
program.name("create-newt-app").version(version).description("Create a new newt-app monorepo").argument("[name]").option("-ni, --no-install", "Skip pnpm install", true).option("-ng, --no-git", "Skip git initialization", true).option("--shadcn", "Include shadcn/ui", false).option("--testing <framework>", "Testing framework: vitest or jest", "jest").option("--database <database>", "Database: sqlite or postgres", "sqlite").option("--linter <linter>", "Linter: eslint or oxc", "eslint").option("--deployment <strategy>", "Deployment: standalone, custom-server, spa", "none").option("--nest-di-only", "Use NestJS for dependency injection only", false).option("--include-example", "Include the todo example", false).option("--extras <list>", "Extras, comma-separated: anti-slop", "").action(async (name, options, command) => {
|
|
12853
13049
|
intro(`Create a ${chalk.blue("newt")} app.`);
|
|
12854
13050
|
const nonInteractive = [
|
|
12855
13051
|
"shadcn",
|
|
@@ -12858,8 +13054,10 @@ program.name("create-newt-app").version(version).description("Create a new newt-
|
|
|
12858
13054
|
"linter",
|
|
12859
13055
|
"deployment",
|
|
12860
13056
|
"nestDiOnly",
|
|
12861
|
-
"
|
|
13057
|
+
"includeExample",
|
|
13058
|
+
"extras"
|
|
12862
13059
|
].some((flag) => command.getOptionValueSource(flag) === "cli");
|
|
13060
|
+
const extras = options.extras.split(",").map((extra) => extra.trim()).filter(Boolean);
|
|
12863
13061
|
const invalid = [
|
|
12864
13062
|
{
|
|
12865
13063
|
flag: "--testing",
|
|
@@ -12880,7 +13078,12 @@ program.name("create-newt-app").version(version).description("Create a new newt-
|
|
|
12880
13078
|
flag: "--deployment",
|
|
12881
13079
|
value: options.deployment,
|
|
12882
13080
|
allowed: DEPLOYMENT_CHOICES
|
|
12883
|
-
}
|
|
13081
|
+
},
|
|
13082
|
+
...extras.map((extra) => ({
|
|
13083
|
+
flag: "--extras",
|
|
13084
|
+
value: extra,
|
|
13085
|
+
allowed: EXTRAS_CHOICES
|
|
13086
|
+
}))
|
|
12884
13087
|
].map(({ flag, value, allowed }) => validateFlagValue(flag, value, allowed)).find((result) => !result.valid);
|
|
12885
13088
|
if (invalid) {
|
|
12886
13089
|
console.error(`Error: ${invalid.error}`);
|
|
@@ -12897,7 +13100,8 @@ program.name("create-newt-app").version(version).description("Create a new newt-
|
|
|
12897
13100
|
linter: options.linter,
|
|
12898
13101
|
deployment: options.deployment,
|
|
12899
13102
|
nestDiOnly: options.nestDiOnly,
|
|
12900
|
-
|
|
13103
|
+
includeExample: options.includeExample,
|
|
13104
|
+
extras
|
|
12901
13105
|
});
|
|
12902
13106
|
});
|
|
12903
13107
|
program.parse();
|