create-taserjs 0.0.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/LICENSE +15 -0
- package/README.md +22 -0
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/cjs/addons/drizzle/index.cjs +124 -0
- package/dist/cjs/addons/drizzle/index.cjs.map +1 -0
- package/dist/cjs/addons/drizzle/index.d.cts +2 -0
- package/dist/cjs/addons/kysely/index.cjs +96 -0
- package/dist/cjs/addons/kysely/index.cjs.map +1 -0
- package/dist/cjs/addons/kysely/index.d.cts +2 -0
- package/dist/cjs/addons/pino/index.cjs +30 -0
- package/dist/cjs/addons/pino/index.cjs.map +1 -0
- package/dist/cjs/addons/pino/index.d.cts +2 -0
- package/dist/cjs/addons/prisma/index.cjs +66 -0
- package/dist/cjs/addons/prisma/index.cjs.map +1 -0
- package/dist/cjs/addons/prisma/index.d.cts +2 -0
- package/dist/cjs/addons/registry.cjs +52 -0
- package/dist/cjs/addons/registry.cjs.map +1 -0
- package/dist/cjs/addons/registry.d.cts +5 -0
- package/dist/cjs/addons/types.d.cts +16 -0
- package/dist/cjs/addons/winston/index.cjs +34 -0
- package/dist/cjs/addons/winston/index.cjs.map +1 -0
- package/dist/cjs/addons/winston/index.d.cts +2 -0
- package/dist/cjs/cli.cjs +56 -0
- package/dist/cjs/cli.cjs.map +1 -0
- package/dist/cjs/cli.d.cts +2 -0
- package/dist/cjs/commands/create.cjs +243 -0
- package/dist/cjs/commands/create.cjs.map +1 -0
- package/dist/cjs/commands/create.d.cts +11 -0
- package/dist/cjs/core/json-output.cjs +16 -0
- package/dist/cjs/core/json-output.cjs.map +1 -0
- package/dist/cjs/core/json-output.d.cts +4 -0
- package/dist/cjs/core/package-manager.cjs +64 -0
- package/dist/cjs/core/package-manager.cjs.map +1 -0
- package/dist/cjs/core/package-manager.d.cts +7 -0
- package/dist/cjs/core/parse-options.cjs +59 -0
- package/dist/cjs/core/parse-options.cjs.map +1 -0
- package/dist/cjs/core/parse-options.d.cts +18 -0
- package/dist/cjs/core/project-config.cjs +18 -0
- package/dist/cjs/core/project-config.cjs.map +1 -0
- package/dist/cjs/core/project-config.d.cts +2 -0
- package/dist/cjs/core/resolve-packages.cjs +52 -0
- package/dist/cjs/core/resolve-packages.cjs.map +1 -0
- package/dist/cjs/core/resolve-packages.d.cts +5 -0
- package/dist/cjs/core/scaffold-engine.cjs +73 -0
- package/dist/cjs/core/scaffold-engine.cjs.map +1 -0
- package/dist/cjs/core/scaffold-engine.d.cts +2 -0
- package/dist/cjs/core/types.cjs +27 -0
- package/dist/cjs/core/types.cjs.map +1 -0
- package/dist/cjs/core/types.d.cts +37 -0
- package/dist/cjs/core/validate-project-name.cjs +45 -0
- package/dist/cjs/core/validate-project-name.cjs.map +1 -0
- package/dist/cjs/core/validate-project-name.d.cts +1 -0
- package/dist/cjs/frameworks/index.cjs +106 -0
- package/dist/cjs/frameworks/index.cjs.map +1 -0
- package/dist/cjs/frameworks/index.d.cts +3 -0
- package/dist/cjs/scaffold.d.cts +3 -0
- package/dist/cjs/templates/base.cjs +186 -0
- package/dist/cjs/templates/base.cjs.map +1 -0
- package/dist/cjs/templates/base.d.cts +12 -0
- package/dist/cjs/types.d.cts +1 -0
- package/dist/esm/addons/drizzle/index.d.ts +2 -0
- package/dist/esm/addons/drizzle/index.js +124 -0
- package/dist/esm/addons/drizzle/index.js.map +1 -0
- package/dist/esm/addons/kysely/index.d.ts +2 -0
- package/dist/esm/addons/kysely/index.js +96 -0
- package/dist/esm/addons/kysely/index.js.map +1 -0
- package/dist/esm/addons/pino/index.d.ts +2 -0
- package/dist/esm/addons/pino/index.js +30 -0
- package/dist/esm/addons/pino/index.js.map +1 -0
- package/dist/esm/addons/prisma/index.d.ts +2 -0
- package/dist/esm/addons/prisma/index.js +66 -0
- package/dist/esm/addons/prisma/index.js.map +1 -0
- package/dist/esm/addons/registry.d.ts +5 -0
- package/dist/esm/addons/registry.js +50 -0
- package/dist/esm/addons/registry.js.map +1 -0
- package/dist/esm/addons/types.d.ts +16 -0
- package/dist/esm/addons/winston/index.d.ts +2 -0
- package/dist/esm/addons/winston/index.js +34 -0
- package/dist/esm/addons/winston/index.js.map +1 -0
- package/dist/esm/cli.d.ts +2 -0
- package/dist/esm/cli.js +53 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/commands/create.d.ts +11 -0
- package/dist/esm/commands/create.js +238 -0
- package/dist/esm/commands/create.js.map +1 -0
- package/dist/esm/core/json-output.d.ts +4 -0
- package/dist/esm/core/json-output.js +14 -0
- package/dist/esm/core/json-output.js.map +1 -0
- package/dist/esm/core/package-manager.d.ts +7 -0
- package/dist/esm/core/package-manager.js +62 -0
- package/dist/esm/core/package-manager.js.map +1 -0
- package/dist/esm/core/parse-options.d.ts +18 -0
- package/dist/esm/core/parse-options.js +56 -0
- package/dist/esm/core/parse-options.js.map +1 -0
- package/dist/esm/core/project-config.d.ts +2 -0
- package/dist/esm/core/project-config.js +16 -0
- package/dist/esm/core/project-config.js.map +1 -0
- package/dist/esm/core/resolve-packages.d.ts +5 -0
- package/dist/esm/core/resolve-packages.js +52 -0
- package/dist/esm/core/resolve-packages.js.map +1 -0
- package/dist/esm/core/scaffold-engine.d.ts +2 -0
- package/dist/esm/core/scaffold-engine.js +71 -0
- package/dist/esm/core/scaffold-engine.js.map +1 -0
- package/dist/esm/core/types.d.ts +37 -0
- package/dist/esm/core/types.js +23 -0
- package/dist/esm/core/types.js.map +1 -0
- package/dist/esm/core/validate-project-name.d.ts +1 -0
- package/dist/esm/core/validate-project-name.js +43 -0
- package/dist/esm/core/validate-project-name.js.map +1 -0
- package/dist/esm/frameworks/index.d.ts +3 -0
- package/dist/esm/frameworks/index.js +105 -0
- package/dist/esm/frameworks/index.js.map +1 -0
- package/dist/esm/scaffold.d.ts +3 -0
- package/dist/esm/templates/base.d.ts +12 -0
- package/dist/esm/templates/base.js +178 -0
- package/dist/esm/templates/base.js.map +1 -0
- package/dist/esm/types.d.ts +1 -0
- package/package.json +45 -0
- package/src/addons/drizzle/index.ts +145 -0
- package/src/addons/kysely/index.ts +111 -0
- package/src/addons/pino/index.ts +30 -0
- package/src/addons/prisma/index.ts +81 -0
- package/src/addons/registry.ts +73 -0
- package/src/addons/types.ts +19 -0
- package/src/addons/winston/index.ts +34 -0
- package/src/cli.ts +57 -0
- package/src/commands/create.ts +253 -0
- package/src/core/json-output.ts +13 -0
- package/src/core/package-manager.ts +68 -0
- package/src/core/parse-options.ts +97 -0
- package/src/core/project-config.ts +27 -0
- package/src/core/resolve-packages.ts +62 -0
- package/src/core/scaffold-engine.ts +82 -0
- package/src/core/types.ts +51 -0
- package/src/core/validate-project-name.ts +59 -0
- package/src/frameworks/index.ts +111 -0
- package/src/scaffold.ts +3 -0
- package/src/templates/base.ts +209 -0
- package/src/types.ts +9 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
//#region src/addons/kysely/index.ts
|
|
2
|
+
function schemaTypesSource() {
|
|
3
|
+
return `export interface UserTable {
|
|
4
|
+
id: number
|
|
5
|
+
email: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface DB {
|
|
9
|
+
users: UserTable
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
}
|
|
13
|
+
function dbIndexSource(driver) {
|
|
14
|
+
switch (driver) {
|
|
15
|
+
case "postgres": return `import { Kysely, PostgresDialect } from 'kysely'
|
|
16
|
+
import pg from 'pg'
|
|
17
|
+
|
|
18
|
+
import type { DB } from './schema.js'
|
|
19
|
+
|
|
20
|
+
export function createDb() {
|
|
21
|
+
const pool = new pg.Pool({
|
|
22
|
+
connectionString: process.env.DATABASE_URL,
|
|
23
|
+
})
|
|
24
|
+
return new Kysely<DB>({
|
|
25
|
+
dialect: new PostgresDialect({ pool }),
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
case "mysql": return `import { Kysely, MysqlDialect } from 'kysely'
|
|
30
|
+
import { createPool } from 'mysql2'
|
|
31
|
+
|
|
32
|
+
import type { DB } from './schema.js'
|
|
33
|
+
|
|
34
|
+
export function createDb() {
|
|
35
|
+
const pool = createPool(process.env.DATABASE_URL ?? '')
|
|
36
|
+
return new Kysely<DB>({
|
|
37
|
+
dialect: new MysqlDialect({ pool }),
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
default: return `import Database from 'better-sqlite3'
|
|
42
|
+
import { Kysely, SqliteDialect } from 'kysely'
|
|
43
|
+
|
|
44
|
+
import type { DB } from './schema.js'
|
|
45
|
+
|
|
46
|
+
export function createDb() {
|
|
47
|
+
const filePath = (process.env.DATABASE_URL ?? 'file:./local.db').replace(/^file:/, '')
|
|
48
|
+
const database = new Database(filePath)
|
|
49
|
+
return new Kysely<DB>({
|
|
50
|
+
dialect: new SqliteDialect({ database }),
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function driverPackages(driver) {
|
|
57
|
+
switch (driver) {
|
|
58
|
+
case "postgres": return ["pg"];
|
|
59
|
+
case "mysql": return ["mysql2"];
|
|
60
|
+
default: return ["better-sqlite3"];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function envExample(driver) {
|
|
64
|
+
switch (driver) {
|
|
65
|
+
case "postgres": return "DATABASE_URL=postgresql://user:password@localhost:5432/mydb\n";
|
|
66
|
+
case "mysql": return "DATABASE_URL=mysql://user:password@localhost:3306/mydb\n";
|
|
67
|
+
default: return "DATABASE_URL=file:./local.db\n";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
var kyselyAddon = {
|
|
71
|
+
id: "kysely",
|
|
72
|
+
category: "database",
|
|
73
|
+
dependencies(ctx) {
|
|
74
|
+
return ["kysely", ...driverPackages(ctx.driver ?? "sqlite")];
|
|
75
|
+
},
|
|
76
|
+
devDependencies() {
|
|
77
|
+
return [];
|
|
78
|
+
},
|
|
79
|
+
bootBinding() {
|
|
80
|
+
return {
|
|
81
|
+
key: "db",
|
|
82
|
+
importPath: "./db/index.js",
|
|
83
|
+
factoryName: "createDb"
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
async apply(ctx, write) {
|
|
87
|
+
const driver = ctx.driver ?? "sqlite";
|
|
88
|
+
await write("src/db/schema.ts", schemaTypesSource());
|
|
89
|
+
await write("src/db/index.ts", dbIndexSource(driver));
|
|
90
|
+
await write(".env.example", envExample(driver));
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
//#endregion
|
|
94
|
+
export { kyselyAddon };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/kysely/index.ts"],"sourcesContent":["import type { AddonDefinition } from '../types.js'\nimport type { DbDriver } from '../../core/types.js'\n\nfunction schemaTypesSource(): string {\n return `export interface UserTable {\n id: number\n email: string\n}\n\nexport interface DB {\n users: UserTable\n}\n`\n}\n\nfunction dbIndexSource(driver: DbDriver): string {\n switch (driver) {\n case 'postgres':\n return `import { Kysely, PostgresDialect } from 'kysely'\nimport pg from 'pg'\n\nimport type { DB } from './schema.js'\n\nexport function createDb() {\n const pool = new pg.Pool({\n connectionString: process.env.DATABASE_URL,\n })\n return new Kysely<DB>({\n dialect: new PostgresDialect({ pool }),\n })\n}\n`\n case 'mysql':\n return `import { Kysely, MysqlDialect } from 'kysely'\nimport { createPool } from 'mysql2'\n\nimport type { DB } from './schema.js'\n\nexport function createDb() {\n const pool = createPool(process.env.DATABASE_URL ?? '')\n return new Kysely<DB>({\n dialect: new MysqlDialect({ pool }),\n })\n}\n`\n case 'sqlite':\n default:\n return `import Database from 'better-sqlite3'\nimport { Kysely, SqliteDialect } from 'kysely'\n\nimport type { DB } from './schema.js'\n\nexport function createDb() {\n const filePath = (process.env.DATABASE_URL ?? 'file:./local.db').replace(/^file:/, '')\n const database = new Database(filePath)\n return new Kysely<DB>({\n dialect: new SqliteDialect({ database }),\n })\n}\n`\n }\n}\n\nfunction driverPackages(driver: DbDriver): string[] {\n switch (driver) {\n case 'postgres':\n return ['pg']\n case 'mysql':\n return ['mysql2']\n case 'sqlite':\n default:\n return ['better-sqlite3']\n }\n}\n\nfunction envExample(driver: DbDriver): string {\n switch (driver) {\n case 'postgres':\n return 'DATABASE_URL=postgresql://user:password@localhost:5432/mydb\\n'\n case 'mysql':\n return 'DATABASE_URL=mysql://user:password@localhost:3306/mydb\\n'\n case 'sqlite':\n default:\n return 'DATABASE_URL=file:./local.db\\n'\n }\n}\n\nexport const kyselyAddon: AddonDefinition = {\n id: 'kysely',\n category: 'database',\n dependencies(ctx) {\n const driver = ctx.driver ?? 'sqlite'\n return ['kysely', ...driverPackages(driver)]\n },\n devDependencies() {\n return []\n },\n bootBinding() {\n return {\n key: 'db',\n importPath: './db/index.js',\n factoryName: 'createDb',\n }\n },\n async apply(ctx, write) {\n const driver = ctx.driver ?? 'sqlite'\n await write('src/db/schema.ts', schemaTypesSource())\n await write('src/db/index.ts', dbIndexSource(driver))\n await write('.env.example', envExample(driver))\n },\n}\n"],"mappings":";AAGA,SAAS,oBAA4B;CACnC,OAAO;;;;;;;;;AAST;AAEA,SAAS,cAAc,QAA0B;CAC/C,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;;;;;;;;;;;;;;EAcT,KAAK,SACH,OAAO;;;;;;;;;;;;EAaT,SACE,OAAO;;;;;;;;;;;;;CAaX;AACF;AAEA,SAAS,eAAe,QAA4B;CAClD,QAAQ,QAAR;EACE,KAAK,YACH,OAAO,CAAC,IAAI;EACd,KAAK,SACH,OAAO,CAAC,QAAQ;EAElB,SACE,OAAO,CAAC,gBAAgB;CAC5B;AACF;AAEA,SAAS,WAAW,QAA0B;CAC5C,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,IAAa,cAA+B;CAC1C,IAAI;CACJ,UAAU;CACV,aAAa,KAAK;EAEhB,OAAO,CAAC,UAAU,GAAG,eADN,IAAI,UAAU,QACa,CAAC;CAC7C;CACA,kBAAkB;EAChB,OAAO,CAAC;CACV;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,KAAK,OAAO;EACtB,MAAM,SAAS,IAAI,UAAU;EAC7B,MAAM,MAAM,oBAAoB,kBAAkB,CAAC;EACnD,MAAM,MAAM,mBAAmB,cAAc,MAAM,CAAC;EACpD,MAAM,MAAM,gBAAgB,WAAW,MAAM,CAAC;CAChD;AACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/addons/pino/index.ts
|
|
2
|
+
var pinoAddon = {
|
|
3
|
+
id: "pino",
|
|
4
|
+
category: "logger",
|
|
5
|
+
dependencies() {
|
|
6
|
+
return ["pino"];
|
|
7
|
+
},
|
|
8
|
+
devDependencies() {
|
|
9
|
+
return [];
|
|
10
|
+
},
|
|
11
|
+
bootBinding() {
|
|
12
|
+
return {
|
|
13
|
+
key: "logger",
|
|
14
|
+
importPath: "./logger.js",
|
|
15
|
+
factoryName: "createLogger"
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
async apply(_ctx, write) {
|
|
19
|
+
await write("src/logger.ts", `import pino from 'pino'
|
|
20
|
+
|
|
21
|
+
export function createLogger() {
|
|
22
|
+
return pino({ level: process.env.LOG_LEVEL ?? 'info' })
|
|
23
|
+
}
|
|
24
|
+
`);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { pinoAddon };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/pino/index.ts"],"sourcesContent":["import type { AddonDefinition } from '../types.js'\n\nexport const pinoAddon: AddonDefinition = {\n id: 'pino',\n category: 'logger',\n dependencies() {\n return ['pino']\n },\n devDependencies() {\n return []\n },\n bootBinding() {\n return {\n key: 'logger',\n importPath: './logger.js',\n factoryName: 'createLogger',\n }\n },\n async apply(_ctx, write) {\n await write(\n 'src/logger.ts',\n `import pino from 'pino'\n\nexport function createLogger() {\n return pino({ level: process.env.LOG_LEVEL ?? 'info' })\n}\n`,\n )\n },\n}\n"],"mappings":";AAEA,IAAa,YAA6B;CACxC,IAAI;CACJ,UAAU;CACV,eAAe;EACb,OAAO,CAAC,MAAM;CAChB;CACA,kBAAkB;EAChB,OAAO,CAAC;CACV;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,MAAM,OAAO;EACvB,MAAM,MACJ,iBACA;;;;;CAMF;CACF;AACF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/addons/prisma/index.ts
|
|
2
|
+
function prismaProvider(driver) {
|
|
3
|
+
switch (driver) {
|
|
4
|
+
case "postgres": return "postgresql";
|
|
5
|
+
case "mysql": return "mysql";
|
|
6
|
+
default: return "sqlite";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function envExample(driver) {
|
|
10
|
+
switch (driver) {
|
|
11
|
+
case "postgres": return "DATABASE_URL=postgresql://user:password@localhost:5432/mydb\n";
|
|
12
|
+
case "mysql": return "DATABASE_URL=mysql://user:password@localhost:3306/mydb\n";
|
|
13
|
+
default: return "DATABASE_URL=file:./local.db\n";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
var prismaAddon = {
|
|
17
|
+
id: "prisma",
|
|
18
|
+
category: "database",
|
|
19
|
+
dependencies() {
|
|
20
|
+
return ["@prisma/client"];
|
|
21
|
+
},
|
|
22
|
+
devDependencies() {
|
|
23
|
+
return ["prisma"];
|
|
24
|
+
},
|
|
25
|
+
scripts() {
|
|
26
|
+
return {
|
|
27
|
+
"db:generate": "prisma generate",
|
|
28
|
+
"db:push": "prisma db push"
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
bootBinding() {
|
|
32
|
+
return {
|
|
33
|
+
key: "db",
|
|
34
|
+
importPath: "./db/index.js",
|
|
35
|
+
factoryName: "createDb"
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
async apply(ctx, write) {
|
|
39
|
+
const driver = ctx.driver ?? "sqlite";
|
|
40
|
+
await write("prisma/schema.prisma", `generator client {
|
|
41
|
+
provider = "prisma-client-js"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
datasource db {
|
|
45
|
+
provider = "${prismaProvider(driver)}"
|
|
46
|
+
url = env("DATABASE_URL")
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
model User {
|
|
50
|
+
id Int @id @default(autoincrement())
|
|
51
|
+
email String
|
|
52
|
+
}
|
|
53
|
+
`);
|
|
54
|
+
await write("src/db/index.ts", `import { PrismaClient } from '@prisma/client'
|
|
55
|
+
|
|
56
|
+
export function createDb() {
|
|
57
|
+
return new PrismaClient()
|
|
58
|
+
}
|
|
59
|
+
`);
|
|
60
|
+
await write(".env.example", envExample(driver));
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
export { prismaAddon };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/prisma/index.ts"],"sourcesContent":["import type { AddonDefinition } from '../types.js'\nimport type { DbDriver } from '../../core/types.js'\n\nfunction prismaProvider(driver: DbDriver): string {\n switch (driver) {\n case 'postgres':\n return 'postgresql'\n case 'mysql':\n return 'mysql'\n case 'sqlite':\n default:\n return 'sqlite'\n }\n}\n\nfunction envExample(driver: DbDriver): string {\n switch (driver) {\n case 'postgres':\n return 'DATABASE_URL=postgresql://user:password@localhost:5432/mydb\\n'\n case 'mysql':\n return 'DATABASE_URL=mysql://user:password@localhost:3306/mydb\\n'\n case 'sqlite':\n default:\n return 'DATABASE_URL=file:./local.db\\n'\n }\n}\n\nexport const prismaAddon: AddonDefinition = {\n id: 'prisma',\n category: 'database',\n dependencies() {\n return ['@prisma/client']\n },\n devDependencies() {\n return ['prisma']\n },\n scripts() {\n return {\n 'db:generate': 'prisma generate',\n 'db:push': 'prisma db push',\n }\n },\n bootBinding() {\n return {\n key: 'db',\n importPath: './db/index.js',\n factoryName: 'createDb',\n }\n },\n async apply(ctx, write) {\n const driver = ctx.driver ?? 'sqlite'\n const provider = prismaProvider(driver)\n await write(\n 'prisma/schema.prisma',\n `generator client {\n provider = \"prisma-client-js\"\n}\n\ndatasource db {\n provider = \"${provider}\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel User {\n id Int @id @default(autoincrement())\n email String\n}\n`,\n )\n await write(\n 'src/db/index.ts',\n `import { PrismaClient } from '@prisma/client'\n\nexport function createDb() {\n return new PrismaClient()\n}\n`,\n )\n await write('.env.example', envExample(driver))\n },\n}\n"],"mappings":";AAGA,SAAS,eAAe,QAA0B;CAChD,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,WAAW,QAA0B;CAC5C,QAAQ,QAAR;EACE,KAAK,YACH,OAAO;EACT,KAAK,SACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,IAAa,cAA+B;CAC1C,IAAI;CACJ,UAAU;CACV,eAAe;EACb,OAAO,CAAC,gBAAgB;CAC1B;CACA,kBAAkB;EAChB,OAAO,CAAC,QAAQ;CAClB;CACA,UAAU;EACR,OAAO;GACL,eAAe;GACf,WAAW;EACb;CACF;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,KAAK,OAAO;EACtB,MAAM,SAAS,IAAI,UAAU;EAE7B,MAAM,MACJ,wBACA;;;;;gBAHe,eAAe,MAQpB,EAAS;;;;;;;;CASrB;EACA,MAAM,MACJ,mBACA;;;;;CAMF;EACA,MAAM,MAAM,gBAAgB,WAAW,MAAM,CAAC;CAChD;AACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AddonDefinition } from './types.js';
|
|
2
|
+
import { CapabilitiesCatalog, ScaffoldContext } from '../core/types.js';
|
|
3
|
+
export declare function getCapabilitiesCatalog(): CapabilitiesCatalog;
|
|
4
|
+
export declare function resolveAddons(ctx: ScaffoldContext): AddonDefinition[];
|
|
5
|
+
export declare function collectBootBindings(ctx: ScaffoldContext): import('./types.js').BootBinding[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { drizzleAddon } from "./drizzle/index.js";
|
|
2
|
+
import { kyselyAddon } from "./kysely/index.js";
|
|
3
|
+
import { pinoAddon } from "./pino/index.js";
|
|
4
|
+
import { prismaAddon } from "./prisma/index.js";
|
|
5
|
+
import { winstonAddon } from "./winston/index.js";
|
|
6
|
+
import { DB_DRIVERS, DB_ODMS, DEFAULT_DB_DRIVER, FRAMEWORKS, LOGGERS } from "../core/types.js";
|
|
7
|
+
//#region src/addons/registry.ts
|
|
8
|
+
var ALL_ADDONS = [
|
|
9
|
+
drizzleAddon,
|
|
10
|
+
prismaAddon,
|
|
11
|
+
kyselyAddon,
|
|
12
|
+
pinoAddon,
|
|
13
|
+
winstonAddon
|
|
14
|
+
];
|
|
15
|
+
var DB_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "database");
|
|
16
|
+
var LOGGER_ADDONS = ALL_ADDONS.filter((addon) => addon.category === "logger");
|
|
17
|
+
function getCapabilitiesCatalog() {
|
|
18
|
+
return {
|
|
19
|
+
frameworks: [...FRAMEWORKS],
|
|
20
|
+
db: {
|
|
21
|
+
odms: [...DB_ODMS],
|
|
22
|
+
drivers: [...DB_DRIVERS],
|
|
23
|
+
defaultDriver: DEFAULT_DB_DRIVER
|
|
24
|
+
},
|
|
25
|
+
loggers: [...LOGGERS]
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function resolveAddons(ctx) {
|
|
29
|
+
const selected = [];
|
|
30
|
+
if (ctx.db) {
|
|
31
|
+
const dbAddon = DB_ADDONS.find((addon) => addon.id === ctx.db);
|
|
32
|
+
if (!dbAddon) throw new Error(`Unknown database addon "${ctx.db}"`);
|
|
33
|
+
selected.push(dbAddon);
|
|
34
|
+
}
|
|
35
|
+
if (ctx.logger) {
|
|
36
|
+
const loggerAddon = LOGGER_ADDONS.find((addon) => addon.id === ctx.logger);
|
|
37
|
+
if (!loggerAddon) throw new Error(`Unknown logger addon "${ctx.logger}"`);
|
|
38
|
+
selected.push(loggerAddon);
|
|
39
|
+
}
|
|
40
|
+
if (selected.filter((addon) => addon.category === "database").length > 1) throw new Error("Only one database addon can be selected");
|
|
41
|
+
if (selected.filter((addon) => addon.category === "logger").length > 1) throw new Error("Only one logger addon can be selected");
|
|
42
|
+
return selected;
|
|
43
|
+
}
|
|
44
|
+
function collectBootBindings(ctx) {
|
|
45
|
+
return resolveAddons(ctx).map((addon) => addon.bootBinding(ctx));
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { collectBootBindings, getCapabilitiesCatalog, resolveAddons };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","names":[],"sources":["../../../src/addons/registry.ts"],"sourcesContent":["import { drizzleAddon } from './drizzle/index.js'\nimport { kyselyAddon } from './kysely/index.js'\nimport { pinoAddon } from './pino/index.js'\nimport { prismaAddon } from './prisma/index.js'\nimport type { AddonDefinition } from './types.js'\nimport { winstonAddon } from './winston/index.js'\nimport type { CapabilitiesCatalog, ScaffoldContext } from '../core/types.js'\nimport {\n DB_DRIVERS,\n DB_ODMS,\n DEFAULT_DB_DRIVER,\n FRAMEWORKS,\n LOGGERS,\n} from '../core/types.js'\n\nconst ALL_ADDONS: AddonDefinition[] = [\n drizzleAddon,\n prismaAddon,\n kyselyAddon,\n pinoAddon,\n winstonAddon,\n]\n\nconst DB_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'database')\nconst LOGGER_ADDONS = ALL_ADDONS.filter(addon => addon.category === 'logger')\n\nexport function getCapabilitiesCatalog(): CapabilitiesCatalog {\n return {\n frameworks: [...FRAMEWORKS],\n db: {\n odms: [...DB_ODMS],\n drivers: [...DB_DRIVERS],\n defaultDriver: DEFAULT_DB_DRIVER,\n },\n loggers: [...LOGGERS],\n }\n}\n\nexport function resolveAddons(ctx: ScaffoldContext): AddonDefinition[] {\n const selected: AddonDefinition[] = []\n\n if (ctx.db) {\n const dbAddon = DB_ADDONS.find(addon => addon.id === ctx.db)\n if (!dbAddon) {\n throw new Error(`Unknown database addon \"${ctx.db}\"`)\n }\n selected.push(dbAddon)\n }\n\n if (ctx.logger) {\n const loggerAddon = LOGGER_ADDONS.find(addon => addon.id === ctx.logger)\n if (!loggerAddon) {\n throw new Error(`Unknown logger addon \"${ctx.logger}\"`)\n }\n selected.push(loggerAddon)\n }\n\n const dbCount = selected.filter(addon => addon.category === 'database').length\n if (dbCount > 1) {\n throw new Error('Only one database addon can be selected')\n }\n\n const loggerCount = selected.filter(addon => addon.category === 'logger').length\n if (loggerCount > 1) {\n throw new Error('Only one logger addon can be selected')\n }\n\n return selected\n}\n\nexport function collectBootBindings(ctx: ScaffoldContext) {\n return resolveAddons(ctx).map(addon => addon.bootBinding(ctx))\n}\n"],"mappings":";;;;;;;AAeA,IAAM,aAAgC;CACpC;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,YAAY,WAAW,QAAO,UAAS,MAAM,aAAa,UAAU;AAC1E,IAAM,gBAAgB,WAAW,QAAO,UAAS,MAAM,aAAa,QAAQ;AAE5E,SAAgB,yBAA8C;CAC5D,OAAO;EACL,YAAY,CAAC,GAAG,UAAU;EAC1B,IAAI;GACF,MAAM,CAAC,GAAG,OAAO;GACjB,SAAS,CAAC,GAAG,UAAU;GACvB,eAAe;EACjB;EACA,SAAS,CAAC,GAAG,OAAO;CACtB;AACF;AAEA,SAAgB,cAAc,KAAyC;CACrE,MAAM,WAA8B,CAAC;CAErC,IAAI,IAAI,IAAI;EACV,MAAM,UAAU,UAAU,MAAK,UAAS,MAAM,OAAO,IAAI,EAAE;EAC3D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,2BAA2B,IAAI,GAAG,EAAE;EAEtD,SAAS,KAAK,OAAO;CACvB;CAEA,IAAI,IAAI,QAAQ;EACd,MAAM,cAAc,cAAc,MAAK,UAAS,MAAM,OAAO,IAAI,MAAM;EACvE,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,yBAAyB,IAAI,OAAO,EAAE;EAExD,SAAS,KAAK,WAAW;CAC3B;CAGA,IADgB,SAAS,QAAO,UAAS,MAAM,aAAa,UAAU,CAAC,CAAC,SAC1D,GACZ,MAAM,IAAI,MAAM,yCAAyC;CAI3D,IADoB,SAAS,QAAO,UAAS,MAAM,aAAa,QAAQ,CAAC,CAAC,SACxD,GAChB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,OAAO;AACT;AAEA,SAAgB,oBAAoB,KAAsB;CACxD,OAAO,cAAc,GAAG,CAAC,CAAC,KAAI,UAAS,MAAM,YAAY,GAAG,CAAC;AAC/D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ScaffoldContext } from '../core/types.js';
|
|
2
|
+
export type BootBinding = {
|
|
3
|
+
key: string;
|
|
4
|
+
importPath: string;
|
|
5
|
+
factoryName: string;
|
|
6
|
+
};
|
|
7
|
+
export type FileWriter = (filePath: string, contents: string) => Promise<void>;
|
|
8
|
+
export type AddonDefinition = {
|
|
9
|
+
id: string;
|
|
10
|
+
category: 'database' | 'logger';
|
|
11
|
+
dependencies: (ctx: ScaffoldContext) => string[];
|
|
12
|
+
devDependencies: (ctx: ScaffoldContext) => string[];
|
|
13
|
+
scripts?: (ctx: ScaffoldContext) => Record<string, string>;
|
|
14
|
+
bootBinding: (ctx: ScaffoldContext) => BootBinding;
|
|
15
|
+
apply: (ctx: ScaffoldContext, write: FileWriter) => Promise<void>;
|
|
16
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/addons/winston/index.ts
|
|
2
|
+
var winstonAddon = {
|
|
3
|
+
id: "winston",
|
|
4
|
+
category: "logger",
|
|
5
|
+
dependencies() {
|
|
6
|
+
return ["winston"];
|
|
7
|
+
},
|
|
8
|
+
devDependencies() {
|
|
9
|
+
return [];
|
|
10
|
+
},
|
|
11
|
+
bootBinding() {
|
|
12
|
+
return {
|
|
13
|
+
key: "logger",
|
|
14
|
+
importPath: "./logger.js",
|
|
15
|
+
factoryName: "createLogger"
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
async apply(_ctx, write) {
|
|
19
|
+
await write("src/logger.ts", `import winston from 'winston'
|
|
20
|
+
|
|
21
|
+
export function createLogger() {
|
|
22
|
+
return winston.createLogger({
|
|
23
|
+
level: process.env.LOG_LEVEL ?? 'info',
|
|
24
|
+
format: winston.format.json(),
|
|
25
|
+
transports: [new winston.transports.Console()],
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { winstonAddon };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/addons/winston/index.ts"],"sourcesContent":["import type { AddonDefinition } from '../types.js'\n\nexport const winstonAddon: AddonDefinition = {\n id: 'winston',\n category: 'logger',\n dependencies() {\n return ['winston']\n },\n devDependencies() {\n return []\n },\n bootBinding() {\n return {\n key: 'logger',\n importPath: './logger.js',\n factoryName: 'createLogger',\n }\n },\n async apply(_ctx, write) {\n await write(\n 'src/logger.ts',\n `import winston from 'winston'\n\nexport function createLogger() {\n return winston.createLogger({\n level: process.env.LOG_LEVEL ?? 'info',\n format: winston.format.json(),\n transports: [new winston.transports.Console()],\n })\n}\n`,\n )\n },\n}\n"],"mappings":";AAEA,IAAa,eAAgC;CAC3C,IAAI;CACJ,UAAU;CACV,eAAe;EACb,OAAO,CAAC,SAAS;CACnB;CACA,kBAAkB;EAChB,OAAO,CAAC;CACV;CACA,cAAc;EACZ,OAAO;GACL,KAAK;GACL,YAAY;GACZ,aAAa;EACf;CACF;CACA,MAAM,MAAM,MAAM,OAAO;EACvB,MAAM,MACJ,iBACA;;;;;;;;;CAUF;CACF;AACF"}
|
package/dist/esm/cli.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { printJsonError } from "./core/json-output.js";
|
|
3
|
+
import { buildParsedArgsFromCli, runCreateCommand } from "./commands/create.js";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
import * as p from "@clack/prompts";
|
|
6
|
+
import color from "picocolors";
|
|
7
|
+
//#region src/cli.ts
|
|
8
|
+
async function main() {
|
|
9
|
+
const { values, positionals } = parseArgs({
|
|
10
|
+
args: process.argv.slice(2),
|
|
11
|
+
options: {
|
|
12
|
+
framework: { type: "string" },
|
|
13
|
+
db: { type: "string" },
|
|
14
|
+
logger: { type: "string" },
|
|
15
|
+
y: {
|
|
16
|
+
type: "boolean",
|
|
17
|
+
short: "y"
|
|
18
|
+
},
|
|
19
|
+
noInstall: { type: "boolean" },
|
|
20
|
+
json: { type: "boolean" }
|
|
21
|
+
},
|
|
22
|
+
allowPositionals: true
|
|
23
|
+
});
|
|
24
|
+
const parsed = buildParsedArgsFromCli({
|
|
25
|
+
...values.framework !== void 0 ? { framework: values.framework } : {},
|
|
26
|
+
...values.db !== void 0 ? { db: values.db } : {},
|
|
27
|
+
...values.logger !== void 0 ? { logger: values.logger } : {},
|
|
28
|
+
...values.y !== void 0 ? { y: values.y } : {},
|
|
29
|
+
...values.noInstall !== void 0 ? { noInstall: values.noInstall } : {},
|
|
30
|
+
...values.json !== void 0 ? { json: values.json } : {}
|
|
31
|
+
}, positionals);
|
|
32
|
+
if (!parsed.json) {
|
|
33
|
+
console.clear();
|
|
34
|
+
p.intro(color.bgCyan(color.black(" create-taser ")));
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
await runCreateCommand(parsed);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
40
|
+
if (parsed.json) {
|
|
41
|
+
printJsonError(message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
main().catch((error) => {
|
|
48
|
+
console.error(error);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
});
|
|
51
|
+
//#endregion
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from 'node:util'\n\nimport * as p from '@clack/prompts'\nimport color from 'picocolors'\n\nimport { buildParsedArgsFromCli, runCreateCommand } from './commands/create.js'\nimport { printJsonError } from './core/json-output.js'\n\nasync function main(): Promise<void> {\n const { values, positionals } = parseArgs({\n args: process.argv.slice(2),\n options: {\n framework: { type: 'string' },\n db: { type: 'string' },\n logger: { type: 'string' },\n y: { type: 'boolean', short: 'y' },\n noInstall: { type: 'boolean' },\n json: { type: 'boolean' },\n },\n allowPositionals: true,\n })\n\n const parsed = buildParsedArgsFromCli(\n {\n ...(values.framework !== undefined ? { framework: values.framework } : {}),\n ...(values.db !== undefined ? { db: values.db } : {}),\n ...(values.logger !== undefined ? { logger: values.logger } : {}),\n ...(values.y !== undefined ? { y: values.y } : {}),\n ...(values.noInstall !== undefined ? { noInstall: values.noInstall } : {}),\n ...(values.json !== undefined ? { json: values.json } : {}),\n },\n positionals,\n )\n\n if (!parsed.json) {\n console.clear()\n p.intro(color.bgCyan(color.black(' create-taser ')))\n }\n\n try {\n await runCreateCommand(parsed)\n }\n catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (parsed.json) {\n printJsonError(message)\n process.exit(1)\n }\n throw error\n }\n}\n\nmain().catch((error: unknown) => {\n console.error(error)\n process.exit(1)\n})\n"],"mappings":";;;;;;;AASA,eAAe,OAAsB;CACnC,MAAM,EAAE,QAAQ,gBAAgB,UAAU;EACxC,MAAM,QAAQ,KAAK,MAAM,CAAC;EAC1B,SAAS;GACP,WAAW,EAAE,MAAM,SAAS;GAC5B,IAAI,EAAE,MAAM,SAAS;GACrB,QAAQ,EAAE,MAAM,SAAS;GACzB,GAAG;IAAE,MAAM;IAAW,OAAO;GAAI;GACjC,WAAW,EAAE,MAAM,UAAU;GAC7B,MAAM,EAAE,MAAM,UAAU;EAC1B;EACA,kBAAkB;CACpB,CAAC;CAED,MAAM,SAAS,uBACb;EACE,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,OAAO,KAAA,IAAY,EAAE,IAAI,OAAO,GAAG,IAAI,CAAC;EACnD,GAAI,OAAO,WAAW,KAAA,IAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;EAC/D,GAAI,OAAO,MAAM,KAAA,IAAY,EAAE,GAAG,OAAO,EAAE,IAAI,CAAC;EAChD,GAAI,OAAO,cAAc,KAAA,IAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EACxE,GAAI,OAAO,SAAS,KAAA,IAAY,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;CAC3D,GACA,WACF;CAEA,IAAI,CAAC,OAAO,MAAM;EAChB,QAAQ,MAAM;EACd,EAAE,MAAM,MAAM,OAAO,MAAM,MAAM,gBAAgB,CAAC,CAAC;CACrD;CAEA,IAAI;EACF,MAAM,iBAAiB,MAAM;CAC/B,SACO,OAAO;EACZ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,IAAI,OAAO,MAAM;GACf,eAAe,OAAO;GACtB,QAAQ,KAAK,CAAC;EAChB;EACA,MAAM;CACR;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,MAAM,KAAK;CACnB,QAAQ,KAAK,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ParsedCreateArgs } from '../core/parse-options.js';
|
|
2
|
+
import { ScaffoldResult } from '../core/types.js';
|
|
3
|
+
export declare function runCreateCommand(args: ParsedCreateArgs): Promise<ScaffoldResult | undefined>;
|
|
4
|
+
export declare function buildParsedArgsFromCli(values: {
|
|
5
|
+
framework?: string;
|
|
6
|
+
db?: string;
|
|
7
|
+
logger?: string;
|
|
8
|
+
y?: boolean;
|
|
9
|
+
noInstall?: boolean;
|
|
10
|
+
json?: boolean;
|
|
11
|
+
}, positionals: string[]): ParsedCreateArgs;
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { DB_DRIVERS, DB_ODMS, FRAMEWORKS, LOGGERS } from "../core/types.js";
|
|
2
|
+
import { getCapabilitiesCatalog } from "../addons/registry.js";
|
|
3
|
+
import { printCapabilitiesCatalog, printJsonError, printScaffoldResult } from "../core/json-output.js";
|
|
4
|
+
import { parseDbFlag, parseFrameworkFlag, parseLoggerFlag, resolveScaffoldDefaults } from "../core/parse-options.js";
|
|
5
|
+
import { resolveUserAgent, runScript } from "../core/package-manager.js";
|
|
6
|
+
import { scaffoldProject } from "../core/scaffold-engine.js";
|
|
7
|
+
import { validateProjectName } from "../core/validate-project-name.js";
|
|
8
|
+
import * as p from "@clack/prompts";
|
|
9
|
+
import color from "picocolors";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
//#region src/commands/create.ts
|
|
12
|
+
function isFramework(value) {
|
|
13
|
+
return typeof value === "string" && FRAMEWORKS.includes(value);
|
|
14
|
+
}
|
|
15
|
+
function isDbOdm(value) {
|
|
16
|
+
return typeof value === "string" && DB_ODMS.includes(value);
|
|
17
|
+
}
|
|
18
|
+
function isDbDriver(value) {
|
|
19
|
+
return typeof value === "string" && DB_DRIVERS.includes(value);
|
|
20
|
+
}
|
|
21
|
+
function isLoggerId(value) {
|
|
22
|
+
return typeof value === "string" && LOGGERS.includes(value);
|
|
23
|
+
}
|
|
24
|
+
async function promptInteractiveOptions(args) {
|
|
25
|
+
const projectName = args.projectName ?? await p.text({
|
|
26
|
+
message: "Project name",
|
|
27
|
+
placeholder: "my-taser-app",
|
|
28
|
+
defaultValue: "my-taser-app",
|
|
29
|
+
validate(value) {
|
|
30
|
+
return validateProjectName(value);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
if (p.isCancel(projectName)) {
|
|
34
|
+
p.cancel("Scaffold cancelled.");
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
const framework = args.framework ?? await p.select({
|
|
38
|
+
message: "Framework adapter",
|
|
39
|
+
options: [
|
|
40
|
+
{
|
|
41
|
+
value: "node",
|
|
42
|
+
label: "Plain Node.js",
|
|
43
|
+
hint: "default"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
value: "express",
|
|
47
|
+
label: "Express"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
value: "hono",
|
|
51
|
+
label: "Hono"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
value: "fastify",
|
|
55
|
+
label: "Fastify"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
initialValue: "node"
|
|
59
|
+
});
|
|
60
|
+
if (p.isCancel(framework) || !isFramework(framework)) {
|
|
61
|
+
p.cancel("Scaffold cancelled.");
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
const dbChoice = args.db ?? await p.select({
|
|
65
|
+
message: "Database",
|
|
66
|
+
options: [
|
|
67
|
+
{
|
|
68
|
+
value: "none",
|
|
69
|
+
label: "None",
|
|
70
|
+
hint: "default"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
value: "drizzle",
|
|
74
|
+
label: "Drizzle"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
value: "prisma",
|
|
78
|
+
label: "Prisma"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
value: "kysely",
|
|
82
|
+
label: "Kysely"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
initialValue: "none"
|
|
86
|
+
});
|
|
87
|
+
if (p.isCancel(dbChoice)) {
|
|
88
|
+
p.cancel("Scaffold cancelled.");
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
let db;
|
|
92
|
+
let driver;
|
|
93
|
+
if (dbChoice !== "none" && isDbOdm(dbChoice)) {
|
|
94
|
+
db = dbChoice;
|
|
95
|
+
const driverChoice = args.driver ?? await p.select({
|
|
96
|
+
message: "Database driver",
|
|
97
|
+
options: [
|
|
98
|
+
{
|
|
99
|
+
value: "sqlite",
|
|
100
|
+
label: "SQLite",
|
|
101
|
+
hint: "default"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
value: "postgres",
|
|
105
|
+
label: "PostgreSQL"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
value: "mysql",
|
|
109
|
+
label: "MySQL"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
initialValue: "sqlite"
|
|
113
|
+
});
|
|
114
|
+
if (p.isCancel(driverChoice) || !isDbDriver(driverChoice)) {
|
|
115
|
+
p.cancel("Scaffold cancelled.");
|
|
116
|
+
process.exit(0);
|
|
117
|
+
}
|
|
118
|
+
driver = driverChoice;
|
|
119
|
+
}
|
|
120
|
+
const loggerChoice = args.logger ?? await p.select({
|
|
121
|
+
message: "Logger",
|
|
122
|
+
options: [
|
|
123
|
+
{
|
|
124
|
+
value: "none",
|
|
125
|
+
label: "None",
|
|
126
|
+
hint: "default"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
value: "pino",
|
|
130
|
+
label: "Pino"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
value: "winston",
|
|
134
|
+
label: "Winston"
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
initialValue: "none"
|
|
138
|
+
});
|
|
139
|
+
if (p.isCancel(loggerChoice)) {
|
|
140
|
+
p.cancel("Scaffold cancelled.");
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
const logger = loggerChoice === "none" ? void 0 : isLoggerId(loggerChoice) ? loggerChoice : void 0;
|
|
144
|
+
return {
|
|
145
|
+
projectName: String(projectName).trim(),
|
|
146
|
+
framework,
|
|
147
|
+
yes: args.yes,
|
|
148
|
+
noInstall: args.noInstall,
|
|
149
|
+
json: args.json,
|
|
150
|
+
...db ? {
|
|
151
|
+
db,
|
|
152
|
+
driver
|
|
153
|
+
} : {},
|
|
154
|
+
...logger ? { logger } : {}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
async function runCreateCommand(args) {
|
|
158
|
+
if (args.json && !args.projectName) {
|
|
159
|
+
printCapabilitiesCatalog(getCapabilitiesCatalog());
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const cwd = process.cwd();
|
|
163
|
+
const resolved = !args.yes ? await promptInteractiveOptions(args) : {
|
|
164
|
+
...args,
|
|
165
|
+
projectName: args.projectName?.trim(),
|
|
166
|
+
framework: args.framework ?? "node"
|
|
167
|
+
};
|
|
168
|
+
if (!resolved.projectName) {
|
|
169
|
+
const message = "Project name is required";
|
|
170
|
+
if (args.json) {
|
|
171
|
+
printJsonError(message);
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
throw new Error(message);
|
|
175
|
+
}
|
|
176
|
+
const nameError = validateProjectName(resolved.projectName, cwd);
|
|
177
|
+
if (nameError) {
|
|
178
|
+
if (args.json) {
|
|
179
|
+
printJsonError(nameError);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
throw new Error(nameError);
|
|
183
|
+
}
|
|
184
|
+
const targetDir = path.resolve(cwd, resolved.projectName);
|
|
185
|
+
const scaffoldCtx = resolveScaffoldDefaults({
|
|
186
|
+
...resolved,
|
|
187
|
+
projectName: resolved.projectName
|
|
188
|
+
});
|
|
189
|
+
scaffoldCtx.targetDir = targetDir;
|
|
190
|
+
if (!args.json) {
|
|
191
|
+
const spinner = p.spinner();
|
|
192
|
+
spinner.start("Scaffolding project");
|
|
193
|
+
try {
|
|
194
|
+
const result = await scaffoldProject({
|
|
195
|
+
...scaffoldCtx,
|
|
196
|
+
targetDir,
|
|
197
|
+
skipInstall: args.noInstall,
|
|
198
|
+
agent: resolveUserAgent()
|
|
199
|
+
});
|
|
200
|
+
spinner.stop("Project created");
|
|
201
|
+
const cdPath = path.relative(cwd, targetDir) || ".";
|
|
202
|
+
p.note([`cd ${cdPath}`, runScript(resolveUserAgent(), "dev")].join("\n"), "Next steps");
|
|
203
|
+
p.outro(color.green("Done."));
|
|
204
|
+
return result;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
spinner.stop("Scaffold failed");
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const result = await scaffoldProject({
|
|
211
|
+
...scaffoldCtx,
|
|
212
|
+
targetDir,
|
|
213
|
+
skipInstall: args.noInstall,
|
|
214
|
+
agent: resolveUserAgent()
|
|
215
|
+
});
|
|
216
|
+
printScaffoldResult(result);
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
function buildParsedArgsFromCli(values, positionals) {
|
|
220
|
+
const args = {
|
|
221
|
+
yes: values.y ?? false,
|
|
222
|
+
noInstall: values.noInstall ?? false,
|
|
223
|
+
json: values.json ?? false
|
|
224
|
+
};
|
|
225
|
+
if (positionals[0]) args.projectName = positionals[0];
|
|
226
|
+
if (values.framework) args.framework = parseFrameworkFlag(values.framework);
|
|
227
|
+
if (values.db) {
|
|
228
|
+
const parsed = parseDbFlag(values.db);
|
|
229
|
+
args.db = parsed.db;
|
|
230
|
+
args.driver = parsed.driver;
|
|
231
|
+
}
|
|
232
|
+
if (values.logger) args.logger = parseLoggerFlag(values.logger);
|
|
233
|
+
return args;
|
|
234
|
+
}
|
|
235
|
+
//#endregion
|
|
236
|
+
export { buildParsedArgsFromCli, runCreateCommand };
|
|
237
|
+
|
|
238
|
+
//# sourceMappingURL=create.js.map
|