@danceroutine/tango-codegen 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +93 -0
- package/dist/chunk-BkvOhyD0.js +12 -0
- package/dist/{generators/repository → commands}/index.d.ts +1 -1
- package/dist/commands/index.js +4 -0
- package/dist/commands/registerCodegenCommands.d.ts +5 -0
- package/dist/commands/runInitCommand.d.ts +13 -0
- package/dist/commands/runInstall.d.ts +2 -0
- package/dist/commands/runNewCommand.d.ts +16 -0
- package/dist/commands-C2Xr9uRE.js +186 -0
- package/dist/commands-C2Xr9uRE.js.map +1 -0
- package/dist/frameworks/contracts/FrameworkScaffoldStrategy.d.ts +39 -0
- package/dist/frameworks/contracts/template/ScaffoldTemplate.d.ts +22 -0
- package/dist/frameworks/contracts/template/TemplateBuilder.d.ts +40 -0
- package/dist/frameworks/contracts/template/implementation/ScaffoldTemplateDescriptor.d.ts +10 -0
- package/dist/frameworks/index.d.ts +11 -0
- package/dist/frameworks/index.js +3 -0
- package/dist/frameworks/registry/FrameworkScaffoldRegistry.d.ts +23 -0
- package/dist/frameworks/scaffold/scaffoldProject.d.ts +17 -0
- package/dist/frameworks/strategies/express/ExpressScaffoldStrategy.d.ts +14 -0
- package/dist/frameworks/strategies/express/templates/appSource.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/bootstrap.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/models.d.ts +10 -0
- package/dist/frameworks/strategies/express/templates/openapi.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/packageJson.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/readme.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/serializers.d.ts +10 -0
- package/dist/frameworks/strategies/express/templates/tangoConfig.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/tangoRegister.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/tsconfig.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/tsconfigBuild.d.ts +6 -0
- package/dist/frameworks/strategies/express/templates/viewSet.d.ts +6 -0
- package/dist/frameworks/strategies/next/NextScaffoldStrategy.d.ts +14 -0
- package/dist/frameworks/strategies/next/templates/bootstrap.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/healthRoute.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/layout.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/models.d.ts +11 -0
- package/dist/frameworks/strategies/next/templates/openapi.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/openapiRoute.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/packageJson.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/page.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/readme.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/serializers.d.ts +10 -0
- package/dist/frameworks/strategies/next/templates/tangoConfig.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/todoRoute.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/tsconfig.d.ts +6 -0
- package/dist/frameworks/strategies/next/templates/viewSet.d.ts +6 -0
- package/dist/frameworks-Bp_9BOt2.js +1366 -0
- package/dist/frameworks-Bp_9BOt2.js.map +1 -0
- package/dist/generators/index.d.ts +0 -2
- package/dist/generators/index.js +2 -2
- package/dist/generators/migration/generateMigrationFromModels.d.ts +6 -0
- package/dist/generators/model/generateModelInterface.d.ts +3 -0
- package/dist/generators/viewset/generateViewSet.d.ts +3 -0
- package/dist/{generators-CDXkQAkq.js → generators-C9UeakCq.js} +18 -55
- package/dist/generators-C9UeakCq.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -7
- package/dist/mappers/fieldType.d.ts +6 -0
- package/package.json +60 -48
- package/dist/generators/repository/generateRepository.d.ts +0 -1
- package/dist/generators-CDXkQAkq.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/mappers/fieldType.js +0 -32
- package/dist/version.d.ts +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frameworks-Bp_9BOt2.js","names":["template: TemplateBuilder","category: ScaffoldTemplateCategory","ctx: FrameworkScaffoldContext","mode: ScaffoldMode","options: { name: string }","packageManager: string","dialect: 'sqlite' | 'postgres'","framework: 'express' | 'next'","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","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/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.0.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 \"yargs\": \"^17.7.2\"\n },\n \"devDependencies\": {\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 }\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'\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'\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 : { '@danceroutine/tango-adapters-next': 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} 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 --name \"${npm_config_name:-manual_change}\"',\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'],\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.default(z.coerce.boolean(), 'false'),\n createdAt: t.default(z.string(), { now: true }),\n updatedAt: t.default(z.string(), { now: true }),\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## Scripts\n\n- \\`${context.packageManager} run dev\\`\n- \\`${context.packageManager} run make:migrations --name add_field\\`\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`;\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 --name \"${npm_config_name:-manual_change}\"',\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'],\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.default(z.coerce.boolean(), 'false'),\n createdAt: t.default(z.string(), { now: true }),\n updatedAt: t.default(z.string(), { now: true }),\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.results.length} todos through Tango's runtime-backed model manager.</p>\n <ul>\n {todos.results.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## Scripts\n\n- \\`${context.packageManager} run dev\\`\n- \\`${context.packageManager} run make:migrations --name add_field\\`\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`;\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 { FrameworkScaffoldStrategy, type SupportedFramework } from '../contracts/FrameworkScaffoldStrategy';\nimport { ExpressScaffoldStrategy } from '../strategies/express/ExpressScaffoldStrategy';\nimport { NextScaffoldStrategy } from '../strategies/next/NextScaffoldStrategy';\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 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 { scaffoldProject, type ScaffoldProjectOptions } from './scaffold/scaffoldProject';\n"],"mappings":"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"}
|
|
@@ -4,9 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export * as migration from './migration/index';
|
|
6
6
|
export * as model from './model/index';
|
|
7
|
-
export * as repository from './repository/index';
|
|
8
7
|
export * as viewset from './viewset/index';
|
|
9
|
-
export { generateRepository } from './repository/index';
|
|
10
8
|
export { generateModelInterface } from './model/index';
|
|
11
9
|
export { generateMigrationFromModels } from './migration/index';
|
|
12
10
|
export { generateViewSet } from './viewset/index';
|
package/dist/generators/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { generateMigrationFromModels, generateModelInterface,
|
|
1
|
+
import { generateMigrationFromModels, generateModelInterface, generateViewSet, migration_exports, model_exports, viewset_exports } from "../generators-C9UeakCq.js";
|
|
2
2
|
|
|
3
|
-
export { generateMigrationFromModels, generateModelInterface,
|
|
3
|
+
export { generateMigrationFromModels, generateModelInterface, generateViewSet, migration_exports as migration, model_exports as model, viewset_exports as viewset };
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import type { CodegenModel } from '../../domain';
|
|
2
|
+
/**
|
|
3
|
+
* Generate a class-based Tango migration source file from model metadata.
|
|
4
|
+
*
|
|
5
|
+
* The generated migration creates one table per model in `up()` and drops
|
|
6
|
+
* those tables in reverse order in `down()` to keep teardown deterministic.
|
|
7
|
+
*/
|
|
2
8
|
export declare function generateMigrationFromModels(models: CodegenModel[]): string;
|
|
@@ -1,14 +1,5 @@
|
|
|
1
|
+
import { __export } from "./chunk-BkvOhyD0.js";
|
|
1
2
|
|
|
2
|
-
//#region rolldown:runtime
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __export = (target, all) => {
|
|
5
|
-
for (var name in all) __defProp(target, name, {
|
|
6
|
-
get: all[name],
|
|
7
|
-
enumerable: true
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
//#endregion
|
|
12
3
|
//#region src/mappers/fieldType.ts
|
|
13
4
|
function mapFieldTypeToTS(type) {
|
|
14
5
|
const typeMap = {
|
|
@@ -22,7 +13,7 @@ function mapFieldTypeToTS(type) {
|
|
|
22
13
|
text: "string",
|
|
23
14
|
bool: "boolean",
|
|
24
15
|
uuid: "string",
|
|
25
|
-
jsonb: "
|
|
16
|
+
jsonb: "unknown",
|
|
26
17
|
timestamptz: "Date"
|
|
27
18
|
};
|
|
28
19
|
return typeMap[type] || "unknown";
|
|
@@ -57,20 +48,20 @@ function generateMigrationFromModels(models) {
|
|
|
57
48
|
}).join("\n");
|
|
58
49
|
return ` op.table('${model.name.toLowerCase()}s').create((cols) => {\n${fields}\n }),`;
|
|
59
50
|
}).join("\n\n");
|
|
60
|
-
const reverseOperations = models.
|
|
51
|
+
const reverseOperations = [...models].reverse().map((model) => ` op.table('${model.name.toLowerCase()}s').drop(),`).join("\n");
|
|
61
52
|
return `
|
|
62
|
-
import { Migration, op } from '@danceroutine/tango-migrations';
|
|
53
|
+
import { Migration, op, type Builder } from '@danceroutine/tango-migrations';
|
|
63
54
|
|
|
64
55
|
export default class ${className} extends Migration {
|
|
65
56
|
id = '${generatedId}';
|
|
66
57
|
|
|
67
|
-
up(m) {
|
|
58
|
+
up(m: Builder) {
|
|
68
59
|
m.run(
|
|
69
60
|
${operations}
|
|
70
61
|
);
|
|
71
62
|
}
|
|
72
63
|
|
|
73
|
-
down() {
|
|
64
|
+
down(m: Builder) {
|
|
74
65
|
m.run(
|
|
75
66
|
${reverseOperations}
|
|
76
67
|
);
|
|
@@ -104,51 +95,25 @@ ${fields}
|
|
|
104
95
|
var model_exports = {};
|
|
105
96
|
__export(model_exports, { generateModelInterface: () => generateModelInterface });
|
|
106
97
|
|
|
107
|
-
//#endregion
|
|
108
|
-
//#region src/generators/repository/generateRepository.ts
|
|
109
|
-
function generateRepository(modelName) {
|
|
110
|
-
return `
|
|
111
|
-
import { Repository } from '@danceroutine/tango-orm';
|
|
112
|
-
import type { DBClient } from '@danceroutine/tango-orm/connection';
|
|
113
|
-
import { ${modelName} } from './models';
|
|
114
|
-
|
|
115
|
-
export class ${modelName}Repository extends Repository<typeof ${modelName}> {
|
|
116
|
-
constructor(client: DBClient) {
|
|
117
|
-
super(client);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Add custom repository methods here
|
|
121
|
-
}
|
|
122
|
-
`.trim();
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
//#endregion
|
|
126
|
-
//#region src/generators/repository/index.ts
|
|
127
|
-
var repository_exports = {};
|
|
128
|
-
__export(repository_exports, { generateRepository: () => generateRepository });
|
|
129
|
-
|
|
130
98
|
//#endregion
|
|
131
99
|
//#region src/generators/viewset/generateViewSet.ts
|
|
132
100
|
function generateViewSet(modelName) {
|
|
133
|
-
const repoName = `${modelName}Repository`;
|
|
134
101
|
return `
|
|
135
102
|
import { ModelViewSet } from '@danceroutine/tango-resources';
|
|
136
103
|
import { FilterSet } from '@danceroutine/tango-resources';
|
|
137
|
-
import { ${
|
|
138
|
-
import { ${modelName} } from './
|
|
104
|
+
import { type ${modelName} } from './models';
|
|
105
|
+
import { ${modelName}Serializer } from './serializers';
|
|
139
106
|
|
|
140
|
-
export class ${modelName}ViewSet extends ModelViewSet
|
|
141
|
-
constructor(
|
|
107
|
+
export class ${modelName}ViewSet extends ModelViewSet<${modelName}, typeof ${modelName}Serializer> {
|
|
108
|
+
constructor() {
|
|
142
109
|
super({
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
110
|
+
serializer: ${modelName}Serializer,
|
|
111
|
+
filters: FilterSet.define<typeof ${modelName}>({
|
|
112
|
+
fields: {
|
|
113
|
+
// Add filters here
|
|
114
|
+
},
|
|
146
115
|
}),
|
|
147
|
-
|
|
148
|
-
defaultLimit: 25,
|
|
149
|
-
maxLimit: 100,
|
|
150
|
-
cursorColumn: 'id',
|
|
151
|
-
},
|
|
116
|
+
orderingFields: ['id'],
|
|
152
117
|
});
|
|
153
118
|
}
|
|
154
119
|
|
|
@@ -168,14 +133,12 @@ var generators_exports = {};
|
|
|
168
133
|
__export(generators_exports, {
|
|
169
134
|
generateMigrationFromModels: () => generateMigrationFromModels,
|
|
170
135
|
generateModelInterface: () => generateModelInterface,
|
|
171
|
-
generateRepository: () => generateRepository,
|
|
172
136
|
generateViewSet: () => generateViewSet,
|
|
173
137
|
migration: () => migration_exports,
|
|
174
138
|
model: () => model_exports,
|
|
175
|
-
repository: () => repository_exports,
|
|
176
139
|
viewset: () => viewset_exports
|
|
177
140
|
});
|
|
178
141
|
|
|
179
142
|
//#endregion
|
|
180
|
-
export { generateMigrationFromModels, generateModelInterface,
|
|
181
|
-
//# sourceMappingURL=generators-
|
|
143
|
+
export { generateMigrationFromModels, generateModelInterface, generateViewSet, generators_exports, mapFieldTypeToTS, mappers_exports, migration_exports, model_exports, normalizeFields, viewset_exports };
|
|
144
|
+
//# sourceMappingURL=generators-C9UeakCq.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generators-C9UeakCq.js","names":["type: string","typeMap: Record<string, string>","fields: CodegenModel['fields']","models: CodegenModel[]","model: CodegenModel","modelName: string"],"sources":["../src/mappers/fieldType.ts","../src/mappers/index.ts","../src/generators/migration/generateMigrationFromModels.ts","../src/generators/migration/index.ts","../src/generators/model/generateModelInterface.ts","../src/generators/model/index.ts","../src/generators/viewset/generateViewSet.ts","../src/generators/viewset/index.ts","../src/generators/index.ts"],"sourcesContent":["import type { CodegenFieldMeta, CodegenModel } from '../domain';\n\n/**\n * Map Tango field metadata to the TypeScript type used in generated source.\n */\nexport function mapFieldTypeToTS(type: string): string {\n const typeMap: Record<string, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'Date',\n serial: 'number',\n int: 'number',\n bigint: 'number',\n text: 'string',\n bool: 'boolean',\n uuid: 'string',\n jsonb: 'unknown',\n timestamptz: 'Date',\n };\n\n return typeMap[type] || 'unknown';\n}\n\n/**\n * Normalize field metadata into a stable iterable shape for generators.\n */\nexport function normalizeFields(fields: CodegenModel['fields']): Array<[string, CodegenFieldMeta]> {\n if (Array.isArray(fields)) {\n return fields.map((field) => [\n field.name,\n {\n type: field.type,\n primaryKey: field.primaryKey,\n unique: field.unique,\n nullable: !field.notNull,\n default: field.default,\n },\n ]);\n }\n\n return Object.entries(fields);\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { mapFieldTypeToTS, normalizeFields } from './fieldType';\n","import type { CodegenModel } from '../../domain';\nimport { normalizeFields } from '../../mappers';\n\n/**\n * Generate a class-based Tango migration source file from model metadata.\n *\n * The generated migration creates one table per model in `up()` and drops\n * those tables in reverse order in `down()` to keep teardown deterministic.\n */\nexport function generateMigrationFromModels(models: CodegenModel[]): string {\n const generatedId = `auto_generated_${Date.now()}`;\n const className = `Migration_${generatedId}`;\n const operations = models\n .map((model) => {\n const fields = normalizeFields(model.fields)\n .map(([name, meta]) => {\n return ` cols.add('${name}', (b) => b.${meta.dbType || meta.type}()${meta.primaryKey ? '.primaryKey()' : ''}${meta.unique ? '.unique()' : ''}${meta.nullable ? '' : '.notNull()'});`;\n })\n .join('\\n');\n\n return ` op.table('${model.name.toLowerCase()}s').create((cols) => {\\n${fields}\\n }),`;\n })\n .join('\\n\\n');\n const reverseOperations = [...models]\n // oxlint-disable-next-line unicorn/no-array-reverse\n .reverse()\n .map((model) => ` op.table('${model.name.toLowerCase()}s').drop(),`)\n .join('\\n');\n\n return `\nimport { Migration, op, type Builder } from '@danceroutine/tango-migrations';\n\nexport default class ${className} extends Migration {\n id = '${generatedId}';\n\n up(m: Builder) {\n m.run(\n${operations}\n );\n }\n\n down(m: Builder) {\n m.run(\n${reverseOperations}\n );\n }\n}\n `.trim();\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateMigrationFromModels } from './generateMigrationFromModels';\n","import type { CodegenModel } from '../../domain';\nimport { mapFieldTypeToTS, normalizeFields } from '../../mappers';\n\n/**\n * Generate a TypeScript interface string from a Tango codegen model.\n */\nexport function generateModelInterface(model: CodegenModel): string {\n const fields = normalizeFields(model.fields)\n .map(([name, meta]) => {\n const type = mapFieldTypeToTS(meta.type);\n const optional = !meta.primaryKey && meta.default !== undefined ? '?' : '';\n return ` ${name}${optional}: ${type};`;\n })\n .join('\\n');\n\n return `\nexport interface ${model.name} {\n${fields}\n}\n `.trim();\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateModelInterface } from './generateModelInterface';\n","/**\n * Generate a `ModelViewSet` scaffold wired directly to a Tango model.\n */\nexport function generateViewSet(modelName: string): string {\n return `\nimport { ModelViewSet } from '@danceroutine/tango-resources';\nimport { FilterSet } from '@danceroutine/tango-resources';\nimport { type ${modelName} } from './models';\nimport { ${modelName}Serializer } from './serializers';\n\nexport class ${modelName}ViewSet extends ModelViewSet<${modelName}, typeof ${modelName}Serializer> {\n constructor() {\n super({\n serializer: ${modelName}Serializer,\n filters: FilterSet.define<typeof ${modelName}>({\n fields: {\n // Add filters here\n },\n }),\n orderingFields: ['id'],\n });\n }\n\n // Add custom actions here\n}\n `.trim();\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateViewSet } from './generateViewSet';\n","/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as migration from './migration/index';\nexport * as model from './model/index';\nexport * as viewset from './viewset/index';\n\nexport { generateModelInterface } from './model/index';\nexport { generateMigrationFromModels } from './migration/index';\nexport { generateViewSet } from './viewset/index';\n"],"mappings":";;;AAKO,SAAS,iBAAiBA,MAAsB;CACnD,MAAMC,UAAkC;EACpC,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,MAAM;EACN,QAAQ;EACR,KAAK;EACL,QAAQ;EACR,MAAM;EACN,MAAM;EACN,MAAM;EACN,OAAO;EACP,aAAa;CAChB;AAED,QAAO,QAAQ,SAAS;AAC3B;AAKM,SAAS,gBAAgBC,QAAmE;AAC/F,KAAI,MAAM,QAAQ,OAAO,CACrB,QAAO,OAAO,IAAI,CAAC,UAAU,CACzB,MAAM,MACN;EACI,MAAM,MAAM;EACZ,YAAY,MAAM;EAClB,QAAQ,MAAM;EACd,WAAW,MAAM;EACjB,SAAS,MAAM;CAEtB,CAAA,EAAC;AAGN,QAAO,OAAO,QAAQ,OAAO;AAChC;;;;;;;;;;;;ACjCM,SAAS,4BAA4BC,QAAgC;CACxE,MAAM,eAAe,iBAAiB,KAAK,KAAK,CAAC;CACjD,MAAM,aAAa,YAAY,YAAY;CAC3C,MAAM,aAAa,OACd,IAAI,CAAC,UAAU;EACZ,MAAM,SAAS,gBAAgB,MAAM,OAAO,CACvC,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK;AACnB,WAAQ,kBAAkB,KAAK,cAAc,KAAK,UAAU,KAAK,KAAK,IAAI,KAAK,aAAa,kBAAkB,GAAG,EAAE,KAAK,SAAS,cAAc,GAAG,EAAE,KAAK,WAAW,KAAK,aAAa;EACzL,EAAC,CACD,KAAK,KAAK;AAEf,UAAQ,kBAAkB,MAAM,KAAK,aAAa,CAAC,0BAA0B,OAAO;CACvF,EAAC,CACD,KAAK,OAAO;CACjB,MAAM,oBAAoB,CAAC,GAAG,MAAO,EAEhC,SAAS,CACT,IAAI,CAAC,WAAW,kBAAkB,MAAM,KAAK,aAAa,CAAC,aAAa,CACxE,KAAK,KAAK;AAEf,QAAO,CAAC;;;uBAGW,UAAU;UACvB,YAAY;;;;EAIpB,WAAW;;;;;;EAMX,kBAAkB;;;;IAIhB,MAAM;AACT;;;;;;;;;AC1CM,SAAS,uBAAuBC,OAA6B;CAChE,MAAM,SAAS,gBAAgB,MAAM,OAAO,CACvC,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK;EACnB,MAAM,OAAO,iBAAiB,KAAK,KAAK;EACxC,MAAM,YAAY,KAAK,cAAc,KAAK,YAAY,YAAY,MAAM;AACxE,UAAQ,IAAI,KAAK,EAAE,SAAS,IAAI,KAAK;CACxC,EAAC,CACD,KAAK,KAAK;AAEf,QAAO,CAAC;mBACO,MAAM,KAAK;EAC5B,OAAO;;IAEL,MAAM;AACT;;;;;;;;;ACjBM,SAAS,gBAAgBC,WAA2B;AACvD,QAAO,CAAC;;;gBAGI,UAAU;WACf,UAAU;;eAEN,UAAU,+BAA+B,UAAU,WAAW,UAAU;;;oBAGnE,UAAU;yCACW,UAAU;;;;;;;;;;;IAW/C,MAAM;AACT"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
export * as domain from './domain/index';
|
|
6
6
|
export * as generators from './generators/index';
|
|
7
7
|
export * as mappers from './mappers/index';
|
|
8
|
-
export
|
|
8
|
+
export * as frameworks from './frameworks/index';
|
|
9
|
+
export * as commands from './commands/index';
|
|
9
10
|
export type { CodegenFieldMeta, CodegenModel } from './domain/index';
|
|
10
|
-
export { generateMigrationFromModels, generateModelInterface,
|
|
11
|
+
export { generateMigrationFromModels, generateModelInterface, generateViewSet } from './generators/index';
|
|
11
12
|
export { mapFieldTypeToTS, normalizeFields } from './mappers/index';
|
|
13
|
+
export { FrameworkScaffoldRegistry, ExpressScaffoldStrategy, NextScaffoldStrategy, scaffoldProject, } from './frameworks/index';
|
|
14
|
+
export type { FrameworkScaffoldContext, FrameworkScaffoldStrategy, PackageManager, ScaffoldDialect, SupportedFramework, } from './frameworks/index';
|
|
15
|
+
export { registerCodegenCommands } from './commands/index';
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { generateMigrationFromModels, generateModelInterface, generateRepository, generateViewSet, generators_exports, mapFieldTypeToTS, mappers_exports, normalizeFields } from "./generators-CDXkQAkq.js";
|
|
2
1
|
import { domain_exports } from "./domain-Cufz6y1q.js";
|
|
2
|
+
import { generateMigrationFromModels, generateModelInterface, generateViewSet, generators_exports, mapFieldTypeToTS, mappers_exports, normalizeFields } from "./generators-C9UeakCq.js";
|
|
3
|
+
import { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, NextScaffoldStrategy, frameworks_exports, scaffoldProject } from "./frameworks-Bp_9BOt2.js";
|
|
4
|
+
import { commands_exports, registerCodegenCommands } from "./commands-C2Xr9uRE.js";
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
const VERSION = "0.1.0";
|
|
6
|
-
|
|
7
|
-
//#endregion
|
|
8
|
-
export { domain_exports as domain, generateMigrationFromModels, generateModelInterface, generateRepository, generateViewSet, generators_exports as generators, mapFieldTypeToTS, mappers_exports as mappers, normalizeFields, VERSION as version };
|
|
9
|
-
//# sourceMappingURL=index.js.map
|
|
6
|
+
export { ExpressScaffoldStrategy, FrameworkScaffoldRegistry, NextScaffoldStrategy, commands_exports as commands, domain_exports as domain, frameworks_exports as frameworks, generateMigrationFromModels, generateModelInterface, generateViewSet, generators_exports as generators, mapFieldTypeToTS, mappers_exports as mappers, normalizeFields, registerCodegenCommands, scaffoldProject };
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import type { CodegenFieldMeta, CodegenModel } from '../domain';
|
|
2
|
+
/**
|
|
3
|
+
* Map Tango field metadata to the TypeScript type used in generated source.
|
|
4
|
+
*/
|
|
2
5
|
export declare function mapFieldTypeToTS(type: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Normalize field metadata into a stable iterable shape for generators.
|
|
8
|
+
*/
|
|
3
9
|
export declare function normalizeFields(fields: CodegenModel['fields']): Array<[string, CodegenFieldMeta]>;
|
package/package.json
CHANGED
|
@@ -1,54 +1,66 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
"./domain": {
|
|
14
|
-
"types": "./dist/domain/index.d.ts",
|
|
15
|
-
"import": "./dist/domain/index.js"
|
|
16
|
-
},
|
|
17
|
-
"./generators": {
|
|
18
|
-
"types": "./dist/generators/index.d.ts",
|
|
19
|
-
"import": "./dist/generators/index.js"
|
|
20
|
-
}
|
|
2
|
+
"name": "@danceroutine/tango-codegen",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI for generating repositories, types, migrations, and OpenAPI specs for Tango",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
21
12
|
},
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"scripts": {
|
|
26
|
-
"build": "tsdown",
|
|
27
|
-
"test": "vitest run --coverage",
|
|
28
|
-
"test:watch": "vitest",
|
|
29
|
-
"typecheck": "tsc --noEmit"
|
|
13
|
+
"./domain": {
|
|
14
|
+
"types": "./dist/domain/index.d.ts",
|
|
15
|
+
"import": "./dist/domain/index.js"
|
|
30
16
|
},
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"cli",
|
|
35
|
-
"generator",
|
|
36
|
-
"migrations"
|
|
37
|
-
],
|
|
38
|
-
"author": "Pedro Del Moral Lopez",
|
|
39
|
-
"license": "MIT",
|
|
40
|
-
"repository": {
|
|
41
|
-
"type": "git",
|
|
42
|
-
"url": "https://github.com/danceroutine/tango.git",
|
|
43
|
-
"directory": "packages/codegen"
|
|
17
|
+
"./generators": {
|
|
18
|
+
"types": "./dist/generators/index.d.ts",
|
|
19
|
+
"import": "./dist/generators/index.js"
|
|
44
20
|
},
|
|
45
|
-
"
|
|
46
|
-
|
|
21
|
+
"./frameworks": {
|
|
22
|
+
"types": "./dist/frameworks/index.d.ts",
|
|
23
|
+
"import": "./dist/frameworks/index.js"
|
|
47
24
|
},
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"typescript": "^5.6.3",
|
|
52
|
-
"vitest": "^4.0.6"
|
|
25
|
+
"./commands": {
|
|
26
|
+
"types": "./dist/commands/index.d.ts",
|
|
27
|
+
"import": "./dist/commands/index.js"
|
|
53
28
|
}
|
|
54
|
-
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"keywords": [
|
|
34
|
+
"tango",
|
|
35
|
+
"codegen",
|
|
36
|
+
"cli",
|
|
37
|
+
"generator",
|
|
38
|
+
"migrations"
|
|
39
|
+
],
|
|
40
|
+
"author": "Pedro Del Moral Lopez",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/danceroutine/tango.git",
|
|
45
|
+
"directory": "packages/codegen"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"yargs": "^17.7.2",
|
|
49
|
+
"@danceroutine/tango-core": "1.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/yargs": "^17.0.33",
|
|
53
|
+
"@types/node": "^22.9.0",
|
|
54
|
+
"tsdown": "^0.4.0",
|
|
55
|
+
"typescript": "^5.6.3",
|
|
56
|
+
"vitest": "^4.0.6"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "tsdown",
|
|
60
|
+
"test": "vitest run --coverage",
|
|
61
|
+
"test:watch": "vitest",
|
|
62
|
+
"typecheck": "pnpm run typecheck:prod && pnpm run typecheck:test",
|
|
63
|
+
"typecheck:prod": "tsc --noEmit -p tsconfig.json",
|
|
64
|
+
"typecheck:test": "tsc --noEmit -p tsconfig.tests.json"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function generateRepository(modelName: string): string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generators-CDXkQAkq.js","names":["type: string","typeMap: Record<string, string>","fields: CodegenModel['fields']","models: CodegenModel[]","model: CodegenModel","modelName: string","modelName: string"],"sources":["../src/mappers/fieldType.ts","../src/mappers/index.ts","../src/generators/migration/generateMigrationFromModels.ts","../src/generators/migration/index.ts","../src/generators/model/generateModelInterface.ts","../src/generators/model/index.ts","../src/generators/repository/generateRepository.ts","../src/generators/repository/index.ts","../src/generators/viewset/generateViewSet.ts","../src/generators/viewset/index.ts","../src/generators/index.ts"],"sourcesContent":["import type { CodegenFieldMeta, CodegenModel } from '../domain';\n\nexport function mapFieldTypeToTS(type: string): string {\n const typeMap: Record<string, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'Date',\n serial: 'number',\n int: 'number',\n bigint: 'number',\n text: 'string',\n bool: 'boolean',\n uuid: 'string',\n jsonb: 'any',\n timestamptz: 'Date',\n };\n\n return typeMap[type] || 'unknown';\n}\n\nexport function normalizeFields(fields: CodegenModel['fields']): Array<[string, CodegenFieldMeta]> {\n if (Array.isArray(fields)) {\n return fields.map((field) => [\n field.name,\n {\n type: field.type,\n primaryKey: field.primaryKey,\n unique: field.unique,\n nullable: !field.notNull,\n default: field.default,\n },\n ]);\n }\n\n return Object.entries(fields);\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { mapFieldTypeToTS, normalizeFields } from './fieldType';\n","import type { CodegenModel } from '../../domain';\nimport { normalizeFields } from '../../mappers';\n\nexport function generateMigrationFromModels(models: CodegenModel[]): string {\n const generatedId = `auto_generated_${Date.now()}`;\n const className = `Migration_${generatedId}`;\n const operations = models\n .map((model) => {\n const fields = normalizeFields(model.fields)\n .map(([name, meta]) => {\n return ` cols.add('${name}', (b) => b.${meta.dbType || meta.type}()${meta.primaryKey ? '.primaryKey()' : ''}${meta.unique ? '.unique()' : ''}${meta.nullable ? '' : '.notNull()'});`;\n })\n .join('\\n');\n\n return ` op.table('${model.name.toLowerCase()}s').create((cols) => {\\n${fields}\\n }),`;\n })\n .join('\\n\\n');\n const reverseOperations = models\n .slice()\n .reverse()\n .map((model) => ` op.table('${model.name.toLowerCase()}s').drop(),`)\n .join('\\n');\n\n return `\nimport { Migration, op } from '@danceroutine/tango-migrations';\n\nexport default class ${className} extends Migration {\n id = '${generatedId}';\n\n up(m) {\n m.run(\n${operations}\n );\n }\n\n down() {\n m.run(\n${reverseOperations}\n );\n }\n}\n `.trim();\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateMigrationFromModels } from './generateMigrationFromModels';\n","import type { CodegenModel } from '../../domain';\nimport { mapFieldTypeToTS, normalizeFields } from '../../mappers';\n\nexport function generateModelInterface(model: CodegenModel): string {\n const fields = normalizeFields(model.fields)\n .map(([name, meta]) => {\n const type = mapFieldTypeToTS(meta.type);\n const optional = !meta.primaryKey && meta.default !== undefined ? '?' : '';\n return ` ${name}${optional}: ${type};`;\n })\n .join('\\n');\n\n return `\nexport interface ${model.name} {\n${fields}\n}\n `.trim();\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateModelInterface } from './generateModelInterface';\n","export function generateRepository(modelName: string): string {\n return `\nimport { Repository } from '@danceroutine/tango-orm';\nimport type { DBClient } from '@danceroutine/tango-orm/connection';\nimport { ${modelName} } from './models';\n\nexport class ${modelName}Repository extends Repository<typeof ${modelName}> {\n constructor(client: DBClient) {\n super(client);\n }\n\n // Add custom repository methods here\n}\n `.trim();\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateRepository } from './generateRepository';\n","export function generateViewSet(modelName: string): string {\n const repoName = `${modelName}Repository`;\n\n return `\nimport { ModelViewSet } from '@danceroutine/tango-resources';\nimport { FilterSet } from '@danceroutine/tango-resources';\nimport { ${repoName} } from './repositories';\nimport { ${modelName} } from './models';\n\nexport class ${modelName}ViewSet extends ModelViewSet<typeof ${modelName}> {\n constructor(repo: ${repoName}) {\n super({\n repository: repo,\n filterSet: new FilterSet({\n // Add filters here\n }),\n pagination: {\n defaultLimit: 25,\n maxLimit: 100,\n cursorColumn: 'id',\n },\n });\n }\n\n // Add custom actions here\n}\n `.trim();\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateViewSet } from './generateViewSet';\n","/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as migration from './migration/index';\nexport * as model from './model/index';\nexport * as repository from './repository/index';\nexport * as viewset from './viewset/index';\n\nexport { generateRepository } from './repository/index';\nexport { generateModelInterface } from './model/index';\nexport { generateMigrationFromModels } from './migration/index';\nexport { generateViewSet } from './viewset/index';\n"],"mappings":";;;;;;;;;;;;AAEO,SAAS,iBAAiBA,MAAsB;CACnD,MAAMC,UAAkC;EACpC,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,MAAM;EACN,QAAQ;EACR,KAAK;EACL,QAAQ;EACR,MAAM;EACN,MAAM;EACN,MAAM;EACN,OAAO;EACP,aAAa;CAChB;AAED,QAAO,QAAQ,SAAS;AAC3B;AAEM,SAAS,gBAAgBC,QAAmE;AAC/F,KAAI,MAAM,QAAQ,OAAO,CACrB,QAAO,OAAO,IAAI,CAAC,UAAU,CACzB,MAAM,MACN;EACI,MAAM,MAAM;EACZ,YAAY,MAAM;EAClB,QAAQ,MAAM;EACd,WAAW,MAAM;EACjB,SAAS,MAAM;CAEtB,CAAA,EAAC;AAGN,QAAO,OAAO,QAAQ,OAAO;AAChC;;;;;;;;;;;;ACjCM,SAAS,4BAA4BC,QAAgC;CACxE,MAAM,eAAe,iBAAiB,KAAK,KAAK,CAAC;CACjD,MAAM,aAAa,YAAY,YAAY;CAC3C,MAAM,aAAa,OACd,IAAI,CAAC,UAAU;EACZ,MAAM,SAAS,gBAAgB,MAAM,OAAO,CACvC,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK;AACnB,WAAQ,kBAAkB,KAAK,cAAc,KAAK,UAAU,KAAK,KAAK,IAAI,KAAK,aAAa,kBAAkB,GAAG,EAAE,KAAK,SAAS,cAAc,GAAG,EAAE,KAAK,WAAW,KAAK,aAAa;EACzL,EAAC,CACD,KAAK,KAAK;AAEf,UAAQ,kBAAkB,MAAM,KAAK,aAAa,CAAC,0BAA0B,OAAO;CACvF,EAAC,CACD,KAAK,OAAO;CACjB,MAAM,oBAAoB,OACrB,OAAO,CACP,SAAS,CACT,IAAI,CAAC,WAAW,kBAAkB,MAAM,KAAK,aAAa,CAAC,aAAa,CACxE,KAAK,KAAK;AAEf,QAAO,CAAC;;;uBAGW,UAAU;UACvB,YAAY;;;;EAIpB,WAAW;;;;;;EAMX,kBAAkB;;;;IAIhB,MAAM;AACT;;;;;;;;;ACvCM,SAAS,uBAAuBC,OAA6B;CAChE,MAAM,SAAS,gBAAgB,MAAM,OAAO,CACvC,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK;EACnB,MAAM,OAAO,iBAAiB,KAAK,KAAK;EACxC,MAAM,YAAY,KAAK,cAAc,KAAK,YAAY,YAAY,MAAM;AACxE,UAAQ,IAAI,KAAK,EAAE,SAAS,IAAI,KAAK;CACxC,EAAC,CACD,KAAK,KAAK;AAEf,QAAO,CAAC;mBACO,MAAM,KAAK;EAC5B,OAAO;;IAEL,MAAM;AACT;;;;;;;;;ACjBM,SAAS,mBAAmBC,WAA2B;AAC1D,QAAO,CAAC;;;WAGD,UAAU;;eAEN,UAAU,uCAAuC,UAAU;;;;;;;IAOtE,MAAM;AACT;;;;;;;;;ACdM,SAAS,gBAAgBC,WAA2B;CACvD,MAAM,YAAY,EAAE,UAAU;AAE9B,QAAO,CAAC;;;WAGD,SAAS;WACT,UAAU;;eAEN,UAAU,sCAAsC,UAAU;sBACnD,SAAS;;;;;;;;;;;;;;;;IAgB3B,MAAM;AACT"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["export const VERSION = '0.1.0';\n"],"mappings":";;;;MAAa,UAAU"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export function mapFieldTypeToTS(type) {
|
|
2
|
-
const typeMap = {
|
|
3
|
-
string: 'string',
|
|
4
|
-
number: 'number',
|
|
5
|
-
boolean: 'boolean',
|
|
6
|
-
date: 'Date',
|
|
7
|
-
serial: 'number',
|
|
8
|
-
int: 'number',
|
|
9
|
-
bigint: 'number',
|
|
10
|
-
text: 'string',
|
|
11
|
-
bool: 'boolean',
|
|
12
|
-
uuid: 'string',
|
|
13
|
-
jsonb: 'unknown',
|
|
14
|
-
timestamptz: 'Date',
|
|
15
|
-
};
|
|
16
|
-
return typeMap[type] || 'unknown';
|
|
17
|
-
}
|
|
18
|
-
export function normalizeFields(fields) {
|
|
19
|
-
if (Array.isArray(fields)) {
|
|
20
|
-
return fields.map((field) => [
|
|
21
|
-
field.name,
|
|
22
|
-
{
|
|
23
|
-
type: field.type,
|
|
24
|
-
primaryKey: field.primaryKey,
|
|
25
|
-
unique: field.unique,
|
|
26
|
-
nullable: !field.notNull,
|
|
27
|
-
default: field.default,
|
|
28
|
-
},
|
|
29
|
-
]);
|
|
30
|
-
}
|
|
31
|
-
return Object.entries(fields);
|
|
32
|
-
}
|
package/dist/version.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.0";
|