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.
- package/LICENSE +21 -0
- package/README.md +241 -0
- package/dist/src/ai/adapters/anthropic.d.ts +31 -0
- package/dist/src/ai/adapters/anthropic.d.ts.map +1 -0
- package/dist/src/ai/adapters/anthropic.js +75 -0
- package/dist/src/ai/adapters/openai.d.ts +33 -0
- package/dist/src/ai/adapters/openai.d.ts.map +1 -0
- package/dist/src/ai/adapters/openai.js +120 -0
- package/dist/src/ai/adapters/vercel.d.ts +434 -0
- package/dist/src/ai/adapters/vercel.d.ts.map +1 -0
- package/dist/src/ai/adapters/vercel.js +162 -0
- package/dist/src/ai/index.d.ts +492 -0
- package/dist/src/ai/index.d.ts.map +1 -0
- package/dist/src/ai/index.js +71 -0
- package/dist/src/ai/state.d.ts +13 -0
- package/dist/src/ai/state.d.ts.map +1 -0
- package/dist/src/ai/state.js +215 -0
- package/dist/src/ai/tools.d.ts +13 -0
- package/dist/src/ai/tools.d.ts.map +1 -0
- package/dist/src/ai/tools.js +257 -0
- package/dist/src/ai/types.d.ts +196 -0
- package/dist/src/ai/types.d.ts.map +1 -0
- package/dist/src/ai/types.js +9 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +540 -0
- package/dist/src/core/utils.d.ts +27 -0
- package/dist/src/core/utils.d.ts.map +1 -0
- package/dist/src/core/utils.js +56 -0
- package/dist/src/entity.d.ts +165 -0
- package/dist/src/entity.d.ts.map +1 -0
- package/dist/src/entity.js +108 -0
- package/dist/src/fields.d.ts +207 -0
- package/dist/src/fields.d.ts.map +1 -0
- package/dist/src/fields.js +291 -0
- package/dist/src/generators/erd-ir.d.ts +10 -0
- package/dist/src/generators/erd-ir.d.ts.map +1 -0
- package/dist/src/generators/erd-ir.js +119 -0
- package/dist/src/index.d.ts +51 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +101 -0
- package/dist/src/init/dependencies.d.ts +31 -0
- package/dist/src/init/dependencies.d.ts.map +1 -0
- package/dist/src/init/dependencies.js +101 -0
- package/dist/src/init/entity-templates.d.ts +42 -0
- package/dist/src/init/entity-templates.d.ts.map +1 -0
- package/dist/src/init/entity-templates.js +367 -0
- package/dist/src/init/index.d.ts +10 -0
- package/dist/src/init/index.d.ts.map +1 -0
- package/dist/src/init/index.js +250 -0
- package/dist/src/init/prompts.d.ts +11 -0
- package/dist/src/init/prompts.d.ts.map +1 -0
- package/dist/src/init/prompts.js +275 -0
- package/dist/src/init/templates.d.ts +24 -0
- package/dist/src/init/templates.d.ts.map +1 -0
- package/dist/src/init/templates.js +587 -0
- package/dist/src/json/index.d.ts +11 -0
- package/dist/src/json/index.d.ts.map +1 -0
- package/dist/src/json/index.js +26 -0
- package/dist/src/json/parser.d.ts +61 -0
- package/dist/src/json/parser.d.ts.map +1 -0
- package/dist/src/json/parser.js +309 -0
- package/dist/src/json/types.d.ts +275 -0
- package/dist/src/json/types.d.ts.map +1 -0
- package/dist/src/json/types.js +10 -0
- package/dist/src/manifest.d.ts +147 -0
- package/dist/src/manifest.d.ts.map +1 -0
- package/dist/src/manifest.js +104 -0
- package/dist/src/relations.d.ts +96 -0
- package/dist/src/relations.d.ts.map +1 -0
- package/dist/src/relations.js +108 -0
- package/dist/src/source.d.ts +93 -0
- package/dist/src/source.d.ts.map +1 -0
- package/dist/src/source.js +89 -0
- package/dist/src/template/context.d.ts +34 -0
- package/dist/src/template/context.d.ts.map +1 -0
- package/dist/src/template/context.js +31 -0
- package/dist/src/template/index.d.ts +6 -0
- package/dist/src/template/index.d.ts.map +1 -0
- package/dist/src/template/index.js +12 -0
- package/dist/src/template/registry.d.ts +18 -0
- package/dist/src/template/registry.d.ts.map +1 -0
- package/dist/src/template/registry.js +89 -0
- package/dist/src/template/runner.d.ts +9 -0
- package/dist/src/template/runner.d.ts.map +1 -0
- package/dist/src/template/runner.js +125 -0
- package/dist/src/template/types.d.ts +73 -0
- package/dist/src/template/types.d.ts.map +1 -0
- package/dist/src/template/types.js +3 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts +22 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/api.js +866 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts +20 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.js +273 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts +22 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.js +237 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts +30 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.js +345 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts +25 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.js +199 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts +8 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/index.js +18 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts +22 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.js +270 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts +23 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/service.js +304 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts +21 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.js +248 -0
- package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts +30 -0
- package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts.map +1 -0
- package/dist/src/templates/nextjs-drizzle-trpc/index.js +71 -0
- package/dist/src/validation/index.d.ts +71 -0
- package/dist/src/validation/index.d.ts.map +1 -0
- package/dist/src/validation/index.js +314 -0
- 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
|