archetype-engine 2.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.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/src/ai/adapters/anthropic.d.ts +31 -0
  4. package/dist/src/ai/adapters/anthropic.d.ts.map +1 -0
  5. package/dist/src/ai/adapters/anthropic.js +75 -0
  6. package/dist/src/ai/adapters/openai.d.ts +33 -0
  7. package/dist/src/ai/adapters/openai.d.ts.map +1 -0
  8. package/dist/src/ai/adapters/openai.js +120 -0
  9. package/dist/src/ai/adapters/vercel.d.ts +434 -0
  10. package/dist/src/ai/adapters/vercel.d.ts.map +1 -0
  11. package/dist/src/ai/adapters/vercel.js +162 -0
  12. package/dist/src/ai/index.d.ts +492 -0
  13. package/dist/src/ai/index.d.ts.map +1 -0
  14. package/dist/src/ai/index.js +71 -0
  15. package/dist/src/ai/state.d.ts +13 -0
  16. package/dist/src/ai/state.d.ts.map +1 -0
  17. package/dist/src/ai/state.js +215 -0
  18. package/dist/src/ai/tools.d.ts +13 -0
  19. package/dist/src/ai/tools.d.ts.map +1 -0
  20. package/dist/src/ai/tools.js +257 -0
  21. package/dist/src/ai/types.d.ts +196 -0
  22. package/dist/src/ai/types.d.ts.map +1 -0
  23. package/dist/src/ai/types.js +9 -0
  24. package/dist/src/cli.d.ts +3 -0
  25. package/dist/src/cli.d.ts.map +1 -0
  26. package/dist/src/cli.js +540 -0
  27. package/dist/src/core/utils.d.ts +27 -0
  28. package/dist/src/core/utils.d.ts.map +1 -0
  29. package/dist/src/core/utils.js +56 -0
  30. package/dist/src/entity.d.ts +165 -0
  31. package/dist/src/entity.d.ts.map +1 -0
  32. package/dist/src/entity.js +108 -0
  33. package/dist/src/fields.d.ts +207 -0
  34. package/dist/src/fields.d.ts.map +1 -0
  35. package/dist/src/fields.js +291 -0
  36. package/dist/src/generators/erd-ir.d.ts +10 -0
  37. package/dist/src/generators/erd-ir.d.ts.map +1 -0
  38. package/dist/src/generators/erd-ir.js +119 -0
  39. package/dist/src/index.d.ts +51 -0
  40. package/dist/src/index.d.ts.map +1 -0
  41. package/dist/src/index.js +101 -0
  42. package/dist/src/init/dependencies.d.ts +31 -0
  43. package/dist/src/init/dependencies.d.ts.map +1 -0
  44. package/dist/src/init/dependencies.js +101 -0
  45. package/dist/src/init/entity-templates.d.ts +42 -0
  46. package/dist/src/init/entity-templates.d.ts.map +1 -0
  47. package/dist/src/init/entity-templates.js +367 -0
  48. package/dist/src/init/index.d.ts +10 -0
  49. package/dist/src/init/index.d.ts.map +1 -0
  50. package/dist/src/init/index.js +250 -0
  51. package/dist/src/init/prompts.d.ts +11 -0
  52. package/dist/src/init/prompts.d.ts.map +1 -0
  53. package/dist/src/init/prompts.js +275 -0
  54. package/dist/src/init/templates.d.ts +24 -0
  55. package/dist/src/init/templates.d.ts.map +1 -0
  56. package/dist/src/init/templates.js +587 -0
  57. package/dist/src/json/index.d.ts +11 -0
  58. package/dist/src/json/index.d.ts.map +1 -0
  59. package/dist/src/json/index.js +26 -0
  60. package/dist/src/json/parser.d.ts +61 -0
  61. package/dist/src/json/parser.d.ts.map +1 -0
  62. package/dist/src/json/parser.js +309 -0
  63. package/dist/src/json/types.d.ts +275 -0
  64. package/dist/src/json/types.d.ts.map +1 -0
  65. package/dist/src/json/types.js +10 -0
  66. package/dist/src/manifest.d.ts +147 -0
  67. package/dist/src/manifest.d.ts.map +1 -0
  68. package/dist/src/manifest.js +104 -0
  69. package/dist/src/relations.d.ts +96 -0
  70. package/dist/src/relations.d.ts.map +1 -0
  71. package/dist/src/relations.js +108 -0
  72. package/dist/src/source.d.ts +93 -0
  73. package/dist/src/source.d.ts.map +1 -0
  74. package/dist/src/source.js +89 -0
  75. package/dist/src/template/context.d.ts +34 -0
  76. package/dist/src/template/context.d.ts.map +1 -0
  77. package/dist/src/template/context.js +31 -0
  78. package/dist/src/template/index.d.ts +6 -0
  79. package/dist/src/template/index.d.ts.map +1 -0
  80. package/dist/src/template/index.js +12 -0
  81. package/dist/src/template/registry.d.ts +18 -0
  82. package/dist/src/template/registry.d.ts.map +1 -0
  83. package/dist/src/template/registry.js +89 -0
  84. package/dist/src/template/runner.d.ts +9 -0
  85. package/dist/src/template/runner.d.ts.map +1 -0
  86. package/dist/src/template/runner.js +125 -0
  87. package/dist/src/template/types.d.ts +73 -0
  88. package/dist/src/template/types.d.ts.map +1 -0
  89. package/dist/src/template/types.js +3 -0
  90. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts +22 -0
  91. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts.map +1 -0
  92. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.js +866 -0
  93. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts +20 -0
  94. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts.map +1 -0
  95. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.js +273 -0
  96. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts +22 -0
  97. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts.map +1 -0
  98. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.js +237 -0
  99. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts +30 -0
  100. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts.map +1 -0
  101. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.js +345 -0
  102. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts +25 -0
  103. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts.map +1 -0
  104. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.js +199 -0
  105. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts +8 -0
  106. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts.map +1 -0
  107. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.js +18 -0
  108. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts +22 -0
  109. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts.map +1 -0
  110. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.js +270 -0
  111. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts +23 -0
  112. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts.map +1 -0
  113. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.js +304 -0
  114. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts +21 -0
  115. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts.map +1 -0
  116. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.js +248 -0
  117. package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts +30 -0
  118. package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts.map +1 -0
  119. package/dist/src/templates/nextjs-drizzle-trpc/index.js +71 -0
  120. package/dist/src/validation/index.d.ts +71 -0
  121. package/dist/src/validation/index.d.ts.map +1 -0
  122. package/dist/src/validation/index.js +314 -0
  123. package/package.json +86 -0
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Manifest definition - collects all entities and settings
3
+ * @module manifest
4
+ */
5
+ import { EntityIR } from './entity';
6
+ import { ExternalSourceConfig } from './source';
7
+ /**
8
+ * Generation mode configuration
9
+ */
10
+ export interface ModeConfig {
11
+ /**
12
+ * 'full' - Generate database schema, API, validation, hooks (default)
13
+ * 'headless' - Skip database schema, generate validation, hooks, services only
14
+ * 'api-only' - Generate API layer only (for backend services)
15
+ */
16
+ type: 'full' | 'headless' | 'api-only';
17
+ /**
18
+ * When headless, optionally specify which generators to include
19
+ * Default: ['validation', 'hooks', 'services', 'i18n']
20
+ */
21
+ include?: ('schema' | 'validation' | 'api' | 'hooks' | 'types' | 'services' | 'i18n')[];
22
+ }
23
+ /**
24
+ * Normalize mode config from shorthand or full config
25
+ */
26
+ export declare function normalizeMode(mode?: ModeConfig | 'full' | 'headless' | 'api-only'): ModeConfig;
27
+ /**
28
+ * Database connection configuration
29
+ */
30
+ export interface DatabaseConfig {
31
+ /** Database type */
32
+ type: 'sqlite' | 'postgres' | 'mysql';
33
+ /** SQLite file path (for SQLite only) */
34
+ file?: string;
35
+ /** Connection URL (for PostgreSQL/MySQL) */
36
+ url?: string;
37
+ }
38
+ export interface AuthConfig {
39
+ enabled: boolean;
40
+ adapter?: 'drizzle';
41
+ providers?: ('credentials' | 'google' | 'github' | 'discord')[];
42
+ sessionStrategy?: 'jwt' | 'database';
43
+ }
44
+ export interface I18nConfig {
45
+ languages: string[];
46
+ defaultLanguage: string;
47
+ outputDir?: string;
48
+ }
49
+ export interface ObservabilityConfig {
50
+ logging?: {
51
+ enabled: boolean;
52
+ level?: 'debug' | 'info' | 'warn' | 'error';
53
+ format?: 'json' | 'pretty';
54
+ };
55
+ telemetry?: {
56
+ enabled: boolean;
57
+ events?: ('create' | 'update' | 'remove')[];
58
+ };
59
+ audit?: {
60
+ enabled: boolean;
61
+ entity?: string;
62
+ };
63
+ }
64
+ export interface TenancyConfig {
65
+ enabled: boolean;
66
+ field: string;
67
+ }
68
+ export interface DefaultBehaviors {
69
+ timestamps?: boolean;
70
+ softDelete?: boolean;
71
+ audit?: boolean;
72
+ }
73
+ export interface ManifestDefinition {
74
+ /** Template ID (e.g., 'nextjs-drizzle-trpc') */
75
+ template?: string;
76
+ /**
77
+ * Generation mode - 'full' | 'headless' | 'api-only' or ModeConfig object
78
+ * - 'full': Generate database schema, API, validation, hooks (default)
79
+ * - 'headless': Skip database schema, generate validation, hooks, services only
80
+ * - 'api-only': Generate API layer only
81
+ */
82
+ mode?: ModeConfig | 'full' | 'headless' | 'api-only';
83
+ /** Entity definitions */
84
+ entities: EntityIR[];
85
+ /**
86
+ * Global default source for all entities.
87
+ * Individual entities can override this with their own source.
88
+ */
89
+ source?: ExternalSourceConfig;
90
+ /** Database configuration (required for 'full' mode, optional for 'headless') */
91
+ database?: DatabaseConfig;
92
+ auth?: AuthConfig;
93
+ i18n?: I18nConfig;
94
+ observability?: ObservabilityConfig;
95
+ tenancy?: TenancyConfig;
96
+ defaults?: DefaultBehaviors;
97
+ }
98
+ export interface ManifestIR {
99
+ /** Template ID - CLI validates if provided */
100
+ template?: string;
101
+ /** Normalized mode configuration */
102
+ mode: ModeConfig;
103
+ /** Entity definitions */
104
+ entities: EntityIR[];
105
+ /** Global default source for entities (optional) */
106
+ source?: ExternalSourceConfig;
107
+ /** Database configuration (optional for headless mode) */
108
+ database?: DatabaseConfig;
109
+ auth: AuthConfig;
110
+ i18n: I18nConfig;
111
+ observability: ObservabilityConfig;
112
+ tenancy: TenancyConfig;
113
+ defaults: DefaultBehaviors;
114
+ }
115
+ /**
116
+ * Define a manifest with entities and configuration
117
+ *
118
+ * @param definition - Manifest configuration
119
+ * @returns Compiled ManifestIR for use by CLI and generators
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const manifest = defineManifest({
124
+ * template: 'nextjs-drizzle-trpc',
125
+ * entities: [User, Post],
126
+ * database: { type: 'sqlite', file: './sqlite.db' },
127
+ * })
128
+ * ```
129
+ */
130
+ export declare function defineManifest(definition: ManifestDefinition): ManifestIR;
131
+ /**
132
+ * Alias for defineManifest - use in archetype.config.ts
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * // archetype.config.ts
137
+ * import { defineConfig } from 'archetype-engine'
138
+ *
139
+ * export default defineConfig({
140
+ * template: 'nextjs-drizzle-trpc',
141
+ * entities: [User, Post],
142
+ * database: { type: 'postgres', url: process.env.DATABASE_URL },
143
+ * })
144
+ * ```
145
+ */
146
+ export declare const defineConfig: typeof defineManifest;
147
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ /**
3
+ * Manifest definition - collects all entities and settings
4
+ * @module manifest
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.defineConfig = void 0;
8
+ exports.normalizeMode = normalizeMode;
9
+ exports.defineManifest = defineManifest;
10
+ /**
11
+ * Normalize mode config from shorthand or full config
12
+ */
13
+ function normalizeMode(mode) {
14
+ if (!mode || mode === 'full') {
15
+ return { type: 'full' };
16
+ }
17
+ if (mode === 'headless') {
18
+ return { type: 'headless', include: ['validation', 'hooks', 'services', 'i18n'] };
19
+ }
20
+ if (mode === 'api-only') {
21
+ return { type: 'api-only', include: ['validation', 'services'] };
22
+ }
23
+ return mode;
24
+ }
25
+ // Compile manifest definition to IR
26
+ function compileManifest(definition) {
27
+ const mode = normalizeMode(definition.mode);
28
+ // Validate: full mode requires database
29
+ if (mode.type === 'full' && !definition.database) {
30
+ throw new Error(`Mode 'full' requires database configuration.\n` +
31
+ `Fix: Add database config or use mode: 'headless' for frontend-only projects.`);
32
+ }
33
+ return {
34
+ template: definition.template,
35
+ mode,
36
+ entities: definition.entities,
37
+ source: definition.source,
38
+ database: definition.database,
39
+ auth: {
40
+ enabled: false,
41
+ adapter: 'drizzle',
42
+ providers: [],
43
+ sessionStrategy: 'jwt',
44
+ ...definition.auth,
45
+ },
46
+ i18n: {
47
+ languages: ['en'],
48
+ defaultLanguage: 'en',
49
+ outputDir: './messages',
50
+ ...definition.i18n,
51
+ },
52
+ observability: {
53
+ logging: { enabled: false, level: 'info', format: 'json' },
54
+ telemetry: { enabled: false, events: [] },
55
+ audit: { enabled: false },
56
+ ...definition.observability,
57
+ },
58
+ tenancy: {
59
+ enabled: false,
60
+ field: 'organizationId',
61
+ ...definition.tenancy,
62
+ },
63
+ defaults: {
64
+ timestamps: true,
65
+ softDelete: false,
66
+ audit: false,
67
+ ...definition.defaults,
68
+ },
69
+ };
70
+ }
71
+ /**
72
+ * Define a manifest with entities and configuration
73
+ *
74
+ * @param definition - Manifest configuration
75
+ * @returns Compiled ManifestIR for use by CLI and generators
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const manifest = defineManifest({
80
+ * template: 'nextjs-drizzle-trpc',
81
+ * entities: [User, Post],
82
+ * database: { type: 'sqlite', file: './sqlite.db' },
83
+ * })
84
+ * ```
85
+ */
86
+ function defineManifest(definition) {
87
+ return compileManifest(definition);
88
+ }
89
+ /**
90
+ * Alias for defineManifest - use in archetype.config.ts
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * // archetype.config.ts
95
+ * import { defineConfig } from 'archetype-engine'
96
+ *
97
+ * export default defineConfig({
98
+ * template: 'nextjs-drizzle-trpc',
99
+ * entities: [User, Post],
100
+ * database: { type: 'postgres', url: process.env.DATABASE_URL },
101
+ * })
102
+ * ```
103
+ */
104
+ exports.defineConfig = defineManifest;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Relation builders for entity definitions
3
+ * @module relations
4
+ */
5
+ import type { FieldBuilder, FieldConfig } from './fields';
6
+ export type RelationType = 'hasOne' | 'hasMany' | 'belongsToMany';
7
+ /**
8
+ * Pivot table configuration for belongsToMany relations
9
+ */
10
+ export interface PivotConfig {
11
+ /** Custom name for the junction/pivot table */
12
+ table?: string;
13
+ /** Additional fields on the pivot table */
14
+ fields?: Record<string, FieldConfig>;
15
+ }
16
+ export interface RelationConfig {
17
+ type: RelationType;
18
+ entity: string;
19
+ /** Optional custom foreign key field name */
20
+ field?: string;
21
+ /** Whether the relation is optional (for hasOne relations) */
22
+ optional?: boolean;
23
+ /** Pivot table configuration for belongsToMany */
24
+ pivot?: PivotConfig;
25
+ }
26
+ export interface RelationBuilder {
27
+ readonly _config: RelationConfig;
28
+ /** Override the default foreign key field name */
29
+ field(name: string): RelationBuilder;
30
+ /** Mark this relation as optional (foreign key can be null) */
31
+ optional(): RelationBuilder;
32
+ }
33
+ export interface BelongsToManyBuilder extends RelationBuilder {
34
+ /** Configure pivot table with additional fields */
35
+ through(options: {
36
+ table?: string;
37
+ fields: Record<string, FieldBuilder>;
38
+ }): BelongsToManyBuilder;
39
+ }
40
+ /**
41
+ * Create a one-to-one relation (adds foreign key to this entity)
42
+ *
43
+ * @param entity - Target entity name
44
+ * @returns RelationBuilder
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * relations: {
49
+ * author: hasOne('User'),
50
+ * category: hasOne('Category').field('categoryId'),
51
+ * }
52
+ * ```
53
+ */
54
+ export declare function hasOne(entity: string): RelationBuilder;
55
+ /**
56
+ * Create a one-to-many relation (target entity has FK to this entity)
57
+ *
58
+ * @param entity - Target entity name
59
+ * @returns RelationBuilder
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * relations: {
64
+ * posts: hasMany('Post'),
65
+ * comments: hasMany('Comment'),
66
+ * }
67
+ * ```
68
+ */
69
+ export declare function hasMany(entity: string): RelationBuilder;
70
+ /**
71
+ * Create a many-to-many relation (creates junction table)
72
+ *
73
+ * @param entity - Target entity name
74
+ * @returns BelongsToManyBuilder
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * // Simple many-to-many
79
+ * relations: {
80
+ * tags: belongsToMany('Tag'),
81
+ * }
82
+ *
83
+ * // With pivot data (e.g., OrderItem with quantity)
84
+ * relations: {
85
+ * products: belongsToMany('Product').through({
86
+ * table: 'order_items',
87
+ * fields: {
88
+ * quantity: number().required().min(1),
89
+ * unitPrice: number().required(),
90
+ * }
91
+ * }),
92
+ * }
93
+ * ```
94
+ */
95
+ export declare function belongsToMany(entity: string): BelongsToManyBuilder;
96
+ //# sourceMappingURL=relations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/relations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEzD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,eAAe,CAAA;AAEjE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kDAAkD;IAClD,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;IAChC,kDAAkD;IAClD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;IACpC,+DAA+D;IAC/D,QAAQ,IAAI,eAAe,CAAA;CAC5B;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D,mDAAmD;IACnD,OAAO,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;KAAE,GAAG,oBAAoB,CAAA;CACjG;AAgCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAKtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAKvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAKlE"}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * Relation builders for entity definitions
4
+ * @module relations
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.hasOne = hasOne;
8
+ exports.hasMany = hasMany;
9
+ exports.belongsToMany = belongsToMany;
10
+ function createRelationBuilder(config) {
11
+ return {
12
+ _config: config,
13
+ field: (name) => createRelationBuilder({ ...config, field: name }),
14
+ optional: () => createRelationBuilder({ ...config, optional: true }),
15
+ };
16
+ }
17
+ function createBelongsToManyBuilder(config) {
18
+ return {
19
+ _config: config,
20
+ field: (name) => createBelongsToManyBuilder({ ...config, field: name }),
21
+ optional: () => createBelongsToManyBuilder({ ...config, optional: true }),
22
+ through: (options) => {
23
+ // Extract field configs from builders
24
+ const fieldConfigs = {};
25
+ for (const [fieldName, builder] of Object.entries(options.fields)) {
26
+ fieldConfigs[fieldName] = builder._config;
27
+ }
28
+ return createBelongsToManyBuilder({
29
+ ...config,
30
+ pivot: {
31
+ table: options.table,
32
+ fields: fieldConfigs,
33
+ },
34
+ });
35
+ },
36
+ };
37
+ }
38
+ /**
39
+ * Create a one-to-one relation (adds foreign key to this entity)
40
+ *
41
+ * @param entity - Target entity name
42
+ * @returns RelationBuilder
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * relations: {
47
+ * author: hasOne('User'),
48
+ * category: hasOne('Category').field('categoryId'),
49
+ * }
50
+ * ```
51
+ */
52
+ function hasOne(entity) {
53
+ return createRelationBuilder({
54
+ type: 'hasOne',
55
+ entity,
56
+ });
57
+ }
58
+ /**
59
+ * Create a one-to-many relation (target entity has FK to this entity)
60
+ *
61
+ * @param entity - Target entity name
62
+ * @returns RelationBuilder
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * relations: {
67
+ * posts: hasMany('Post'),
68
+ * comments: hasMany('Comment'),
69
+ * }
70
+ * ```
71
+ */
72
+ function hasMany(entity) {
73
+ return createRelationBuilder({
74
+ type: 'hasMany',
75
+ entity,
76
+ });
77
+ }
78
+ /**
79
+ * Create a many-to-many relation (creates junction table)
80
+ *
81
+ * @param entity - Target entity name
82
+ * @returns BelongsToManyBuilder
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * // Simple many-to-many
87
+ * relations: {
88
+ * tags: belongsToMany('Tag'),
89
+ * }
90
+ *
91
+ * // With pivot data (e.g., OrderItem with quantity)
92
+ * relations: {
93
+ * products: belongsToMany('Product').through({
94
+ * table: 'order_items',
95
+ * fields: {
96
+ * quantity: number().required().min(1),
97
+ * unitPrice: number().required(),
98
+ * }
99
+ * }),
100
+ * }
101
+ * ```
102
+ */
103
+ function belongsToMany(entity) {
104
+ return createBelongsToManyBuilder({
105
+ type: 'belongsToMany',
106
+ entity,
107
+ });
108
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * External API source configuration
3
+ * @module source
4
+ */
5
+ /**
6
+ * Options for external API source configuration
7
+ */
8
+ export interface ExternalSourceOptions {
9
+ /** Path prefix like '/v1' or '/api' - prepended to all endpoints */
10
+ pathPrefix?: string;
11
+ /** Override auto-pluralization: 'product' instead of 'products' */
12
+ resourceName?: string;
13
+ /** Override specific endpoints when API doesn't follow REST conventions */
14
+ override?: {
15
+ list?: string;
16
+ get?: string;
17
+ create?: string;
18
+ update?: string;
19
+ delete?: string;
20
+ };
21
+ /** Auth config for this API */
22
+ auth?: {
23
+ type: 'bearer' | 'api-key';
24
+ header?: string;
25
+ };
26
+ }
27
+ /**
28
+ * Compiled external source configuration
29
+ */
30
+ export interface ExternalSourceConfig {
31
+ type: 'external';
32
+ /** Base URL - can use 'env:VARIABLE_NAME' syntax */
33
+ baseUrl: string;
34
+ /** Path prefix */
35
+ pathPrefix: string;
36
+ /** Resource name (pluralized entity name) */
37
+ resourceName?: string;
38
+ /** Resolved endpoints */
39
+ endpoints: {
40
+ list: string;
41
+ get: string;
42
+ create: string;
43
+ update: string;
44
+ delete: string;
45
+ };
46
+ /** Auth configuration */
47
+ auth?: {
48
+ type: 'bearer' | 'api-key';
49
+ header: string;
50
+ };
51
+ }
52
+ /**
53
+ * Database source configuration (default when no external source)
54
+ */
55
+ export interface DatabaseSourceConfig {
56
+ type: 'database';
57
+ }
58
+ /**
59
+ * Entity source configuration - either database or external API
60
+ */
61
+ export type SourceConfig = DatabaseSourceConfig | ExternalSourceConfig;
62
+ /**
63
+ * Create an external API source configuration
64
+ *
65
+ * @param baseUrl - Base URL for the API. Supports 'env:VARIABLE_NAME' syntax.
66
+ * @param options - Optional configuration for path prefix, resource name, endpoint overrides
67
+ * @returns ExternalSourceConfig for use in entity or manifest source field
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * // Simple - all defaults
72
+ * source: external('env:API_URL')
73
+ * // Generates: GET/POST /products, GET/PUT/DELETE /products/:id
74
+ *
75
+ * // With version prefix
76
+ * source: external('env:API_URL', { pathPrefix: '/v1' })
77
+ * // Generates: /v1/products, /v1/products/:id
78
+ *
79
+ * // Override weird endpoints
80
+ * source: external('env:LEGACY_API', {
81
+ * override: {
82
+ * list: 'GET /catalog/search',
83
+ * get: 'GET /catalog/item/:sku',
84
+ * }
85
+ * })
86
+ * ```
87
+ */
88
+ export declare function external(baseUrl: string, options?: ExternalSourceOptions): ExternalSourceConfig;
89
+ /**
90
+ * Resolve the final endpoints for an entity, using its name for pluralization
91
+ */
92
+ export declare function resolveEndpoints(entityName: string, source: ExternalSourceConfig): ExternalSourceConfig['endpoints'];
93
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/source.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,+BAA+B;IAC/B,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAA;QAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAA;IAChB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,yBAAyB;IACzB,SAAS,EAAE;QACT,IAAI,EAAE,MAAM,CAAA;QACZ,GAAG,EAAE,MAAM,CAAA;QACX,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,yBAAyB;IACzB,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAA;QAC1B,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,oBAAoB,GAAG,oBAAoB,CAAA;AAqBtE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CA0BtB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,oBAAoB,GAC3B,oBAAoB,CAAC,WAAW,CAAC,CAWnC"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ /**
3
+ * External API source configuration
4
+ * @module source
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.external = external;
8
+ exports.resolveEndpoints = resolveEndpoints;
9
+ const utils_1 = require("./core/utils");
10
+ /**
11
+ * Generate REST endpoints from entity name and options
12
+ */
13
+ function generateEndpoints(entityName, options = {}) {
14
+ const resource = options.resourceName || (0, utils_1.pluralize)(entityName.toLowerCase());
15
+ const prefix = options.pathPrefix || '';
16
+ return {
17
+ list: options.override?.list || `GET ${prefix}/${resource}`,
18
+ get: options.override?.get || `GET ${prefix}/${resource}/:id`,
19
+ create: options.override?.create || `POST ${prefix}/${resource}`,
20
+ update: options.override?.update || `PUT ${prefix}/${resource}/:id`,
21
+ delete: options.override?.delete || `DELETE ${prefix}/${resource}/:id`,
22
+ };
23
+ }
24
+ /**
25
+ * Create an external API source configuration
26
+ *
27
+ * @param baseUrl - Base URL for the API. Supports 'env:VARIABLE_NAME' syntax.
28
+ * @param options - Optional configuration for path prefix, resource name, endpoint overrides
29
+ * @returns ExternalSourceConfig for use in entity or manifest source field
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Simple - all defaults
34
+ * source: external('env:API_URL')
35
+ * // Generates: GET/POST /products, GET/PUT/DELETE /products/:id
36
+ *
37
+ * // With version prefix
38
+ * source: external('env:API_URL', { pathPrefix: '/v1' })
39
+ * // Generates: /v1/products, /v1/products/:id
40
+ *
41
+ * // Override weird endpoints
42
+ * source: external('env:LEGACY_API', {
43
+ * override: {
44
+ * list: 'GET /catalog/search',
45
+ * get: 'GET /catalog/item/:sku',
46
+ * }
47
+ * })
48
+ * ```
49
+ */
50
+ function external(baseUrl, options = {}) {
51
+ // Generate default auth header based on type
52
+ let auth;
53
+ if (options.auth) {
54
+ auth = {
55
+ type: options.auth.type,
56
+ header: options.auth.header || (options.auth.type === 'api-key' ? 'X-API-Key' : 'Authorization'),
57
+ };
58
+ }
59
+ return {
60
+ type: 'external',
61
+ baseUrl,
62
+ pathPrefix: options.pathPrefix || '',
63
+ resourceName: options.resourceName,
64
+ // Endpoints will be generated per-entity when compiled
65
+ // Using placeholder - actual generation happens in resolveEntitySource
66
+ endpoints: {
67
+ list: options.override?.list || '',
68
+ get: options.override?.get || '',
69
+ create: options.override?.create || '',
70
+ update: options.override?.update || '',
71
+ delete: options.override?.delete || '',
72
+ },
73
+ auth,
74
+ };
75
+ }
76
+ /**
77
+ * Resolve the final endpoints for an entity, using its name for pluralization
78
+ */
79
+ function resolveEndpoints(entityName, source) {
80
+ const resource = source.resourceName || (0, utils_1.pluralize)(entityName.toLowerCase());
81
+ const prefix = source.pathPrefix;
82
+ return {
83
+ list: source.endpoints.list || `GET ${prefix}/${resource}`,
84
+ get: source.endpoints.get || `GET ${prefix}/${resource}/:id`,
85
+ create: source.endpoints.create || `POST ${prefix}/${resource}`,
86
+ update: source.endpoints.update || `PUT ${prefix}/${resource}/:id`,
87
+ delete: source.endpoints.delete || `DELETE ${prefix}/${resource}/:id`,
88
+ };
89
+ }
@@ -0,0 +1,34 @@
1
+ import type { ManifestIR } from '../manifest';
2
+ import type { TemplateConfig } from './types';
3
+ import { toSnakeCase, pluralize, toCamelCase, toPascalCase, getTableName, getColumnName } from '../core/utils';
4
+ /**
5
+ * Context passed to generators with common utilities
6
+ */
7
+ export interface GeneratorContext {
8
+ /** Template configuration */
9
+ config: TemplateConfig;
10
+ /** Naming utilities */
11
+ naming: {
12
+ toSnakeCase: typeof toSnakeCase;
13
+ pluralize: typeof pluralize;
14
+ toCamelCase: typeof toCamelCase;
15
+ toPascalCase: typeof toPascalCase;
16
+ getTableName: typeof getTableName;
17
+ getColumnName: typeof getColumnName;
18
+ };
19
+ /** Database info from manifest (undefined in headless mode) */
20
+ database: {
21
+ type: 'sqlite' | 'postgres' | 'mysql' | undefined;
22
+ isSqlite: boolean;
23
+ isPostgres: boolean;
24
+ isMysql: boolean;
25
+ isHeadless: boolean;
26
+ };
27
+ /** Resolve import path using aliases */
28
+ resolvePath: (alias: string) => string;
29
+ }
30
+ /**
31
+ * Create a generator context from manifest and config
32
+ */
33
+ export declare function createContext(manifest: ManifestIR, config: TemplateConfig): GeneratorContext;
34
+ //# sourceMappingURL=context.d.ts.map