create-taserjs 0.0.1 → 0.0.3
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 +2 -0
- package/dist/cjs/addons/arktype/index.cjs +6 -0
- package/dist/cjs/addons/arktype/index.cjs.map +1 -0
- package/dist/cjs/addons/drizzle/index.cjs +9 -2
- package/dist/cjs/addons/drizzle/index.cjs.map +1 -1
- package/dist/cjs/addons/kysely/index.cjs +9 -2
- package/dist/cjs/addons/kysely/index.cjs.map +1 -1
- package/dist/cjs/addons/pino/index.cjs.map +1 -1
- package/dist/cjs/addons/prisma/index.cjs +84 -24
- package/dist/cjs/addons/prisma/index.cjs.map +1 -1
- package/dist/cjs/addons/registry.cjs +17 -13
- package/dist/cjs/addons/registry.cjs.map +1 -1
- package/dist/cjs/addons/types.d.cts +1 -1
- package/dist/cjs/addons/valibot/index.cjs +6 -0
- package/dist/cjs/addons/valibot/index.cjs.map +1 -0
- package/dist/cjs/addons/validators.cjs +2 -2
- package/dist/cjs/addons/validators.cjs.map +1 -1
- package/dist/cjs/addons/winston/index.cjs.map +1 -1
- package/dist/cjs/addons/zod/index.cjs.map +1 -1
- package/dist/cjs/cli.cjs +7 -0
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/commands/create.cjs +45 -11
- package/dist/cjs/commands/create.cjs.map +1 -1
- package/dist/cjs/commands/create.d.cts +2 -0
- package/dist/cjs/core/json-output.cjs.map +1 -1
- package/dist/cjs/core/package-manager.cjs +5 -13
- package/dist/cjs/core/package-manager.cjs.map +1 -1
- package/dist/cjs/core/package-manager.d.cts +3 -2
- package/dist/cjs/core/parse-options.cjs +17 -7
- package/dist/cjs/core/parse-options.cjs.map +1 -1
- package/dist/cjs/core/parse-options.d.cts +4 -3
- package/dist/cjs/core/project-config.cjs +2 -1
- package/dist/cjs/core/project-config.cjs.map +1 -1
- package/dist/cjs/core/resolve-packages.cjs +41 -7
- package/dist/cjs/core/resolve-packages.cjs.map +1 -1
- package/dist/cjs/core/resolve-packages.d.cts +2 -2
- package/dist/cjs/core/scaffold-engine.cjs +37 -8
- package/dist/cjs/core/scaffold-engine.cjs.map +1 -1
- package/dist/cjs/core/types.cjs +11 -3
- package/dist/cjs/core/types.cjs.map +1 -1
- package/dist/cjs/core/types.d.cts +8 -8
- package/dist/cjs/core/validate-project-name.cjs.map +1 -1
- package/dist/cjs/frameworks/index.cjs +138 -17
- package/dist/cjs/frameworks/index.cjs.map +1 -1
- package/dist/cjs/frameworks/index.d.cts +3 -3
- package/dist/cjs/scaffold.d.cts +1 -1
- package/dist/cjs/templates/base.cjs +15 -12
- package/dist/cjs/templates/base.cjs.map +1 -1
- package/dist/cjs/types.d.cts +1 -1
- package/dist/esm/addons/arktype/index.js +7 -0
- package/dist/esm/addons/arktype/index.js.map +1 -0
- package/dist/esm/addons/drizzle/index.js +9 -2
- package/dist/esm/addons/drizzle/index.js.map +1 -1
- package/dist/esm/addons/kysely/index.js +9 -2
- package/dist/esm/addons/kysely/index.js.map +1 -1
- package/dist/esm/addons/pino/index.js.map +1 -1
- package/dist/esm/addons/prisma/index.js +84 -24
- package/dist/esm/addons/prisma/index.js.map +1 -1
- package/dist/esm/addons/registry.js +8 -4
- package/dist/esm/addons/registry.js.map +1 -1
- package/dist/esm/addons/types.d.ts +1 -1
- package/dist/esm/addons/valibot/index.js +7 -0
- package/dist/esm/addons/valibot/index.js.map +1 -0
- package/dist/esm/addons/validators.js +2 -2
- package/dist/esm/addons/validators.js.map +1 -1
- package/dist/esm/addons/winston/index.js.map +1 -1
- package/dist/esm/addons/zod/index.js.map +1 -1
- package/dist/esm/cli.js +7 -0
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/create.d.ts +2 -0
- package/dist/esm/commands/create.js +47 -13
- package/dist/esm/commands/create.js.map +1 -1
- package/dist/esm/core/json-output.js.map +1 -1
- package/dist/esm/core/package-manager.d.ts +3 -2
- package/dist/esm/core/package-manager.js +5 -14
- package/dist/esm/core/package-manager.js.map +1 -1
- package/dist/esm/core/parse-options.d.ts +4 -3
- package/dist/esm/core/parse-options.js +17 -8
- package/dist/esm/core/parse-options.js.map +1 -1
- package/dist/esm/core/project-config.js +2 -1
- package/dist/esm/core/project-config.js.map +1 -1
- package/dist/esm/core/resolve-packages.d.ts +2 -2
- package/dist/esm/core/resolve-packages.js +41 -7
- package/dist/esm/core/resolve-packages.js.map +1 -1
- package/dist/esm/core/scaffold-engine.js +38 -9
- package/dist/esm/core/scaffold-engine.js.map +1 -1
- package/dist/esm/core/types.d.ts +8 -8
- package/dist/esm/core/types.js +11 -3
- package/dist/esm/core/types.js.map +1 -1
- package/dist/esm/core/validate-project-name.js.map +1 -1
- package/dist/esm/frameworks/index.d.ts +3 -3
- package/dist/esm/frameworks/index.js +138 -17
- package/dist/esm/frameworks/index.js.map +1 -1
- package/dist/esm/scaffold.d.ts +1 -1
- package/dist/esm/templates/base.js +15 -12
- package/dist/esm/templates/base.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/package.json +13 -13
- package/src/addons/arktype/index.ts +2 -2
- package/src/addons/drizzle/index.ts +60 -47
- package/src/addons/kysely/index.ts +49 -36
- package/src/addons/pino/index.ts +12 -12
- package/src/addons/prisma/index.ts +128 -55
- package/src/addons/registry.ts +39 -35
- package/src/addons/types.ts +14 -14
- package/src/addons/valibot/index.ts +2 -2
- package/src/addons/validators.ts +11 -11
- package/src/addons/winston/index.ts +12 -12
- package/src/addons/zod/index.ts +2 -2
- package/src/cli.ts +28 -25
- package/src/commands/create.ts +185 -150
- package/src/core/json-output.ts +4 -4
- package/src/core/package-manager.ts +39 -35
- package/src/core/parse-options.ts +62 -43
- package/src/core/project-config.ts +13 -13
- package/src/core/resolve-packages.ts +79 -41
- package/src/core/scaffold-engine.ts +108 -36
- package/src/core/types.ts +61 -36
- package/src/core/validate-project-name.ts +40 -40
- package/src/frameworks/index.ts +164 -29
- package/src/scaffold.ts +3 -3
- package/src/templates/base.ts +65 -56
- package/src/types.ts +5 -4
|
@@ -1,81 +1,154 @@
|
|
|
1
|
-
import type { AddonDefinition } from
|
|
2
|
-
import type { DbDriver } from
|
|
1
|
+
import type { AddonDefinition } from "../types.js";
|
|
2
|
+
import type { DbDriver } from "../../core/types.js";
|
|
3
3
|
|
|
4
4
|
function prismaProvider(driver: DbDriver): string {
|
|
5
5
|
switch (driver) {
|
|
6
|
-
case
|
|
7
|
-
return
|
|
8
|
-
case
|
|
9
|
-
return
|
|
10
|
-
case
|
|
6
|
+
case "postgres":
|
|
7
|
+
return "postgresql";
|
|
8
|
+
case "mysql":
|
|
9
|
+
return "mysql";
|
|
10
|
+
case "sqlite":
|
|
11
11
|
default:
|
|
12
|
-
return
|
|
12
|
+
return "sqlite";
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function envExample(driver: DbDriver): string {
|
|
17
17
|
switch (driver) {
|
|
18
|
-
case
|
|
19
|
-
return
|
|
20
|
-
case
|
|
21
|
-
return
|
|
22
|
-
case
|
|
18
|
+
case "postgres":
|
|
19
|
+
return "DATABASE_URL=postgresql://user:password@localhost:5432/mydb\n";
|
|
20
|
+
case "mysql":
|
|
21
|
+
return "DATABASE_URL=mysql://user:password@localhost:3306/mydb\n";
|
|
22
|
+
case "sqlite":
|
|
23
23
|
default:
|
|
24
|
-
return
|
|
24
|
+
return "DATABASE_URL=file:./local.db\n";
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
function driverPackages(driver: DbDriver): string[] {
|
|
29
|
+
switch (driver) {
|
|
30
|
+
case "postgres":
|
|
31
|
+
return ["@prisma/adapter-pg", "pg"];
|
|
32
|
+
case "mysql":
|
|
33
|
+
return ["@prisma/adapter-mariadb", "mariadb"];
|
|
34
|
+
case "sqlite":
|
|
35
|
+
default:
|
|
36
|
+
return ["@prisma/adapter-better-sqlite3", "better-sqlite3"];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function driverDevPackages(driver: DbDriver): string[] {
|
|
41
|
+
switch (driver) {
|
|
42
|
+
case "postgres":
|
|
43
|
+
return ["@types/pg"];
|
|
44
|
+
case "sqlite":
|
|
45
|
+
return ["@types/better-sqlite3"];
|
|
46
|
+
case "mysql":
|
|
47
|
+
default:
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function dbIndexSource(driver: DbDriver): string {
|
|
53
|
+
switch (driver) {
|
|
54
|
+
case "postgres":
|
|
55
|
+
return `import { PrismaPg } from '@prisma/adapter-pg'
|
|
56
|
+
|
|
57
|
+
import { PrismaClient } from './prisma/client.js'
|
|
58
|
+
|
|
59
|
+
export function createDb() {
|
|
60
|
+
const adapter = new PrismaPg({
|
|
61
|
+
connectionString: process.env.DATABASE_URL,
|
|
62
|
+
})
|
|
63
|
+
return new PrismaClient({ adapter })
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
case "mysql":
|
|
67
|
+
return `import { PrismaMariaDb } from '@prisma/adapter-mariadb'
|
|
68
|
+
|
|
69
|
+
import { PrismaClient } from './prisma/client.js'
|
|
70
|
+
|
|
71
|
+
export function createDb() {
|
|
72
|
+
const adapter = new PrismaMariaDb(process.env.DATABASE_URL ?? 'mariadb://root:@localhost:3306/mydb')
|
|
73
|
+
return new PrismaClient({ adapter })
|
|
74
|
+
}
|
|
75
|
+
`;
|
|
76
|
+
case "sqlite":
|
|
77
|
+
default:
|
|
78
|
+
return `import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3'
|
|
79
|
+
|
|
80
|
+
import { PrismaClient } from './prisma/client.js'
|
|
81
|
+
|
|
82
|
+
export function createDb() {
|
|
83
|
+
const adapter = new PrismaBetterSqlite3({
|
|
84
|
+
url: process.env.DATABASE_URL ?? 'file:./local.db',
|
|
85
|
+
})
|
|
86
|
+
return new PrismaClient({ adapter })
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function prismaConfigSource(): string {
|
|
93
|
+
return `import 'dotenv/config'
|
|
94
|
+
import { defineConfig, env } from 'prisma/config'
|
|
95
|
+
|
|
96
|
+
export default defineConfig({
|
|
97
|
+
schema: 'prisma/schema.prisma',
|
|
98
|
+
datasource: {
|
|
99
|
+
url: env('DATABASE_URL'),
|
|
49
100
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
101
|
+
})
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function schemaSource(driver: DbDriver): string {
|
|
106
|
+
const provider = prismaProvider(driver);
|
|
107
|
+
return `generator client {
|
|
108
|
+
provider = "prisma-client"
|
|
109
|
+
output = "../src/db/prisma"
|
|
57
110
|
}
|
|
58
111
|
|
|
59
112
|
datasource db {
|
|
60
113
|
provider = "${provider}"
|
|
61
|
-
url = env("DATABASE_URL")
|
|
62
114
|
}
|
|
63
115
|
|
|
64
116
|
model User {
|
|
65
117
|
id Int @id @default(autoincrement())
|
|
66
118
|
email String
|
|
67
119
|
}
|
|
68
|
-
|
|
69
|
-
)
|
|
70
|
-
await write(
|
|
71
|
-
'src/db/index.ts',
|
|
72
|
-
`import { PrismaClient } from '@prisma/client'
|
|
73
|
-
|
|
74
|
-
export function createDb() {
|
|
75
|
-
return new PrismaClient()
|
|
120
|
+
`;
|
|
76
121
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
122
|
+
|
|
123
|
+
export const prismaAddon: AddonDefinition = {
|
|
124
|
+
id: "prisma",
|
|
125
|
+
category: "database",
|
|
126
|
+
dependencies(ctx) {
|
|
127
|
+
const driver = ctx.driver ?? "sqlite";
|
|
128
|
+
return ["@prisma/client", ...driverPackages(driver)];
|
|
80
129
|
},
|
|
81
|
-
|
|
130
|
+
devDependencies(ctx) {
|
|
131
|
+
const driver = ctx.driver ?? "sqlite";
|
|
132
|
+
return ["prisma", ...driverDevPackages(driver)];
|
|
133
|
+
},
|
|
134
|
+
scripts() {
|
|
135
|
+
return {
|
|
136
|
+
"db:generate": "prisma generate",
|
|
137
|
+
"db:push": "prisma db push",
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
bootBinding() {
|
|
141
|
+
return {
|
|
142
|
+
key: "db",
|
|
143
|
+
importPath: "./db/index.js",
|
|
144
|
+
factoryName: "createDb",
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
async apply(ctx, write) {
|
|
148
|
+
const driver = ctx.driver ?? "sqlite";
|
|
149
|
+
await write("prisma.config.ts", prismaConfigSource());
|
|
150
|
+
await write("prisma/schema.prisma", schemaSource(driver));
|
|
151
|
+
await write("src/db/index.ts", dbIndexSource(driver));
|
|
152
|
+
await write(".env.example", envExample(driver));
|
|
153
|
+
},
|
|
154
|
+
};
|
package/src/addons/registry.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import { winstonAddon } from
|
|
8
|
-
import
|
|
1
|
+
import { arktypeAddon } from "./arktype/index.js";
|
|
2
|
+
import { drizzleAddon } from "./drizzle/index.js";
|
|
3
|
+
import { kyselyAddon } from "./kysely/index.js";
|
|
4
|
+
import { pinoAddon } from "./pino/index.js";
|
|
5
|
+
import { prismaAddon } from "./prisma/index.js";
|
|
6
|
+
import { valibotAddon } from "./valibot/index.js";
|
|
7
|
+
import { winstonAddon } from "./winston/index.js";
|
|
8
|
+
import { zodAddon } from "./zod/index.js";
|
|
9
|
+
import type { AddonDefinition } from "./types.js";
|
|
10
|
+
import type { CapabilitiesCatalog, ScaffoldContext } from "../core/types.js";
|
|
9
11
|
import {
|
|
10
12
|
DB_DRIVERS,
|
|
11
13
|
DB_ODMS,
|
|
12
14
|
DEFAULT_DB_DRIVER,
|
|
13
|
-
FRAMEWORKS,
|
|
14
15
|
LOGGERS,
|
|
16
|
+
PROJECT_TYPES,
|
|
15
17
|
VALIDATORS,
|
|
16
|
-
} from
|
|
18
|
+
} from "../core/types.js";
|
|
17
19
|
|
|
18
20
|
const ALL_ADDONS: AddonDefinition[] = [
|
|
19
21
|
drizzleAddon,
|
|
@@ -22,15 +24,17 @@ const ALL_ADDONS: AddonDefinition[] = [
|
|
|
22
24
|
pinoAddon,
|
|
23
25
|
winstonAddon,
|
|
24
26
|
zodAddon,
|
|
25
|
-
|
|
27
|
+
arktypeAddon,
|
|
28
|
+
valibotAddon,
|
|
29
|
+
];
|
|
26
30
|
|
|
27
|
-
const DB_ADDONS = ALL_ADDONS.filter(addon => addon.category ===
|
|
28
|
-
const LOGGER_ADDONS = ALL_ADDONS.filter(addon => addon.category ===
|
|
29
|
-
const VALIDATOR_ADDONS = ALL_ADDONS.filter(addon => addon.category ===
|
|
31
|
+
const DB_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "database");
|
|
32
|
+
const LOGGER_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "logger");
|
|
33
|
+
const VALIDATOR_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "validator");
|
|
30
34
|
|
|
31
35
|
export function getCapabilitiesCatalog(): CapabilitiesCatalog {
|
|
32
36
|
return {
|
|
33
|
-
|
|
37
|
+
types: [...PROJECT_TYPES],
|
|
34
38
|
db: {
|
|
35
39
|
odms: [...DB_ODMS],
|
|
36
40
|
drivers: [...DB_DRIVERS],
|
|
@@ -38,56 +42,56 @@ export function getCapabilitiesCatalog(): CapabilitiesCatalog {
|
|
|
38
42
|
},
|
|
39
43
|
loggers: [...LOGGERS],
|
|
40
44
|
validators: [...VALIDATORS],
|
|
41
|
-
}
|
|
45
|
+
};
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
export function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {
|
|
45
|
-
const selected: AddonDefinition[] = []
|
|
49
|
+
const selected: AddonDefinition[] = [];
|
|
46
50
|
|
|
47
51
|
if (ctx.db) {
|
|
48
|
-
const dbAddon = DB_ADDONS.find(addon => addon.id === ctx.db)
|
|
52
|
+
const dbAddon = DB_ADDONS.find((addon) => addon.id === ctx.db);
|
|
49
53
|
if (!dbAddon) {
|
|
50
|
-
throw new Error(`Unknown database addon "${ctx.db}"`)
|
|
54
|
+
throw new Error(`Unknown database addon "${ctx.db}"`);
|
|
51
55
|
}
|
|
52
|
-
selected.push(dbAddon)
|
|
56
|
+
selected.push(dbAddon);
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
if (ctx.logger) {
|
|
56
|
-
const loggerAddon = LOGGER_ADDONS.find(addon => addon.id === ctx.logger)
|
|
60
|
+
const loggerAddon = LOGGER_ADDONS.find((addon) => addon.id === ctx.logger);
|
|
57
61
|
if (!loggerAddon) {
|
|
58
|
-
throw new Error(`Unknown logger addon "${ctx.logger}"`)
|
|
62
|
+
throw new Error(`Unknown logger addon "${ctx.logger}"`);
|
|
59
63
|
}
|
|
60
|
-
selected.push(loggerAddon)
|
|
64
|
+
selected.push(loggerAddon);
|
|
61
65
|
}
|
|
62
66
|
|
|
63
|
-
const dbCount = selected.filter(addon => addon.category ===
|
|
67
|
+
const dbCount = selected.filter((addon) => addon.category === "database").length;
|
|
64
68
|
if (dbCount > 1) {
|
|
65
|
-
throw new Error(
|
|
69
|
+
throw new Error("Only one database addon can be selected");
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
const loggerCount = selected.filter(addon => addon.category ===
|
|
72
|
+
const loggerCount = selected.filter((addon) => addon.category === "logger").length;
|
|
69
73
|
if (loggerCount > 1) {
|
|
70
|
-
throw new Error(
|
|
74
|
+
throw new Error("Only one logger addon can be selected");
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
if (ctx.validator) {
|
|
74
|
-
const validatorAddon = VALIDATOR_ADDONS.find(addon => addon.id === ctx.validator)
|
|
78
|
+
const validatorAddon = VALIDATOR_ADDONS.find((addon) => addon.id === ctx.validator);
|
|
75
79
|
if (!validatorAddon) {
|
|
76
|
-
throw new Error(`Unknown validator addon "${ctx.validator}"`)
|
|
80
|
+
throw new Error(`Unknown validator addon "${ctx.validator}"`);
|
|
77
81
|
}
|
|
78
|
-
selected.push(validatorAddon)
|
|
82
|
+
selected.push(validatorAddon);
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
const validatorCount = selected.filter(addon => addon.category ===
|
|
85
|
+
const validatorCount = selected.filter((addon) => addon.category === "validator").length;
|
|
82
86
|
if (validatorCount > 1) {
|
|
83
|
-
throw new Error(
|
|
87
|
+
throw new Error("Only one validator addon can be selected");
|
|
84
88
|
}
|
|
85
89
|
|
|
86
|
-
return selected
|
|
90
|
+
return selected;
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
export function collectBootBindings(ctx: ScaffoldContext) {
|
|
90
94
|
return resolveAddons(ctx)
|
|
91
|
-
.map(addon => addon.bootBinding?.(ctx))
|
|
92
|
-
.filter((v): v is NonNullable<typeof v> => Boolean(v))
|
|
95
|
+
.map((addon) => addon.bootBinding?.(ctx))
|
|
96
|
+
.filter((v): v is NonNullable<typeof v> => Boolean(v));
|
|
93
97
|
}
|
package/src/addons/types.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type { ScaffoldContext } from
|
|
1
|
+
import type { ScaffoldContext } from "../core/types.js";
|
|
2
2
|
|
|
3
3
|
export type BootBinding = {
|
|
4
|
-
key: string
|
|
5
|
-
importPath: string
|
|
6
|
-
factoryName: string
|
|
7
|
-
}
|
|
4
|
+
key: string;
|
|
5
|
+
importPath: string;
|
|
6
|
+
factoryName: string;
|
|
7
|
+
};
|
|
8
8
|
|
|
9
|
-
export type FileWriter = (filePath: string, contents: string) => Promise<void
|
|
9
|
+
export type FileWriter = (filePath: string, contents: string) => Promise<void>;
|
|
10
10
|
|
|
11
11
|
export type AddonDefinition = {
|
|
12
|
-
id: string
|
|
13
|
-
category:
|
|
14
|
-
dependencies: (ctx: ScaffoldContext) => string[]
|
|
15
|
-
devDependencies: (ctx: ScaffoldContext) => string[]
|
|
16
|
-
scripts?: (ctx: ScaffoldContext) => Record<string, string
|
|
17
|
-
bootBinding?: (ctx: ScaffoldContext) => BootBinding
|
|
18
|
-
apply: (ctx: ScaffoldContext, write: FileWriter) => Promise<void
|
|
19
|
-
}
|
|
12
|
+
id: string;
|
|
13
|
+
category: "database" | "logger" | "validator";
|
|
14
|
+
dependencies: (ctx: ScaffoldContext) => string[];
|
|
15
|
+
devDependencies: (ctx: ScaffoldContext) => string[];
|
|
16
|
+
scripts?: (ctx: ScaffoldContext) => Record<string, string>;
|
|
17
|
+
bootBinding?: (ctx: ScaffoldContext) => BootBinding;
|
|
18
|
+
apply: (ctx: ScaffoldContext, write: FileWriter) => Promise<void>;
|
|
19
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ValidatorAddon } from
|
|
1
|
+
import { ValidatorAddon } from "../validators.js";
|
|
2
2
|
|
|
3
|
-
export const valibotAddon = ValidatorAddon(
|
|
3
|
+
export const valibotAddon = ValidatorAddon("valibot");
|
package/src/addons/validators.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { ValidatorId } from
|
|
2
|
-
import type { AddonDefinition } from
|
|
1
|
+
import type { ValidatorId } from "../core/types";
|
|
2
|
+
import type { AddonDefinition } from "./types";
|
|
3
3
|
|
|
4
4
|
export const IMPORT_LINES: Record<ValidatorId, string> = {
|
|
5
5
|
zod: `import { z } from 'zod'`,
|
|
6
6
|
arktype: `import { type } from 'arktype'`,
|
|
7
7
|
valibot: `import * as v from 'valibot'`,
|
|
8
|
-
}
|
|
8
|
+
};
|
|
9
9
|
|
|
10
10
|
export const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {
|
|
11
11
|
zod: `, {
|
|
@@ -17,23 +17,23 @@ export const VALIDATION_BLOCK_TEMPLATE: Record<ValidatorId, string> = {
|
|
|
17
17
|
valibot: `, {
|
|
18
18
|
query: v.object({ name: v.string() }),
|
|
19
19
|
}`,
|
|
20
|
-
}
|
|
20
|
+
};
|
|
21
21
|
|
|
22
|
-
const ROUTE_TEMPLATE = (validator: ValidatorId) => `
|
|
22
|
+
const ROUTE_TEMPLATE = (validator: ValidatorId) => `import { reply } from '@taserjs/router'
|
|
23
23
|
import { t } from '#src/taser.js'
|
|
24
24
|
${IMPORT_LINES[validator]}
|
|
25
25
|
|
|
26
26
|
export const Route = t.get('/'${VALIDATION_BLOCK_TEMPLATE[validator]}).handler((ctx) => {
|
|
27
|
-
return
|
|
27
|
+
return reply.json({ message: \`Hello, \${ctx.query.name}!\` })
|
|
28
28
|
})
|
|
29
|
-
|
|
29
|
+
`;
|
|
30
30
|
|
|
31
31
|
export const ValidatorAddon = (validator: ValidatorId): AddonDefinition => {
|
|
32
32
|
return {
|
|
33
33
|
id: validator,
|
|
34
|
-
category:
|
|
34
|
+
category: "validator",
|
|
35
35
|
dependencies: () => [validator],
|
|
36
36
|
devDependencies: () => [],
|
|
37
|
-
apply: (ctx, write) => write(
|
|
38
|
-
}
|
|
39
|
-
}
|
|
37
|
+
apply: (ctx, write) => write("src/routes/index.get.ts", ROUTE_TEMPLATE(validator)),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import type { AddonDefinition } from
|
|
1
|
+
import type { AddonDefinition } from "../types.js";
|
|
2
2
|
|
|
3
3
|
export const winstonAddon: AddonDefinition = {
|
|
4
|
-
id:
|
|
5
|
-
category:
|
|
4
|
+
id: "winston",
|
|
5
|
+
category: "logger",
|
|
6
6
|
dependencies() {
|
|
7
|
-
return [
|
|
7
|
+
return ["winston"];
|
|
8
8
|
},
|
|
9
9
|
devDependencies() {
|
|
10
|
-
return []
|
|
10
|
+
return [];
|
|
11
11
|
},
|
|
12
12
|
bootBinding() {
|
|
13
13
|
return {
|
|
14
|
-
key:
|
|
15
|
-
importPath:
|
|
16
|
-
factoryName:
|
|
17
|
-
}
|
|
14
|
+
key: "logger",
|
|
15
|
+
importPath: "./logger.js",
|
|
16
|
+
factoryName: "createLogger",
|
|
17
|
+
};
|
|
18
18
|
},
|
|
19
19
|
async apply(_ctx, write) {
|
|
20
20
|
await write(
|
|
21
|
-
|
|
21
|
+
"src/logger.ts",
|
|
22
22
|
`import winston from 'winston'
|
|
23
23
|
|
|
24
24
|
export function createLogger() {
|
|
@@ -29,6 +29,6 @@ export function createLogger() {
|
|
|
29
29
|
})
|
|
30
30
|
}
|
|
31
31
|
`,
|
|
32
|
-
)
|
|
32
|
+
);
|
|
33
33
|
},
|
|
34
|
-
}
|
|
34
|
+
};
|
package/src/addons/zod/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ValidatorAddon } from
|
|
1
|
+
import { ValidatorAddon } from "../validators.js";
|
|
2
2
|
|
|
3
|
-
export const zodAddon = ValidatorAddon(
|
|
3
|
+
export const zodAddon = ValidatorAddon("zod");
|
package/src/cli.ts
CHANGED
|
@@ -1,57 +1,60 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { parseArgs } from
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
3
|
|
|
4
|
-
import * as p from
|
|
5
|
-
import color from
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import color from "picocolors";
|
|
6
6
|
|
|
7
|
-
import { buildParsedArgsFromCli, runCreateCommand } from
|
|
8
|
-
import { printJsonError } from
|
|
7
|
+
import { buildParsedArgsFromCli, runCreateCommand } from "./commands/create.js";
|
|
8
|
+
import { printJsonError } from "./core/json-output.js";
|
|
9
9
|
|
|
10
10
|
async function main(): Promise<void> {
|
|
11
11
|
const { values, positionals } = parseArgs({
|
|
12
12
|
args: process.argv.slice(2),
|
|
13
13
|
options: {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
type: { type: "string", short: "t" },
|
|
15
|
+
framework: { type: "string" },
|
|
16
|
+
db: { type: "string" },
|
|
17
|
+
logger: { type: "string" },
|
|
18
|
+
validator: { type: "string" },
|
|
19
|
+
y: { type: "boolean", short: "y" },
|
|
20
|
+
noInstall: { type: "boolean" },
|
|
21
|
+
json: { type: "boolean" },
|
|
20
22
|
},
|
|
21
23
|
allowPositionals: true,
|
|
22
|
-
})
|
|
24
|
+
});
|
|
23
25
|
|
|
24
26
|
const parsed = buildParsedArgsFromCli(
|
|
25
27
|
{
|
|
28
|
+
...(values.type !== undefined ? { type: values.type } : {}),
|
|
26
29
|
...(values.framework !== undefined ? { framework: values.framework } : {}),
|
|
27
30
|
...(values.db !== undefined ? { db: values.db } : {}),
|
|
28
31
|
...(values.logger !== undefined ? { logger: values.logger } : {}),
|
|
32
|
+
...(values.validator !== undefined ? { validator: values.validator } : {}),
|
|
29
33
|
...(values.y !== undefined ? { y: values.y } : {}),
|
|
30
34
|
...(values.noInstall !== undefined ? { noInstall: values.noInstall } : {}),
|
|
31
35
|
...(values.json !== undefined ? { json: values.json } : {}),
|
|
32
36
|
},
|
|
33
37
|
positionals,
|
|
34
|
-
)
|
|
38
|
+
);
|
|
35
39
|
|
|
36
40
|
if (!parsed.json) {
|
|
37
|
-
console.clear()
|
|
38
|
-
p.intro(color.bgCyan(color.black(
|
|
41
|
+
console.clear();
|
|
42
|
+
p.intro(color.bgCyan(color.black(" create-taser ")));
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
try {
|
|
42
|
-
await runCreateCommand(parsed)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
46
|
+
await runCreateCommand(parsed);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
46
49
|
if (parsed.json) {
|
|
47
|
-
printJsonError(message)
|
|
48
|
-
process.exit(1)
|
|
50
|
+
printJsonError(message);
|
|
51
|
+
process.exit(1);
|
|
49
52
|
}
|
|
50
|
-
throw error
|
|
53
|
+
throw error;
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
main().catch((error: unknown) => {
|
|
55
|
-
console.error(error)
|
|
56
|
-
process.exit(1)
|
|
57
|
-
})
|
|
58
|
+
console.error(error);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|