@danceroutine/tango-codegen 1.10.0 → 1.10.1
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/commands/index.js +1 -1
- package/dist/commands-CFAq4wXC.js +1 -1
- package/dist/frameworks/contracts/template/TemplateBuilder.d.ts +3 -1
- package/dist/frameworks/index.js +1 -1
- package/dist/{frameworks-DfgUTyLt.js → frameworks-BQp-rqXU.js} +135 -60
- package/dist/frameworks-BQp-rqXU.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/frameworks-DfgUTyLt.js.map +0 -1
package/dist/commands/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../relations-DqDEZ6MV.js";
|
|
2
|
-
import "../frameworks-
|
|
2
|
+
import "../frameworks-BQp-rqXU.js";
|
|
3
3
|
import { loadProjectModule, registerCodegenCommands, runGenerateRelationsCommand, withGenerateRelationsCommand } from "../commands-CFAq4wXC.js";
|
|
4
4
|
|
|
5
5
|
export { loadProjectModule, registerCodegenCommands, runGenerateRelationsCommand, withGenerateRelationsCommand };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __export } from "./chunk-BkvOhyD0.js";
|
|
2
2
|
import { writeRelationRegistryArtifacts } from "./relations-DqDEZ6MV.js";
|
|
3
|
-
import { FrameworkScaffoldRegistry, PACKAGE_MANAGER, SCAFFOLD_DATABASE_DIALECT, SUPPORTED_FRAMEWORK, scaffoldProject } from "./frameworks-
|
|
3
|
+
import { FrameworkScaffoldRegistry, PACKAGE_MANAGER, SCAFFOLD_DATABASE_DIALECT, SUPPORTED_FRAMEWORK, scaffoldProject } from "./frameworks-BQp-rqXU.js";
|
|
4
4
|
import { GENERATED_RELATION_REGISTRY_DIRNAME, GENERATED_RELATION_REGISTRY_METADATA_FILENAME, GENERATED_RELATION_REGISTRY_TYPES_FILENAME, ModelRegistry } from "@danceroutine/tango-schema";
|
|
5
5
|
import { extname, relative, resolve as resolve$1, resolve as resolve$2 } from "node:path";
|
|
6
6
|
import { getLogger, getLogger as getLogger$1, getLogger as getLogger$2 } from "@danceroutine/tango-core";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PackageManager } from '../FrameworkScaffoldStrategy';
|
|
1
2
|
import type { FrameworkScaffoldContext } from './ScaffoldTemplate';
|
|
2
3
|
/**
|
|
3
4
|
* Interface for a context-bound template that the strategy's add* methods accept.
|
|
@@ -21,7 +22,8 @@ export declare abstract class TemplateBuilder implements BoundTemplate {
|
|
|
21
22
|
/**
|
|
22
23
|
* One-liner to install Tango + dialect deps and Tango CLI (for init success message).
|
|
23
24
|
*/
|
|
24
|
-
static getTangoInstallOneLiner(packageManager:
|
|
25
|
+
static getTangoInstallOneLiner(packageManager: PackageManager, dialect: 'sqlite' | 'postgres', framework: 'express' | 'next' | 'nuxt'): string;
|
|
26
|
+
static getRunScriptCommand(packageManager: PackageManager, scriptName: string, scriptArgs?: readonly string[]): string;
|
|
25
27
|
/**
|
|
26
28
|
* Shorthand for static content (no subclass needed). Returns a BoundTemplate that add* methods accept.
|
|
27
29
|
*/
|
package/dist/frameworks/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, FrameworkScaffoldStrategy, NextScaffoldStrategy, NuxtScaffoldStrategy, SCAFFOLD_TEMPLATE_CATEGORY, ScaffoldTemplateDescriptor, scaffoldProject } from "../frameworks-
|
|
1
|
+
import { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, FrameworkScaffoldStrategy, NextScaffoldStrategy, NuxtScaffoldStrategy, SCAFFOLD_TEMPLATE_CATEGORY, ScaffoldTemplateDescriptor, scaffoldProject } from "../frameworks-BQp-rqXU.js";
|
|
2
2
|
|
|
3
3
|
export { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, FrameworkScaffoldStrategy, NextScaffoldStrategy, NuxtScaffoldStrategy, SCAFFOLD_TEMPLATE_CATEGORY, ScaffoldTemplateDescriptor, scaffoldProject };
|
|
@@ -31,7 +31,7 @@ var ScaffoldTemplateDescriptor = class {
|
|
|
31
31
|
//#endregion
|
|
32
32
|
//#region package.json
|
|
33
33
|
var name = "@danceroutine/tango-codegen";
|
|
34
|
-
var version$1 = "1.10.
|
|
34
|
+
var version$1 = "1.10.1";
|
|
35
35
|
var description = "CLI for generating repositories, types, migrations, and OpenAPI specs for Tango";
|
|
36
36
|
var type = "module";
|
|
37
37
|
var main = "./dist/index.js";
|
|
@@ -135,6 +135,16 @@ var TemplateBuilder = class TemplateBuilder {
|
|
|
135
135
|
const addDevCmd = packageManager === "npm" ? "npm install -D" : `${packageManager} add -D`;
|
|
136
136
|
return `${addCmd} ${depList} && ${addDevCmd} ${devList}`;
|
|
137
137
|
}
|
|
138
|
+
static getRunScriptCommand(packageManager, scriptName, scriptArgs = []) {
|
|
139
|
+
const serializedArgs = scriptArgs.join(" ");
|
|
140
|
+
switch (packageManager) {
|
|
141
|
+
case PACKAGE_MANAGER.NPM: return serializedArgs.length > 0 ? `npm run ${scriptName} -- ${serializedArgs}` : `npm run ${scriptName}`;
|
|
142
|
+
case PACKAGE_MANAGER.YARN: return serializedArgs.length > 0 ? `yarn run ${scriptName} ${serializedArgs}` : `yarn run ${scriptName}`;
|
|
143
|
+
case PACKAGE_MANAGER.BUN: return serializedArgs.length > 0 ? `bun run ${scriptName} ${serializedArgs}` : `bun run ${scriptName}`;
|
|
144
|
+
case PACKAGE_MANAGER.PNPM:
|
|
145
|
+
default: return serializedArgs.length > 0 ? `pnpm run ${scriptName} ${serializedArgs}` : `pnpm run ${scriptName}`;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
138
148
|
/**
|
|
139
149
|
* Shorthand for static content (no subclass needed). Returns a BoundTemplate that add* methods accept.
|
|
140
150
|
*/
|
|
@@ -150,7 +160,7 @@ var TemplateBuilder = class TemplateBuilder {
|
|
|
150
160
|
static getTangoVersion() {
|
|
151
161
|
return `^${version}`;
|
|
152
162
|
}
|
|
153
|
-
static getTangoDependencyEntriesFor(
|
|
163
|
+
static getTangoDependencyEntriesFor(_dialect, framework) {
|
|
154
164
|
const v = TemplateBuilder.getTangoVersion();
|
|
155
165
|
const core = {
|
|
156
166
|
"@danceroutine/tango-core": v,
|
|
@@ -162,7 +172,10 @@ var TemplateBuilder = class TemplateBuilder {
|
|
|
162
172
|
"@danceroutine/tango-config": v
|
|
163
173
|
};
|
|
164
174
|
const adapter = framework === "express" ? { "@danceroutine/tango-adapters-express": v } : framework === "next" ? { "@danceroutine/tango-adapters-next": v } : { "@danceroutine/tango-adapters-nuxt": v };
|
|
165
|
-
const dialectDeps =
|
|
175
|
+
const dialectDeps = {
|
|
176
|
+
"better-sqlite3": "^11.10.0",
|
|
177
|
+
pg: "^8.16.3"
|
|
178
|
+
};
|
|
166
179
|
return {
|
|
167
180
|
...core,
|
|
168
181
|
...adapter,
|
|
@@ -170,7 +183,10 @@ var TemplateBuilder = class TemplateBuilder {
|
|
|
170
183
|
};
|
|
171
184
|
}
|
|
172
185
|
static getTangoDevDependencyEntriesFor() {
|
|
173
|
-
return {
|
|
186
|
+
return {
|
|
187
|
+
"@danceroutine/tango-cli": TemplateBuilder.getTangoVersion(),
|
|
188
|
+
"@types/better-sqlite3": "^7.6.12"
|
|
189
|
+
};
|
|
174
190
|
}
|
|
175
191
|
/** Bind context and return this for chaining. Use before passing to add* methods. */
|
|
176
192
|
setContext(context) {
|
|
@@ -458,9 +474,11 @@ var TodoModelTemplateBuilder$2 = class extends TemplateBuilder {
|
|
|
458
474
|
}
|
|
459
475
|
resolveTemplate(_context) {
|
|
460
476
|
return `import { z } from 'zod';
|
|
461
|
-
import '@danceroutine/tango-orm/runtime';
|
|
477
|
+
import { registerModelObjects } from '@danceroutine/tango-orm/runtime';
|
|
462
478
|
import { Model, t } from '@danceroutine/tango-schema';
|
|
463
479
|
|
|
480
|
+
registerModelObjects();
|
|
481
|
+
|
|
464
482
|
export const TodoReadSchema = z.object({
|
|
465
483
|
id: z.number(),
|
|
466
484
|
title: z.string().min(1),
|
|
@@ -597,7 +615,11 @@ var BootstrapTemplateBuilder$2 = class extends TemplateBuilder {
|
|
|
597
615
|
super({ name: "src/bootstrap.ts" });
|
|
598
616
|
}
|
|
599
617
|
resolveTemplate(_context) {
|
|
600
|
-
return `import {
|
|
618
|
+
return `import { initializeTangoRuntime } from '@danceroutine/tango-orm/runtime';
|
|
619
|
+
import tangoConfig from '../tango.config.js';
|
|
620
|
+
import { TodoModel, type Todo } from './models/index.js';
|
|
621
|
+
|
|
622
|
+
initializeTangoRuntime(() => tangoConfig);
|
|
601
623
|
|
|
602
624
|
export async function seedExampleData(count = 100): Promise<void> {
|
|
603
625
|
const existing = await TodoModel.objects.query().count();
|
|
@@ -640,6 +662,13 @@ var ReadmeTemplateBuilder$2 = class extends TemplateBuilder {
|
|
|
640
662
|
super({ name: "README.md" });
|
|
641
663
|
}
|
|
642
664
|
resolveTemplate(context) {
|
|
665
|
+
const makeMigrations = TemplateBuilder.getRunScriptCommand(context.packageManager, "make:migrations", ["--name", "initial"]);
|
|
666
|
+
const makeNamedMigration = TemplateBuilder.getRunScriptCommand(context.packageManager, "make:migrations", ["--name", "add_field"]);
|
|
667
|
+
const dev = TemplateBuilder.getRunScriptCommand(context.packageManager, "dev");
|
|
668
|
+
const codegenRelations = TemplateBuilder.getRunScriptCommand(context.packageManager, "codegen:relations");
|
|
669
|
+
const setupSchema = TemplateBuilder.getRunScriptCommand(context.packageManager, "setup:schema");
|
|
670
|
+
const bootstrap = TemplateBuilder.getRunScriptCommand(context.packageManager, "bootstrap");
|
|
671
|
+
const typecheck = TemplateBuilder.getRunScriptCommand(context.packageManager, "typecheck");
|
|
643
672
|
return `# ${context.projectName}
|
|
644
673
|
|
|
645
674
|
This project was scaffolded by \`tango new --framework express\`.
|
|
@@ -651,22 +680,20 @@ Express still owns the server and route registration; Tango owns model metadata,
|
|
|
651
680
|
Generate your first migration from the scaffolded models, then start the app:
|
|
652
681
|
|
|
653
682
|
\`\`\`bash
|
|
654
|
-
${
|
|
655
|
-
${
|
|
683
|
+
${makeMigrations}
|
|
684
|
+
${dev}
|
|
656
685
|
\`\`\`
|
|
657
686
|
|
|
658
|
-
\`make:migrations\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \`${
|
|
659
|
-
|
|
660
|
-
When you run the package script, pass Tango flags after \`--\` so the script forwards them to the CLI unchanged.
|
|
687
|
+
\`make:migrations\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \`${codegenRelations}\`.
|
|
661
688
|
|
|
662
689
|
## Scripts
|
|
663
690
|
|
|
664
|
-
- \`${
|
|
665
|
-
- \`${
|
|
666
|
-
- \`${
|
|
667
|
-
- \`${
|
|
668
|
-
- \`${
|
|
669
|
-
- \`${
|
|
691
|
+
- \`${dev}\`
|
|
692
|
+
- \`${makeNamedMigration}\`
|
|
693
|
+
- \`${codegenRelations}\`
|
|
694
|
+
- \`${setupSchema}\`
|
|
695
|
+
- \`${bootstrap}\`
|
|
696
|
+
- \`${typecheck}\`
|
|
670
697
|
|
|
671
698
|
## Useful endpoints
|
|
672
699
|
|
|
@@ -674,17 +701,24 @@ When you run the package script, pass Tango flags after \`--\` so the script for
|
|
|
674
701
|
- \`GET /api/openapi.json\`
|
|
675
702
|
- \`GET|POST|PATCH|DELETE /api/todos...\`
|
|
676
703
|
|
|
677
|
-
##
|
|
704
|
+
## Durable app code
|
|
678
705
|
|
|
679
706
|
- \`tango.config.ts\` Tango configuration
|
|
680
|
-
- \`src/
|
|
707
|
+
- \`src/index.ts\` Express app entrypoint; you own server boot, ports, and middleware here
|
|
708
|
+
- \`src/tango.ts\` Express registration helper for Tango routes and OpenAPI wiring
|
|
681
709
|
- \`src/models/\` schemas and Tango model metadata; importing the model module enables \`Model.objects\`
|
|
682
710
|
- \`src/serializers/\` serializer-backed API contracts for Tango resources
|
|
683
711
|
- \`src/viewsets/\` CRUD resources backed by \`Model.objects\`
|
|
684
712
|
- \`src/openapi.ts\` OpenAPI document generation
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
713
|
+
|
|
714
|
+
## Generated artifacts
|
|
715
|
+
|
|
716
|
+
- \`.tango/\` generated relation typing artifacts; regenerate through \`make:migrations\` or \`codegen:relations\`
|
|
717
|
+
- \`migrations/\` checked-in Tango migrations; review them like source, but let Tango generate the files
|
|
718
|
+
|
|
719
|
+
## Utility surface
|
|
720
|
+
|
|
721
|
+
- \`src/bootstrap.ts\` sample seed utility; keep it if it helps your app, or replace it once your own seed flow exists
|
|
688
722
|
`;
|
|
689
723
|
}
|
|
690
724
|
};
|
|
@@ -815,6 +849,7 @@ var TsConfigTemplateBuilder$1 = class extends TemplateBuilder {
|
|
|
815
849
|
isolatedModules: true,
|
|
816
850
|
jsx: "preserve",
|
|
817
851
|
esModuleInterop: true,
|
|
852
|
+
skipLibCheck: true,
|
|
818
853
|
baseUrl: ".",
|
|
819
854
|
paths: { "@/*": ["src/*"] }
|
|
820
855
|
},
|
|
@@ -921,9 +956,11 @@ var TodoModelTemplateBuilder$1 = class TodoModelTemplateBuilder$1 extends Templa
|
|
|
921
956
|
}
|
|
922
957
|
resolveTemplate(_context) {
|
|
923
958
|
return `import { z } from 'zod';
|
|
924
|
-
import '@danceroutine/tango-orm/runtime';
|
|
959
|
+
import { registerModelObjects } from '@danceroutine/tango-orm/runtime';
|
|
925
960
|
import { Model, t } from '@danceroutine/tango-schema';
|
|
926
961
|
|
|
962
|
+
registerModelObjects();
|
|
963
|
+
|
|
927
964
|
export const TodoReadSchema = z.object({
|
|
928
965
|
id: z.number(),
|
|
929
966
|
title: z.string().min(1),
|
|
@@ -1163,7 +1200,11 @@ var BootstrapTemplateBuilder$1 = class extends TemplateBuilder {
|
|
|
1163
1200
|
super({ name: "scripts/bootstrap.ts" });
|
|
1164
1201
|
}
|
|
1165
1202
|
resolveTemplate(_context) {
|
|
1166
|
-
return `import {
|
|
1203
|
+
return `import { initializeTangoRuntime } from '@danceroutine/tango-orm/runtime';
|
|
1204
|
+
import tangoConfig from '../tango.config.js';
|
|
1205
|
+
import { TodoModel, type Todo } from '../src/lib/models';
|
|
1206
|
+
|
|
1207
|
+
initializeTangoRuntime(() => tangoConfig);
|
|
1167
1208
|
|
|
1168
1209
|
async function seedExampleData(count = 100): Promise<void> {
|
|
1169
1210
|
const existing = await TodoModel.objects.query().count();
|
|
@@ -1204,6 +1245,13 @@ var ReadmeTemplateBuilder$1 = class extends TemplateBuilder {
|
|
|
1204
1245
|
super({ name: "README.md" });
|
|
1205
1246
|
}
|
|
1206
1247
|
resolveTemplate(context) {
|
|
1248
|
+
const makeMigrations = TemplateBuilder.getRunScriptCommand(context.packageManager, "make:migrations", ["--name", "initial"]);
|
|
1249
|
+
const makeNamedMigration = TemplateBuilder.getRunScriptCommand(context.packageManager, "make:migrations", ["--name", "add_field"]);
|
|
1250
|
+
const dev = TemplateBuilder.getRunScriptCommand(context.packageManager, "dev");
|
|
1251
|
+
const codegenRelations = TemplateBuilder.getRunScriptCommand(context.packageManager, "codegen:relations");
|
|
1252
|
+
const setupSchema = TemplateBuilder.getRunScriptCommand(context.packageManager, "setup:schema");
|
|
1253
|
+
const bootstrap = TemplateBuilder.getRunScriptCommand(context.packageManager, "bootstrap");
|
|
1254
|
+
const typecheck = TemplateBuilder.getRunScriptCommand(context.packageManager, "typecheck");
|
|
1207
1255
|
return `# ${context.projectName}
|
|
1208
1256
|
|
|
1209
1257
|
This project was scaffolded by \`tango new --framework next\`.
|
|
@@ -1215,41 +1263,46 @@ Next.js still owns pages and route handlers; Tango owns model metadata, \`Model.
|
|
|
1215
1263
|
Generate your first migration from the scaffolded models, then start the app:
|
|
1216
1264
|
|
|
1217
1265
|
\`\`\`bash
|
|
1218
|
-
${
|
|
1219
|
-
${
|
|
1266
|
+
${makeMigrations}
|
|
1267
|
+
${dev}
|
|
1220
1268
|
\`\`\`
|
|
1221
1269
|
|
|
1222
|
-
\`make:migrations\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \`${
|
|
1223
|
-
|
|
1224
|
-
When you run the package script, pass Tango flags after \`--\` so the script forwards them to the CLI unchanged.
|
|
1270
|
+
\`make:migrations\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \`${codegenRelations}\`.
|
|
1225
1271
|
|
|
1226
1272
|
## Scripts
|
|
1227
1273
|
|
|
1228
|
-
- \`${
|
|
1229
|
-
- \`${
|
|
1230
|
-
- \`${
|
|
1231
|
-
- \`${
|
|
1232
|
-
- \`${
|
|
1233
|
-
- \`${
|
|
1274
|
+
- \`${dev}\`
|
|
1275
|
+
- \`${makeNamedMigration}\`
|
|
1276
|
+
- \`${codegenRelations}\`
|
|
1277
|
+
- \`${setupSchema}\`
|
|
1278
|
+
- \`${bootstrap}\`
|
|
1279
|
+
- \`${typecheck}\`
|
|
1234
1280
|
|
|
1235
1281
|
## Useful endpoints
|
|
1236
1282
|
|
|
1283
|
+
- \`GET /\` browser entry route rendered by \`src/app/page.tsx\`
|
|
1237
1284
|
- \`GET /api/health\`
|
|
1238
1285
|
- \`GET /api/openapi\`
|
|
1239
1286
|
- \`GET|POST|PATCH|DELETE /api/todos...\`
|
|
1240
1287
|
|
|
1241
|
-
##
|
|
1288
|
+
## Durable app code
|
|
1242
1289
|
|
|
1243
1290
|
- \`tango.config.ts\` Tango configuration
|
|
1244
1291
|
- \`src/lib/models/\` schemas and Tango model metadata; importing the model module enables \`Model.objects\`
|
|
1245
1292
|
- \`src/serializers/\` serializer-backed API contracts for Tango resources
|
|
1246
1293
|
- \`src/viewsets/\` CRUD resources backed by \`Model.objects\`
|
|
1247
|
-
- \`src/app/page.tsx\`
|
|
1294
|
+
- \`src/app/page.tsx\` browser entry route at \`/\`; replace the Todo page once your own app shell is ready
|
|
1248
1295
|
- \`src/app/api/todos/[[...tango]]/route.ts\` Next adapter wiring for the viewset
|
|
1249
1296
|
- \`src/lib/openapi.ts\` OpenAPI document generation
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1297
|
+
|
|
1298
|
+
## Generated artifacts
|
|
1299
|
+
|
|
1300
|
+
- \`.tango/\` generated relation typing artifacts; regenerate through \`make:migrations\` or \`codegen:relations\`
|
|
1301
|
+
- \`migrations/\` checked-in Tango migrations; review them like source, but let Tango generate the files
|
|
1302
|
+
|
|
1303
|
+
## Utility surface
|
|
1304
|
+
|
|
1305
|
+
- \`scripts/bootstrap.ts\` sample seed utility; keep it if it helps your app, or replace it once your own seed flow exists
|
|
1253
1306
|
`;
|
|
1254
1307
|
}
|
|
1255
1308
|
};
|
|
@@ -1341,7 +1394,10 @@ var TsConfigTemplateBuilder = class extends TemplateBuilder {
|
|
|
1341
1394
|
resolveTemplate(_context) {
|
|
1342
1395
|
return JSON.stringify({
|
|
1343
1396
|
extends: "./.nuxt/tsconfig.json",
|
|
1344
|
-
compilerOptions: {
|
|
1397
|
+
compilerOptions: {
|
|
1398
|
+
strict: true,
|
|
1399
|
+
skipLibCheck: true
|
|
1400
|
+
},
|
|
1345
1401
|
include: [
|
|
1346
1402
|
".nuxt/**/*.d.ts",
|
|
1347
1403
|
"**/*.ts",
|
|
@@ -1530,7 +1586,7 @@ var PageTemplateBuilder = class extends TemplateBuilder {
|
|
|
1530
1586
|
}
|
|
1531
1587
|
resolveTemplate(_context) {
|
|
1532
1588
|
return `<script setup lang="ts">
|
|
1533
|
-
import { TodoModel, TodoReadSchema } from '
|
|
1589
|
+
import { TodoModel, TodoReadSchema } from '~~/lib/models';
|
|
1534
1590
|
|
|
1535
1591
|
const todos = await TodoModel.objects.query().orderBy('-createdAt').limit(10).fetch(TodoReadSchema);
|
|
1536
1592
|
</script>
|
|
@@ -1611,7 +1667,11 @@ var BootstrapTemplateBuilder = class extends TemplateBuilder {
|
|
|
1611
1667
|
super({ name: "scripts/bootstrap.ts" });
|
|
1612
1668
|
}
|
|
1613
1669
|
resolveTemplate(_context) {
|
|
1614
|
-
return `import {
|
|
1670
|
+
return `import { initializeTangoRuntime } from '@danceroutine/tango-orm/runtime';
|
|
1671
|
+
import tangoConfig from '../tango.config.js';
|
|
1672
|
+
import { TodoModel, type Todo } from '../lib/models';
|
|
1673
|
+
|
|
1674
|
+
initializeTangoRuntime(() => tangoConfig);
|
|
1615
1675
|
|
|
1616
1676
|
async function seedExampleData(count = 100): Promise<void> {
|
|
1617
1677
|
const existing = await TodoModel.objects.query().count();
|
|
@@ -1732,6 +1792,13 @@ var ReadmeTemplateBuilder = class extends TemplateBuilder {
|
|
|
1732
1792
|
super({ name: "README.md" });
|
|
1733
1793
|
}
|
|
1734
1794
|
resolveTemplate(context) {
|
|
1795
|
+
const makeMigrations = TemplateBuilder.getRunScriptCommand(context.packageManager, "make:migrations", ["--name", "initial"]);
|
|
1796
|
+
const makeNamedMigration = TemplateBuilder.getRunScriptCommand(context.packageManager, "make:migrations", ["--name", "add_field"]);
|
|
1797
|
+
const dev = TemplateBuilder.getRunScriptCommand(context.packageManager, "dev");
|
|
1798
|
+
const codegenRelations = TemplateBuilder.getRunScriptCommand(context.packageManager, "codegen:relations");
|
|
1799
|
+
const setupSchema = TemplateBuilder.getRunScriptCommand(context.packageManager, "setup:schema");
|
|
1800
|
+
const bootstrap = TemplateBuilder.getRunScriptCommand(context.packageManager, "bootstrap");
|
|
1801
|
+
const typecheck = TemplateBuilder.getRunScriptCommand(context.packageManager, "typecheck");
|
|
1735
1802
|
return `# ${context.projectName}
|
|
1736
1803
|
|
|
1737
1804
|
This project was scaffolded by \`tango new --framework nuxt\`.
|
|
@@ -1743,42 +1810,50 @@ Nuxt still owns pages and SSR rendering; Tango owns model metadata, \`Model.obje
|
|
|
1743
1810
|
Generate your first migration from the scaffolded models, then start the app:
|
|
1744
1811
|
|
|
1745
1812
|
\`\`\`bash
|
|
1746
|
-
${
|
|
1747
|
-
${
|
|
1813
|
+
${makeMigrations}
|
|
1814
|
+
${dev}
|
|
1748
1815
|
\`\`\`
|
|
1749
1816
|
|
|
1750
|
-
\`make:migrations\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \`${
|
|
1751
|
-
|
|
1752
|
-
When you run the package script, pass Tango flags after \`--\` so the script forwards them to the CLI unchanged.
|
|
1817
|
+
\`make:migrations\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \`${codegenRelations}\`.
|
|
1753
1818
|
|
|
1754
1819
|
## Scripts
|
|
1755
1820
|
|
|
1756
|
-
- \`${
|
|
1757
|
-
- \`${
|
|
1758
|
-
- \`${
|
|
1759
|
-
- \`${
|
|
1760
|
-
- \`${
|
|
1761
|
-
- \`${
|
|
1821
|
+
- \`${dev}\`
|
|
1822
|
+
- \`${makeNamedMigration}\`
|
|
1823
|
+
- \`${codegenRelations}\`
|
|
1824
|
+
- \`${setupSchema}\`
|
|
1825
|
+
- \`${bootstrap}\`
|
|
1826
|
+
- \`${typecheck}\`
|
|
1762
1827
|
|
|
1763
1828
|
## Useful endpoints
|
|
1764
1829
|
|
|
1830
|
+
- \`GET /\` browser entry route rendered by \`app/pages/index.server.vue\`
|
|
1765
1831
|
- \`GET /api/health\`
|
|
1766
1832
|
- \`GET /api/openapi\`
|
|
1767
1833
|
- \`GET|POST|PATCH|DELETE /api/todos...\`
|
|
1768
1834
|
|
|
1769
|
-
|
|
1835
|
+
Nuxt owns the public page route at \`/\`. Tango-owned endpoints stay under \`/api/*\`.
|
|
1836
|
+
|
|
1837
|
+
## Durable app code
|
|
1770
1838
|
|
|
1771
1839
|
- \`nuxt.config.ts\` Nuxt config and explicit Tango server handler registration
|
|
1772
1840
|
- \`tango.config.ts\` Tango configuration
|
|
1773
1841
|
- \`lib/models/\` schemas and Tango model metadata; explicit ORM registration keeps \`Model.objects\` available in SSR pages and handlers
|
|
1774
1842
|
- \`serializers/\` serializer-backed API contracts for Tango resources
|
|
1775
1843
|
- \`viewsets/\` CRUD resources backed by \`Model.objects\`
|
|
1776
|
-
- \`app/pages/index.server.vue\`
|
|
1844
|
+
- \`app/pages/index.server.vue\` browser entry route at \`/\`; replace the Todo page once your own app shell is ready
|
|
1777
1845
|
- \`server/tango/todos.ts\` Nuxt adapter wiring for the viewset
|
|
1846
|
+
- \`server/tango/openapi.ts\` Tango-owned API surface for your OpenAPI document
|
|
1778
1847
|
- \`lib/openapi.ts\` OpenAPI document generation
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1848
|
+
|
|
1849
|
+
## Generated artifacts
|
|
1850
|
+
|
|
1851
|
+
- \`.tango/\` generated relation typing artifacts; regenerate through \`make:migrations\` or \`codegen:relations\`
|
|
1852
|
+
- \`migrations/\` checked-in Tango migrations; review them like source, but let Tango generate the files
|
|
1853
|
+
|
|
1854
|
+
## Utility surface
|
|
1855
|
+
|
|
1856
|
+
- \`scripts/bootstrap.ts\` sample seed utility; keep it if it helps your app, or replace it once your own seed flow exists
|
|
1782
1857
|
`;
|
|
1783
1858
|
}
|
|
1784
1859
|
};
|
|
@@ -1914,4 +1989,4 @@ __export(frameworks_exports, {
|
|
|
1914
1989
|
|
|
1915
1990
|
//#endregion
|
|
1916
1991
|
export { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, FrameworkScaffoldStrategy, NextScaffoldStrategy, NuxtScaffoldStrategy, PACKAGE_MANAGER, SCAFFOLD_DATABASE_DIALECT, SCAFFOLD_TEMPLATE_CATEGORY, SUPPORTED_FRAMEWORK, ScaffoldTemplateDescriptor, frameworks_exports, scaffoldProject };
|
|
1917
|
-
//# sourceMappingURL=frameworks-
|
|
1992
|
+
//# sourceMappingURL=frameworks-BQp-rqXU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frameworks-BQp-rqXU.js","names":["template: TemplateBuilder","category: ScaffoldTemplateCategory","ctx: FrameworkScaffoldContext","mode: ScaffoldMode","options: { name: string }","packageManager: PackageManager","dialect: 'sqlite' | 'postgres'","framework: 'express' | 'next' | 'nuxt'","scriptName: string","scriptArgs: readonly string[]","fileName: string","template: string | (() => string)","_context: FrameworkScaffoldContext","_dialect: 'sqlite' | 'postgres'","core: Record<string, string>","adapter: Record<string, string>","dialectDeps: Record<string, string>","context: FrameworkScaffoldContext","packageManager: PackageManager","context: FrameworkScaffoldContext","template: TemplateBuilder","category: ScaffoldTemplateCategory","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","strategy: FrameworkScaffoldStrategy","id: SupportedFramework","targetDir: string","options: ScaffoldProjectOptions & { mode: ScaffoldMode }","context: FrameworkScaffoldContext","strategy: FrameworkScaffoldStrategy","options: ScaffoldProjectOptions"],"sources":["../src/frameworks/contracts/template/ScaffoldTemplate.ts","../src/frameworks/contracts/template/implementation/ScaffoldTemplateDescriptor.ts","../package.json","../src/frameworks/contracts/template/TemplateBuilder.ts","../src/frameworks/contracts/FrameworkScaffoldStrategy.ts","../src/frameworks/strategies/express/templates/packageJson.ts","../src/frameworks/strategies/express/templates/tsconfig.ts","../src/frameworks/strategies/express/templates/tsconfigBuild.ts","../src/frameworks/strategies/express/templates/tangoConfig.ts","../src/frameworks/strategies/express/templates/appSource.ts","../src/frameworks/strategies/express/templates/models.ts","../src/frameworks/strategies/express/templates/serializers.ts","../src/frameworks/strategies/express/templates/openapi.ts","../src/frameworks/strategies/express/templates/viewSet.ts","../src/frameworks/strategies/express/templates/bootstrap.ts","../src/frameworks/strategies/express/templates/readme.ts","../src/frameworks/strategies/express/templates/tangoRegister.ts","../src/frameworks/strategies/express/ExpressScaffoldStrategy.ts","../src/frameworks/strategies/next/templates/packageJson.ts","../src/frameworks/strategies/next/templates/tsconfig.ts","../src/frameworks/strategies/next/templates/tangoConfig.ts","../src/frameworks/strategies/next/templates/models.ts","../src/frameworks/strategies/next/templates/serializers.ts","../src/frameworks/strategies/next/templates/openapi.ts","../src/frameworks/strategies/next/templates/viewSet.ts","../src/frameworks/strategies/next/templates/page.ts","../src/frameworks/strategies/next/templates/layout.ts","../src/frameworks/strategies/next/templates/healthRoute.ts","../src/frameworks/strategies/next/templates/todoRoute.ts","../src/frameworks/strategies/next/templates/openapiRoute.ts","../src/frameworks/strategies/next/templates/bootstrap.ts","../src/frameworks/strategies/next/templates/readme.ts","../src/frameworks/strategies/next/NextScaffoldStrategy.ts","../src/frameworks/strategies/nuxt/templates/packageJson.ts","../src/frameworks/strategies/nuxt/templates/tsconfig.ts","../src/frameworks/strategies/nuxt/templates/nuxtConfig.ts","../src/frameworks/strategies/nuxt/templates/models.ts","../src/frameworks/strategies/nuxt/templates/serializers.ts","../src/frameworks/strategies/nuxt/templates/openapi.ts","../src/frameworks/strategies/nuxt/templates/viewSet.ts","../src/frameworks/strategies/nuxt/templates/page.ts","../src/frameworks/strategies/nuxt/templates/layout.ts","../src/frameworks/strategies/nuxt/templates/healthRoute.ts","../src/frameworks/strategies/nuxt/templates/todoRoute.ts","../src/frameworks/strategies/nuxt/templates/openapiRoute.ts","../src/frameworks/strategies/nuxt/templates/bootstrap.ts","../src/frameworks/strategies/nuxt/templates/tangoConfig.ts","../src/frameworks/strategies/nuxt/templates/readme.ts","../src/frameworks/strategies/nuxt/NuxtScaffoldStrategy.ts","../src/frameworks/registry/FrameworkScaffoldRegistry.ts","../src/frameworks/scaffold/scaffoldProject.ts","../src/frameworks/index.ts"],"sourcesContent":["import type { SupportedFramework, PackageManager, ScaffoldDatabaseDialect } from '../FrameworkScaffoldStrategy';\n\nexport const SCAFFOLD_TEMPLATE_CATEGORY = {\n FRAMEWORK: 'framework',\n TANGO: 'tango',\n INIT_ONLY: 'init-only',\n} as const;\nexport type ScaffoldTemplateCategory = (typeof SCAFFOLD_TEMPLATE_CATEGORY)[keyof typeof SCAFFOLD_TEMPLATE_CATEGORY];\n\nexport type ScaffoldMode = 'new' | 'init';\n\nexport type FrameworkScaffoldContext = {\n projectName: string;\n targetDir: string;\n framework: SupportedFramework;\n packageManager: PackageManager;\n dialect: ScaffoldDatabaseDialect;\n includeSeed: boolean;\n};\n\nexport interface ScaffoldTemplate {\n readonly path: string;\n readonly category: ScaffoldTemplateCategory;\n render(ctx: FrameworkScaffoldContext): string;\n shouldEmit(mode: ScaffoldMode): boolean;\n}\n","import {\n type ScaffoldTemplate,\n type ScaffoldTemplateCategory,\n type FrameworkScaffoldContext,\n type ScaffoldMode,\n SCAFFOLD_TEMPLATE_CATEGORY,\n} from '../ScaffoldTemplate';\nimport type { TemplateBuilder } from '../TemplateBuilder';\n\nexport class ScaffoldTemplateDescriptor implements ScaffoldTemplate {\n constructor(\n readonly template: TemplateBuilder,\n readonly category: ScaffoldTemplateCategory\n ) {}\n public get path(): string {\n return this.template.getPath();\n }\n\n render(ctx: FrameworkScaffoldContext): string {\n return this.template.setContext(ctx).build();\n }\n\n shouldEmit(mode: ScaffoldMode): boolean {\n if (mode === 'new') {\n return (\n this.category === SCAFFOLD_TEMPLATE_CATEGORY.FRAMEWORK ||\n this.category === SCAFFOLD_TEMPLATE_CATEGORY.TANGO\n );\n }\n return (\n this.category === SCAFFOLD_TEMPLATE_CATEGORY.TANGO || this.category === SCAFFOLD_TEMPLATE_CATEGORY.INIT_ONLY\n );\n }\n}\n","({\n \"name\": \"@danceroutine/tango-codegen\",\n \"version\": \"1.10.1\",\n \"description\": \"CLI for generating repositories, types, migrations, and OpenAPI specs for Tango\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./domain\": {\n \"types\": \"./dist/domain/index.d.ts\",\n \"import\": \"./dist/domain/index.js\"\n },\n \"./generators\": {\n \"types\": \"./dist/generators/index.d.ts\",\n \"import\": \"./dist/generators/index.js\"\n },\n \"./frameworks\": {\n \"types\": \"./dist/frameworks/index.d.ts\",\n \"import\": \"./dist/frameworks/index.js\"\n },\n \"./commands\": {\n \"types\": \"./dist/commands/index.d.ts\",\n \"import\": \"./dist/commands/index.js\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsdown\",\n \"test\": \"vitest run --coverage\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"pnpm run typecheck:prod && pnpm run typecheck:test\",\n \"typecheck:prod\": \"tsc --noEmit -p tsconfig.json\",\n \"typecheck:test\": \"tsc --noEmit -p tsconfig.tests.json\"\n },\n \"keywords\": [\n \"tango\",\n \"codegen\",\n \"cli\",\n \"generator\",\n \"migrations\"\n ],\n \"author\": \"Pedro Del Moral Lopez\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/danceroutine/tango.git\",\n \"directory\": \"packages/codegen\"\n },\n \"dependencies\": {\n \"@danceroutine/tango-core\": \"workspace:*\",\n \"@danceroutine/tango-schema\": \"workspace:*\",\n \"jiti\": \"^2.6.1\",\n \"yargs\": \"^17.7.2\"\n },\n \"devDependencies\": {\n \"@danceroutine/tango-testing\": \"workspace:*\",\n \"@types/yargs\": \"^17.0.33\",\n \"@types/node\": \"^22.9.0\",\n \"tsdown\": \"^0.4.0\",\n \"typescript\": \"^5.6.3\",\n \"vitest\": \"^4.0.6\",\n \"zod\": \"^4.0.0\"\n }\n}\n)","import packageJson from '../../../../package.json';\nimport { PACKAGE_MANAGER, type PackageManager } from '../FrameworkScaffoldStrategy';\nimport type { FrameworkScaffoldContext } from './ScaffoldTemplate';\n\nconst { version } = packageJson as { version: string };\n\n/**\n * Interface for a context-bound template that the strategy's add* methods accept.\n * Implemented by bound TemplateBuilder instances and by the return value of createStaticTemplate.\n */\nexport interface BoundTemplate {\n getPath(): string;\n build(): string;\n}\n\n/**\n * Base class for scaffold template builders. Subclasses override resolveTemplate().\n * Use new WhateverBuilder().setContext(context) for registration with add* methods.\n * Deps logic (getTangoDependencyEntries, getTangoDevDependencyEntries) and version live here.\n */\nexport abstract class TemplateBuilder implements BoundTemplate {\n protected readonly name: string;\n protected _context?: FrameworkScaffoldContext;\n\n constructor(options: { name: string }) {\n this.name = options.name;\n }\n\n /**\n * One-liner to install Tango + dialect deps and Tango CLI (for init success message).\n */\n static getTangoInstallOneLiner(\n packageManager: PackageManager,\n dialect: 'sqlite' | 'postgres',\n framework: 'express' | 'next' | 'nuxt'\n ): string {\n const deps = TemplateBuilder.getTangoDependencyEntriesFor(dialect, framework);\n const devDeps = TemplateBuilder.getTangoDevDependencyEntriesFor();\n const depList = Object.entries(deps)\n .map(([pkg, ver]) => `${pkg}@${ver}`)\n .join(' ');\n const devList = Object.entries(devDeps)\n .map(([pkg, ver]) => `${pkg}@${ver}`)\n .join(' ');\n const addCmd = packageManager === 'npm' ? 'npm install' : `${packageManager} add`;\n const addDevCmd = packageManager === 'npm' ? 'npm install -D' : `${packageManager} add -D`;\n return `${addCmd} ${depList} && ${addDevCmd} ${devList}`;\n }\n\n static getRunScriptCommand(\n packageManager: PackageManager,\n scriptName: string,\n scriptArgs: readonly string[] = []\n ): string {\n const serializedArgs = scriptArgs.join(' ');\n\n switch (packageManager) {\n case PACKAGE_MANAGER.NPM:\n return serializedArgs.length > 0\n ? `npm run ${scriptName} -- ${serializedArgs}`\n : `npm run ${scriptName}`;\n case PACKAGE_MANAGER.YARN:\n return serializedArgs.length > 0 ? `yarn run ${scriptName} ${serializedArgs}` : `yarn run ${scriptName}`;\n case PACKAGE_MANAGER.BUN:\n return serializedArgs.length > 0 ? `bun run ${scriptName} ${serializedArgs}` : `bun run ${scriptName}`;\n case PACKAGE_MANAGER.PNPM:\n default:\n return serializedArgs.length > 0 ? `pnpm run ${scriptName} ${serializedArgs}` : `pnpm run ${scriptName}`;\n }\n }\n\n /**\n * Shorthand for static content (no subclass needed). Returns a BoundTemplate that add* methods accept.\n */\n static createStaticTemplate(fileName: string, template: string | (() => string)): TemplateBuilder {\n class TransientStaticTemplateBuilder extends TemplateBuilder {\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return typeof template === 'string' ? template : template();\n }\n }\n return new TransientStaticTemplateBuilder({ name: fileName });\n }\n\n /** Tango package version (semver range) for scaffolded dependency entries. */\n private static getTangoVersion(): string {\n return `^${version}`;\n }\n\n private static getTangoDependencyEntriesFor(\n _dialect: 'sqlite' | 'postgres',\n framework: 'express' | 'next' | 'nuxt'\n ): Record<string, string> {\n const v = TemplateBuilder.getTangoVersion();\n const core: Record<string, string> = {\n '@danceroutine/tango-core': v,\n '@danceroutine/tango-schema': v,\n '@danceroutine/tango-orm': v,\n '@danceroutine/tango-resources': v,\n '@danceroutine/tango-migrations': v,\n '@danceroutine/tango-openapi': v,\n '@danceroutine/tango-config': v,\n };\n const adapter: Record<string, string> =\n framework === 'express'\n ? { '@danceroutine/tango-adapters-express': v }\n : framework === 'next'\n ? { '@danceroutine/tango-adapters-next': v }\n : { '@danceroutine/tango-adapters-nuxt': v };\n const dialectDeps: Record<string, string> = {\n 'better-sqlite3': '^11.10.0',\n pg: '^8.16.3',\n };\n return { ...core, ...adapter, ...dialectDeps };\n }\n\n private static getTangoDevDependencyEntriesFor(): Record<string, string> {\n return {\n '@danceroutine/tango-cli': TemplateBuilder.getTangoVersion(),\n '@types/better-sqlite3': '^7.6.12',\n };\n }\n\n /** Bind context and return this for chaining. Use before passing to add* methods. */\n setContext(context: FrameworkScaffoldContext): this {\n this._context = context;\n return this;\n }\n\n getPath(): string {\n return this.name;\n }\n\n protected abstract resolveTemplate(context: FrameworkScaffoldContext): string;\n\n build(): string {\n if (this._context === undefined) {\n throw new Error('TemplateBuilder: context not bound. Call .setContext(context) before .build().');\n }\n return this.resolveTemplate(this._context);\n }\n\n protected getTangoDependencyEntries(context: FrameworkScaffoldContext): Record<string, string> {\n return TemplateBuilder.getTangoDependencyEntriesFor(context.dialect, context.framework);\n }\n\n protected getTangoDevDependencyEntries(_context: FrameworkScaffoldContext): Record<string, string> {\n return TemplateBuilder.getTangoDevDependencyEntriesFor();\n }\n}\n","import {\n SCAFFOLD_TEMPLATE_CATEGORY,\n type ScaffoldTemplate,\n type ScaffoldTemplateCategory,\n type FrameworkScaffoldContext,\n} from './template/ScaffoldTemplate';\nimport { ScaffoldTemplateDescriptor } from './template/implementation/ScaffoldTemplateDescriptor';\nimport { TemplateBuilder } from './template/TemplateBuilder';\n\nexport const SUPPORTED_FRAMEWORK = {\n EXPRESS: 'express',\n NEXT: 'next',\n NUXT: 'nuxt',\n} as const;\nexport type SupportedFramework = (typeof SUPPORTED_FRAMEWORK)[keyof typeof SUPPORTED_FRAMEWORK];\n\nexport const PACKAGE_MANAGER = {\n PNPM: 'pnpm',\n NPM: 'npm',\n YARN: 'yarn',\n BUN: 'bun',\n} as const;\nexport type PackageManager = (typeof PACKAGE_MANAGER)[keyof typeof PACKAGE_MANAGER];\n\nexport const SCAFFOLD_DATABASE_DIALECT = {\n SQLITE: 'sqlite',\n POSTGRES: 'postgres',\n} as const;\nexport type ScaffoldDatabaseDialect = (typeof SCAFFOLD_DATABASE_DIALECT)[keyof typeof SCAFFOLD_DATABASE_DIALECT];\n\n/**\n * Base scaffold strategy contract and helpers for Tango framework scaffolds.\n *\n * Concrete strategies extend this class and assemble their template lists\n * through the protected helpers below.\n */\nexport abstract class FrameworkScaffoldStrategy {\n abstract readonly id: SupportedFramework;\n abstract readonly name: string;\n abstract readonly description: string;\n\n /**\n * One-liner to install Tango + dialect deps and Tango CLI, for init success message.\n */\n getTangoInstallOneLiner(packageManager: PackageManager, context: FrameworkScaffoldContext): string {\n return TemplateBuilder.getTangoInstallOneLiner(packageManager, context.dialect, context.framework);\n }\n\n abstract getTemplates(): readonly ScaffoldTemplate[];\n\n protected addFrameworkTemplate(template: TemplateBuilder): ScaffoldTemplate {\n return this.createTemplate(template, SCAFFOLD_TEMPLATE_CATEGORY.FRAMEWORK);\n }\n\n protected addTangoTemplate(template: TemplateBuilder): ScaffoldTemplate {\n return this.createTemplate(template, SCAFFOLD_TEMPLATE_CATEGORY.TANGO);\n }\n\n protected addInitOnlyTemplate(template: TemplateBuilder): ScaffoldTemplate {\n return this.createTemplate(template, SCAFFOLD_TEMPLATE_CATEGORY.INIT_ONLY);\n }\n\n private createTemplate(template: TemplateBuilder, category: ScaffoldTemplateCategory): ScaffoldTemplate {\n return new ScaffoldTemplateDescriptor(template, category);\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PackageJsonTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'package.json' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const deps = this.getTangoDependencyEntries(context);\n const devDeps = this.getTangoDevDependencyEntries(context);\n\n return JSON.stringify(\n {\n name: context.projectName,\n private: true,\n type: 'module',\n scripts: {\n predev: 'tango migrate --config ./tango.config.ts',\n dev: 'tsx watch src/index.ts',\n prestart: 'tango migrate --config ./tango.config.ts',\n build: 'tsc -p tsconfig.build.json',\n start: 'node dist/index.js',\n typecheck: 'tsc --noEmit',\n 'setup:schema':\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n 'make:migrations':\n 'tango make:migrations --config ./tango.config.ts --models ./src/models/index.ts',\n 'codegen:relations': 'tango codegen relations --models ./src/models/index.ts',\n prebootstrap:\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n bootstrap: 'tsx src/bootstrap.ts',\n },\n dependencies: {\n ...deps,\n express: '^4.21.2',\n zod: '^4.0.0',\n },\n devDependencies: {\n ...devDeps,\n '@types/express': '^5.0.0',\n '@types/node': '^22.9.0',\n tsx: '^4.20.6',\n typescript: '^5.6.3',\n },\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n lib: ['ES2022', 'DOM'],\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n strict: true,\n noEmit: true,\n esModuleInterop: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n types: ['node'],\n },\n include: ['src', 'migrations/**/*.ts', 'tango.config.ts', '.tango/**/*.d.ts'],\n exclude: ['node_modules', 'dist'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigBuildTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.build.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n extends: './tsconfig.json',\n compilerOptions: {\n noEmit: false,\n outDir: './dist',\n rootDir: '.',\n sourceMap: true,\n declaration: false,\n },\n include: ['src', 'tango.config.ts'],\n exclude: ['node_modules', 'dist', 'migrations', '**/*.test.ts'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tango.config.ts' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n if (context.dialect === 'sqlite') {\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || ':memory:',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n },\n});\n`;\n }\n\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 10,\n },\n migrations: { dir: './migrations', online: true },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}_test',\n maxConnections: 5,\n },\n migrations: { dir: './migrations', online: true },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 20,\n },\n migrations: { dir: './migrations', online: true },\n },\n },\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class AppSourceTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import express from 'express';\nimport { seedExampleData } from './bootstrap.js';\nimport { registerTango } from './tango.js';\n\nasync function main(): Promise<void> {\n const app = express();\n app.use(express.json());\n\n if (process.env.AUTO_BOOTSTRAP === 'true') {\n await seedExampleData(Number(process.env.SEED_TODOS_COUNT || '100'));\n }\n\n app.get('/health', (_req, res) => {\n res.json({ ok: true });\n });\n\n await registerTango(app);\n\n const port = Number(process.env.PORT || '3000');\n app.listen(port, () => {\n console.log(\\`Tango Express app listening on http://localhost:\\${String(port)}\\`);\n });\n}\n\n// oxlint-disable-next-line unicorn/prefer-top-level-await\nmain().catch((error: unknown) => {\n console.error('Failed to start app:', error);\n process.exit(1);\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoModelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/models/TodoModel.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { z } from 'zod';\nimport { registerModelObjects } from '@danceroutine/tango-orm/runtime';\nimport { Model, t } from '@danceroutine/tango-schema';\n\nregisterModelObjects();\n\nexport const TodoReadSchema = z.object({\n id: z.number(),\n title: z.string().min(1),\n completed: z.coerce.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nexport const TodoCreateSchema = z.object({\n title: z.string().min(1),\n completed: z.boolean().optional().default(false),\n});\n\nexport const TodoUpdateSchema = TodoCreateSchema.partial();\n\nexport type Todo = z.output<typeof TodoReadSchema>;\n\nexport const TodoModel = Model({\n namespace: 'app',\n name: 'Todo',\n schema: TodoReadSchema.extend({\n id: t.primaryKey(z.number().int()),\n title: z.string().min(1),\n completed: t.field(z.coerce.boolean()).defaultValue('false').build(),\n createdAt: t.field(z.string()).defaultValue({ now: true }).build(),\n updatedAt: t.field(z.string()).defaultValue({ now: true }).build(),\n }),\n});\n`;\n }\n}\n\nexport class ModelsBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/models/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoReadSchema, TodoCreateSchema, TodoUpdateSchema, TodoModel, type Todo } from './TodoModel.js';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoSerializerTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/TodoSerializer.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { ModelSerializer } from '@danceroutine/tango-resources';\nimport { TodoCreateSchema, TodoModel, TodoReadSchema, TodoUpdateSchema, type Todo } from '../models/index.js';\n\nexport class TodoSerializer extends ModelSerializer<\n Todo,\n typeof TodoCreateSchema,\n typeof TodoUpdateSchema,\n typeof TodoReadSchema\n> {\n static readonly model = TodoModel;\n static readonly createSchema = TodoCreateSchema;\n static readonly updateSchema = TodoUpdateSchema;\n static readonly outputSchema = TodoReadSchema;\n}\n`;\n }\n}\n\nexport class SerializersBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoSerializer } from './TodoSerializer.js';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPITemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { describeViewSet, generateOpenAPISpec, type OpenAPISpec } from '@danceroutine/tango-openapi';\nimport { TodoViewSet } from './viewsets/TodoViewSet.js';\n\nexport function createOpenAPISpec(): OpenAPISpec {\n return generateOpenAPISpec({\n title: 'Tango Express Todo API',\n version: '1.0.0',\n description: 'OpenAPI document generated from Tango resource instances.',\n resources: [describeViewSet({ basePath: '/api/todos', resource: new TodoViewSet() })],\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ViewSetTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/viewsets/TodoViewSet.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { FilterSet, ModelViewSet } from '@danceroutine/tango-resources';\nimport { type Todo } from '../models/index.js';\nimport { TodoSerializer } from '../serializers/index.js';\n\nexport class TodoViewSet extends ModelViewSet<Todo, typeof TodoSerializer> {\n constructor() {\n super({\n serializer: TodoSerializer,\n filters: FilterSet.define<Todo>({\n fields: {\n completed: true,\n },\n aliases: {\n q: { fields: ['title'], lookup: 'icontains' },\n },\n }),\n orderingFields: ['id', 'createdAt', 'updatedAt', 'title'],\n searchFields: ['title'],\n });\n }\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class BootstrapTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/bootstrap.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { initializeTangoRuntime } from '@danceroutine/tango-orm/runtime';\nimport tangoConfig from '../tango.config.js';\nimport { TodoModel, type Todo } from './models/index.js';\n\ninitializeTangoRuntime(() => tangoConfig);\n\nexport async function seedExampleData(count = 100): Promise<void> {\n const existing = await TodoModel.objects.query().count();\n if (existing >= count) {\n console.log(\\`[bootstrap] Skipped; already have \\${existing} todos.\\`);\n return;\n }\n\n const rows: Array<Partial<Todo>> = [];\n for (let index = existing; index < count; index += 1) {\n const now = new Date(Date.now() - index * 60_000).toISOString();\n rows.push({\n title: \\`Seeded todo #\\${index + 1}\\`,\n completed: index % 3 === 0,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n await TodoModel.objects.bulkCreate(rows);\n console.log(\\`[bootstrap] Seeded \\${rows.length} todos.\\`);\n}\n\nif (import.meta.url === \\`file://\\${process.argv[1]}\\`) {\n const count = Number(process.env.SEED_TODOS_COUNT || '100');\n // oxlint-disable-next-line unicorn/prefer-top-level-await\n seedExampleData(Number.isFinite(count) ? count : 100).catch((error: unknown) => {\n console.error('[bootstrap] Failed:', error);\n process.exit(1);\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ReadmeTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'README.md' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const makeMigrations = TemplateBuilder.getRunScriptCommand(context.packageManager, 'make:migrations', [\n '--name',\n 'initial',\n ]);\n const makeNamedMigration = TemplateBuilder.getRunScriptCommand(context.packageManager, 'make:migrations', [\n '--name',\n 'add_field',\n ]);\n const dev = TemplateBuilder.getRunScriptCommand(context.packageManager, 'dev');\n const codegenRelations = TemplateBuilder.getRunScriptCommand(context.packageManager, 'codegen:relations');\n const setupSchema = TemplateBuilder.getRunScriptCommand(context.packageManager, 'setup:schema');\n const bootstrap = TemplateBuilder.getRunScriptCommand(context.packageManager, 'bootstrap');\n const typecheck = TemplateBuilder.getRunScriptCommand(context.packageManager, 'typecheck');\n\n return `# ${context.projectName}\n\nThis project was scaffolded by \\`tango new --framework express\\`.\n\nExpress still owns the server and route registration; Tango owns model metadata, \\`Model.objects\\`, serializers, migrations, querying, and resource behavior.\n\n## First-time setup\n\nGenerate your first migration from the scaffolded models, then start the app:\n\n\\`\\`\\`bash\n${makeMigrations}\n${dev}\n\\`\\`\\`\n\n\\`make:migrations\\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \\`${codegenRelations}\\`.\n\n## Scripts\n\n- \\`${dev}\\`\n- \\`${makeNamedMigration}\\`\n- \\`${codegenRelations}\\`\n- \\`${setupSchema}\\`\n- \\`${bootstrap}\\`\n- \\`${typecheck}\\`\n\n## Useful endpoints\n\n- \\`GET /health\\`\n- \\`GET /api/openapi.json\\`\n- \\`GET|POST|PATCH|DELETE /api/todos...\\`\n\n## Durable app code\n\n- \\`tango.config.ts\\` Tango configuration\n- \\`src/index.ts\\` Express app entrypoint; you own server boot, ports, and middleware here\n- \\`src/tango.ts\\` Express registration helper for Tango routes and OpenAPI wiring\n- \\`src/models/\\` schemas and Tango model metadata; importing the model module enables \\`Model.objects\\`\n- \\`src/serializers/\\` serializer-backed API contracts for Tango resources\n- \\`src/viewsets/\\` CRUD resources backed by \\`Model.objects\\`\n- \\`src/openapi.ts\\` OpenAPI document generation\n\n## Generated artifacts\n\n- \\`.tango/\\` generated relation typing artifacts; regenerate through \\`make:migrations\\` or \\`codegen:relations\\`\n- \\`migrations/\\` checked-in Tango migrations; review them like source, but let Tango generate the files\n\n## Utility surface\n\n- \\`src/bootstrap.ts\\` sample seed utility; keep it if it helps your app, or replace it once your own seed flow exists\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoRegisterTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/tango.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import type { Application } from 'express';\nimport { ExpressAdapter } from '@danceroutine/tango-adapters-express/adapter';\nimport { createOpenAPISpec } from './openapi.js';\nimport { TodoViewSet } from './viewsets/TodoViewSet.js';\n\n/**\n * Register Tango API routes and OpenAPI spec on an existing Express app.\n * Use from your app entry (for example, \\`index.ts\\`): \\`await registerTango(app);\\`\n */\nexport async function registerTango(app: Application): Promise<void> {\n const adapter = new ExpressAdapter();\n adapter.registerViewSet(app, '/api/todos', new TodoViewSet());\n app.get('/api/openapi.json', (_req, res) => {\n res.json(createOpenAPISpec());\n });\n}\n`;\n }\n}\n","import { FrameworkScaffoldStrategy } from '../../contracts/FrameworkScaffoldStrategy';\nimport { TemplateBuilder } from '../../contracts/template/TemplateBuilder';\nimport type { ScaffoldTemplate } from '../../contracts/template/ScaffoldTemplate';\nimport { PackageJsonTemplateBuilder } from './templates/packageJson';\nimport { TsConfigTemplateBuilder } from './templates/tsconfig';\nimport { TsConfigBuildTemplateBuilder } from './templates/tsconfigBuild';\nimport { TangoConfigTemplateBuilder } from './templates/tangoConfig';\nimport { AppSourceTemplateBuilder } from './templates/appSource';\nimport { TodoModelTemplateBuilder, ModelsBarrelTemplateBuilder } from './templates/models';\nimport { TodoSerializerTemplateBuilder, SerializersBarrelTemplateBuilder } from './templates/serializers';\nimport { OpenAPITemplateBuilder } from './templates/openapi';\nimport { ViewSetTemplateBuilder } from './templates/viewSet';\nimport { BootstrapTemplateBuilder } from './templates/bootstrap';\nimport { ReadmeTemplateBuilder } from './templates/readme';\nimport { TangoRegisterTemplateBuilder } from './templates/tangoRegister';\n\n/**\n * Scaffold strategy for creating an Express-hosted Tango project.\n */\nexport class ExpressScaffoldStrategy extends FrameworkScaffoldStrategy {\n readonly id = 'express' as const;\n\n readonly name = 'Express';\n\n readonly description = 'Bootstrap a Tango application hosted by Express.';\n\n /**\n * Return the file templates needed for the generated Express project.\n */\n getTemplates(): readonly ScaffoldTemplate[] {\n return [\n this.addFrameworkTemplate(new PackageJsonTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigBuildTemplateBuilder()),\n this.addTangoTemplate(new TangoConfigTemplateBuilder()),\n this.addFrameworkTemplate(new AppSourceTemplateBuilder()),\n this.addTangoTemplate(new TodoModelTemplateBuilder()),\n this.addTangoTemplate(new ModelsBarrelTemplateBuilder()),\n this.addTangoTemplate(new TodoSerializerTemplateBuilder()),\n this.addTangoTemplate(new SerializersBarrelTemplateBuilder()),\n this.addTangoTemplate(new OpenAPITemplateBuilder()),\n this.addTangoTemplate(new ViewSetTemplateBuilder()),\n this.addTangoTemplate(new BootstrapTemplateBuilder()),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('migrations/.gitkeep', '')),\n this.addFrameworkTemplate(new ReadmeTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate('.gitignore', 'node_modules\\ndist\\n.data\\n.env\\n')\n ),\n this.addTangoTemplate(new TangoRegisterTemplateBuilder()),\n ];\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PackageJsonTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'package.json' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const deps = this.getTangoDependencyEntries(context);\n const devDeps = this.getTangoDevDependencyEntries(context);\n\n return JSON.stringify(\n {\n name: context.projectName,\n private: true,\n type: 'module',\n scripts: {\n predev: 'tango migrate --config ./tango.config.ts',\n dev: 'next dev',\n prestart: 'tango migrate --config ./tango.config.ts',\n build: 'next build',\n start: 'next start',\n typecheck: 'tsc --noEmit',\n 'setup:schema':\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n 'make:migrations':\n 'tango make:migrations --config ./tango.config.ts --models ./src/lib/models/index.ts',\n 'codegen:relations': 'tango codegen relations --models ./src/lib/models/index.ts',\n prebootstrap:\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n bootstrap: 'tsx scripts/bootstrap.ts',\n },\n dependencies: {\n ...deps,\n next: '^15.1.6',\n react: '^19.0.0',\n 'react-dom': '^19.0.0',\n zod: '^4.0.0',\n },\n devDependencies: {\n ...devDeps,\n '@types/node': '^22.9.0',\n '@types/react': '^19.0.6',\n '@types/react-dom': '^19.0.2',\n tsx: '^4.20.6',\n typescript: '^5.6.3',\n },\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n lib: ['dom', 'dom.iterable', 'es2022'],\n strict: true,\n noEmit: true,\n module: 'esnext',\n moduleResolution: 'bundler',\n resolveJsonModule: true,\n isolatedModules: true,\n jsx: 'preserve',\n esModuleInterop: true,\n skipLibCheck: true,\n baseUrl: '.',\n paths: {\n '@/*': ['src/*'],\n },\n },\n include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', 'migrations/**/*.ts', '.tango/**/*.d.ts'],\n exclude: ['node_modules'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tango.config.ts' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n if (context.dialect === 'sqlite') {\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || ':memory:',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n },\n});\n`;\n }\n\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 10,\n },\n migrations: { dir: './migrations', online: true },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}_test',\n maxConnections: 5,\n },\n migrations: { dir: './migrations', online: true },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 20,\n },\n migrations: { dir: './migrations', online: true },\n },\n },\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoModelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/lib/models/TodoModel.ts' });\n }\n static context(context: FrameworkScaffoldContext): TodoModelTemplateBuilder {\n return new TodoModelTemplateBuilder().setContext(context);\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { z } from 'zod';\nimport { registerModelObjects } from '@danceroutine/tango-orm/runtime';\nimport { Model, t } from '@danceroutine/tango-schema';\n\nregisterModelObjects();\n\nexport const TodoReadSchema = z.object({\n id: z.number(),\n title: z.string().min(1),\n completed: z.coerce.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nexport const TodoCreateSchema = z.object({\n title: z.string().min(1),\n completed: z.boolean().optional().default(false),\n});\n\nexport const TodoUpdateSchema = TodoCreateSchema.partial();\n\nexport type Todo = z.output<typeof TodoReadSchema>;\n\nexport const TodoModel = Model({\n namespace: 'app',\n name: 'Todo',\n schema: TodoReadSchema.extend({\n id: t.primaryKey(z.number().int()),\n title: z.string().min(1),\n completed: t.field(z.coerce.boolean()).defaultValue('false').build(),\n createdAt: t.field(z.string()).defaultValue({ now: true }).build(),\n updatedAt: t.field(z.string()).defaultValue({ now: true }).build(),\n }),\n});\n`;\n }\n}\n\nexport class ModelsBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/lib/models/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoReadSchema, TodoCreateSchema, TodoUpdateSchema, TodoModel, type Todo } from './TodoModel';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoSerializerTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/TodoSerializer.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { ModelSerializer } from '@danceroutine/tango-resources';\nimport { TodoCreateSchema, TodoModel, TodoReadSchema, TodoUpdateSchema, type Todo } from '@/lib/models';\n\nexport class TodoSerializer extends ModelSerializer<\n Todo,\n typeof TodoCreateSchema,\n typeof TodoUpdateSchema,\n typeof TodoReadSchema\n> {\n static readonly model = TodoModel;\n static readonly createSchema = TodoCreateSchema;\n static readonly updateSchema = TodoUpdateSchema;\n static readonly outputSchema = TodoReadSchema;\n}\n`;\n }\n}\n\nexport class SerializersBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoSerializer } from './TodoSerializer';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPITemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/lib/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { describeViewSet, generateOpenAPISpec, type OpenAPISpec } from '@danceroutine/tango-openapi';\nimport { TodoViewSet } from '@/viewsets/TodoViewSet';\n\nexport function createOpenAPISpec(): OpenAPISpec {\n return generateOpenAPISpec({\n title: 'Tango Next.js Todo API',\n version: '1.0.0',\n description: 'OpenAPI document generated from Tango resource instances.',\n resources: [describeViewSet({ basePath: '/api/todos', resource: new TodoViewSet() })],\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ViewSetTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/viewsets/TodoViewSet.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { FilterSet, ModelViewSet } from '@danceroutine/tango-resources';\nimport { type Todo } from '@/lib/models';\nimport { TodoSerializer } from '@/serializers';\n\nexport class TodoViewSet extends ModelViewSet<Todo, typeof TodoSerializer> {\n constructor() {\n super({\n serializer: TodoSerializer,\n filters: FilterSet.define<Todo>({\n fields: {\n completed: true,\n },\n aliases: {\n q: { fields: ['title'], lookup: 'icontains' },\n },\n }),\n orderingFields: ['id', 'createdAt', 'updatedAt', 'title'],\n searchFields: ['title'],\n });\n }\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PageTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/page.tsx' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { TodoModel, TodoReadSchema } from '@/lib/models';\n\nexport default async function HomePage() {\n const todos = await TodoModel.objects.query().orderBy('-createdAt').limit(10).fetch(TodoReadSchema);\n\n return (\n <main style={{ fontFamily: 'system-ui', margin: '2rem auto', maxWidth: '60ch' }}>\n <h1>Tango + Next.js</h1>\n <p>Showing {todos.length} todos through Tango's runtime-backed model manager.</p>\n <ul>\n {todos.map((todo) => (\n <li key={todo.id}>{todo.title}</li>\n ))}\n </ul>\n </main>\n );\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class LayoutTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/layout.tsx' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'Tango Todo App',\n description: 'Generated by tango new --framework next',\n};\n\nexport default function RootLayout({\n children,\n}: Readonly<{\n children: React.ReactNode;\n}>) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n );\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class HealthRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/api/health/route.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export async function GET(): Promise<Response> {\n return Response.json({ ok: true });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/api/todos/[[...tango]]/route.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { NextAdapter } from '@danceroutine/tango-adapters-next/adapter';\nimport { TodoViewSet } from '@/viewsets/TodoViewSet';\n\nconst adapter = new NextAdapter();\nexport const { GET, POST, PUT, PATCH, DELETE } = adapter.adaptViewSet(new TodoViewSet());\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPIRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/api/openapi/route.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { createOpenAPISpec } from '@/lib/openapi';\n\nexport async function GET(): Promise<Response> {\n return Response.json(createOpenAPISpec());\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class BootstrapTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'scripts/bootstrap.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { initializeTangoRuntime } from '@danceroutine/tango-orm/runtime';\nimport tangoConfig from '../tango.config.js';\nimport { TodoModel, type Todo } from '../src/lib/models';\n\ninitializeTangoRuntime(() => tangoConfig);\n\nasync function seedExampleData(count = 100): Promise<void> {\n const existing = await TodoModel.objects.query().count();\n if (existing >= count) {\n console.log(\\`[bootstrap] Skipped; already have \\${existing} todos.\\`);\n return;\n }\n\n const rows: Array<Partial<Todo>> = [];\n for (let index = existing; index < count; index += 1) {\n const now = new Date(Date.now() - index * 60_000).toISOString();\n rows.push({\n title: \\`Seeded todo #\\${index + 1}\\`,\n completed: index % 3 === 0,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n await TodoModel.objects.bulkCreate(rows);\n console.log(\\`[bootstrap] Seeded \\${rows.length} todos.\\`);\n}\n\nconst count = Number(process.env.SEED_TODOS_COUNT || '100');\n// oxlint-disable-next-line unicorn/prefer-top-level-await\nseedExampleData(Number.isFinite(count) ? count : 100).catch((error: unknown) => {\n console.error('[bootstrap] Failed:', error);\n process.exit(1);\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ReadmeTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'README.md' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const makeMigrations = TemplateBuilder.getRunScriptCommand(context.packageManager, 'make:migrations', [\n '--name',\n 'initial',\n ]);\n const makeNamedMigration = TemplateBuilder.getRunScriptCommand(context.packageManager, 'make:migrations', [\n '--name',\n 'add_field',\n ]);\n const dev = TemplateBuilder.getRunScriptCommand(context.packageManager, 'dev');\n const codegenRelations = TemplateBuilder.getRunScriptCommand(context.packageManager, 'codegen:relations');\n const setupSchema = TemplateBuilder.getRunScriptCommand(context.packageManager, 'setup:schema');\n const bootstrap = TemplateBuilder.getRunScriptCommand(context.packageManager, 'bootstrap');\n const typecheck = TemplateBuilder.getRunScriptCommand(context.packageManager, 'typecheck');\n\n return `# ${context.projectName}\n\nThis project was scaffolded by \\`tango new --framework next\\`.\n\nNext.js still owns pages and route handlers; Tango owns model metadata, \\`Model.objects\\`, serializers, migrations, querying, and resource behavior.\n\n## First-time setup\n\nGenerate your first migration from the scaffolded models, then start the app:\n\n\\`\\`\\`bash\n${makeMigrations}\n${dev}\n\\`\\`\\`\n\n\\`make:migrations\\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \\`${codegenRelations}\\`.\n\n## Scripts\n\n- \\`${dev}\\`\n- \\`${makeNamedMigration}\\`\n- \\`${codegenRelations}\\`\n- \\`${setupSchema}\\`\n- \\`${bootstrap}\\`\n- \\`${typecheck}\\`\n\n## Useful endpoints\n\n- \\`GET /\\` browser entry route rendered by \\`src/app/page.tsx\\`\n- \\`GET /api/health\\`\n- \\`GET /api/openapi\\`\n- \\`GET|POST|PATCH|DELETE /api/todos...\\`\n\n## Durable app code\n\n- \\`tango.config.ts\\` Tango configuration\n- \\`src/lib/models/\\` schemas and Tango model metadata; importing the model module enables \\`Model.objects\\`\n- \\`src/serializers/\\` serializer-backed API contracts for Tango resources\n- \\`src/viewsets/\\` CRUD resources backed by \\`Model.objects\\`\n- \\`src/app/page.tsx\\` browser entry route at \\`/\\`; replace the Todo page once your own app shell is ready\n- \\`src/app/api/todos/[[...tango]]/route.ts\\` Next adapter wiring for the viewset\n- \\`src/lib/openapi.ts\\` OpenAPI document generation\n\n## Generated artifacts\n\n- \\`.tango/\\` generated relation typing artifacts; regenerate through \\`make:migrations\\` or \\`codegen:relations\\`\n- \\`migrations/\\` checked-in Tango migrations; review them like source, but let Tango generate the files\n\n## Utility surface\n\n- \\`scripts/bootstrap.ts\\` sample seed utility; keep it if it helps your app, or replace it once your own seed flow exists\n`;\n }\n}\n","import { FrameworkScaffoldStrategy } from '../../contracts/FrameworkScaffoldStrategy';\nimport { TemplateBuilder } from '../../contracts/template/TemplateBuilder';\nimport type { ScaffoldTemplate } from '../../contracts/template/ScaffoldTemplate';\nimport { PackageJsonTemplateBuilder } from './templates/packageJson';\nimport { TsConfigTemplateBuilder } from './templates/tsconfig';\nimport { TangoConfigTemplateBuilder } from './templates/tangoConfig';\nimport { TodoModelTemplateBuilder, ModelsBarrelTemplateBuilder } from './templates/models';\nimport { TodoSerializerTemplateBuilder, SerializersBarrelTemplateBuilder } from './templates/serializers';\nimport { OpenAPITemplateBuilder } from './templates/openapi';\nimport { ViewSetTemplateBuilder } from './templates/viewSet';\nimport { PageTemplateBuilder } from './templates/page';\nimport { LayoutTemplateBuilder } from './templates/layout';\nimport { HealthRouteTemplateBuilder } from './templates/healthRoute';\nimport { TodoRouteTemplateBuilder } from './templates/todoRoute';\nimport { OpenAPIRouteTemplateBuilder } from './templates/openapiRoute';\nimport { BootstrapTemplateBuilder } from './templates/bootstrap';\nimport { ReadmeTemplateBuilder } from './templates/readme';\n\n/**\n * Scaffold strategy for creating a Next.js-hosted Tango project.\n */\nexport class NextScaffoldStrategy extends FrameworkScaffoldStrategy {\n readonly id = 'next' as const;\n\n readonly name = 'Next.js';\n\n readonly description = 'Bootstrap a Tango application hosted by Next.js App Router.';\n\n /**\n * Return the file templates needed for the generated Next.js project.\n */\n getTemplates(): readonly ScaffoldTemplate[] {\n return [\n this.addFrameworkTemplate(new PackageJsonTemplateBuilder()),\n this.addTangoTemplate(new TangoConfigTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate(\n 'next-env.d.ts',\n '/// <reference types=\"next\" />\\n/// <reference types=\"next/image-types/global\" />\\n'\n )\n ),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('next.config.mjs', 'export default {};\\n')),\n this.addTangoTemplate(new TodoModelTemplateBuilder()),\n this.addTangoTemplate(new ModelsBarrelTemplateBuilder()),\n this.addTangoTemplate(new TodoSerializerTemplateBuilder()),\n this.addTangoTemplate(new SerializersBarrelTemplateBuilder()),\n this.addTangoTemplate(new OpenAPITemplateBuilder()),\n this.addTangoTemplate(new ViewSetTemplateBuilder()),\n this.addFrameworkTemplate(new LayoutTemplateBuilder()),\n this.addFrameworkTemplate(new PageTemplateBuilder()),\n this.addTangoTemplate(new HealthRouteTemplateBuilder()),\n this.addTangoTemplate(new OpenAPIRouteTemplateBuilder()),\n this.addTangoTemplate(new TodoRouteTemplateBuilder()),\n this.addTangoTemplate(new BootstrapTemplateBuilder()),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('migrations/.gitkeep', '')),\n this.addFrameworkTemplate(new ReadmeTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate('.gitignore', 'node_modules\\n.next\\n.data\\n.env\\n')\n ),\n ];\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PackageJsonTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'package.json' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const deps = this.getTangoDependencyEntries(context);\n const devDeps = this.getTangoDevDependencyEntries(context);\n\n return JSON.stringify(\n {\n name: context.projectName,\n private: true,\n type: 'module',\n scripts: {\n predev: 'sh -c \\'if [ \"$TANGO_SKIP_SETUP_SCHEMA\" = \"true\" ]; then exit 0; fi; pnpm run setup:schema\\'',\n dev: 'NUXT_TELEMETRY_DISABLED=1 nuxt dev',\n prestart:\n 'sh -c \\'if [ \"$TANGO_SKIP_SETUP_SCHEMA\" = \"true\" ]; then exit 0; fi; pnpm run setup:schema\\'',\n build: 'NUXT_TELEMETRY_DISABLED=1 nuxt build',\n start: 'NUXT_TELEMETRY_DISABLED=1 nuxt preview',\n typecheck: 'NUXT_TELEMETRY_DISABLED=1 nuxt typecheck',\n 'setup:schema': 'pnpm exec tango migrate --config ./tango.config.ts',\n 'make:migrations':\n 'tango make:migrations --config ./tango.config.ts --models ./lib/models/index.ts',\n 'codegen:relations': 'pnpm exec tango codegen relations --models ./lib/models/index.ts',\n prebootstrap: 'pnpm run setup:schema',\n bootstrap: 'tsx scripts/bootstrap.ts',\n },\n dependencies: {\n ...deps,\n nuxt: '^4.4.2',\n vue: '^3.5.31',\n zod: '^4.0.0',\n },\n devDependencies: {\n ...devDeps,\n '@types/node': '^22.9.0',\n tsx: '^4.20.6',\n typescript: '^5.6.3',\n 'vue-tsc': '^3.1.2',\n },\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n extends: './.nuxt/tsconfig.json',\n compilerOptions: {\n strict: true,\n skipLibCheck: true,\n },\n include: ['.nuxt/**/*.d.ts', '**/*.ts', '**/*.vue', 'migrations/**/*.ts', '.tango/**/*.d.ts'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class NuxtConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'nuxt.config.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { defineNuxtConfig } from 'nuxt/config';\n\nexport default defineNuxtConfig({\n compatibilityDate: '2026-03-31',\n serverHandlers: [\n { route: '/api/health', handler: './server/tango/health.ts' },\n { route: '/api/openapi', handler: './server/tango/openapi.ts' },\n { route: '/api/todos', handler: './server/tango/todos.ts' },\n { route: '/api/todos/**:tango', handler: './server/tango/todos.ts' },\n ],\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoModelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'lib/models/TodoModel.ts' });\n }\n static context(context: FrameworkScaffoldContext): TodoModelTemplateBuilder {\n return new TodoModelTemplateBuilder().setContext(context);\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { z } from 'zod';\nimport { registerModelObjects } from '@danceroutine/tango-orm/runtime';\nimport { Model, t } from '@danceroutine/tango-schema';\n\n// Nuxt/Nitro can tree-shake side-effect-only runtime imports from source-linked packages.\n// Registering model objects here keeps \\`TodoModel.objects\\` available in SSR pages and handlers.\nregisterModelObjects();\n\nexport const TodoReadSchema = z.object({\n id: z.number(),\n title: z.string().min(1),\n completed: z.coerce.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nexport const TodoCreateSchema = z.object({\n title: z.string().min(1),\n completed: z.boolean().optional().default(false),\n});\n\nexport const TodoUpdateSchema = TodoCreateSchema.partial();\n\nexport type Todo = z.output<typeof TodoReadSchema>;\n\nexport const TodoModel = Model({\n namespace: 'app',\n name: 'Todo',\n schema: TodoReadSchema.extend({\n id: t.primaryKey(z.number().int()),\n title: z.string().min(1),\n completed: t.field(z.coerce.boolean()).defaultValue('false').build(),\n createdAt: t.field(z.string()).defaultValue({ now: true }).build(),\n updatedAt: t.field(z.string()).defaultValue({ now: true }).build(),\n }),\n});\n`;\n }\n}\n\nexport class ModelsBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'lib/models/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoReadSchema, TodoCreateSchema, TodoUpdateSchema, TodoModel, type Todo } from './TodoModel';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoSerializerTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'serializers/TodoSerializer.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { ModelSerializer } from '@danceroutine/tango-resources';\nimport { TodoCreateSchema, TodoModel, TodoReadSchema, TodoUpdateSchema, type Todo } from '~~/lib/models';\n\nexport class TodoSerializer extends ModelSerializer<\n Todo,\n typeof TodoCreateSchema,\n typeof TodoUpdateSchema,\n typeof TodoReadSchema\n> {\n static override readonly model = TodoModel;\n static override readonly createSchema = TodoCreateSchema;\n static override readonly updateSchema = TodoUpdateSchema;\n static override readonly outputSchema = TodoReadSchema;\n}\n`;\n }\n}\n\nexport class SerializersBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'serializers/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoSerializer } from './TodoSerializer';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPITemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'lib/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { describeViewSet, generateOpenAPISpec, type OpenAPISpec } from '@danceroutine/tango-openapi';\nimport { TodoViewSet } from '~~/viewsets/TodoViewSet';\n\nexport function createOpenAPISpec(): OpenAPISpec {\n return generateOpenAPISpec({\n title: 'Tango Nuxt Todo API',\n version: '1.0.0',\n description: 'OpenAPI document generated from Tango resource instances.',\n resources: [describeViewSet({ basePath: '/api/todos', resource: new TodoViewSet() })],\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ViewSetTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'viewsets/TodoViewSet.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { FilterSet, ModelViewSet } from '@danceroutine/tango-resources';\nimport { type Todo } from '~~/lib/models';\nimport { TodoSerializer } from '~~/serializers';\n\nexport class TodoViewSet extends ModelViewSet<Todo, typeof TodoSerializer> {\n constructor() {\n super({\n serializer: TodoSerializer,\n filters: FilterSet.define<Todo>({\n fields: {\n completed: true,\n },\n aliases: {\n q: { fields: ['title'], lookup: 'icontains' },\n },\n }),\n orderingFields: ['id', 'createdAt', 'updatedAt', 'title'],\n searchFields: ['title'],\n });\n }\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PageTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'app/pages/index.server.vue' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `<script setup lang=\"ts\">\nimport { TodoModel, TodoReadSchema } from '~~/lib/models';\n\nconst todos = await TodoModel.objects.query().orderBy('-createdAt').limit(10).fetch(TodoReadSchema);\n</script>\n\n<template>\n <main style=\"font-family: system-ui; margin: 2rem auto; max-width: 60ch;\">\n <h1>Tango + Nuxt</h1>\n <p>Showing {{ todos.length }} todos through Tango's runtime-backed model manager.</p>\n <ul>\n <li v-for=\"todo in todos\" :key=\"todo.id\">{{ todo.title }}</li>\n </ul>\n </main>\n</template>\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class AppShellTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'app/app.vue' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `<template>\n <NuxtPage />\n</template>\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class HealthRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'server/tango/health.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export default defineEventHandler(() => ({ ok: true }));\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'server/tango/todos.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { NuxtAdapter } from '@danceroutine/tango-adapters-nuxt/adapter';\nimport { TodoViewSet } from '~~/viewsets/TodoViewSet';\n\nconst adapter = new NuxtAdapter();\nexport default adapter.adaptViewSet(new TodoViewSet());\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPIRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'server/tango/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { createOpenAPISpec } from '~~/lib/openapi';\n\nexport default defineEventHandler(() => createOpenAPISpec());\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class BootstrapTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'scripts/bootstrap.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { initializeTangoRuntime } from '@danceroutine/tango-orm/runtime';\nimport tangoConfig from '../tango.config.js';\nimport { TodoModel, type Todo } from '../lib/models';\n\ninitializeTangoRuntime(() => tangoConfig);\n\nasync function seedExampleData(count = 100): Promise<void> {\n const existing = await TodoModel.objects.query().count();\n if (existing >= count) {\n console.log(\\`[bootstrap] Skipped; already have \\${existing} todos.\\`);\n return;\n }\n\n const rows: Array<Partial<Todo>> = [];\n for (let index = existing; index < count; index += 1) {\n const now = new Date(Date.now() - index * 60_000).toISOString();\n rows.push({\n title: \\`Seeded todo #\\${index + 1}\\`,\n completed: index % 3 === 0,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n await TodoModel.objects.bulkCreate(rows);\n console.log(\\`[bootstrap] Seeded \\${rows.length} todos.\\`);\n}\n\nconst count = Number(process.env.SEED_TODOS_COUNT || '100');\n// oxlint-disable-next-line unicorn/prefer-top-level-await\nseedExampleData(Number.isFinite(count) ? count : 100).catch((error: unknown) => {\n console.error('[bootstrap] Failed:', error);\n process.exit(1);\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tango.config.ts' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n if (context.dialect === 'sqlite') {\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || ':memory:',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n },\n});\n`;\n }\n\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 10,\n },\n migrations: { dir: './migrations', online: true },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}_test',\n maxConnections: 5,\n },\n migrations: { dir: './migrations', online: true },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 20,\n },\n migrations: { dir: './migrations', online: true },\n },\n },\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ReadmeTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'README.md' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const makeMigrations = TemplateBuilder.getRunScriptCommand(context.packageManager, 'make:migrations', [\n '--name',\n 'initial',\n ]);\n const makeNamedMigration = TemplateBuilder.getRunScriptCommand(context.packageManager, 'make:migrations', [\n '--name',\n 'add_field',\n ]);\n const dev = TemplateBuilder.getRunScriptCommand(context.packageManager, 'dev');\n const codegenRelations = TemplateBuilder.getRunScriptCommand(context.packageManager, 'codegen:relations');\n const setupSchema = TemplateBuilder.getRunScriptCommand(context.packageManager, 'setup:schema');\n const bootstrap = TemplateBuilder.getRunScriptCommand(context.packageManager, 'bootstrap');\n const typecheck = TemplateBuilder.getRunScriptCommand(context.packageManager, 'typecheck');\n\n return `# ${context.projectName}\n\nThis project was scaffolded by \\`tango new --framework nuxt\\`.\n\nNuxt still owns pages and SSR rendering; Tango owns model metadata, \\`Model.objects\\`, serializers, migrations, querying, and resource behavior.\n\n## First-time setup\n\nGenerate your first migration from the scaffolded models, then start the app:\n\n\\`\\`\\`bash\n${makeMigrations}\n${dev}\n\\`\\`\\`\n\n\\`make:migrations\\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \\`${codegenRelations}\\`.\n\n## Scripts\n\n- \\`${dev}\\`\n- \\`${makeNamedMigration}\\`\n- \\`${codegenRelations}\\`\n- \\`${setupSchema}\\`\n- \\`${bootstrap}\\`\n- \\`${typecheck}\\`\n\n## Useful endpoints\n\n- \\`GET /\\` browser entry route rendered by \\`app/pages/index.server.vue\\`\n- \\`GET /api/health\\`\n- \\`GET /api/openapi\\`\n- \\`GET|POST|PATCH|DELETE /api/todos...\\`\n\nNuxt owns the public page route at \\`/\\`. Tango-owned endpoints stay under \\`/api/*\\`.\n\n## Durable app code\n\n- \\`nuxt.config.ts\\` Nuxt config and explicit Tango server handler registration\n- \\`tango.config.ts\\` Tango configuration\n- \\`lib/models/\\` schemas and Tango model metadata; explicit ORM registration keeps \\`Model.objects\\` available in SSR pages and handlers\n- \\`serializers/\\` serializer-backed API contracts for Tango resources\n- \\`viewsets/\\` CRUD resources backed by \\`Model.objects\\`\n- \\`app/pages/index.server.vue\\` browser entry route at \\`/\\`; replace the Todo page once your own app shell is ready\n- \\`server/tango/todos.ts\\` Nuxt adapter wiring for the viewset\n- \\`server/tango/openapi.ts\\` Tango-owned API surface for your OpenAPI document\n- \\`lib/openapi.ts\\` OpenAPI document generation\n\n## Generated artifacts\n\n- \\`.tango/\\` generated relation typing artifacts; regenerate through \\`make:migrations\\` or \\`codegen:relations\\`\n- \\`migrations/\\` checked-in Tango migrations; review them like source, but let Tango generate the files\n\n## Utility surface\n\n- \\`scripts/bootstrap.ts\\` sample seed utility; keep it if it helps your app, or replace it once your own seed flow exists\n`;\n }\n}\n","import { FrameworkScaffoldStrategy } from '../../contracts/FrameworkScaffoldStrategy';\nimport { TemplateBuilder } from '../../contracts/template/TemplateBuilder';\nimport type { ScaffoldTemplate } from '../../contracts/template/ScaffoldTemplate';\nimport { PackageJsonTemplateBuilder } from './templates/packageJson';\nimport { TsConfigTemplateBuilder } from './templates/tsconfig';\nimport { NuxtConfigTemplateBuilder } from './templates/nuxtConfig';\nimport { TodoModelTemplateBuilder, ModelsBarrelTemplateBuilder } from './templates/models';\nimport { TodoSerializerTemplateBuilder, SerializersBarrelTemplateBuilder } from './templates/serializers';\nimport { OpenAPITemplateBuilder } from './templates/openapi';\nimport { ViewSetTemplateBuilder } from './templates/viewSet';\nimport { PageTemplateBuilder } from './templates/page';\nimport { AppShellTemplateBuilder } from './templates/layout';\nimport { HealthRouteTemplateBuilder } from './templates/healthRoute';\nimport { TodoRouteTemplateBuilder } from './templates/todoRoute';\nimport { OpenAPIRouteTemplateBuilder } from './templates/openapiRoute';\nimport { BootstrapTemplateBuilder } from './templates/bootstrap';\nimport { TangoConfigTemplateBuilder } from './templates/tangoConfig';\nimport { ReadmeTemplateBuilder } from './templates/readme';\n\n/**\n * Scaffold strategy for creating a Nuxt-hosted Tango project.\n */\nexport class NuxtScaffoldStrategy extends FrameworkScaffoldStrategy {\n readonly id = 'nuxt' as const;\n\n readonly name = 'Nuxt';\n\n readonly description = 'Bootstrap a Tango application hosted by Nuxt Nitro and SSR pages.';\n\n /**\n * Return the file templates needed for the generated Nuxt project.\n */\n getTemplates(): readonly ScaffoldTemplate[] {\n return [\n this.addFrameworkTemplate(new PackageJsonTemplateBuilder()),\n this.addFrameworkTemplate(new NuxtConfigTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigTemplateBuilder()),\n this.addFrameworkTemplate(new AppShellTemplateBuilder()),\n this.addFrameworkTemplate(new PageTemplateBuilder()),\n this.addTangoTemplate(new TangoConfigTemplateBuilder()),\n this.addTangoTemplate(new TodoModelTemplateBuilder()),\n this.addTangoTemplate(new ModelsBarrelTemplateBuilder()),\n this.addTangoTemplate(new TodoSerializerTemplateBuilder()),\n this.addTangoTemplate(new SerializersBarrelTemplateBuilder()),\n this.addTangoTemplate(new OpenAPITemplateBuilder()),\n this.addTangoTemplate(new ViewSetTemplateBuilder()),\n this.addTangoTemplate(new HealthRouteTemplateBuilder()),\n this.addTangoTemplate(new OpenAPIRouteTemplateBuilder()),\n this.addTangoTemplate(new TodoRouteTemplateBuilder()),\n this.addTangoTemplate(new BootstrapTemplateBuilder()),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('migrations/.gitkeep', '')),\n this.addFrameworkTemplate(new ReadmeTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate('.gitignore', 'node_modules\\n.nuxt\\n.output\\n.data\\n.env\\n')\n ),\n ];\n }\n}\n","import { FrameworkScaffoldStrategy, type SupportedFramework } from '../contracts/FrameworkScaffoldStrategy';\nimport { ExpressScaffoldStrategy } from '../strategies/express/ExpressScaffoldStrategy';\nimport { NextScaffoldStrategy } from '../strategies/next/NextScaffoldStrategy';\nimport { NuxtScaffoldStrategy } from '../strategies/nuxt/NuxtScaffoldStrategy';\n\n/**\n * Registry for framework scaffolding strategies keyed by framework id.\n */\nexport class FrameworkScaffoldRegistry {\n private readonly strategies = new Map<SupportedFramework, FrameworkScaffoldStrategy>();\n\n /**\n * Create a registry preloaded with Tango's built-in framework scaffolds.\n */\n static createDefault(): FrameworkScaffoldRegistry {\n const registry = new FrameworkScaffoldRegistry();\n registry.register(new ExpressScaffoldStrategy());\n registry.register(new NextScaffoldStrategy());\n registry.register(new NuxtScaffoldStrategy());\n return registry;\n }\n\n /**\n * Register a strategy under its declared framework id.\n */\n register(strategy: FrameworkScaffoldStrategy): void {\n const existing = this.strategies.get(strategy.id);\n if (existing) {\n throw new Error(`Framework scaffold strategy '${strategy.id}' is already registered.`);\n }\n this.strategies.set(strategy.id, strategy);\n }\n\n /**\n * Resolve a strategy for a known framework id.\n */\n get(id: SupportedFramework): FrameworkScaffoldStrategy | undefined {\n return this.strategies.get(id);\n }\n\n /**\n * List all registered framework strategies in registration order.\n */\n list(): readonly FrameworkScaffoldStrategy[] {\n return [...this.strategies.values()];\n }\n}\n","import { mkdir, readdir, stat, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport type { FrameworkScaffoldStrategy } from '../contracts/FrameworkScaffoldStrategy';\nimport type { FrameworkScaffoldContext, ScaffoldMode } from '../contracts/template/ScaffoldTemplate';\n\nexport type ScaffoldProjectOptions = {\n force?: boolean;\n /** 'new' = full scaffold; 'init' = only Tango + init-only files. Default 'new'. */\n mode?: ScaffoldMode;\n /** When true, do not overwrite existing files. Default true when mode === 'init', otherwise false. */\n skipExisting?: boolean;\n};\n\nfunction resolveTargetDir(targetDir: string): string {\n if (isAbsolute(targetDir)) {\n return targetDir;\n }\n return resolve(process.cwd(), targetDir);\n}\n\nasync function ensureWritableTargetDir(\n targetDir: string,\n options: ScaffoldProjectOptions & { mode: ScaffoldMode }\n): Promise<void> {\n const absoluteTargetDir = resolveTargetDir(targetDir);\n\n try {\n const targetStats = await stat(absoluteTargetDir);\n if (!targetStats.isDirectory()) {\n throw new Error(`Target path '${absoluteTargetDir}' exists and is not a directory.`);\n }\n\n if (options.mode === 'new') {\n const contents = await readdir(absoluteTargetDir);\n if (contents.length > 0 && !options.force) {\n throw new Error(\n `Target directory '${absoluteTargetDir}' is not empty. Pass --force to allow scaffolding into a non-empty directory.`\n );\n }\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n await mkdir(absoluteTargetDir, { recursive: true });\n return;\n }\n throw error;\n }\n}\n\n/**\n * Write a framework scaffold into a target directory after basic safety checks.\n *\n * The selected strategy controls which files are created, while this helper\n * owns directory validation and filesystem writes. With mode 'init', only\n * Tango and init-only templates are emitted, and existing files can be skipped.\n */\nexport async function scaffoldProject(\n context: FrameworkScaffoldContext,\n strategy: FrameworkScaffoldStrategy,\n options: ScaffoldProjectOptions = {}\n): Promise<void> {\n const mode = options.mode ?? 'new';\n const skipExisting = options.skipExisting ?? mode === 'init';\n const resolvedOptions = { ...options, mode, skipExisting };\n\n await ensureWritableTargetDir(context.targetDir, resolvedOptions);\n\n const allTemplates = strategy.getTemplates();\n const templates = allTemplates.filter((t) => t.shouldEmit(mode));\n\n for (const template of templates) {\n const absolutePath = resolveTargetDir(resolve(context.targetDir, template.path));\n if (skipExisting && !options.force) {\n try {\n await stat(absolutePath);\n continue;\n } catch {\n // ENOENT or other: proceed to write\n }\n }\n await mkdir(dirname(absolutePath), { recursive: true });\n await writeFile(absolutePath, template.render(context), 'utf8');\n }\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport {\n type FrameworkScaffoldContext,\n type ScaffoldMode,\n type ScaffoldTemplate,\n type ScaffoldTemplateCategory,\n SCAFFOLD_TEMPLATE_CATEGORY,\n} from './contracts/template/ScaffoldTemplate';\nexport type {\n PackageManager,\n ScaffoldDatabaseDialect as ScaffoldDialect,\n SupportedFramework,\n} from './contracts/FrameworkScaffoldStrategy';\nexport { FrameworkScaffoldStrategy } from './contracts/FrameworkScaffoldStrategy';\nexport { ScaffoldTemplateDescriptor } from './contracts/template/implementation/ScaffoldTemplateDescriptor';\nexport { FrameworkScaffoldRegistry } from './registry/FrameworkScaffoldRegistry';\nexport { ExpressScaffoldStrategy } from './strategies/express/ExpressScaffoldStrategy';\nexport { NextScaffoldStrategy } from './strategies/next/NextScaffoldStrategy';\nexport { NuxtScaffoldStrategy } from './strategies/nuxt/NuxtScaffoldStrategy';\nexport { scaffoldProject, type ScaffoldProjectOptions } from './scaffold/scaffoldProject';\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { domain_exports } from "./domain-Cufz6y1q.js";
|
|
2
2
|
import { generateMigrationFromModels, generateModelInterface, generateViewSet, generators_exports, mapFieldTypeToTS, mappers_exports, normalizeFields } from "./generators-DuAuGNR2.js";
|
|
3
3
|
import { generateRelationRegistryArtifacts, writeRelationRegistryArtifacts } from "./relations-DqDEZ6MV.js";
|
|
4
|
-
import { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, NextScaffoldStrategy, NuxtScaffoldStrategy, frameworks_exports, scaffoldProject } from "./frameworks-
|
|
4
|
+
import { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, NextScaffoldStrategy, NuxtScaffoldStrategy, frameworks_exports, scaffoldProject } from "./frameworks-BQp-rqXU.js";
|
|
5
5
|
import { commands_exports, loadProjectModule, registerCodegenCommands, runGenerateRelationsCommand } from "./commands-CFAq4wXC.js";
|
|
6
6
|
|
|
7
7
|
export { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, NextScaffoldStrategy, NuxtScaffoldStrategy, commands_exports as commands, domain_exports as domain, frameworks_exports as frameworks, generateMigrationFromModels, generateModelInterface, generateRelationRegistryArtifacts, generateViewSet, generators_exports as generators, loadProjectModule, mapFieldTypeToTS, mappers_exports as mappers, normalizeFields, registerCodegenCommands, runGenerateRelationsCommand, scaffoldProject, writeRelationRegistryArtifacts };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danceroutine/tango-codegen",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "CLI for generating repositories, types, migrations, and OpenAPI specs for Tango",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"jiti": "^2.6.1",
|
|
49
49
|
"yargs": "^17.7.2",
|
|
50
|
-
"@danceroutine/tango-core": "1.10.
|
|
51
|
-
"@danceroutine/tango-schema": "1.10.
|
|
50
|
+
"@danceroutine/tango-core": "1.10.1",
|
|
51
|
+
"@danceroutine/tango-schema": "1.10.1"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/yargs": "^17.0.33",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"typescript": "^5.6.3",
|
|
58
58
|
"vitest": "^4.0.6",
|
|
59
59
|
"zod": "^4.0.0",
|
|
60
|
-
"@danceroutine/tango-testing": "1.10.
|
|
60
|
+
"@danceroutine/tango-testing": "1.10.1"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "tsdown",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"frameworks-DfgUTyLt.js","names":["template: TemplateBuilder","category: ScaffoldTemplateCategory","ctx: FrameworkScaffoldContext","mode: ScaffoldMode","options: { name: string }","packageManager: string","dialect: 'sqlite' | 'postgres'","framework: 'express' | 'next' | 'nuxt'","fileName: string","template: string | (() => string)","_context: FrameworkScaffoldContext","core: Record<string, string>","adapter: Record<string, string>","dialectDeps: Record<string, string>","context: FrameworkScaffoldContext","packageManager: PackageManager","context: FrameworkScaffoldContext","template: TemplateBuilder","category: ScaffoldTemplateCategory","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","_context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","context: FrameworkScaffoldContext","strategy: FrameworkScaffoldStrategy","id: SupportedFramework","targetDir: string","options: ScaffoldProjectOptions & { mode: ScaffoldMode }","context: FrameworkScaffoldContext","strategy: FrameworkScaffoldStrategy","options: ScaffoldProjectOptions"],"sources":["../src/frameworks/contracts/template/ScaffoldTemplate.ts","../src/frameworks/contracts/template/implementation/ScaffoldTemplateDescriptor.ts","../package.json","../src/frameworks/contracts/template/TemplateBuilder.ts","../src/frameworks/contracts/FrameworkScaffoldStrategy.ts","../src/frameworks/strategies/express/templates/packageJson.ts","../src/frameworks/strategies/express/templates/tsconfig.ts","../src/frameworks/strategies/express/templates/tsconfigBuild.ts","../src/frameworks/strategies/express/templates/tangoConfig.ts","../src/frameworks/strategies/express/templates/appSource.ts","../src/frameworks/strategies/express/templates/models.ts","../src/frameworks/strategies/express/templates/serializers.ts","../src/frameworks/strategies/express/templates/openapi.ts","../src/frameworks/strategies/express/templates/viewSet.ts","../src/frameworks/strategies/express/templates/bootstrap.ts","../src/frameworks/strategies/express/templates/readme.ts","../src/frameworks/strategies/express/templates/tangoRegister.ts","../src/frameworks/strategies/express/ExpressScaffoldStrategy.ts","../src/frameworks/strategies/next/templates/packageJson.ts","../src/frameworks/strategies/next/templates/tsconfig.ts","../src/frameworks/strategies/next/templates/tangoConfig.ts","../src/frameworks/strategies/next/templates/models.ts","../src/frameworks/strategies/next/templates/serializers.ts","../src/frameworks/strategies/next/templates/openapi.ts","../src/frameworks/strategies/next/templates/viewSet.ts","../src/frameworks/strategies/next/templates/page.ts","../src/frameworks/strategies/next/templates/layout.ts","../src/frameworks/strategies/next/templates/healthRoute.ts","../src/frameworks/strategies/next/templates/todoRoute.ts","../src/frameworks/strategies/next/templates/openapiRoute.ts","../src/frameworks/strategies/next/templates/bootstrap.ts","../src/frameworks/strategies/next/templates/readme.ts","../src/frameworks/strategies/next/NextScaffoldStrategy.ts","../src/frameworks/strategies/nuxt/templates/packageJson.ts","../src/frameworks/strategies/nuxt/templates/tsconfig.ts","../src/frameworks/strategies/nuxt/templates/nuxtConfig.ts","../src/frameworks/strategies/nuxt/templates/models.ts","../src/frameworks/strategies/nuxt/templates/serializers.ts","../src/frameworks/strategies/nuxt/templates/openapi.ts","../src/frameworks/strategies/nuxt/templates/viewSet.ts","../src/frameworks/strategies/nuxt/templates/page.ts","../src/frameworks/strategies/nuxt/templates/layout.ts","../src/frameworks/strategies/nuxt/templates/healthRoute.ts","../src/frameworks/strategies/nuxt/templates/todoRoute.ts","../src/frameworks/strategies/nuxt/templates/openapiRoute.ts","../src/frameworks/strategies/nuxt/templates/bootstrap.ts","../src/frameworks/strategies/nuxt/templates/tangoConfig.ts","../src/frameworks/strategies/nuxt/templates/readme.ts","../src/frameworks/strategies/nuxt/NuxtScaffoldStrategy.ts","../src/frameworks/registry/FrameworkScaffoldRegistry.ts","../src/frameworks/scaffold/scaffoldProject.ts","../src/frameworks/index.ts"],"sourcesContent":["import type { SupportedFramework, PackageManager, ScaffoldDatabaseDialect } from '../FrameworkScaffoldStrategy';\n\nexport const SCAFFOLD_TEMPLATE_CATEGORY = {\n FRAMEWORK: 'framework',\n TANGO: 'tango',\n INIT_ONLY: 'init-only',\n} as const;\nexport type ScaffoldTemplateCategory = (typeof SCAFFOLD_TEMPLATE_CATEGORY)[keyof typeof SCAFFOLD_TEMPLATE_CATEGORY];\n\nexport type ScaffoldMode = 'new' | 'init';\n\nexport type FrameworkScaffoldContext = {\n projectName: string;\n targetDir: string;\n framework: SupportedFramework;\n packageManager: PackageManager;\n dialect: ScaffoldDatabaseDialect;\n includeSeed: boolean;\n};\n\nexport interface ScaffoldTemplate {\n readonly path: string;\n readonly category: ScaffoldTemplateCategory;\n render(ctx: FrameworkScaffoldContext): string;\n shouldEmit(mode: ScaffoldMode): boolean;\n}\n","import {\n type ScaffoldTemplate,\n type ScaffoldTemplateCategory,\n type FrameworkScaffoldContext,\n type ScaffoldMode,\n SCAFFOLD_TEMPLATE_CATEGORY,\n} from '../ScaffoldTemplate';\nimport type { TemplateBuilder } from '../TemplateBuilder';\n\nexport class ScaffoldTemplateDescriptor implements ScaffoldTemplate {\n constructor(\n readonly template: TemplateBuilder,\n readonly category: ScaffoldTemplateCategory\n ) {}\n public get path(): string {\n return this.template.getPath();\n }\n\n render(ctx: FrameworkScaffoldContext): string {\n return this.template.setContext(ctx).build();\n }\n\n shouldEmit(mode: ScaffoldMode): boolean {\n if (mode === 'new') {\n return (\n this.category === SCAFFOLD_TEMPLATE_CATEGORY.FRAMEWORK ||\n this.category === SCAFFOLD_TEMPLATE_CATEGORY.TANGO\n );\n }\n return (\n this.category === SCAFFOLD_TEMPLATE_CATEGORY.TANGO || this.category === SCAFFOLD_TEMPLATE_CATEGORY.INIT_ONLY\n );\n }\n}\n","({\n \"name\": \"@danceroutine/tango-codegen\",\n \"version\": \"1.10.0\",\n \"description\": \"CLI for generating repositories, types, migrations, and OpenAPI specs for Tango\",\n \"type\": \"module\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./domain\": {\n \"types\": \"./dist/domain/index.d.ts\",\n \"import\": \"./dist/domain/index.js\"\n },\n \"./generators\": {\n \"types\": \"./dist/generators/index.d.ts\",\n \"import\": \"./dist/generators/index.js\"\n },\n \"./frameworks\": {\n \"types\": \"./dist/frameworks/index.d.ts\",\n \"import\": \"./dist/frameworks/index.js\"\n },\n \"./commands\": {\n \"types\": \"./dist/commands/index.d.ts\",\n \"import\": \"./dist/commands/index.js\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsdown\",\n \"test\": \"vitest run --coverage\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"pnpm run typecheck:prod && pnpm run typecheck:test\",\n \"typecheck:prod\": \"tsc --noEmit -p tsconfig.json\",\n \"typecheck:test\": \"tsc --noEmit -p tsconfig.tests.json\"\n },\n \"keywords\": [\n \"tango\",\n \"codegen\",\n \"cli\",\n \"generator\",\n \"migrations\"\n ],\n \"author\": \"Pedro Del Moral Lopez\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/danceroutine/tango.git\",\n \"directory\": \"packages/codegen\"\n },\n \"dependencies\": {\n \"@danceroutine/tango-core\": \"workspace:*\",\n \"@danceroutine/tango-schema\": \"workspace:*\",\n \"jiti\": \"^2.6.1\",\n \"yargs\": \"^17.7.2\"\n },\n \"devDependencies\": {\n \"@danceroutine/tango-testing\": \"workspace:*\",\n \"@types/yargs\": \"^17.0.33\",\n \"@types/node\": \"^22.9.0\",\n \"tsdown\": \"^0.4.0\",\n \"typescript\": \"^5.6.3\",\n \"vitest\": \"^4.0.6\",\n \"zod\": \"^4.0.0\"\n }\n}\n)","import packageJson from '../../../../package.json';\nimport type { FrameworkScaffoldContext } from './ScaffoldTemplate';\n\nconst { version } = packageJson as { version: string };\n\n/**\n * Interface for a context-bound template that the strategy's add* methods accept.\n * Implemented by bound TemplateBuilder instances and by the return value of createStaticTemplate.\n */\nexport interface BoundTemplate {\n getPath(): string;\n build(): string;\n}\n\n/**\n * Base class for scaffold template builders. Subclasses override resolveTemplate().\n * Use new WhateverBuilder().setContext(context) for registration with add* methods.\n * Deps logic (getTangoDependencyEntries, getTangoDevDependencyEntries) and version live here.\n */\nexport abstract class TemplateBuilder implements BoundTemplate {\n protected readonly name: string;\n protected _context?: FrameworkScaffoldContext;\n\n constructor(options: { name: string }) {\n this.name = options.name;\n }\n\n /**\n * One-liner to install Tango + dialect deps and Tango CLI (for init success message).\n */\n static getTangoInstallOneLiner(\n packageManager: string,\n dialect: 'sqlite' | 'postgres',\n framework: 'express' | 'next' | 'nuxt'\n ): string {\n const deps = TemplateBuilder.getTangoDependencyEntriesFor(dialect, framework);\n const devDeps = TemplateBuilder.getTangoDevDependencyEntriesFor();\n const depList = Object.entries(deps)\n .map(([pkg, ver]) => `${pkg}@${ver}`)\n .join(' ');\n const devList = Object.entries(devDeps)\n .map(([pkg, ver]) => `${pkg}@${ver}`)\n .join(' ');\n const addCmd = packageManager === 'npm' ? 'npm install' : `${packageManager} add`;\n const addDevCmd = packageManager === 'npm' ? 'npm install -D' : `${packageManager} add -D`;\n return `${addCmd} ${depList} && ${addDevCmd} ${devList}`;\n }\n\n /**\n * Shorthand for static content (no subclass needed). Returns a BoundTemplate that add* methods accept.\n */\n static createStaticTemplate(fileName: string, template: string | (() => string)): TemplateBuilder {\n class TransientStaticTemplateBuilder extends TemplateBuilder {\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return typeof template === 'string' ? template : template();\n }\n }\n return new TransientStaticTemplateBuilder({ name: fileName });\n }\n\n /** Tango package version (semver range) for scaffolded dependency entries. */\n private static getTangoVersion(): string {\n return `^${version}`;\n }\n\n private static getTangoDependencyEntriesFor(\n dialect: 'sqlite' | 'postgres',\n framework: 'express' | 'next' | 'nuxt'\n ): Record<string, string> {\n const v = TemplateBuilder.getTangoVersion();\n const core: Record<string, string> = {\n '@danceroutine/tango-core': v,\n '@danceroutine/tango-schema': v,\n '@danceroutine/tango-orm': v,\n '@danceroutine/tango-resources': v,\n '@danceroutine/tango-migrations': v,\n '@danceroutine/tango-openapi': v,\n '@danceroutine/tango-config': v,\n };\n const adapter: Record<string, string> =\n framework === 'express'\n ? { '@danceroutine/tango-adapters-express': v }\n : framework === 'next'\n ? { '@danceroutine/tango-adapters-next': v }\n : { '@danceroutine/tango-adapters-nuxt': v };\n const dialectDeps: Record<string, string> =\n dialect === 'sqlite' ? { 'better-sqlite3': '^11.10.0' } : { pg: '^8.16.3' };\n return { ...core, ...adapter, ...dialectDeps };\n }\n\n private static getTangoDevDependencyEntriesFor(): Record<string, string> {\n return { '@danceroutine/tango-cli': TemplateBuilder.getTangoVersion() };\n }\n\n /** Bind context and return this for chaining. Use before passing to add* methods. */\n setContext(context: FrameworkScaffoldContext): this {\n this._context = context;\n return this;\n }\n\n getPath(): string {\n return this.name;\n }\n\n protected abstract resolveTemplate(context: FrameworkScaffoldContext): string;\n\n build(): string {\n if (this._context === undefined) {\n throw new Error('TemplateBuilder: context not bound. Call .setContext(context) before .build().');\n }\n return this.resolveTemplate(this._context);\n }\n\n protected getTangoDependencyEntries(context: FrameworkScaffoldContext): Record<string, string> {\n return TemplateBuilder.getTangoDependencyEntriesFor(context.dialect, context.framework);\n }\n\n protected getTangoDevDependencyEntries(_context: FrameworkScaffoldContext): Record<string, string> {\n return TemplateBuilder.getTangoDevDependencyEntriesFor();\n }\n}\n","import {\n SCAFFOLD_TEMPLATE_CATEGORY,\n type ScaffoldTemplate,\n type ScaffoldTemplateCategory,\n type FrameworkScaffoldContext,\n} from './template/ScaffoldTemplate';\nimport { ScaffoldTemplateDescriptor } from './template/implementation/ScaffoldTemplateDescriptor';\nimport { TemplateBuilder } from './template/TemplateBuilder';\n\nexport const SUPPORTED_FRAMEWORK = {\n EXPRESS: 'express',\n NEXT: 'next',\n NUXT: 'nuxt',\n} as const;\nexport type SupportedFramework = (typeof SUPPORTED_FRAMEWORK)[keyof typeof SUPPORTED_FRAMEWORK];\n\nexport const PACKAGE_MANAGER = {\n PNPM: 'pnpm',\n NPM: 'npm',\n YARN: 'yarn',\n BUN: 'bun',\n} as const;\nexport type PackageManager = (typeof PACKAGE_MANAGER)[keyof typeof PACKAGE_MANAGER];\n\nexport const SCAFFOLD_DATABASE_DIALECT = {\n SQLITE: 'sqlite',\n POSTGRES: 'postgres',\n} as const;\nexport type ScaffoldDatabaseDialect = (typeof SCAFFOLD_DATABASE_DIALECT)[keyof typeof SCAFFOLD_DATABASE_DIALECT];\n\n/**\n * Base scaffold strategy contract and helpers for Tango framework scaffolds.\n *\n * Concrete strategies extend this class and assemble their template lists\n * through the protected helpers below.\n */\nexport abstract class FrameworkScaffoldStrategy {\n abstract readonly id: SupportedFramework;\n abstract readonly name: string;\n abstract readonly description: string;\n\n /**\n * One-liner to install Tango + dialect deps and Tango CLI, for init success message.\n */\n getTangoInstallOneLiner(packageManager: PackageManager, context: FrameworkScaffoldContext): string {\n return TemplateBuilder.getTangoInstallOneLiner(packageManager, context.dialect, context.framework);\n }\n\n abstract getTemplates(): readonly ScaffoldTemplate[];\n\n protected addFrameworkTemplate(template: TemplateBuilder): ScaffoldTemplate {\n return this.createTemplate(template, SCAFFOLD_TEMPLATE_CATEGORY.FRAMEWORK);\n }\n\n protected addTangoTemplate(template: TemplateBuilder): ScaffoldTemplate {\n return this.createTemplate(template, SCAFFOLD_TEMPLATE_CATEGORY.TANGO);\n }\n\n protected addInitOnlyTemplate(template: TemplateBuilder): ScaffoldTemplate {\n return this.createTemplate(template, SCAFFOLD_TEMPLATE_CATEGORY.INIT_ONLY);\n }\n\n private createTemplate(template: TemplateBuilder, category: ScaffoldTemplateCategory): ScaffoldTemplate {\n return new ScaffoldTemplateDescriptor(template, category);\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PackageJsonTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'package.json' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const deps = this.getTangoDependencyEntries(context);\n const devDeps = this.getTangoDevDependencyEntries(context);\n\n return JSON.stringify(\n {\n name: context.projectName,\n private: true,\n type: 'module',\n scripts: {\n predev: 'tango migrate --config ./tango.config.ts',\n dev: 'tsx watch src/index.ts',\n prestart: 'tango migrate --config ./tango.config.ts',\n build: 'tsc -p tsconfig.build.json',\n start: 'node dist/index.js',\n typecheck: 'tsc --noEmit',\n 'setup:schema':\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n 'make:migrations':\n 'tango make:migrations --config ./tango.config.ts --models ./src/models/index.ts',\n 'codegen:relations': 'tango codegen relations --models ./src/models/index.ts',\n prebootstrap:\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n bootstrap: 'tsx src/bootstrap.ts',\n },\n dependencies: {\n ...deps,\n express: '^4.21.2',\n zod: '^4.0.0',\n },\n devDependencies: {\n ...devDeps,\n '@types/express': '^5.0.0',\n '@types/node': '^22.9.0',\n tsx: '^4.20.6',\n typescript: '^5.6.3',\n },\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n lib: ['ES2022', 'DOM'],\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n strict: true,\n noEmit: true,\n esModuleInterop: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n types: ['node'],\n },\n include: ['src', 'migrations/**/*.ts', 'tango.config.ts', '.tango/**/*.d.ts'],\n exclude: ['node_modules', 'dist'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigBuildTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.build.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n extends: './tsconfig.json',\n compilerOptions: {\n noEmit: false,\n outDir: './dist',\n rootDir: '.',\n sourceMap: true,\n declaration: false,\n },\n include: ['src', 'tango.config.ts'],\n exclude: ['node_modules', 'dist', 'migrations', '**/*.test.ts'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tango.config.ts' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n if (context.dialect === 'sqlite') {\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || ':memory:',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n },\n});\n`;\n }\n\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 10,\n },\n migrations: { dir: './migrations', online: true },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}_test',\n maxConnections: 5,\n },\n migrations: { dir: './migrations', online: true },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 20,\n },\n migrations: { dir: './migrations', online: true },\n },\n },\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class AppSourceTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import express from 'express';\nimport { seedExampleData } from './bootstrap.js';\nimport { registerTango } from './tango.js';\n\nasync function main(): Promise<void> {\n const app = express();\n app.use(express.json());\n\n if (process.env.AUTO_BOOTSTRAP === 'true') {\n await seedExampleData(Number(process.env.SEED_TODOS_COUNT || '100'));\n }\n\n app.get('/health', (_req, res) => {\n res.json({ ok: true });\n });\n\n await registerTango(app);\n\n const port = Number(process.env.PORT || '3000');\n app.listen(port, () => {\n console.log(\\`Tango Express app listening on http://localhost:\\${String(port)}\\`);\n });\n}\n\n// oxlint-disable-next-line unicorn/prefer-top-level-await\nmain().catch((error: unknown) => {\n console.error('Failed to start app:', error);\n process.exit(1);\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoModelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/models/TodoModel.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { z } from 'zod';\nimport '@danceroutine/tango-orm/runtime';\nimport { Model, t } from '@danceroutine/tango-schema';\n\nexport const TodoReadSchema = z.object({\n id: z.number(),\n title: z.string().min(1),\n completed: z.coerce.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nexport const TodoCreateSchema = z.object({\n title: z.string().min(1),\n completed: z.boolean().optional().default(false),\n});\n\nexport const TodoUpdateSchema = TodoCreateSchema.partial();\n\nexport type Todo = z.output<typeof TodoReadSchema>;\n\nexport const TodoModel = Model({\n namespace: 'app',\n name: 'Todo',\n schema: TodoReadSchema.extend({\n id: t.primaryKey(z.number().int()),\n title: z.string().min(1),\n completed: t.field(z.coerce.boolean()).defaultValue('false').build(),\n createdAt: t.field(z.string()).defaultValue({ now: true }).build(),\n updatedAt: t.field(z.string()).defaultValue({ now: true }).build(),\n }),\n});\n`;\n }\n}\n\nexport class ModelsBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/models/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoReadSchema, TodoCreateSchema, TodoUpdateSchema, TodoModel, type Todo } from './TodoModel.js';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoSerializerTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/TodoSerializer.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { ModelSerializer } from '@danceroutine/tango-resources';\nimport { TodoCreateSchema, TodoModel, TodoReadSchema, TodoUpdateSchema, type Todo } from '../models/index.js';\n\nexport class TodoSerializer extends ModelSerializer<\n Todo,\n typeof TodoCreateSchema,\n typeof TodoUpdateSchema,\n typeof TodoReadSchema\n> {\n static readonly model = TodoModel;\n static readonly createSchema = TodoCreateSchema;\n static readonly updateSchema = TodoUpdateSchema;\n static readonly outputSchema = TodoReadSchema;\n}\n`;\n }\n}\n\nexport class SerializersBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoSerializer } from './TodoSerializer.js';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPITemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { describeViewSet, generateOpenAPISpec, type OpenAPISpec } from '@danceroutine/tango-openapi';\nimport { TodoViewSet } from './viewsets/TodoViewSet.js';\n\nexport function createOpenAPISpec(): OpenAPISpec {\n return generateOpenAPISpec({\n title: 'Tango Express Todo API',\n version: '1.0.0',\n description: 'OpenAPI document generated from Tango resource instances.',\n resources: [describeViewSet({ basePath: '/api/todos', resource: new TodoViewSet() })],\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ViewSetTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/viewsets/TodoViewSet.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { FilterSet, ModelViewSet } from '@danceroutine/tango-resources';\nimport { type Todo } from '../models/index.js';\nimport { TodoSerializer } from '../serializers/index.js';\n\nexport class TodoViewSet extends ModelViewSet<Todo, typeof TodoSerializer> {\n constructor() {\n super({\n serializer: TodoSerializer,\n filters: FilterSet.define<Todo>({\n fields: {\n completed: true,\n },\n aliases: {\n q: { fields: ['title'], lookup: 'icontains' },\n },\n }),\n orderingFields: ['id', 'createdAt', 'updatedAt', 'title'],\n searchFields: ['title'],\n });\n }\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class BootstrapTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/bootstrap.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { TodoModel, type Todo } from './models/index.js';\n\nexport async function seedExampleData(count = 100): Promise<void> {\n const existing = await TodoModel.objects.query().count();\n if (existing >= count) {\n console.log(\\`[bootstrap] Skipped; already have \\${existing} todos.\\`);\n return;\n }\n\n const rows: Array<Partial<Todo>> = [];\n for (let index = existing; index < count; index += 1) {\n const now = new Date(Date.now() - index * 60_000).toISOString();\n rows.push({\n title: \\`Seeded todo #\\${index + 1}\\`,\n completed: index % 3 === 0,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n await TodoModel.objects.bulkCreate(rows);\n console.log(\\`[bootstrap] Seeded \\${rows.length} todos.\\`);\n}\n\nif (import.meta.url === \\`file://\\${process.argv[1]}\\`) {\n const count = Number(process.env.SEED_TODOS_COUNT || '100');\n // oxlint-disable-next-line unicorn/prefer-top-level-await\n seedExampleData(Number.isFinite(count) ? count : 100).catch((error: unknown) => {\n console.error('[bootstrap] Failed:', error);\n process.exit(1);\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ReadmeTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'README.md' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n return `# ${context.projectName}\n\nThis project was scaffolded by \\`tango new --framework express\\`.\n\nExpress still owns the server and route registration; Tango owns model metadata, \\`Model.objects\\`, serializers, migrations, querying, and resource behavior.\n\n## First-time setup\n\nGenerate your first migration from the scaffolded models, then start the app:\n\n\\`\\`\\`bash\n${context.packageManager} run make:migrations -- --name initial\n${context.packageManager} run dev\n\\`\\`\\`\n\n\\`make:migrations\\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \\`${context.packageManager} run codegen:relations\\`.\n\nWhen you run the package script, pass Tango flags after \\`--\\` so the script forwards them to the CLI unchanged.\n\n## Scripts\n\n- \\`${context.packageManager} run dev\\`\n- \\`${context.packageManager} run make:migrations -- --name add_field\\`\n- \\`${context.packageManager} run codegen:relations\\`\n- \\`${context.packageManager} run setup:schema\\`\n- \\`${context.packageManager} run bootstrap\\`\n- \\`${context.packageManager} run typecheck\\`\n\n## Useful endpoints\n\n- \\`GET /health\\`\n- \\`GET /api/openapi.json\\`\n- \\`GET|POST|PATCH|DELETE /api/todos...\\`\n\n## Project layout\n\n- \\`tango.config.ts\\` Tango configuration\n- \\`src/tango.ts\\` Express registration helper for Tango routes\n- \\`src/models/\\` schemas and Tango model metadata; importing the model module enables \\`Model.objects\\`\n- \\`src/serializers/\\` serializer-backed API contracts for Tango resources\n- \\`src/viewsets/\\` CRUD resources backed by \\`Model.objects\\`\n- \\`src/openapi.ts\\` OpenAPI document generation\n- \\`src/bootstrap.ts\\` seed utility for a larger demo dataset\n- \\`migrations/\\` checked-in Tango migrations\n- \\`.tango/\\` generated relation typing artifacts\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoRegisterTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/tango.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import type { Application } from 'express';\nimport { ExpressAdapter } from '@danceroutine/tango-adapters-express/adapter';\nimport { createOpenAPISpec } from './openapi.js';\nimport { TodoViewSet } from './viewsets/TodoViewSet.js';\n\n/**\n * Register Tango API routes and OpenAPI spec on an existing Express app.\n * Use from your app entry (for example, \\`index.ts\\`): \\`await registerTango(app);\\`\n */\nexport async function registerTango(app: Application): Promise<void> {\n const adapter = new ExpressAdapter();\n adapter.registerViewSet(app, '/api/todos', new TodoViewSet());\n app.get('/api/openapi.json', (_req, res) => {\n res.json(createOpenAPISpec());\n });\n}\n`;\n }\n}\n","import { FrameworkScaffoldStrategy } from '../../contracts/FrameworkScaffoldStrategy';\nimport { TemplateBuilder } from '../../contracts/template/TemplateBuilder';\nimport type { ScaffoldTemplate } from '../../contracts/template/ScaffoldTemplate';\nimport { PackageJsonTemplateBuilder } from './templates/packageJson';\nimport { TsConfigTemplateBuilder } from './templates/tsconfig';\nimport { TsConfigBuildTemplateBuilder } from './templates/tsconfigBuild';\nimport { TangoConfigTemplateBuilder } from './templates/tangoConfig';\nimport { AppSourceTemplateBuilder } from './templates/appSource';\nimport { TodoModelTemplateBuilder, ModelsBarrelTemplateBuilder } from './templates/models';\nimport { TodoSerializerTemplateBuilder, SerializersBarrelTemplateBuilder } from './templates/serializers';\nimport { OpenAPITemplateBuilder } from './templates/openapi';\nimport { ViewSetTemplateBuilder } from './templates/viewSet';\nimport { BootstrapTemplateBuilder } from './templates/bootstrap';\nimport { ReadmeTemplateBuilder } from './templates/readme';\nimport { TangoRegisterTemplateBuilder } from './templates/tangoRegister';\n\n/**\n * Scaffold strategy for creating an Express-hosted Tango project.\n */\nexport class ExpressScaffoldStrategy extends FrameworkScaffoldStrategy {\n readonly id = 'express' as const;\n\n readonly name = 'Express';\n\n readonly description = 'Bootstrap a Tango application hosted by Express.';\n\n /**\n * Return the file templates needed for the generated Express project.\n */\n getTemplates(): readonly ScaffoldTemplate[] {\n return [\n this.addFrameworkTemplate(new PackageJsonTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigBuildTemplateBuilder()),\n this.addTangoTemplate(new TangoConfigTemplateBuilder()),\n this.addFrameworkTemplate(new AppSourceTemplateBuilder()),\n this.addTangoTemplate(new TodoModelTemplateBuilder()),\n this.addTangoTemplate(new ModelsBarrelTemplateBuilder()),\n this.addTangoTemplate(new TodoSerializerTemplateBuilder()),\n this.addTangoTemplate(new SerializersBarrelTemplateBuilder()),\n this.addTangoTemplate(new OpenAPITemplateBuilder()),\n this.addTangoTemplate(new ViewSetTemplateBuilder()),\n this.addTangoTemplate(new BootstrapTemplateBuilder()),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('migrations/.gitkeep', '')),\n this.addFrameworkTemplate(new ReadmeTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate('.gitignore', 'node_modules\\ndist\\n.data\\n.env\\n')\n ),\n this.addTangoTemplate(new TangoRegisterTemplateBuilder()),\n ];\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PackageJsonTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'package.json' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const deps = this.getTangoDependencyEntries(context);\n const devDeps = this.getTangoDevDependencyEntries(context);\n\n return JSON.stringify(\n {\n name: context.projectName,\n private: true,\n type: 'module',\n scripts: {\n predev: 'tango migrate --config ./tango.config.ts',\n dev: 'next dev',\n prestart: 'tango migrate --config ./tango.config.ts',\n build: 'next build',\n start: 'next start',\n typecheck: 'tsc --noEmit',\n 'setup:schema':\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n 'make:migrations':\n 'tango make:migrations --config ./tango.config.ts --models ./src/lib/models/index.ts',\n 'codegen:relations': 'tango codegen relations --models ./src/lib/models/index.ts',\n prebootstrap:\n \"node -e \\\"require('node:fs').mkdirSync('./.data',{recursive:true})\\\" && tango migrate --config ./tango.config.ts\",\n bootstrap: 'tsx scripts/bootstrap.ts',\n },\n dependencies: {\n ...deps,\n next: '^15.1.6',\n react: '^19.0.0',\n 'react-dom': '^19.0.0',\n zod: '^4.0.0',\n },\n devDependencies: {\n ...devDeps,\n '@types/node': '^22.9.0',\n '@types/react': '^19.0.6',\n '@types/react-dom': '^19.0.2',\n tsx: '^4.20.6',\n typescript: '^5.6.3',\n },\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n lib: ['dom', 'dom.iterable', 'es2022'],\n strict: true,\n noEmit: true,\n module: 'esnext',\n moduleResolution: 'bundler',\n resolveJsonModule: true,\n isolatedModules: true,\n jsx: 'preserve',\n esModuleInterop: true,\n baseUrl: '.',\n paths: {\n '@/*': ['src/*'],\n },\n },\n include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', 'migrations/**/*.ts', '.tango/**/*.d.ts'],\n exclude: ['node_modules'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tango.config.ts' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n if (context.dialect === 'sqlite') {\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || ':memory:',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n },\n});\n`;\n }\n\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 10,\n },\n migrations: { dir: './migrations', online: true },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}_test',\n maxConnections: 5,\n },\n migrations: { dir: './migrations', online: true },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 20,\n },\n migrations: { dir: './migrations', online: true },\n },\n },\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoModelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/lib/models/TodoModel.ts' });\n }\n static context(context: FrameworkScaffoldContext): TodoModelTemplateBuilder {\n return new TodoModelTemplateBuilder().setContext(context);\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { z } from 'zod';\nimport '@danceroutine/tango-orm/runtime';\nimport { Model, t } from '@danceroutine/tango-schema';\n\nexport const TodoReadSchema = z.object({\n id: z.number(),\n title: z.string().min(1),\n completed: z.coerce.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nexport const TodoCreateSchema = z.object({\n title: z.string().min(1),\n completed: z.boolean().optional().default(false),\n});\n\nexport const TodoUpdateSchema = TodoCreateSchema.partial();\n\nexport type Todo = z.output<typeof TodoReadSchema>;\n\nexport const TodoModel = Model({\n namespace: 'app',\n name: 'Todo',\n schema: TodoReadSchema.extend({\n id: t.primaryKey(z.number().int()),\n title: z.string().min(1),\n completed: t.field(z.coerce.boolean()).defaultValue('false').build(),\n createdAt: t.field(z.string()).defaultValue({ now: true }).build(),\n updatedAt: t.field(z.string()).defaultValue({ now: true }).build(),\n }),\n});\n`;\n }\n}\n\nexport class ModelsBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/lib/models/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoReadSchema, TodoCreateSchema, TodoUpdateSchema, TodoModel, type Todo } from './TodoModel';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoSerializerTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/TodoSerializer.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { ModelSerializer } from '@danceroutine/tango-resources';\nimport { TodoCreateSchema, TodoModel, TodoReadSchema, TodoUpdateSchema, type Todo } from '@/lib/models';\n\nexport class TodoSerializer extends ModelSerializer<\n Todo,\n typeof TodoCreateSchema,\n typeof TodoUpdateSchema,\n typeof TodoReadSchema\n> {\n static readonly model = TodoModel;\n static readonly createSchema = TodoCreateSchema;\n static readonly updateSchema = TodoUpdateSchema;\n static readonly outputSchema = TodoReadSchema;\n}\n`;\n }\n}\n\nexport class SerializersBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/serializers/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoSerializer } from './TodoSerializer';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPITemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/lib/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { describeViewSet, generateOpenAPISpec, type OpenAPISpec } from '@danceroutine/tango-openapi';\nimport { TodoViewSet } from '@/viewsets/TodoViewSet';\n\nexport function createOpenAPISpec(): OpenAPISpec {\n return generateOpenAPISpec({\n title: 'Tango Next.js Todo API',\n version: '1.0.0',\n description: 'OpenAPI document generated from Tango resource instances.',\n resources: [describeViewSet({ basePath: '/api/todos', resource: new TodoViewSet() })],\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ViewSetTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/viewsets/TodoViewSet.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { FilterSet, ModelViewSet } from '@danceroutine/tango-resources';\nimport { type Todo } from '@/lib/models';\nimport { TodoSerializer } from '@/serializers';\n\nexport class TodoViewSet extends ModelViewSet<Todo, typeof TodoSerializer> {\n constructor() {\n super({\n serializer: TodoSerializer,\n filters: FilterSet.define<Todo>({\n fields: {\n completed: true,\n },\n aliases: {\n q: { fields: ['title'], lookup: 'icontains' },\n },\n }),\n orderingFields: ['id', 'createdAt', 'updatedAt', 'title'],\n searchFields: ['title'],\n });\n }\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PageTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/page.tsx' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { TodoModel, TodoReadSchema } from '@/lib/models';\n\nexport default async function HomePage() {\n const todos = await TodoModel.objects.query().orderBy('-createdAt').limit(10).fetch(TodoReadSchema);\n\n return (\n <main style={{ fontFamily: 'system-ui', margin: '2rem auto', maxWidth: '60ch' }}>\n <h1>Tango + Next.js</h1>\n <p>Showing {todos.length} todos through Tango's runtime-backed model manager.</p>\n <ul>\n {todos.map((todo) => (\n <li key={todo.id}>{todo.title}</li>\n ))}\n </ul>\n </main>\n );\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class LayoutTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/layout.tsx' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: 'Tango Todo App',\n description: 'Generated by tango new --framework next',\n};\n\nexport default function RootLayout({\n children,\n}: Readonly<{\n children: React.ReactNode;\n}>) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n );\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class HealthRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/api/health/route.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export async function GET(): Promise<Response> {\n return Response.json({ ok: true });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/api/todos/[[...tango]]/route.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { NextAdapter } from '@danceroutine/tango-adapters-next/adapter';\nimport { TodoViewSet } from '@/viewsets/TodoViewSet';\n\nconst adapter = new NextAdapter();\nexport const { GET, POST, PUT, PATCH, DELETE } = adapter.adaptViewSet(new TodoViewSet());\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPIRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'src/app/api/openapi/route.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { createOpenAPISpec } from '@/lib/openapi';\n\nexport async function GET(): Promise<Response> {\n return Response.json(createOpenAPISpec());\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class BootstrapTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'scripts/bootstrap.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { TodoModel, type Todo } from '../src/lib/models';\n\nasync function seedExampleData(count = 100): Promise<void> {\n const existing = await TodoModel.objects.query().count();\n if (existing >= count) {\n console.log(\\`[bootstrap] Skipped; already have \\${existing} todos.\\`);\n return;\n }\n\n const rows: Array<Partial<Todo>> = [];\n for (let index = existing; index < count; index += 1) {\n const now = new Date(Date.now() - index * 60_000).toISOString();\n rows.push({\n title: \\`Seeded todo #\\${index + 1}\\`,\n completed: index % 3 === 0,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n await TodoModel.objects.bulkCreate(rows);\n console.log(\\`[bootstrap] Seeded \\${rows.length} todos.\\`);\n}\n\nconst count = Number(process.env.SEED_TODOS_COUNT || '100');\n// oxlint-disable-next-line unicorn/prefer-top-level-await\nseedExampleData(Number.isFinite(count) ? count : 100).catch((error: unknown) => {\n console.error('[bootstrap] Failed:', error);\n process.exit(1);\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ReadmeTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'README.md' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n return `# ${context.projectName}\n\nThis project was scaffolded by \\`tango new --framework next\\`.\n\nNext.js still owns pages and route handlers; Tango owns model metadata, \\`Model.objects\\`, serializers, migrations, querying, and resource behavior.\n\n## First-time setup\n\nGenerate your first migration from the scaffolded models, then start the app:\n\n\\`\\`\\`bash\n${context.packageManager} run make:migrations -- --name initial\n${context.packageManager} run dev\n\\`\\`\\`\n\n\\`make:migrations\\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \\`${context.packageManager} run codegen:relations\\`.\n\nWhen you run the package script, pass Tango flags after \\`--\\` so the script forwards them to the CLI unchanged.\n\n## Scripts\n\n- \\`${context.packageManager} run dev\\`\n- \\`${context.packageManager} run make:migrations -- --name add_field\\`\n- \\`${context.packageManager} run codegen:relations\\`\n- \\`${context.packageManager} run setup:schema\\`\n- \\`${context.packageManager} run bootstrap\\`\n- \\`${context.packageManager} run typecheck\\`\n\n## Useful endpoints\n\n- \\`GET /api/health\\`\n- \\`GET /api/openapi\\`\n- \\`GET|POST|PATCH|DELETE /api/todos...\\`\n\n## Project layout\n\n- \\`tango.config.ts\\` Tango configuration\n- \\`src/lib/models/\\` schemas and Tango model metadata; importing the model module enables \\`Model.objects\\`\n- \\`src/serializers/\\` serializer-backed API contracts for Tango resources\n- \\`src/viewsets/\\` CRUD resources backed by \\`Model.objects\\`\n- \\`src/app/page.tsx\\` server-rendered page reading through \\`TodoModel.objects\\`\n- \\`src/app/api/todos/[[...tango]]/route.ts\\` Next adapter wiring for the viewset\n- \\`src/lib/openapi.ts\\` OpenAPI document generation\n- \\`scripts/bootstrap.ts\\` seed utility for a larger demo dataset\n- \\`migrations/\\` checked-in Tango migrations\n- \\`.tango/\\` generated relation typing artifacts\n`;\n }\n}\n","import { FrameworkScaffoldStrategy } from '../../contracts/FrameworkScaffoldStrategy';\nimport { TemplateBuilder } from '../../contracts/template/TemplateBuilder';\nimport type { ScaffoldTemplate } from '../../contracts/template/ScaffoldTemplate';\nimport { PackageJsonTemplateBuilder } from './templates/packageJson';\nimport { TsConfigTemplateBuilder } from './templates/tsconfig';\nimport { TangoConfigTemplateBuilder } from './templates/tangoConfig';\nimport { TodoModelTemplateBuilder, ModelsBarrelTemplateBuilder } from './templates/models';\nimport { TodoSerializerTemplateBuilder, SerializersBarrelTemplateBuilder } from './templates/serializers';\nimport { OpenAPITemplateBuilder } from './templates/openapi';\nimport { ViewSetTemplateBuilder } from './templates/viewSet';\nimport { PageTemplateBuilder } from './templates/page';\nimport { LayoutTemplateBuilder } from './templates/layout';\nimport { HealthRouteTemplateBuilder } from './templates/healthRoute';\nimport { TodoRouteTemplateBuilder } from './templates/todoRoute';\nimport { OpenAPIRouteTemplateBuilder } from './templates/openapiRoute';\nimport { BootstrapTemplateBuilder } from './templates/bootstrap';\nimport { ReadmeTemplateBuilder } from './templates/readme';\n\n/**\n * Scaffold strategy for creating a Next.js-hosted Tango project.\n */\nexport class NextScaffoldStrategy extends FrameworkScaffoldStrategy {\n readonly id = 'next' as const;\n\n readonly name = 'Next.js';\n\n readonly description = 'Bootstrap a Tango application hosted by Next.js App Router.';\n\n /**\n * Return the file templates needed for the generated Next.js project.\n */\n getTemplates(): readonly ScaffoldTemplate[] {\n return [\n this.addFrameworkTemplate(new PackageJsonTemplateBuilder()),\n this.addTangoTemplate(new TangoConfigTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate(\n 'next-env.d.ts',\n '/// <reference types=\"next\" />\\n/// <reference types=\"next/image-types/global\" />\\n'\n )\n ),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('next.config.mjs', 'export default {};\\n')),\n this.addTangoTemplate(new TodoModelTemplateBuilder()),\n this.addTangoTemplate(new ModelsBarrelTemplateBuilder()),\n this.addTangoTemplate(new TodoSerializerTemplateBuilder()),\n this.addTangoTemplate(new SerializersBarrelTemplateBuilder()),\n this.addTangoTemplate(new OpenAPITemplateBuilder()),\n this.addTangoTemplate(new ViewSetTemplateBuilder()),\n this.addFrameworkTemplate(new LayoutTemplateBuilder()),\n this.addFrameworkTemplate(new PageTemplateBuilder()),\n this.addTangoTemplate(new HealthRouteTemplateBuilder()),\n this.addTangoTemplate(new OpenAPIRouteTemplateBuilder()),\n this.addTangoTemplate(new TodoRouteTemplateBuilder()),\n this.addTangoTemplate(new BootstrapTemplateBuilder()),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('migrations/.gitkeep', '')),\n this.addFrameworkTemplate(new ReadmeTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate('.gitignore', 'node_modules\\n.next\\n.data\\n.env\\n')\n ),\n ];\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PackageJsonTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'package.json' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n const deps = this.getTangoDependencyEntries(context);\n const devDeps = this.getTangoDevDependencyEntries(context);\n\n return JSON.stringify(\n {\n name: context.projectName,\n private: true,\n type: 'module',\n scripts: {\n predev: 'sh -c \\'if [ \"$TANGO_SKIP_SETUP_SCHEMA\" = \"true\" ]; then exit 0; fi; pnpm run setup:schema\\'',\n dev: 'NUXT_TELEMETRY_DISABLED=1 nuxt dev',\n prestart:\n 'sh -c \\'if [ \"$TANGO_SKIP_SETUP_SCHEMA\" = \"true\" ]; then exit 0; fi; pnpm run setup:schema\\'',\n build: 'NUXT_TELEMETRY_DISABLED=1 nuxt build',\n start: 'NUXT_TELEMETRY_DISABLED=1 nuxt preview',\n typecheck: 'NUXT_TELEMETRY_DISABLED=1 nuxt typecheck',\n 'setup:schema': 'pnpm exec tango migrate --config ./tango.config.ts',\n 'make:migrations':\n 'tango make:migrations --config ./tango.config.ts --models ./lib/models/index.ts',\n 'codegen:relations': 'pnpm exec tango codegen relations --models ./lib/models/index.ts',\n prebootstrap: 'pnpm run setup:schema',\n bootstrap: 'tsx scripts/bootstrap.ts',\n },\n dependencies: {\n ...deps,\n nuxt: '^4.4.2',\n vue: '^3.5.31',\n zod: '^4.0.0',\n },\n devDependencies: {\n ...devDeps,\n '@types/node': '^22.9.0',\n tsx: '^4.20.6',\n typescript: '^5.6.3',\n 'vue-tsc': '^3.1.2',\n },\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TsConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tsconfig.json' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return JSON.stringify(\n {\n extends: './.nuxt/tsconfig.json',\n compilerOptions: {\n strict: true,\n },\n include: ['.nuxt/**/*.d.ts', '**/*.ts', '**/*.vue', 'migrations/**/*.ts', '.tango/**/*.d.ts'],\n },\n null,\n 4\n );\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class NuxtConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'nuxt.config.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { defineNuxtConfig } from 'nuxt/config';\n\nexport default defineNuxtConfig({\n compatibilityDate: '2026-03-31',\n serverHandlers: [\n { route: '/api/health', handler: './server/tango/health.ts' },\n { route: '/api/openapi', handler: './server/tango/openapi.ts' },\n { route: '/api/todos', handler: './server/tango/todos.ts' },\n { route: '/api/todos/**:tango', handler: './server/tango/todos.ts' },\n ],\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoModelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'lib/models/TodoModel.ts' });\n }\n static context(context: FrameworkScaffoldContext): TodoModelTemplateBuilder {\n return new TodoModelTemplateBuilder().setContext(context);\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { z } from 'zod';\nimport { registerModelObjects } from '@danceroutine/tango-orm/runtime';\nimport { Model, t } from '@danceroutine/tango-schema';\n\n// Nuxt/Nitro can tree-shake side-effect-only runtime imports from source-linked packages.\n// Registering model objects here keeps \\`TodoModel.objects\\` available in SSR pages and handlers.\nregisterModelObjects();\n\nexport const TodoReadSchema = z.object({\n id: z.number(),\n title: z.string().min(1),\n completed: z.coerce.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\n\nexport const TodoCreateSchema = z.object({\n title: z.string().min(1),\n completed: z.boolean().optional().default(false),\n});\n\nexport const TodoUpdateSchema = TodoCreateSchema.partial();\n\nexport type Todo = z.output<typeof TodoReadSchema>;\n\nexport const TodoModel = Model({\n namespace: 'app',\n name: 'Todo',\n schema: TodoReadSchema.extend({\n id: t.primaryKey(z.number().int()),\n title: z.string().min(1),\n completed: t.field(z.coerce.boolean()).defaultValue('false').build(),\n createdAt: t.field(z.string()).defaultValue({ now: true }).build(),\n updatedAt: t.field(z.string()).defaultValue({ now: true }).build(),\n }),\n});\n`;\n }\n}\n\nexport class ModelsBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'lib/models/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoReadSchema, TodoCreateSchema, TodoUpdateSchema, TodoModel, type Todo } from './TodoModel';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoSerializerTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'serializers/TodoSerializer.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { ModelSerializer } from '@danceroutine/tango-resources';\nimport { TodoCreateSchema, TodoModel, TodoReadSchema, TodoUpdateSchema, type Todo } from '~~/lib/models';\n\nexport class TodoSerializer extends ModelSerializer<\n Todo,\n typeof TodoCreateSchema,\n typeof TodoUpdateSchema,\n typeof TodoReadSchema\n> {\n static override readonly model = TodoModel;\n static override readonly createSchema = TodoCreateSchema;\n static override readonly updateSchema = TodoUpdateSchema;\n static override readonly outputSchema = TodoReadSchema;\n}\n`;\n }\n}\n\nexport class SerializersBarrelTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'serializers/index.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export { TodoSerializer } from './TodoSerializer';\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPITemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'lib/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { describeViewSet, generateOpenAPISpec, type OpenAPISpec } from '@danceroutine/tango-openapi';\nimport { TodoViewSet } from '~~/viewsets/TodoViewSet';\n\nexport function createOpenAPISpec(): OpenAPISpec {\n return generateOpenAPISpec({\n title: 'Tango Nuxt Todo API',\n version: '1.0.0',\n description: 'OpenAPI document generated from Tango resource instances.',\n resources: [describeViewSet({ basePath: '/api/todos', resource: new TodoViewSet() })],\n });\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ViewSetTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'viewsets/TodoViewSet.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { FilterSet, ModelViewSet } from '@danceroutine/tango-resources';\nimport { type Todo } from '~~/lib/models';\nimport { TodoSerializer } from '~~/serializers';\n\nexport class TodoViewSet extends ModelViewSet<Todo, typeof TodoSerializer> {\n constructor() {\n super({\n serializer: TodoSerializer,\n filters: FilterSet.define<Todo>({\n fields: {\n completed: true,\n },\n aliases: {\n q: { fields: ['title'], lookup: 'icontains' },\n },\n }),\n orderingFields: ['id', 'createdAt', 'updatedAt', 'title'],\n searchFields: ['title'],\n });\n }\n}\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class PageTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'app/pages/index.server.vue' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `<script setup lang=\"ts\">\nimport { TodoModel, TodoReadSchema } from '~/lib/models';\n\nconst todos = await TodoModel.objects.query().orderBy('-createdAt').limit(10).fetch(TodoReadSchema);\n</script>\n\n<template>\n <main style=\"font-family: system-ui; margin: 2rem auto; max-width: 60ch;\">\n <h1>Tango + Nuxt</h1>\n <p>Showing {{ todos.length }} todos through Tango's runtime-backed model manager.</p>\n <ul>\n <li v-for=\"todo in todos\" :key=\"todo.id\">{{ todo.title }}</li>\n </ul>\n </main>\n</template>\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class AppShellTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'app/app.vue' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `<template>\n <NuxtPage />\n</template>\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class HealthRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'server/tango/health.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `export default defineEventHandler(() => ({ ok: true }));\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TodoRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'server/tango/todos.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { NuxtAdapter } from '@danceroutine/tango-adapters-nuxt/adapter';\nimport { TodoViewSet } from '~~/viewsets/TodoViewSet';\n\nconst adapter = new NuxtAdapter();\nexport default adapter.adaptViewSet(new TodoViewSet());\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class OpenAPIRouteTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'server/tango/openapi.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { createOpenAPISpec } from '~~/lib/openapi';\n\nexport default defineEventHandler(() => createOpenAPISpec());\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class BootstrapTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'scripts/bootstrap.ts' });\n }\n\n protected override resolveTemplate(_context: FrameworkScaffoldContext): string {\n return `import { TodoModel, type Todo } from '../lib/models';\n\nasync function seedExampleData(count = 100): Promise<void> {\n const existing = await TodoModel.objects.query().count();\n if (existing >= count) {\n console.log(\\`[bootstrap] Skipped; already have \\${existing} todos.\\`);\n return;\n }\n\n const rows: Array<Partial<Todo>> = [];\n for (let index = existing; index < count; index += 1) {\n const now = new Date(Date.now() - index * 60_000).toISOString();\n rows.push({\n title: \\`Seeded todo #\\${index + 1}\\`,\n completed: index % 3 === 0,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n await TodoModel.objects.bulkCreate(rows);\n console.log(\\`[bootstrap] Seeded \\${rows.length} todos.\\`);\n}\n\nconst count = Number(process.env.SEED_TODOS_COUNT || '100');\n// oxlint-disable-next-line unicorn/prefer-top-level-await\nseedExampleData(Number.isFinite(count) ? count : 100).catch((error: unknown) => {\n console.error('[bootstrap] Failed:', error);\n process.exit(1);\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class TangoConfigTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'tango.config.ts' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n if (context.dialect === 'sqlite') {\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || ':memory:',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'sqlite',\n filename: process.env.TANGO_SQLITE_FILENAME || './.data/${context.projectName}.sqlite',\n maxConnections: 1,\n },\n migrations: { dir: './migrations', online: false },\n },\n },\n});\n`;\n }\n\n return `import { defineConfig } from '@danceroutine/tango-config';\n\nexport default defineConfig({\n current: (process.env.NODE_ENV || 'development') as 'development' | 'test' | 'production',\n environments: {\n development: {\n name: 'development',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 10,\n },\n migrations: { dir: './migrations', online: true },\n },\n test: {\n name: 'test',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}_test',\n maxConnections: 5,\n },\n migrations: { dir: './migrations', online: true },\n },\n production: {\n name: 'production',\n db: {\n adapter: 'postgres',\n url: process.env.TANGO_DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/${context.projectName}',\n maxConnections: 20,\n },\n migrations: { dir: './migrations', online: true },\n },\n },\n});\n`;\n }\n}\n","import { TemplateBuilder } from '../../../contracts/template/TemplateBuilder';\nimport type { FrameworkScaffoldContext } from '../../../contracts/template/ScaffoldTemplate';\n\nexport class ReadmeTemplateBuilder extends TemplateBuilder {\n constructor() {\n super({ name: 'README.md' });\n }\n\n protected override resolveTemplate(context: FrameworkScaffoldContext): string {\n return `# ${context.projectName}\n\nThis project was scaffolded by \\`tango new --framework nuxt\\`.\n\nNuxt still owns pages and SSR rendering; Tango owns model metadata, \\`Model.objects\\`, serializers, migrations, querying, and resource behavior.\n\n## First-time setup\n\nGenerate your first migration from the scaffolded models, then start the app:\n\n\\`\\`\\`bash\n${context.packageManager} run make:migrations -- --name initial\n${context.packageManager} run dev\n\\`\\`\\`\n\n\\`make:migrations\\` also refreshes the generated relation registry for the scaffolded model module. If you later change relation metadata without needing a new migration file, run \\`${context.packageManager} run codegen:relations\\`.\n\nWhen you run the package script, pass Tango flags after \\`--\\` so the script forwards them to the CLI unchanged.\n\n## Scripts\n\n- \\`${context.packageManager} run dev\\`\n- \\`${context.packageManager} run make:migrations -- --name add_field\\`\n- \\`${context.packageManager} run codegen:relations\\`\n- \\`${context.packageManager} run setup:schema\\`\n- \\`${context.packageManager} run bootstrap\\`\n- \\`${context.packageManager} run typecheck\\`\n\n## Useful endpoints\n\n- \\`GET /api/health\\`\n- \\`GET /api/openapi\\`\n- \\`GET|POST|PATCH|DELETE /api/todos...\\`\n\n## Project layout\n\n- \\`nuxt.config.ts\\` Nuxt config and explicit Tango server handler registration\n- \\`tango.config.ts\\` Tango configuration\n- \\`lib/models/\\` schemas and Tango model metadata; explicit ORM registration keeps \\`Model.objects\\` available in SSR pages and handlers\n- \\`serializers/\\` serializer-backed API contracts for Tango resources\n- \\`viewsets/\\` CRUD resources backed by \\`Model.objects\\`\n- \\`app/pages/index.server.vue\\` server-rendered page reading through \\`TodoModel.objects\\`\n- \\`server/tango/todos.ts\\` Nuxt adapter wiring for the viewset\n- \\`lib/openapi.ts\\` OpenAPI document generation\n- \\`scripts/bootstrap.ts\\` seed utility for a larger demo dataset\n- \\`migrations/\\` checked-in Tango migrations\n- \\`.tango/\\` generated relation typing artifacts\n`;\n }\n}\n","import { FrameworkScaffoldStrategy } from '../../contracts/FrameworkScaffoldStrategy';\nimport { TemplateBuilder } from '../../contracts/template/TemplateBuilder';\nimport type { ScaffoldTemplate } from '../../contracts/template/ScaffoldTemplate';\nimport { PackageJsonTemplateBuilder } from './templates/packageJson';\nimport { TsConfigTemplateBuilder } from './templates/tsconfig';\nimport { NuxtConfigTemplateBuilder } from './templates/nuxtConfig';\nimport { TodoModelTemplateBuilder, ModelsBarrelTemplateBuilder } from './templates/models';\nimport { TodoSerializerTemplateBuilder, SerializersBarrelTemplateBuilder } from './templates/serializers';\nimport { OpenAPITemplateBuilder } from './templates/openapi';\nimport { ViewSetTemplateBuilder } from './templates/viewSet';\nimport { PageTemplateBuilder } from './templates/page';\nimport { AppShellTemplateBuilder } from './templates/layout';\nimport { HealthRouteTemplateBuilder } from './templates/healthRoute';\nimport { TodoRouteTemplateBuilder } from './templates/todoRoute';\nimport { OpenAPIRouteTemplateBuilder } from './templates/openapiRoute';\nimport { BootstrapTemplateBuilder } from './templates/bootstrap';\nimport { TangoConfigTemplateBuilder } from './templates/tangoConfig';\nimport { ReadmeTemplateBuilder } from './templates/readme';\n\n/**\n * Scaffold strategy for creating a Nuxt-hosted Tango project.\n */\nexport class NuxtScaffoldStrategy extends FrameworkScaffoldStrategy {\n readonly id = 'nuxt' as const;\n\n readonly name = 'Nuxt';\n\n readonly description = 'Bootstrap a Tango application hosted by Nuxt Nitro and SSR pages.';\n\n /**\n * Return the file templates needed for the generated Nuxt project.\n */\n getTemplates(): readonly ScaffoldTemplate[] {\n return [\n this.addFrameworkTemplate(new PackageJsonTemplateBuilder()),\n this.addFrameworkTemplate(new NuxtConfigTemplateBuilder()),\n this.addFrameworkTemplate(new TsConfigTemplateBuilder()),\n this.addFrameworkTemplate(new AppShellTemplateBuilder()),\n this.addFrameworkTemplate(new PageTemplateBuilder()),\n this.addTangoTemplate(new TangoConfigTemplateBuilder()),\n this.addTangoTemplate(new TodoModelTemplateBuilder()),\n this.addTangoTemplate(new ModelsBarrelTemplateBuilder()),\n this.addTangoTemplate(new TodoSerializerTemplateBuilder()),\n this.addTangoTemplate(new SerializersBarrelTemplateBuilder()),\n this.addTangoTemplate(new OpenAPITemplateBuilder()),\n this.addTangoTemplate(new ViewSetTemplateBuilder()),\n this.addTangoTemplate(new HealthRouteTemplateBuilder()),\n this.addTangoTemplate(new OpenAPIRouteTemplateBuilder()),\n this.addTangoTemplate(new TodoRouteTemplateBuilder()),\n this.addTangoTemplate(new BootstrapTemplateBuilder()),\n this.addFrameworkTemplate(TemplateBuilder.createStaticTemplate('migrations/.gitkeep', '')),\n this.addFrameworkTemplate(new ReadmeTemplateBuilder()),\n this.addFrameworkTemplate(\n TemplateBuilder.createStaticTemplate('.gitignore', 'node_modules\\n.nuxt\\n.output\\n.data\\n.env\\n')\n ),\n ];\n }\n}\n","import { FrameworkScaffoldStrategy, type SupportedFramework } from '../contracts/FrameworkScaffoldStrategy';\nimport { ExpressScaffoldStrategy } from '../strategies/express/ExpressScaffoldStrategy';\nimport { NextScaffoldStrategy } from '../strategies/next/NextScaffoldStrategy';\nimport { NuxtScaffoldStrategy } from '../strategies/nuxt/NuxtScaffoldStrategy';\n\n/**\n * Registry for framework scaffolding strategies keyed by framework id.\n */\nexport class FrameworkScaffoldRegistry {\n private readonly strategies = new Map<SupportedFramework, FrameworkScaffoldStrategy>();\n\n /**\n * Create a registry preloaded with Tango's built-in framework scaffolds.\n */\n static createDefault(): FrameworkScaffoldRegistry {\n const registry = new FrameworkScaffoldRegistry();\n registry.register(new ExpressScaffoldStrategy());\n registry.register(new NextScaffoldStrategy());\n registry.register(new NuxtScaffoldStrategy());\n return registry;\n }\n\n /**\n * Register a strategy under its declared framework id.\n */\n register(strategy: FrameworkScaffoldStrategy): void {\n const existing = this.strategies.get(strategy.id);\n if (existing) {\n throw new Error(`Framework scaffold strategy '${strategy.id}' is already registered.`);\n }\n this.strategies.set(strategy.id, strategy);\n }\n\n /**\n * Resolve a strategy for a known framework id.\n */\n get(id: SupportedFramework): FrameworkScaffoldStrategy | undefined {\n return this.strategies.get(id);\n }\n\n /**\n * List all registered framework strategies in registration order.\n */\n list(): readonly FrameworkScaffoldStrategy[] {\n return [...this.strategies.values()];\n }\n}\n","import { mkdir, readdir, stat, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, resolve } from 'node:path';\nimport type { FrameworkScaffoldStrategy } from '../contracts/FrameworkScaffoldStrategy';\nimport type { FrameworkScaffoldContext, ScaffoldMode } from '../contracts/template/ScaffoldTemplate';\n\nexport type ScaffoldProjectOptions = {\n force?: boolean;\n /** 'new' = full scaffold; 'init' = only Tango + init-only files. Default 'new'. */\n mode?: ScaffoldMode;\n /** When true, do not overwrite existing files. Default true when mode === 'init', otherwise false. */\n skipExisting?: boolean;\n};\n\nfunction resolveTargetDir(targetDir: string): string {\n if (isAbsolute(targetDir)) {\n return targetDir;\n }\n return resolve(process.cwd(), targetDir);\n}\n\nasync function ensureWritableTargetDir(\n targetDir: string,\n options: ScaffoldProjectOptions & { mode: ScaffoldMode }\n): Promise<void> {\n const absoluteTargetDir = resolveTargetDir(targetDir);\n\n try {\n const targetStats = await stat(absoluteTargetDir);\n if (!targetStats.isDirectory()) {\n throw new Error(`Target path '${absoluteTargetDir}' exists and is not a directory.`);\n }\n\n if (options.mode === 'new') {\n const contents = await readdir(absoluteTargetDir);\n if (contents.length > 0 && !options.force) {\n throw new Error(\n `Target directory '${absoluteTargetDir}' is not empty. Pass --force to allow scaffolding into a non-empty directory.`\n );\n }\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n await mkdir(absoluteTargetDir, { recursive: true });\n return;\n }\n throw error;\n }\n}\n\n/**\n * Write a framework scaffold into a target directory after basic safety checks.\n *\n * The selected strategy controls which files are created, while this helper\n * owns directory validation and filesystem writes. With mode 'init', only\n * Tango and init-only templates are emitted, and existing files can be skipped.\n */\nexport async function scaffoldProject(\n context: FrameworkScaffoldContext,\n strategy: FrameworkScaffoldStrategy,\n options: ScaffoldProjectOptions = {}\n): Promise<void> {\n const mode = options.mode ?? 'new';\n const skipExisting = options.skipExisting ?? mode === 'init';\n const resolvedOptions = { ...options, mode, skipExisting };\n\n await ensureWritableTargetDir(context.targetDir, resolvedOptions);\n\n const allTemplates = strategy.getTemplates();\n const templates = allTemplates.filter((t) => t.shouldEmit(mode));\n\n for (const template of templates) {\n const absolutePath = resolveTargetDir(resolve(context.targetDir, template.path));\n if (skipExisting && !options.force) {\n try {\n await stat(absolutePath);\n continue;\n } catch {\n // ENOENT or other: proceed to write\n }\n }\n await mkdir(dirname(absolutePath), { recursive: true });\n await writeFile(absolutePath, template.render(context), 'utf8');\n }\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport {\n type FrameworkScaffoldContext,\n type ScaffoldMode,\n type ScaffoldTemplate,\n type ScaffoldTemplateCategory,\n SCAFFOLD_TEMPLATE_CATEGORY,\n} from './contracts/template/ScaffoldTemplate';\nexport type {\n PackageManager,\n ScaffoldDatabaseDialect as ScaffoldDialect,\n SupportedFramework,\n} from './contracts/FrameworkScaffoldStrategy';\nexport { FrameworkScaffoldStrategy } from './contracts/FrameworkScaffoldStrategy';\nexport { ScaffoldTemplateDescriptor } from './contracts/template/implementation/ScaffoldTemplateDescriptor';\nexport { FrameworkScaffoldRegistry } from './registry/FrameworkScaffoldRegistry';\nexport { ExpressScaffoldStrategy } from './strategies/express/ExpressScaffoldStrategy';\nexport { NextScaffoldStrategy } from './strategies/next/NextScaffoldStrategy';\nexport { NuxtScaffoldStrategy } from './strategies/nuxt/NuxtScaffoldStrategy';\nexport { scaffoldProject, type ScaffoldProjectOptions } from './scaffold/scaffoldProject';\n"],"mappings":";;;;;MAEa,6BAA6B;CACtC,WAAW;CACX,OAAO;CACP,WAAW;AACd;;;;ICGY,6BAAN,MAA6D;CAChE,YACaA,UACAC,UACX;AAAA,OAFW,WAAA;AAAA,OACA,WAAA;CACT;CACJ,IAAW,OAAe;AACtB,SAAO,KAAK,SAAS,SAAS;CACjC;CAED,OAAOC,KAAuC;AAC1C,SAAO,KAAK,SAAS,WAAW,IAAI,CAAC,OAAO;CAC/C;CAED,WAAWC,MAA6B;AACpC,MAAI,SAAS,MACT,QACI,KAAK,aAAa,2BAA2B,aAC7C,KAAK,aAAa,2BAA2B;AAGrD,SACI,KAAK,aAAa,2BAA2B,SAAS,KAAK,aAAa,2BAA2B;CAE1G;AACJ;;;;WChCW;gBACG;kBACI;WACP;WACA;YACC;cACE;CACP,KAAK;EACD,SAAS;EACT,UAAU;CACb;CACD,YAAY;EACR,SAAS;EACT,UAAU;CACb;CACD,gBAAgB;EACZ,SAAS;EACT,UAAU;CACb;CACD,gBAAgB;EACZ,SAAS;EACT,UAAU;CACb;CACD,cAAc;EACV,SAAS;EACT,UAAU;CACb;AACJ;YACQ,CACL,MACH;cACU;CACP,SAAS;CACT,QAAQ;CACR,cAAc;CACd,aAAa;CACb,kBAAkB;CAClB,kBAAkB;AACrB;eACW;CACR;CACA;CACA;CACA;CACA;AACH;aACS;cACC;iBACG;CACV,QAAQ;CACR,OAAO;CACP,aAAa;AAChB;mBACe;CACZ,4BAA4B;CAC5B,8BAA8B;CAC9B,QAAQ;CACR,SAAS;AACZ;sBACkB;CACf,+BAA+B;CAC/B,gBAAgB;CAChB,eAAe;CACf,UAAU;CACV,cAAc;CACd,UAAU;CACV,OAAO;AACV;sBApEJ;;;;;;;;;;;;;;;;AAqEA;;;;AClED,MAAM,EAAE,SAAS,GAAG;IAgBE,kBAAf,MAAe,gBAAyC;CAC3D;CACA;CAEA,YAAYC,SAA2B;AACnC,OAAK,OAAO,QAAQ;CACvB;;;;CAKD,OAAO,wBACHC,gBACAC,SACAC,WACM;EACN,MAAM,OAAO,gBAAgB,6BAA6B,SAAS,UAAU;EAC7E,MAAM,UAAU,gBAAgB,iCAAiC;EACjE,MAAM,UAAU,OAAO,QAAQ,KAAK,CAC/B,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CACpC,KAAK,IAAI;EACd,MAAM,UAAU,OAAO,QAAQ,QAAQ,CAClC,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CACpC,KAAK,IAAI;EACd,MAAM,SAAS,mBAAmB,QAAQ,iBAAiB,EAAE,eAAe;EAC5E,MAAM,YAAY,mBAAmB,QAAQ,oBAAoB,EAAE,eAAe;AAClF,UAAQ,EAAE,OAAO,GAAG,QAAQ,MAAM,UAAU,GAAG,QAAQ;CAC1D;;;;CAKD,OAAO,qBAAqBC,UAAkBC,UAAoD;EAC9F,MAAM,uCAAuC,gBAAgB;GACzD,gBAAmCC,UAA4C;AAC3E,kBAAc,aAAa,WAAW,WAAW,UAAU;GAC9D;EACJ;AACD,SAAO,IAAI,+BAA+B,EAAE,MAAM,SAAU;CAC/D;;CAGD,OAAe,kBAA0B;AACrC,UAAQ,GAAG,QAAQ;CACtB;CAED,OAAe,6BACXJ,SACAC,WACsB;EACtB,MAAM,IAAI,gBAAgB,iBAAiB;EAC3C,MAAMI,OAA+B;GACjC,4BAA4B;GAC5B,8BAA8B;GAC9B,2BAA2B;GAC3B,iCAAiC;GACjC,kCAAkC;GAClC,+BAA+B;GAC/B,8BAA8B;EACjC;EACD,MAAMC,UACF,cAAc,YACR,EAAE,wCAAwC,EAAG,IAC7C,cAAc,SACZ,EAAE,qCAAqC,EAAG,IAC1C,EAAE,qCAAqC,EAAG;EACtD,MAAMC,cACF,YAAY,WAAW,EAAE,kBAAkB,WAAY,IAAG,EAAE,IAAI,UAAW;AAC/E,SAAO;GAAE,GAAG;GAAM,GAAG;GAAS,GAAG;EAAa;CACjD;CAED,OAAe,kCAA0D;AACrE,SAAO,EAAE,2BAA2B,gBAAgB,iBAAiB,CAAE;CAC1E;;CAGD,WAAWC,SAAyC;AAChD,OAAK,WAAW;AAChB,SAAO;CACV;CAED,UAAkB;AACd,SAAO,KAAK;CACf;CAID,QAAgB;AACZ,MAAI,KAAK,aAAa,UAClB,OAAM,IAAI,MAAM;AAEpB,SAAO,KAAK,gBAAgB,KAAK,SAAS;CAC7C;CAED,0BAAoCA,SAA2D;AAC3F,SAAO,gBAAgB,6BAA6B,QAAQ,SAAS,QAAQ,UAAU;CAC1F;CAED,6BAAuCJ,UAA4D;AAC/F,SAAO,gBAAgB,iCAAiC;CAC3D;AACJ;;;;MC/GY,sBAAsB;CAC/B,SAAS;CACT,MAAM;CACN,MAAM;AACT;MAGY,kBAAkB;CAC3B,MAAM;CACN,KAAK;CACL,MAAM;CACN,KAAK;AACR;MAGY,4BAA4B;CACrC,QAAQ;CACR,UAAU;AACb;IASqB,4BAAf,MAAyC;;;;CAQ5C,wBAAwBK,gBAAgCC,SAA2C;AAC/F,SAAO,gBAAgB,wBAAwB,gBAAgB,QAAQ,SAAS,QAAQ,UAAU;CACrG;CAID,qBAA+BC,UAA6C;AACxE,SAAO,KAAK,eAAe,UAAU,2BAA2B,UAAU;CAC7E;CAED,iBAA2BA,UAA6C;AACpE,SAAO,KAAK,eAAe,UAAU,2BAA2B,MAAM;CACzE;CAED,oBAA8BA,UAA6C;AACvE,SAAO,KAAK,eAAe,UAAU,2BAA2B,UAAU;CAC7E;CAED,eAAuBA,UAA2BC,UAAsD;AACpG,SAAO,IAAI,2BAA2B,UAAU;CACnD;AACJ;;;;IC9DY,+BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,eAAgB,EAAC;CAClC;CAED,gBAAmCC,SAA2C;EAC1E,MAAM,OAAO,KAAK,0BAA0B,QAAQ;EACpD,MAAM,UAAU,KAAK,6BAA6B,QAAQ;AAE1D,SAAO,KAAK,UACR;GACI,MAAM,QAAQ;GACd,SAAS;GACT,MAAM;GACN,SAAS;IACL,QAAQ;IACR,KAAK;IACL,UAAU;IACV,OAAO;IACP,OAAO;IACP,WAAW;IACX,gBACI;IACJ,mBACI;IACJ,qBAAqB;IACrB,cACI;IACJ,WAAW;GACd;GACD,cAAc;IACV,GAAG;IACH,SAAS;IACT,KAAK;GACR;GACD,iBAAiB;IACb,GAAG;IACH,kBAAkB;IAClB,eAAe;IACf,KAAK;IACL,YAAY;GACf;EACJ,GACD,MACA,EACH;CACJ;AACJ;;;;IC/CY,4BAAN,cAAsC,gBAAgB;CACzD,cAAc;AACV,QAAM,EAAE,MAAM,gBAAiB,EAAC;CACnC;CAED,gBAAmCC,UAA4C;AAC3E,SAAO,KAAK,UACR;GACI,iBAAiB;IACb,QAAQ;IACR,KAAK,CAAC,UAAU,KAAM;IACtB,QAAQ;IACR,kBAAkB;IAClB,QAAQ;IACR,QAAQ;IACR,iBAAiB;IACjB,cAAc;IACd,mBAAmB;IACnB,OAAO,CAAC,MAAO;GAClB;GACD,SAAS;IAAC;IAAO;IAAsB;IAAmB;GAAmB;GAC7E,SAAS,CAAC,gBAAgB,MAAO;EACpC,GACD,MACA,EACH;CACJ;AACJ;;;;IC3BY,+BAAN,cAA2C,gBAAgB;CAC9D,cAAc;AACV,QAAM,EAAE,MAAM,sBAAuB,EAAC;CACzC;CAED,gBAAmCC,UAA4C;AAC3E,SAAO,KAAK,UACR;GACI,SAAS;GACT,iBAAiB;IACb,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,WAAW;IACX,aAAa;GAChB;GACD,SAAS,CAAC,OAAO,iBAAkB;GACnC,SAAS;IAAC;IAAgB;IAAQ;IAAc;GAAe;EAClE,GACD,MACA,EACH;CACJ;AACJ;;;;ICvBY,+BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,kBAAmB,EAAC;CACrC;CAED,gBAAmCC,SAA2C;AAC1E,MAAI,QAAQ,YAAY,SACpB,SAAQ;;;;;;;;;0EASsD,QAAQ,YAAY;;;;;;;;;;;;;;;;;;0EAkBpB,QAAQ,YAAY;;;;;;;;AAUtF,UAAQ;;;;;;;;;sGASsF,QAAQ,YAAY;;;;;;;;;sGASpB,QAAQ,YAAY;;;;;;;;;sGASpB,QAAQ,YAAY;;;;;;;;CAQrH;AACJ;;;;IChFY,2BAAN,cAAuC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,eAAgB,EAAC;CAClC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BX;AACJ;;;;ICrCY,6BAAN,cAAuC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,0BAA2B,EAAC;CAC7C;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCX;AACJ;IAEY,gCAAN,cAA0C,gBAAgB;CAC7D,cAAc;AACV,QAAM,EAAE,MAAM,sBAAuB,EAAC;CACzC;CAED,gBAAmCA,UAA4C;AAC3E,UAAQ;;CAEX;AACJ;;;;ICnDY,kCAAN,cAA4C,gBAAgB;CAC/D,cAAc;AACV,QAAM,EAAE,MAAM,oCAAqC,EAAC;CACvD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;CAeX;AACJ;IAEY,qCAAN,cAA+C,gBAAgB;CAClE,cAAc;AACV,QAAM,EAAE,MAAM,2BAA4B,EAAC;CAC9C;CAED,gBAAmCA,UAA4C;AAC3E,UAAQ;;CAEX;AACJ;;;;ICjCY,2BAAN,cAAqC,gBAAgB;CACxD,cAAc;AACV,QAAM,EAAE,MAAM,iBAAkB,EAAC;CACpC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;CAYX;AACJ;;;;ICnBY,2BAAN,cAAqC,gBAAgB;CACxD,cAAc;AACV,QAAM,EAAE,MAAM,8BAA+B,EAAC;CACjD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;CAsBX;AACJ;;;;IC7BY,6BAAN,cAAuC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,mBAAoB,EAAC;CACtC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCX;AACJ;;;;ICxCY,0BAAN,cAAoC,gBAAgB;CACvD,cAAc;AACV,QAAM,EAAE,MAAM,YAAa,EAAC;CAC/B;CAED,gBAAmCC,SAA2C;AAC1E,UAAQ,IAAI,QAAQ,YAAY;;;;;;;;;;;EAWtC,QAAQ,eAAe;EACvB,QAAQ,eAAe;;;wLAG+J,QAAQ,eAAe;;;;;;MAMzM,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;;;;;;;;;;;;;;;;;;;;CAoBxB;AACJ;;;;ICrDY,+BAAN,cAA2C,gBAAgB;CAC9D,cAAc;AACV,QAAM,EAAE,MAAM,eAAgB,EAAC;CAClC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;CAiBX;AACJ;;;;ICRY,0BAAN,cAAsC,0BAA0B;CACnE,KAAc;CAEd,OAAgB;CAEhB,cAAuB;;;;CAKvB,eAA4C;AACxC,SAAO;GACH,KAAK,qBAAqB,IAAI,+BAA6B;GAC3D,KAAK,qBAAqB,IAAI,4BAA0B;GACxD,KAAK,qBAAqB,IAAI,+BAA+B;GAC7D,KAAK,iBAAiB,IAAI,+BAA6B;GACvD,KAAK,qBAAqB,IAAI,2BAA2B;GACzD,KAAK,iBAAiB,IAAI,6BAA2B;GACrD,KAAK,iBAAiB,IAAI,gCAA8B;GACxD,KAAK,iBAAiB,IAAI,kCAAgC;GAC1D,KAAK,iBAAiB,IAAI,qCAAmC;GAC7D,KAAK,iBAAiB,IAAI,2BAAyB;GACnD,KAAK,iBAAiB,IAAI,2BAAyB;GACnD,KAAK,iBAAiB,IAAI,6BAA2B;GACrD,KAAK,qBAAqB,gBAAgB,qBAAqB,uBAAuB,GAAG,CAAC;GAC1F,KAAK,qBAAqB,IAAI,0BAAwB;GACtD,KAAK,qBACD,gBAAgB,qBAAqB,cAAc,oCAAoC,CAC1F;GACD,KAAK,iBAAiB,IAAI,+BAA+B;EAC5D;CACJ;AACJ;;;;IChDY,+BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,eAAgB,EAAC;CAClC;CAED,gBAAmCC,SAA2C;EAC1E,MAAM,OAAO,KAAK,0BAA0B,QAAQ;EACpD,MAAM,UAAU,KAAK,6BAA6B,QAAQ;AAE1D,SAAO,KAAK,UACR;GACI,MAAM,QAAQ;GACd,SAAS;GACT,MAAM;GACN,SAAS;IACL,QAAQ;IACR,KAAK;IACL,UAAU;IACV,OAAO;IACP,OAAO;IACP,WAAW;IACX,gBACI;IACJ,mBACI;IACJ,qBAAqB;IACrB,cACI;IACJ,WAAW;GACd;GACD,cAAc;IACV,GAAG;IACH,MAAM;IACN,OAAO;IACP,aAAa;IACb,KAAK;GACR;GACD,iBAAiB;IACb,GAAG;IACH,eAAe;IACf,gBAAgB;IAChB,oBAAoB;IACpB,KAAK;IACL,YAAY;GACf;EACJ,GACD,MACA,EACH;CACJ;AACJ;;;;IClDY,4BAAN,cAAsC,gBAAgB;CACzD,cAAc;AACV,QAAM,EAAE,MAAM,gBAAiB,EAAC;CACnC;CAED,gBAAmCC,UAA4C;AAC3E,SAAO,KAAK,UACR;GACI,iBAAiB;IACb,QAAQ;IACR,KAAK;KAAC;KAAO;KAAgB;IAAS;IACtC,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,kBAAkB;IAClB,mBAAmB;IACnB,iBAAiB;IACjB,KAAK;IACL,iBAAiB;IACjB,SAAS;IACT,OAAO,EACH,OAAO,CAAC,OAAQ,EACnB;GACJ;GACD,SAAS;IAAC;IAAiB;IAAW;IAAY;IAAsB;GAAmB;GAC3F,SAAS,CAAC,cAAe;EAC5B,GACD,MACA,EACH;CACJ;AACJ;;;;IC/BY,+BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,kBAAmB,EAAC;CACrC;CAED,gBAAmCC,SAA2C;AAC1E,MAAI,QAAQ,YAAY,SACpB,SAAQ;;;;;;;;;0EASsD,QAAQ,YAAY;;;;;;;;;;;;;;;;;;0EAkBpB,QAAQ,YAAY;;;;;;;;AAUtF,UAAQ;;;;;;;;;sGASsF,QAAQ,YAAY;;;;;;;;;sGASpB,QAAQ,YAAY;;;;;;;;;sGASpB,QAAQ,YAAY;;;;;;;;CAQrH;AACJ;;;;IChFY,6BAAN,MAAM,mCAAiC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,8BAA+B,EAAC;CACjD;CACD,OAAO,QAAQC,SAA6D;AACxE,SAAO,IAAI,6BAA2B,WAAW,QAAQ;CAC5D;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCX;AACJ;IAEY,gCAAN,cAA0C,gBAAgB;CAC7D,cAAc;AACV,QAAM,EAAE,MAAM,0BAA2B,EAAC;CAC7C;CAED,gBAAmCA,UAA4C;AAC3E,UAAQ;;CAEX;AACJ;;;;ICtDY,kCAAN,cAA4C,gBAAgB;CAC/D,cAAc;AACV,QAAM,EAAE,MAAM,oCAAqC,EAAC;CACvD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;CAeX;AACJ;IAEY,qCAAN,cAA+C,gBAAgB;CAClE,cAAc;AACV,QAAM,EAAE,MAAM,2BAA4B,EAAC;CAC9C;CAED,gBAAmCA,UAA4C;AAC3E,UAAQ;;CAEX;AACJ;;;;ICjCY,2BAAN,cAAqC,gBAAgB;CACxD,cAAc;AACV,QAAM,EAAE,MAAM,qBAAsB,EAAC;CACxC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;CAYX;AACJ;;;;ICnBY,2BAAN,cAAqC,gBAAgB;CACxD,cAAc;AACV,QAAM,EAAE,MAAM,8BAA+B,EAAC;CACjD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;CAsBX;AACJ;;;;IC7BY,wBAAN,cAAkC,gBAAgB;CACrD,cAAc;AACV,QAAM,EAAE,MAAM,mBAAoB,EAAC;CACtC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;CAkBX;AACJ;;;;ICzBY,wBAAN,cAAoC,gBAAgB;CACvD,cAAc;AACV,QAAM,EAAE,MAAM,qBAAsB,EAAC;CACxC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;CAmBX;AACJ;;;;IC1BY,+BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,8BAA+B,EAAC;CACjD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;CAIX;AACJ;;;;ICXY,6BAAN,cAAuC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,0CAA2C,EAAC;CAC7D;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;CAMX;AACJ;;;;ICbY,gCAAN,cAA0C,gBAAgB;CAC7D,cAAc;AACV,QAAM,EAAE,MAAM,+BAAgC,EAAC;CAClD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;CAMX;AACJ;;;;ICbY,6BAAN,cAAuC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,uBAAwB,EAAC;CAC1C;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BX;AACJ;;;;ICtCY,0BAAN,cAAoC,gBAAgB;CACvD,cAAc;AACV,QAAM,EAAE,MAAM,YAAa,EAAC;CAC/B;CAED,gBAAmCC,SAA2C;AAC1E,UAAQ,IAAI,QAAQ,YAAY;;;;;;;;;;;EAWtC,QAAQ,eAAe;EACvB,QAAQ,eAAe;;;wLAG+J,QAAQ,eAAe;;;;;;MAMzM,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;;;;;;;;;;;;;;;;;;;;;CAqBxB;AACJ;;;;ICpCY,uBAAN,cAAmC,0BAA0B;CAChE,KAAc;CAEd,OAAgB;CAEhB,cAAuB;;;;CAKvB,eAA4C;AACxC,SAAO;GACH,KAAK,qBAAqB,IAAI,+BAA6B;GAC3D,KAAK,iBAAiB,IAAI,+BAA6B;GACvD,KAAK,qBAAqB,IAAI,4BAA0B;GACxD,KAAK,qBACD,gBAAgB,qBACZ,iBACA,0FACH,CACJ;GACD,KAAK,qBAAqB,gBAAgB,qBAAqB,mBAAmB,uBAAuB,CAAC;GAC1G,KAAK,iBAAiB,IAAI,6BAA2B;GACrD,KAAK,iBAAiB,IAAI,gCAA8B;GACxD,KAAK,iBAAiB,IAAI,kCAAgC;GAC1D,KAAK,iBAAiB,IAAI,qCAAmC;GAC7D,KAAK,iBAAiB,IAAI,2BAAyB;GACnD,KAAK,iBAAiB,IAAI,2BAAyB;GACnD,KAAK,qBAAqB,IAAI,wBAAwB;GACtD,KAAK,qBAAqB,IAAI,wBAAsB;GACpD,KAAK,iBAAiB,IAAI,+BAA6B;GACvD,KAAK,iBAAiB,IAAI,gCAA8B;GACxD,KAAK,iBAAiB,IAAI,6BAA2B;GACrD,KAAK,iBAAiB,IAAI,6BAA2B;GACrD,KAAK,qBAAqB,gBAAgB,qBAAqB,uBAAuB,GAAG,CAAC;GAC1F,KAAK,qBAAqB,IAAI,0BAAwB;GACtD,KAAK,qBACD,gBAAgB,qBAAqB,cAAc,qCAAqC,CAC3F;EACJ;CACJ;AACJ;;;;IC3DY,6BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,eAAgB,EAAC;CAClC;CAED,gBAAmCC,SAA2C;EAC1E,MAAM,OAAO,KAAK,0BAA0B,QAAQ;EACpD,MAAM,UAAU,KAAK,6BAA6B,QAAQ;AAE1D,SAAO,KAAK,UACR;GACI,MAAM,QAAQ;GACd,SAAS;GACT,MAAM;GACN,SAAS;IACL,QAAQ;IACR,KAAK;IACL,UACI;IACJ,OAAO;IACP,OAAO;IACP,WAAW;IACX,gBAAgB;IAChB,mBACI;IACJ,qBAAqB;IACrB,cAAc;IACd,WAAW;GACd;GACD,cAAc;IACV,GAAG;IACH,MAAM;IACN,KAAK;IACL,KAAK;GACR;GACD,iBAAiB;IACb,GAAG;IACH,eAAe;IACf,KAAK;IACL,YAAY;IACZ,WAAW;GACd;EACJ,GACD,MACA,EACH;CACJ;AACJ;;;;IC/CY,0BAAN,cAAsC,gBAAgB;CACzD,cAAc;AACV,QAAM,EAAE,MAAM,gBAAiB,EAAC;CACnC;CAED,gBAAmCC,UAA4C;AAC3E,SAAO,KAAK,UACR;GACI,SAAS;GACT,iBAAiB,EACb,QAAQ,KACX;GACD,SAAS;IAAC;IAAmB;IAAW;IAAY;IAAsB;GAAmB;EAChG,GACD,MACA,EACH;CACJ;AACJ;;;;IClBY,4BAAN,cAAwC,gBAAgB;CAC3D,cAAc;AACV,QAAM,EAAE,MAAM,iBAAkB,EAAC;CACpC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;CAYX;AACJ;;;;ICnBY,2BAAN,MAAM,iCAAiC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,0BAA2B,EAAC;CAC7C;CACD,OAAO,QAAQC,SAA6D;AACxE,SAAO,IAAI,2BAA2B,WAAW,QAAQ;CAC5D;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCX;AACJ;IAEY,8BAAN,cAA0C,gBAAgB;CAC7D,cAAc;AACV,QAAM,EAAE,MAAM,sBAAuB,EAAC;CACzC;CAED,gBAAmCA,UAA4C;AAC3E,UAAQ;;CAEX;AACJ;;;;IC1DY,gCAAN,cAA4C,gBAAgB;CAC/D,cAAc;AACV,QAAM,EAAE,MAAM,gCAAiC,EAAC;CACnD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;CAeX;AACJ;IAEY,mCAAN,cAA+C,gBAAgB;CAClE,cAAc;AACV,QAAM,EAAE,MAAM,uBAAwB,EAAC;CAC1C;CAED,gBAAmCA,UAA4C;AAC3E,UAAQ;;CAEX;AACJ;;;;ICjCY,yBAAN,cAAqC,gBAAgB;CACxD,cAAc;AACV,QAAM,EAAE,MAAM,iBAAkB,EAAC;CACpC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;CAYX;AACJ;;;;ICnBY,yBAAN,cAAqC,gBAAgB;CACxD,cAAc;AACV,QAAM,EAAE,MAAM,0BAA2B,EAAC;CAC7C;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;CAsBX;AACJ;;;;IC7BY,sBAAN,cAAkC,gBAAgB;CACrD,cAAc;AACV,QAAM,EAAE,MAAM,6BAA8B,EAAC;CAChD;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;CAgBX;AACJ;;;;ICvBY,0BAAN,cAAsC,gBAAgB;CACzD,cAAc;AACV,QAAM,EAAE,MAAM,cAAe,EAAC;CACjC;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;CAIX;AACJ;;;;ICXY,6BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,yBAA0B,EAAC;CAC5C;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;CAEX;AACJ;;;;ICTY,2BAAN,cAAuC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,wBAAyB,EAAC;CAC3C;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;CAMX;AACJ;;;;ICbY,8BAAN,cAA0C,gBAAgB;CAC7D,cAAc;AACV,QAAM,EAAE,MAAM,0BAA2B,EAAC;CAC7C;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;CAIX;AACJ;;;;ICXY,2BAAN,cAAuC,gBAAgB;CAC1D,cAAc;AACV,QAAM,EAAE,MAAM,uBAAwB,EAAC;CAC1C;CAED,gBAAmCC,UAA4C;AAC3E,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BX;AACJ;;;;ICtCY,6BAAN,cAAyC,gBAAgB;CAC5D,cAAc;AACV,QAAM,EAAE,MAAM,kBAAmB,EAAC;CACrC;CAED,gBAAmCC,SAA2C;AAC1E,MAAI,QAAQ,YAAY,SACpB,SAAQ;;;;;;;;;0EASsD,QAAQ,YAAY;;;;;;;;;;;;;;;;;;0EAkBpB,QAAQ,YAAY;;;;;;;;AAUtF,UAAQ;;;;;;;;;sGASsF,QAAQ,YAAY;;;;;;;;;sGASpB,QAAQ,YAAY;;;;;;;;;sGASpB,QAAQ,YAAY;;;;;;;;CAQrH;AACJ;;;;IChFY,wBAAN,cAAoC,gBAAgB;CACvD,cAAc;AACV,QAAM,EAAE,MAAM,YAAa,EAAC;CAC/B;CAED,gBAAmCC,SAA2C;AAC1E,UAAQ,IAAI,QAAQ,YAAY;;;;;;;;;;;EAWtC,QAAQ,eAAe;EACvB,QAAQ,eAAe;;;wLAG+J,QAAQ,eAAe;;;;;;MAMzM,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;MACvB,QAAQ,eAAe;;;;;;;;;;;;;;;;;;;;;;CAsBxB;AACJ;;;;ICpCY,uBAAN,cAAmC,0BAA0B;CAChE,KAAc;CAEd,OAAgB;CAEhB,cAAuB;;;;CAKvB,eAA4C;AACxC,SAAO;GACH,KAAK,qBAAqB,IAAI,6BAA6B;GAC3D,KAAK,qBAAqB,IAAI,4BAA4B;GAC1D,KAAK,qBAAqB,IAAI,0BAA0B;GACxD,KAAK,qBAAqB,IAAI,0BAA0B;GACxD,KAAK,qBAAqB,IAAI,sBAAsB;GACpD,KAAK,iBAAiB,IAAI,6BAA6B;GACvD,KAAK,iBAAiB,IAAI,2BAA2B;GACrD,KAAK,iBAAiB,IAAI,8BAA8B;GACxD,KAAK,iBAAiB,IAAI,gCAAgC;GAC1D,KAAK,iBAAiB,IAAI,mCAAmC;GAC7D,KAAK,iBAAiB,IAAI,yBAAyB;GACnD,KAAK,iBAAiB,IAAI,yBAAyB;GACnD,KAAK,iBAAiB,IAAI,6BAA6B;GACvD,KAAK,iBAAiB,IAAI,8BAA8B;GACxD,KAAK,iBAAiB,IAAI,2BAA2B;GACrD,KAAK,iBAAiB,IAAI,2BAA2B;GACrD,KAAK,qBAAqB,gBAAgB,qBAAqB,uBAAuB,GAAG,CAAC;GAC1F,KAAK,qBAAqB,IAAI,wBAAwB;GACtD,KAAK,qBACD,gBAAgB,qBAAqB,cAAc,8CAA8C,CACpG;EACJ;CACJ;AACJ;;;;ICjDY,4BAAN,MAAM,0BAA0B;CACnC,aAA8B,IAAI;;;;CAKlC,OAAO,gBAA2C;EAC9C,MAAM,WAAW,IAAI;AACrB,WAAS,SAAS,IAAI,0BAA0B;AAChD,WAAS,SAAS,IAAI,uBAAuB;AAC7C,WAAS,SAAS,IAAI,uBAAuB;AAC7C,SAAO;CACV;;;;CAKD,SAASC,UAA2C;EAChD,MAAM,WAAW,KAAK,WAAW,IAAI,SAAS,GAAG;AACjD,MAAI,SACA,OAAM,IAAI,OAAO,+BAA+B,SAAS,GAAG;AAEhE,OAAK,WAAW,IAAI,SAAS,IAAI,SAAS;CAC7C;;;;CAKD,IAAIC,IAA+D;AAC/D,SAAO,KAAK,WAAW,IAAI,GAAG;CACjC;;;;CAKD,OAA6C;AACzC,SAAO,CAAC,GAAG,KAAK,WAAW,QAAQ,AAAC;CACvC;AACJ;;;;ACjCD,SAAS,iBAAiBC,WAA2B;AACjD,KAAI,WAAW,UAAU,CACrB,QAAO;AAEX,QAAO,QAAQ,QAAQ,KAAK,EAAE,UAAU;AAC3C;AAED,eAAe,wBACXA,WACAC,SACa;CACb,MAAM,oBAAoB,iBAAiB,UAAU;AAErD,KAAI;EACA,MAAM,cAAc,MAAM,KAAK,kBAAkB;AACjD,OAAK,YAAY,aAAa,CAC1B,OAAM,IAAI,OAAO,eAAe,kBAAkB;AAGtD,MAAI,QAAQ,SAAS,OAAO;GACxB,MAAM,WAAW,MAAM,QAAQ,kBAAkB;AACjD,OAAI,SAAS,SAAS,MAAM,QAAQ,MAChC,OAAM,IAAI,OACL,oBAAoB,kBAAkB;EAGlD;CACJ,SAAQ,OAAO;AACZ,MAAK,MAAgC,SAAS,UAAU;AACpD,SAAM,MAAM,mBAAmB,EAAE,WAAW,KAAM,EAAC;AACnD;EACH;AACD,QAAM;CACT;AACJ;AASM,eAAe,gBAClBC,SACAC,UACAC,UAAkC,CAAE,GACvB;CACb,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,eAAe,QAAQ,gBAAgB,SAAS;CACtD,MAAM,kBAAkB;EAAE,GAAG;EAAS;EAAM;CAAc;AAE1D,OAAM,wBAAwB,QAAQ,WAAW,gBAAgB;CAEjE,MAAM,eAAe,SAAS,cAAc;CAC5C,MAAM,YAAY,aAAa,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC;AAEhE,MAAK,MAAM,YAAY,WAAW;EAC9B,MAAM,eAAe,iBAAiB,QAAQ,QAAQ,WAAW,SAAS,KAAK,CAAC;AAChF,MAAI,iBAAiB,QAAQ,MACzB,KAAI;AACA,SAAM,KAAK,aAAa;AACxB;EACH,QAAO,CAEP;AAEL,QAAM,MAAM,QAAQ,aAAa,EAAE,EAAE,WAAW,KAAM,EAAC;AACvD,QAAM,UAAU,cAAc,SAAS,OAAO,QAAQ,EAAE,OAAO;CAClE;AACJ"}
|