@newt-app/templates 0.20.2 → 0.21.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 +3 -0
- package/dist/index.js +356 -56
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
type TemplateData = {
|
|
2
2
|
projectName: string;
|
|
3
3
|
testing: 'jest' | 'vitest';
|
|
4
|
+
database: 'sqlite' | 'postgres';
|
|
4
5
|
};
|
|
5
6
|
type Template = {
|
|
6
7
|
filename: string;
|
|
@@ -36,6 +37,8 @@ declare const templates: {
|
|
|
36
37
|
web: Module;
|
|
37
38
|
api: Module;
|
|
38
39
|
auth: Module;
|
|
40
|
+
dbSqlite: Module;
|
|
41
|
+
dbPostgres: Module;
|
|
39
42
|
ui: Module;
|
|
40
43
|
shadcnUi: Module;
|
|
41
44
|
eslintConfig: Module;
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var package_json_default = {
|
|
|
14
14
|
"test": "turbo run test",
|
|
15
15
|
"format": "prettier --write \\"**/*.{ts,tsx,js,jsx,json,md,yaml,yml}\\"",
|
|
16
16
|
"format:check": "prettier --check \\"**/*.{ts,tsx,js,jsx,json,md,yaml,yml}\\"",
|
|
17
|
+
"db:make": "pnpm --filter @<%= projectName %>/db run make",
|
|
17
18
|
"db:migrate": "turbo run migrate",
|
|
18
19
|
"db:generate": "turbo run generate"
|
|
19
20
|
},
|
|
@@ -127,6 +128,7 @@ var turbo_json_default = {
|
|
|
127
128
|
"persistent": true
|
|
128
129
|
},
|
|
129
130
|
"migrate": {
|
|
131
|
+
"dependsOn": ["^migrate"],
|
|
130
132
|
"cache": false
|
|
131
133
|
},
|
|
132
134
|
"generate": {
|
|
@@ -179,9 +181,9 @@ Open [http://localhost:3000](http://localhost:3000).
|
|
|
179
181
|
// src/root/templates/env-example.ts
|
|
180
182
|
var env_example_default = {
|
|
181
183
|
filename: ".env",
|
|
182
|
-
template:
|
|
183
|
-
|
|
184
|
-
BETTER_AUTH_URL=http://localhost:3000
|
|
184
|
+
template: `<% if (database === 'postgres') { %>DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
|
|
185
|
+
<% } else { %># Local SQLite database, written to dev.db at the repo root
|
|
186
|
+
<% } %>BETTER_AUTH_URL=http://localhost:3000
|
|
185
187
|
BETTER_AUTH_SECRET=your-secret-here`
|
|
186
188
|
};
|
|
187
189
|
|
|
@@ -787,6 +789,7 @@ var package_json_default3 = {
|
|
|
787
789
|
"@nestjs/core": "^11.0.1",
|
|
788
790
|
"@nestjs/platform-express": "^11.0.1",
|
|
789
791
|
"@<%= projectName %>/auth": "workspace:*",
|
|
792
|
+
"@<%= projectName %>/db": "workspace:*",
|
|
790
793
|
"@thallesp/nestjs-better-auth": "^2.5.1",
|
|
791
794
|
"dotenv": "^17.3.1",
|
|
792
795
|
"reflect-metadata": "^0.2.2",
|
|
@@ -1001,15 +1004,12 @@ var package_json_default4 = {
|
|
|
1001
1004
|
"generate": "dotenv -e ../../.env -- auth generate --config src/index.ts"
|
|
1002
1005
|
},
|
|
1003
1006
|
"dependencies": {
|
|
1007
|
+
"@<%= projectName %>/db": "workspace:*",
|
|
1004
1008
|
"auth": "^1.5.5",
|
|
1005
|
-
"better-auth": "^1.2.8"
|
|
1006
|
-
"better-sqlite3": "^12.11.1",
|
|
1007
|
-
"pg": "^8.14.1"
|
|
1009
|
+
"better-auth": "^1.2.8"
|
|
1008
1010
|
},
|
|
1009
1011
|
"devDependencies": {
|
|
1010
1012
|
"@<%= projectName %>/typescript-config": "workspace:*",
|
|
1011
|
-
"@types/better-sqlite3": "^7.6.13",
|
|
1012
|
-
"@types/pg": "^8.11.13",
|
|
1013
1013
|
"dotenv-cli": "^11.0.0",
|
|
1014
1014
|
"typescript": "6.0.2"
|
|
1015
1015
|
}
|
|
@@ -1020,16 +1020,10 @@ var package_json_default4 = {
|
|
|
1020
1020
|
var src_index_default = {
|
|
1021
1021
|
filename: "packages/auth/src/index.ts",
|
|
1022
1022
|
template: `import { betterAuth } from "better-auth";
|
|
1023
|
-
import {
|
|
1024
|
-
import Database from "better-sqlite3";
|
|
1025
|
-
import path from "node:path";
|
|
1026
|
-
|
|
1027
|
-
const database = process.env.DATABASE_URL
|
|
1028
|
-
? new Pool({ connectionString: process.env.DATABASE_URL })
|
|
1029
|
-
: new Database(path.resolve(process.cwd(), "../../dev.db"));
|
|
1023
|
+
import { driver } from "@<%= projectName %>/db";
|
|
1030
1024
|
|
|
1031
1025
|
export const auth = betterAuth({
|
|
1032
|
-
database,
|
|
1026
|
+
database: driver,
|
|
1033
1027
|
emailAndPassword: { enabled: true },
|
|
1034
1028
|
trustedOrigins: [process.env.BETTER_AUTH_URL ?? "http://localhost:3000"],
|
|
1035
1029
|
});
|
|
@@ -1042,14 +1036,11 @@ var tsconfig_default3 = {
|
|
|
1042
1036
|
filename: "packages/auth/tsconfig.json",
|
|
1043
1037
|
template: `{
|
|
1044
1038
|
"compilerOptions": {
|
|
1045
|
-
"declaration": true,
|
|
1046
|
-
"declarationMap": true,
|
|
1047
1039
|
"esModuleInterop": true,
|
|
1048
1040
|
"lib": ["es2022"],
|
|
1049
1041
|
"module": "NodeNext",
|
|
1050
1042
|
"moduleResolution": "NodeNext",
|
|
1051
|
-
"
|
|
1052
|
-
"rootDir": "src",
|
|
1043
|
+
"noEmit": true,
|
|
1053
1044
|
"skipLibCheck": true,
|
|
1054
1045
|
"strict": true,
|
|
1055
1046
|
"target": "ES2022"
|
|
@@ -1065,6 +1056,236 @@ var auth = {
|
|
|
1065
1056
|
};
|
|
1066
1057
|
var auth_default = auth;
|
|
1067
1058
|
|
|
1059
|
+
// src/db/templates/tsconfig.ts
|
|
1060
|
+
var tsconfig_default4 = {
|
|
1061
|
+
filename: "packages/db/tsconfig.json",
|
|
1062
|
+
template: `{
|
|
1063
|
+
"compilerOptions": {
|
|
1064
|
+
"esModuleInterop": true,
|
|
1065
|
+
"lib": ["es2022"],
|
|
1066
|
+
"module": "NodeNext",
|
|
1067
|
+
"moduleResolution": "NodeNext",
|
|
1068
|
+
"noEmit": true,
|
|
1069
|
+
"skipLibCheck": true,
|
|
1070
|
+
"strict": true,
|
|
1071
|
+
"target": "ES2022"
|
|
1072
|
+
},
|
|
1073
|
+
"include": ["src", "scripts"],
|
|
1074
|
+
"exclude": ["node_modules", "dist"]
|
|
1075
|
+
}`
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
// src/db/templates/src-schema.ts
|
|
1079
|
+
var src_schema_default = {
|
|
1080
|
+
filename: "packages/db/src/schema.ts",
|
|
1081
|
+
template: `// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
1082
|
+
export interface DB {}`
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
// src/db/templates/src-migrate.ts
|
|
1086
|
+
var src_migrate_default = {
|
|
1087
|
+
filename: "packages/db/src/migrate.ts",
|
|
1088
|
+
template: `import { promises as fs } from "node:fs";
|
|
1089
|
+
import path from "node:path";
|
|
1090
|
+
import { FileMigrationProvider, Migrator } from "kysely";
|
|
1091
|
+
import { db } from "./index.js";
|
|
1092
|
+
|
|
1093
|
+
async function main() {
|
|
1094
|
+
const migrator = new Migrator({
|
|
1095
|
+
db,
|
|
1096
|
+
provider: new FileMigrationProvider({
|
|
1097
|
+
fs,
|
|
1098
|
+
path,
|
|
1099
|
+
migrationFolder: path.join(process.cwd(), "src/migrations"),
|
|
1100
|
+
}),
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
const { error, results } = await migrator.migrateToLatest();
|
|
1104
|
+
|
|
1105
|
+
for (const it of results ?? []) {
|
|
1106
|
+
if (it.status === "Success") {
|
|
1107
|
+
console.log("applied " + it.migrationName);
|
|
1108
|
+
} else if (it.status === "Error") {
|
|
1109
|
+
console.error("failed " + it.migrationName);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
if (error) {
|
|
1114
|
+
console.error("migration failed");
|
|
1115
|
+
console.error(error);
|
|
1116
|
+
process.exit(1);
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
await db.destroy();
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
main();`
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
// src/db/templates/scripts-new-migration.ts
|
|
1126
|
+
var scripts_new_migration_default = {
|
|
1127
|
+
filename: "packages/db/scripts/new-migration.ts",
|
|
1128
|
+
template: `import { promises as fs } from "node:fs";
|
|
1129
|
+
import path from "node:path";
|
|
1130
|
+
|
|
1131
|
+
async function main() {
|
|
1132
|
+
const name = process.argv[2];
|
|
1133
|
+
if (!name) {
|
|
1134
|
+
console.error("Usage: pnpm db:make <name>");
|
|
1135
|
+
process.exit(1);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
const timestamp = new Date()
|
|
1139
|
+
.toISOString()
|
|
1140
|
+
.replace(/[-:T]/g, "")
|
|
1141
|
+
.slice(0, 14);
|
|
1142
|
+
const slug = name.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1143
|
+
const filename = timestamp + "_" + slug + ".ts";
|
|
1144
|
+
const dir = path.join(process.cwd(), "src/migrations");
|
|
1145
|
+
const stub = [
|
|
1146
|
+
'import { Kysely, sql } from "kysely";',
|
|
1147
|
+
"",
|
|
1148
|
+
"export async function up(db: Kysely<any>): Promise<void> {",
|
|
1149
|
+
" // await db.schema.createTable(...).execute();",
|
|
1150
|
+
"}",
|
|
1151
|
+
"",
|
|
1152
|
+
"export async function down(db: Kysely<any>): Promise<void> {",
|
|
1153
|
+
" // await db.schema.dropTable(...).execute();",
|
|
1154
|
+
"}",
|
|
1155
|
+
"",
|
|
1156
|
+
].join("\\n");
|
|
1157
|
+
|
|
1158
|
+
await fs.mkdir(dir, { recursive: true });
|
|
1159
|
+
await fs.writeFile(path.join(dir, filename), stub);
|
|
1160
|
+
console.log("created src/migrations/" + filename);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
main();`
|
|
1164
|
+
};
|
|
1165
|
+
|
|
1166
|
+
// src/db/templates/migrations-readme.ts
|
|
1167
|
+
var migrations_readme_default = {
|
|
1168
|
+
filename: "packages/db/src/migrations/README.md",
|
|
1169
|
+
template: `# Migrations
|
|
1170
|
+
|
|
1171
|
+
Kysely migrations run in filename order. Each file exports \`up\` and \`down\`.
|
|
1172
|
+
|
|
1173
|
+
\`\`\`bash
|
|
1174
|
+
pnpm db:make add_widgets # scaffold a new migration
|
|
1175
|
+
pnpm db:migrate # apply pending migrations
|
|
1176
|
+
\`\`\`
|
|
1177
|
+
|
|
1178
|
+
Migrations are written with Kysely's schema builder, so one file compiles to
|
|
1179
|
+
both SQLite (dev) and Postgres (prod). Prefer dialect-agnostic column types
|
|
1180
|
+
(\`text\`, \`integer\`) and app-generated string ids over auto-increment.`
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1183
|
+
// src/db/templates/package-json-sqlite.ts
|
|
1184
|
+
var package_json_sqlite_default = {
|
|
1185
|
+
filename: "packages/db/package.json",
|
|
1186
|
+
template: `{
|
|
1187
|
+
"name": "@<%= projectName %>/db",
|
|
1188
|
+
"version": "0.0.0",
|
|
1189
|
+
"private": true,
|
|
1190
|
+
"exports": {
|
|
1191
|
+
".": "./src/index.ts"
|
|
1192
|
+
},
|
|
1193
|
+
"scripts": {
|
|
1194
|
+
"migrate": "dotenv -e ../../.env -- tsx src/migrate.ts",
|
|
1195
|
+
"make": "tsx scripts/new-migration.ts"
|
|
1196
|
+
},
|
|
1197
|
+
"dependencies": {
|
|
1198
|
+
"better-sqlite3": "^12.11.1",
|
|
1199
|
+
"kysely": "^0.28.2"
|
|
1200
|
+
},
|
|
1201
|
+
"devDependencies": {
|
|
1202
|
+
"@<%= projectName %>/typescript-config": "workspace:*",
|
|
1203
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
1204
|
+
"dotenv-cli": "^11.0.0",
|
|
1205
|
+
"tsx": "^4.19.2",
|
|
1206
|
+
"typescript": "6.0.2"
|
|
1207
|
+
}
|
|
1208
|
+
}`
|
|
1209
|
+
};
|
|
1210
|
+
|
|
1211
|
+
// src/db/templates/package-json-postgres.ts
|
|
1212
|
+
var package_json_postgres_default = {
|
|
1213
|
+
filename: "packages/db/package.json",
|
|
1214
|
+
template: `{
|
|
1215
|
+
"name": "@<%= projectName %>/db",
|
|
1216
|
+
"version": "0.0.0",
|
|
1217
|
+
"private": true,
|
|
1218
|
+
"exports": {
|
|
1219
|
+
".": "./src/index.ts"
|
|
1220
|
+
},
|
|
1221
|
+
"scripts": {
|
|
1222
|
+
"migrate": "dotenv -e ../../.env -- tsx src/migrate.ts",
|
|
1223
|
+
"make": "tsx scripts/new-migration.ts"
|
|
1224
|
+
},
|
|
1225
|
+
"dependencies": {
|
|
1226
|
+
"kysely": "^0.28.2",
|
|
1227
|
+
"pg": "^8.14.1"
|
|
1228
|
+
},
|
|
1229
|
+
"devDependencies": {
|
|
1230
|
+
"@<%= projectName %>/typescript-config": "workspace:*",
|
|
1231
|
+
"@types/pg": "^8.11.13",
|
|
1232
|
+
"dotenv-cli": "^11.0.0",
|
|
1233
|
+
"tsx": "^4.19.2",
|
|
1234
|
+
"typescript": "6.0.2"
|
|
1235
|
+
}
|
|
1236
|
+
}`
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
// src/db/templates/src-index-sqlite.ts
|
|
1240
|
+
var src_index_sqlite_default = {
|
|
1241
|
+
filename: "packages/db/src/index.ts",
|
|
1242
|
+
template: `import BetterSqlite3 from "better-sqlite3";
|
|
1243
|
+
import { Kysely, SqliteDialect } from "kysely";
|
|
1244
|
+
import path from "node:path";
|
|
1245
|
+
import type { DB } from "./schema.js";
|
|
1246
|
+
|
|
1247
|
+
export const driver = new BetterSqlite3(
|
|
1248
|
+
path.resolve(process.cwd(), "../../dev.db"),
|
|
1249
|
+
);
|
|
1250
|
+
|
|
1251
|
+
export const db = new Kysely<DB>({
|
|
1252
|
+
dialect: new SqliteDialect({ database: driver }),
|
|
1253
|
+
});
|
|
1254
|
+
|
|
1255
|
+
export type Database = Kysely<DB>;`
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
// src/db/templates/src-index-postgres.ts
|
|
1259
|
+
var src_index_postgres_default = {
|
|
1260
|
+
filename: "packages/db/src/index.ts",
|
|
1261
|
+
template: `import { Kysely, PostgresDialect } from "kysely";
|
|
1262
|
+
import { Pool } from "pg";
|
|
1263
|
+
import type { DB } from "./schema.js";
|
|
1264
|
+
|
|
1265
|
+
export const driver = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
1266
|
+
|
|
1267
|
+
export const db = new Kysely<DB>({
|
|
1268
|
+
dialect: new PostgresDialect({ pool: driver }),
|
|
1269
|
+
});
|
|
1270
|
+
|
|
1271
|
+
export type Database = Kysely<DB>;`
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
// src/db/index.ts
|
|
1275
|
+
var shared = [
|
|
1276
|
+
tsconfig_default4,
|
|
1277
|
+
src_schema_default,
|
|
1278
|
+
src_migrate_default,
|
|
1279
|
+
scripts_new_migration_default,
|
|
1280
|
+
migrations_readme_default
|
|
1281
|
+
];
|
|
1282
|
+
var dbSqlite = {
|
|
1283
|
+
templates: [...shared, package_json_sqlite_default, src_index_sqlite_default]
|
|
1284
|
+
};
|
|
1285
|
+
var dbPostgres = {
|
|
1286
|
+
templates: [...shared, package_json_postgres_default, src_index_postgres_default]
|
|
1287
|
+
};
|
|
1288
|
+
|
|
1068
1289
|
// src/ui/templates/package-json.ts
|
|
1069
1290
|
var package_json_default5 = {
|
|
1070
1291
|
filename: "packages/ui/package.json",
|
|
@@ -1313,7 +1534,7 @@ export default config;`
|
|
|
1313
1534
|
};
|
|
1314
1535
|
|
|
1315
1536
|
// src/ui/templates/tsconfig.ts
|
|
1316
|
-
var
|
|
1537
|
+
var tsconfig_default5 = {
|
|
1317
1538
|
filename: "packages/ui/tsconfig.json",
|
|
1318
1539
|
template: `{
|
|
1319
1540
|
"extends": "@<%= projectName %>/typescript-config/react-library.json",
|
|
@@ -1337,7 +1558,7 @@ export default config;`
|
|
|
1337
1558
|
|
|
1338
1559
|
// src/ui/index.ts
|
|
1339
1560
|
var ui = {
|
|
1340
|
-
templates: [package_json_default5, button_default, card_default, code_default, link_default, logo_default, utils_default, globals_css_default, postcss_config_default2,
|
|
1561
|
+
templates: [package_json_default5, button_default, card_default, code_default, link_default, logo_default, utils_default, globals_css_default, postcss_config_default2, tsconfig_default5, eslint_config_default3]
|
|
1341
1562
|
};
|
|
1342
1563
|
var ui_default = ui;
|
|
1343
1564
|
|
|
@@ -1627,7 +1848,7 @@ export default config;`
|
|
|
1627
1848
|
};
|
|
1628
1849
|
|
|
1629
1850
|
// src/shadcn-ui/templates/tsconfig.ts
|
|
1630
|
-
var
|
|
1851
|
+
var tsconfig_default6 = {
|
|
1631
1852
|
filename: "packages/ui/tsconfig.json",
|
|
1632
1853
|
template: `{
|
|
1633
1854
|
"extends": "@<%= projectName %>/typescript-config/react-library.json",
|
|
@@ -9003,7 +9224,7 @@ var shadcnUi = {
|
|
|
9003
9224
|
use_mobile_default,
|
|
9004
9225
|
globals_css_default2,
|
|
9005
9226
|
postcss_config_default3,
|
|
9006
|
-
|
|
9227
|
+
tsconfig_default6,
|
|
9007
9228
|
eslint_config_default4,
|
|
9008
9229
|
link_default2,
|
|
9009
9230
|
logo_default2,
|
|
@@ -10034,6 +10255,7 @@ var api_package_json_default3 = {
|
|
|
10034
10255
|
"@nestjs/common": "^11.0.1",
|
|
10035
10256
|
"@nestjs/core": "^11.0.1",
|
|
10036
10257
|
"@<%= projectName %>/auth": "workspace:*",
|
|
10258
|
+
"@<%= projectName %>/db": "workspace:*",
|
|
10037
10259
|
"@thallesp/nestjs-better-auth": "^2.5.1",
|
|
10038
10260
|
"dotenv": "^17.3.1",
|
|
10039
10261
|
"reflect-metadata": "^0.2.2",
|
|
@@ -10140,6 +10362,7 @@ var web_package_json_default2 = {
|
|
|
10140
10362
|
"dependencies": {
|
|
10141
10363
|
"@<%= projectName %>/api": "workspace:*",
|
|
10142
10364
|
"@<%= projectName %>/auth": "workspace:*",
|
|
10365
|
+
"@<%= projectName %>/db": "workspace:*",
|
|
10143
10366
|
"@<%= projectName %>/ui": "workspace:*",
|
|
10144
10367
|
"@nestjs/common": "^11.0.1",
|
|
10145
10368
|
"@nestjs/core": "^11.0.1",
|
|
@@ -10179,6 +10402,7 @@ dotenv.config({ path: resolve(process.cwd(), '.env') });
|
|
|
10179
10402
|
const nextConfig = {
|
|
10180
10403
|
serverExternalPackages: [
|
|
10181
10404
|
'@<%= projectName %>/api',
|
|
10405
|
+
'@<%= projectName %>/db',
|
|
10182
10406
|
'@nestjs/core',
|
|
10183
10407
|
'@nestjs/common',
|
|
10184
10408
|
'@nestjs/microservices',
|
|
@@ -10372,39 +10596,68 @@ export class TodosModule {}`
|
|
|
10372
10596
|
var todos_service_default = {
|
|
10373
10597
|
filename: "apps/api/src/todos/todos.service.ts",
|
|
10374
10598
|
template: `import { Injectable, NotFoundException } from '@nestjs/common';
|
|
10599
|
+
import { randomUUID } from 'node:crypto';
|
|
10600
|
+
import { db } from '@<%= projectName %>/db';
|
|
10375
10601
|
|
|
10376
10602
|
export interface Todo {
|
|
10377
|
-
id:
|
|
10603
|
+
id: string;
|
|
10378
10604
|
title: string;
|
|
10379
10605
|
done: boolean;
|
|
10606
|
+
createdAt: string;
|
|
10380
10607
|
}
|
|
10381
10608
|
|
|
10609
|
+
const columns = ['id', 'title', 'done', 'createdAt'] as const;
|
|
10610
|
+
|
|
10382
10611
|
@Injectable()
|
|
10383
10612
|
export class TodosService {
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10613
|
+
async findAll(): Promise<Todo[]> {
|
|
10614
|
+
const rows = await db
|
|
10615
|
+
.selectFrom('todo')
|
|
10616
|
+
.select(columns)
|
|
10617
|
+
.orderBy('createdAt desc')
|
|
10618
|
+
.execute();
|
|
10619
|
+
return rows.map((row) => ({ ...row, done: Boolean(row.done) }));
|
|
10389
10620
|
}
|
|
10390
10621
|
|
|
10391
|
-
create(title: string): Todo {
|
|
10392
|
-
const
|
|
10393
|
-
|
|
10394
|
-
|
|
10622
|
+
async create(title: string): Promise<Todo> {
|
|
10623
|
+
const id = randomUUID();
|
|
10624
|
+
await db.insertInto('todo').values({ id, title }).execute();
|
|
10625
|
+
const row = await db
|
|
10626
|
+
.selectFrom('todo')
|
|
10627
|
+
.select(columns)
|
|
10628
|
+
.where('id', '=', id)
|
|
10629
|
+
.executeTakeFirstOrThrow();
|
|
10630
|
+
return { ...row, done: Boolean(row.done) };
|
|
10395
10631
|
}
|
|
10396
10632
|
|
|
10397
|
-
toggle(id:
|
|
10398
|
-
const
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10633
|
+
async toggle(id: string): Promise<Todo> {
|
|
10634
|
+
const current = await db
|
|
10635
|
+
.selectFrom('todo')
|
|
10636
|
+
.select('done')
|
|
10637
|
+
.where('id', '=', id)
|
|
10638
|
+
.executeTakeFirst();
|
|
10639
|
+
if (!current) throw new NotFoundException('Todo ' + id + ' not found');
|
|
10640
|
+
await db
|
|
10641
|
+
.updateTable('todo')
|
|
10642
|
+
.set({ done: current.done ? 0 : 1 })
|
|
10643
|
+
.where('id', '=', id)
|
|
10644
|
+
.execute();
|
|
10645
|
+
const row = await db
|
|
10646
|
+
.selectFrom('todo')
|
|
10647
|
+
.select(columns)
|
|
10648
|
+
.where('id', '=', id)
|
|
10649
|
+
.executeTakeFirstOrThrow();
|
|
10650
|
+
return { ...row, done: Boolean(row.done) };
|
|
10402
10651
|
}
|
|
10403
10652
|
|
|
10404
|
-
remove(id:
|
|
10405
|
-
const
|
|
10406
|
-
|
|
10407
|
-
|
|
10653
|
+
async remove(id: string): Promise<void> {
|
|
10654
|
+
const result = await db
|
|
10655
|
+
.deleteFrom('todo')
|
|
10656
|
+
.where('id', '=', id)
|
|
10657
|
+
.executeTakeFirst();
|
|
10658
|
+
if (!result.numDeletedRows) {
|
|
10659
|
+
throw new NotFoundException('Todo ' + id + ' not found');
|
|
10660
|
+
}
|
|
10408
10661
|
}
|
|
10409
10662
|
}`
|
|
10410
10663
|
};
|
|
@@ -10432,6 +10685,45 @@ describe('TodosService', () => {
|
|
|
10432
10685
|
});`
|
|
10433
10686
|
};
|
|
10434
10687
|
|
|
10688
|
+
// src/todo-example/templates/db-schema.ts
|
|
10689
|
+
var db_schema_default = {
|
|
10690
|
+
filename: "packages/db/src/schema.ts",
|
|
10691
|
+
template: `import type { Generated } from "kysely";
|
|
10692
|
+
|
|
10693
|
+
export interface TodoTable {
|
|
10694
|
+
id: string;
|
|
10695
|
+
title: string;
|
|
10696
|
+
done: Generated<number>;
|
|
10697
|
+
createdAt: Generated<string>;
|
|
10698
|
+
}
|
|
10699
|
+
|
|
10700
|
+
export interface DB {
|
|
10701
|
+
todo: TodoTable;
|
|
10702
|
+
}`
|
|
10703
|
+
};
|
|
10704
|
+
|
|
10705
|
+
// src/todo-example/templates/db-migration-todos.ts
|
|
10706
|
+
var db_migration_todos_default = {
|
|
10707
|
+
filename: "packages/db/src/migrations/0001_create_todos.ts",
|
|
10708
|
+
template: `import { Kysely, sql } from "kysely";
|
|
10709
|
+
|
|
10710
|
+
export async function up(db: Kysely<any>): Promise<void> {
|
|
10711
|
+
await db.schema
|
|
10712
|
+
.createTable("todo")
|
|
10713
|
+
.addColumn("id", "text", (c) => c.primaryKey())
|
|
10714
|
+
.addColumn("title", "text", (c) => c.notNull())
|
|
10715
|
+
.addColumn("done", "integer", (c) => c.notNull().defaultTo(0))
|
|
10716
|
+
.addColumn("createdAt", "text", (c) =>
|
|
10717
|
+
c.notNull().defaultTo(sql\`CURRENT_TIMESTAMP\`),
|
|
10718
|
+
)
|
|
10719
|
+
.execute();
|
|
10720
|
+
}
|
|
10721
|
+
|
|
10722
|
+
export async function down(db: Kysely<any>): Promise<void> {
|
|
10723
|
+
await db.schema.dropTable("todo").execute();
|
|
10724
|
+
}`
|
|
10725
|
+
};
|
|
10726
|
+
|
|
10435
10727
|
// src/todo-example/templates/todos-controller.ts
|
|
10436
10728
|
var todos_controller_default = {
|
|
10437
10729
|
filename: "apps/api/src/todos/todos.controller.ts",
|
|
@@ -10462,12 +10754,12 @@ export class TodosController {
|
|
|
10462
10754
|
|
|
10463
10755
|
@Patch(':id/toggle')
|
|
10464
10756
|
toggle(@Param('id') id: string) {
|
|
10465
|
-
return this.todosService.toggle(
|
|
10757
|
+
return this.todosService.toggle(id);
|
|
10466
10758
|
}
|
|
10467
10759
|
|
|
10468
10760
|
@Delete(':id')
|
|
10469
10761
|
remove(@Param('id') id: string) {
|
|
10470
|
-
return this.todosService.remove(
|
|
10762
|
+
return this.todosService.remove(id);
|
|
10471
10763
|
}
|
|
10472
10764
|
}`
|
|
10473
10765
|
};
|
|
@@ -10537,13 +10829,13 @@ import { TodosService } from '@<%= projectName %>/api';
|
|
|
10537
10829
|
|
|
10538
10830
|
export async function GET() {
|
|
10539
10831
|
const todos = await inject(TodosService);
|
|
10540
|
-
return NextResponse.json(todos.findAll());
|
|
10832
|
+
return NextResponse.json(await todos.findAll());
|
|
10541
10833
|
}
|
|
10542
10834
|
|
|
10543
10835
|
export async function POST(req: Request) {
|
|
10544
10836
|
const { title } = await req.json();
|
|
10545
10837
|
const todos = await inject(TodosService);
|
|
10546
|
-
return NextResponse.json(todos.create(title), { status: 201 });
|
|
10838
|
+
return NextResponse.json(await todos.create(title), { status: 201 });
|
|
10547
10839
|
}`
|
|
10548
10840
|
};
|
|
10549
10841
|
|
|
@@ -10557,7 +10849,7 @@ import { TodosService } from '@<%= projectName %>/api';
|
|
|
10557
10849
|
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
10558
10850
|
const { id } = await params;
|
|
10559
10851
|
const todos = await inject(TodosService);
|
|
10560
|
-
todos.remove(
|
|
10852
|
+
await todos.remove(id);
|
|
10561
10853
|
return new NextResponse(null, { status: 204 });
|
|
10562
10854
|
}`
|
|
10563
10855
|
};
|
|
@@ -10572,7 +10864,7 @@ import { TodosService } from '@<%= projectName %>/api';
|
|
|
10572
10864
|
export async function PATCH(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
|
10573
10865
|
const { id } = await params;
|
|
10574
10866
|
const todos = await inject(TodosService);
|
|
10575
|
-
return NextResponse.json(todos.toggle(
|
|
10867
|
+
return NextResponse.json(await todos.toggle(id));
|
|
10576
10868
|
}`
|
|
10577
10869
|
};
|
|
10578
10870
|
|
|
@@ -10587,7 +10879,7 @@ import { authClient } from '@/lib/auth-client';
|
|
|
10587
10879
|
import { Button } from '@<%= projectName %>/ui/button';
|
|
10588
10880
|
|
|
10589
10881
|
interface Todo {
|
|
10590
|
-
id:
|
|
10882
|
+
id: string;
|
|
10591
10883
|
title: string;
|
|
10592
10884
|
done: boolean;
|
|
10593
10885
|
}
|
|
@@ -10600,9 +10892,9 @@ const api = {
|
|
|
10600
10892
|
headers: { 'Content-Type': 'application/json' },
|
|
10601
10893
|
body: JSON.stringify({ title }),
|
|
10602
10894
|
}).then((r) => r.json()),
|
|
10603
|
-
toggleTodo: (id:
|
|
10895
|
+
toggleTodo: (id: string): Promise<Todo> =>
|
|
10604
10896
|
fetch(\`/api/todos/\${id}/toggle\`, { method: 'PATCH' }).then((r) => r.json()),
|
|
10605
|
-
deleteTodo: (id:
|
|
10897
|
+
deleteTodo: (id: string): Promise<void> =>
|
|
10606
10898
|
fetch(\`/api/todos/\${id}\`, { method: 'DELETE' }).then(() => undefined),
|
|
10607
10899
|
};
|
|
10608
10900
|
|
|
@@ -10813,7 +11105,7 @@ import { Input } from '@<%= projectName %>/ui/input';
|
|
|
10813
11105
|
import { Checkbox } from '@<%= projectName %>/ui/checkbox';
|
|
10814
11106
|
|
|
10815
11107
|
interface Todo {
|
|
10816
|
-
id:
|
|
11108
|
+
id: string;
|
|
10817
11109
|
title: string;
|
|
10818
11110
|
done: boolean;
|
|
10819
11111
|
}
|
|
@@ -10826,9 +11118,9 @@ const api = {
|
|
|
10826
11118
|
headers: { 'Content-Type': 'application/json' },
|
|
10827
11119
|
body: JSON.stringify({ title }),
|
|
10828
11120
|
}).then((r) => r.json()),
|
|
10829
|
-
toggleTodo: (id:
|
|
11121
|
+
toggleTodo: (id: string): Promise<Todo> =>
|
|
10830
11122
|
fetch(\`/api/todos/\${id}/toggle\`, { method: 'PATCH' }).then((r) => r.json()),
|
|
10831
|
-
deleteTodo: (id:
|
|
11123
|
+
deleteTodo: (id: string): Promise<void> =>
|
|
10832
11124
|
fetch(\`/api/todos/\${id}\`, { method: 'DELETE' }).then(() => undefined),
|
|
10833
11125
|
};
|
|
10834
11126
|
|
|
@@ -11053,7 +11345,13 @@ export default function Home() {
|
|
|
11053
11345
|
|
|
11054
11346
|
// src/todo-example/index.ts
|
|
11055
11347
|
var todoExampleApi = {
|
|
11056
|
-
templates: [
|
|
11348
|
+
templates: [
|
|
11349
|
+
todos_module_default,
|
|
11350
|
+
todos_service_default,
|
|
11351
|
+
todos_service_spec_default,
|
|
11352
|
+
db_schema_default,
|
|
11353
|
+
db_migration_todos_default
|
|
11354
|
+
]
|
|
11057
11355
|
};
|
|
11058
11356
|
var todoExampleControllers = {
|
|
11059
11357
|
templates: [todos_controller_default, todos_module_controllers_default, app_module_controllers_default]
|
|
@@ -11079,6 +11377,8 @@ var templates = {
|
|
|
11079
11377
|
web: web_default,
|
|
11080
11378
|
api: api_default,
|
|
11081
11379
|
auth: auth_default,
|
|
11380
|
+
dbSqlite,
|
|
11381
|
+
dbPostgres,
|
|
11082
11382
|
ui: ui_default,
|
|
11083
11383
|
shadcnUi: shadcn_ui_default,
|
|
11084
11384
|
eslintConfig: eslint_config_default5,
|