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,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity definition and compilation to IR
|
|
3
|
+
* @module entity
|
|
4
|
+
*/
|
|
5
|
+
import { FieldBuilder, FieldConfig } from './fields';
|
|
6
|
+
import { RelationBuilder, RelationConfig } from './relations';
|
|
7
|
+
import { ExternalSourceConfig } from './source';
|
|
8
|
+
/**
|
|
9
|
+
* Shorthand protection options for common patterns
|
|
10
|
+
*/
|
|
11
|
+
export type ProtectedShorthand = 'write' | 'all' | boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Granular protection config per CRUD operation
|
|
14
|
+
*/
|
|
15
|
+
export interface ProtectedConfig {
|
|
16
|
+
list?: boolean;
|
|
17
|
+
get?: boolean;
|
|
18
|
+
create?: boolean;
|
|
19
|
+
update?: boolean;
|
|
20
|
+
remove?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Protection option - shorthand or granular
|
|
24
|
+
* @example
|
|
25
|
+
* protected: 'write' // list/get public, mutations protected (most common)
|
|
26
|
+
* protected: 'all' // everything requires auth
|
|
27
|
+
* protected: true // alias for 'all'
|
|
28
|
+
* protected: false // everything public (default)
|
|
29
|
+
* protected: { list: false, get: false, create: true, update: true, remove: true }
|
|
30
|
+
*/
|
|
31
|
+
export type ProtectedOption = ProtectedShorthand | ProtectedConfig;
|
|
32
|
+
/**
|
|
33
|
+
* Normalized protection config (always granular)
|
|
34
|
+
*/
|
|
35
|
+
export interface ProtectedIR {
|
|
36
|
+
list: boolean;
|
|
37
|
+
get: boolean;
|
|
38
|
+
create: boolean;
|
|
39
|
+
update: boolean;
|
|
40
|
+
remove: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Entity definition input - what you write when defining an entity
|
|
44
|
+
*/
|
|
45
|
+
export interface EntityDefinition {
|
|
46
|
+
/** Fields for this entity, using field builders like `text()`, `number()` */
|
|
47
|
+
fields: Record<string, FieldBuilder>;
|
|
48
|
+
/** Relations to other entities using `hasOne()`, `hasMany()`, `belongsToMany()` */
|
|
49
|
+
relations?: Record<string, RelationBuilder>;
|
|
50
|
+
/** Entity behaviors like timestamps, soft delete, audit logging */
|
|
51
|
+
behaviors?: EntityBehaviors;
|
|
52
|
+
/** Mark as auth entity for next-auth integration */
|
|
53
|
+
auth?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Protection level for CRUD operations (requires auth.enabled in config)
|
|
56
|
+
* - 'write': list/get public, create/update/remove protected (most common)
|
|
57
|
+
* - 'all' or true: all operations require auth
|
|
58
|
+
* - false: all operations public (default)
|
|
59
|
+
* - object: granular control per operation
|
|
60
|
+
*/
|
|
61
|
+
protected?: ProtectedOption;
|
|
62
|
+
/**
|
|
63
|
+
* External API source for this entity.
|
|
64
|
+
* If not specified, inherits from manifest.source or uses database.
|
|
65
|
+
*/
|
|
66
|
+
source?: ExternalSourceConfig;
|
|
67
|
+
/**
|
|
68
|
+
* CRUD hooks configuration.
|
|
69
|
+
* Enable specific hooks or use `true` to enable all hooks.
|
|
70
|
+
* @example
|
|
71
|
+
* hooks: true // Enable all hooks
|
|
72
|
+
* hooks: { beforeCreate: true, afterCreate: true } // Enable specific hooks
|
|
73
|
+
*/
|
|
74
|
+
hooks?: boolean | HooksConfig;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Configurable behaviors for an entity
|
|
78
|
+
*/
|
|
79
|
+
export interface EntityBehaviors {
|
|
80
|
+
/** Enable soft delete (adds `deletedAt` field instead of hard delete) */
|
|
81
|
+
softDelete?: boolean;
|
|
82
|
+
/** Enable audit logging for all changes */
|
|
83
|
+
audit?: boolean;
|
|
84
|
+
/** Add `createdAt` and `updatedAt` timestamps (default: true) */
|
|
85
|
+
timestamps?: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* CRUD hook configuration - enables hook points in generated routers
|
|
89
|
+
*
|
|
90
|
+
* When enabled, hooks are invoked at the appropriate points in CRUD operations.
|
|
91
|
+
* Hook implementations are defined in user-managed files (hooks/{entity}.ts).
|
|
92
|
+
*/
|
|
93
|
+
export interface HooksConfig {
|
|
94
|
+
/** Called before creating a record. Can modify input or throw to abort. */
|
|
95
|
+
beforeCreate?: boolean;
|
|
96
|
+
/** Called after a record is created. For side effects (email, audit, etc). */
|
|
97
|
+
afterCreate?: boolean;
|
|
98
|
+
/** Called before updating a record. Can modify input or throw to abort. */
|
|
99
|
+
beforeUpdate?: boolean;
|
|
100
|
+
/** Called after a record is updated. For side effects. */
|
|
101
|
+
afterUpdate?: boolean;
|
|
102
|
+
/** Called before removing a record. Can throw to abort. */
|
|
103
|
+
beforeRemove?: boolean;
|
|
104
|
+
/** Called after a record is removed. For cleanup/archival. */
|
|
105
|
+
afterRemove?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Normalized hooks config (all boolean values)
|
|
109
|
+
*/
|
|
110
|
+
export interface HooksIR {
|
|
111
|
+
beforeCreate: boolean;
|
|
112
|
+
afterCreate: boolean;
|
|
113
|
+
beforeUpdate: boolean;
|
|
114
|
+
afterUpdate: boolean;
|
|
115
|
+
beforeRemove: boolean;
|
|
116
|
+
afterRemove: boolean;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compiled entity intermediate representation - consumed by templates
|
|
120
|
+
*/
|
|
121
|
+
export interface EntityIR {
|
|
122
|
+
/** Entity name in PascalCase */
|
|
123
|
+
name: string;
|
|
124
|
+
/** Compiled field configurations */
|
|
125
|
+
fields: Record<string, FieldConfig>;
|
|
126
|
+
/** Compiled relation configurations */
|
|
127
|
+
relations: Record<string, RelationConfig>;
|
|
128
|
+
/** Entity behaviors */
|
|
129
|
+
behaviors: EntityBehaviors;
|
|
130
|
+
/** Whether this is an auth entity */
|
|
131
|
+
auth: boolean;
|
|
132
|
+
/** Normalized protection config for CRUD operations */
|
|
133
|
+
protected: ProtectedIR;
|
|
134
|
+
/** External API source (optional - inherits from manifest if not specified) */
|
|
135
|
+
source?: ExternalSourceConfig;
|
|
136
|
+
/** Normalized hooks config */
|
|
137
|
+
hooks: HooksIR;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Define an entity with fields, relations, and behaviors
|
|
141
|
+
*
|
|
142
|
+
* @param name - Entity name in PascalCase (e.g., 'User', 'BlogPost')
|
|
143
|
+
* @param definition - Entity configuration with fields, relations, and behaviors
|
|
144
|
+
* @returns Compiled EntityIR for use by generators
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const User = defineEntity('User', {
|
|
149
|
+
* fields: {
|
|
150
|
+
* email: text().required().unique().email(),
|
|
151
|
+
* name: text().required().min(2).max(100),
|
|
152
|
+
* age: number().optional().min(0).integer(),
|
|
153
|
+
* },
|
|
154
|
+
* relations: {
|
|
155
|
+
* posts: hasMany('Post'),
|
|
156
|
+
* },
|
|
157
|
+
* behaviors: {
|
|
158
|
+
* timestamps: true,
|
|
159
|
+
* softDelete: true,
|
|
160
|
+
* }
|
|
161
|
+
* })
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export declare function defineEntity<Name extends string>(name: Name, definition: EntityDefinition): EntityIR;
|
|
165
|
+
//# sourceMappingURL=entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../src/entity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Entity definition and compilation to IR
|
|
4
|
+
* @module entity
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.defineEntity = defineEntity;
|
|
8
|
+
/**
|
|
9
|
+
* Normalize protection option to granular config
|
|
10
|
+
*/
|
|
11
|
+
function normalizeProtected(option) {
|
|
12
|
+
const allPublic = { list: false, get: false, create: false, update: false, remove: false };
|
|
13
|
+
const allProtected = { list: true, get: true, create: true, update: true, remove: true };
|
|
14
|
+
const writeProtected = { list: false, get: false, create: true, update: true, remove: true };
|
|
15
|
+
if (option === undefined || option === false)
|
|
16
|
+
return allPublic;
|
|
17
|
+
if (option === true || option === 'all')
|
|
18
|
+
return allProtected;
|
|
19
|
+
if (option === 'write')
|
|
20
|
+
return writeProtected;
|
|
21
|
+
// Granular config - merge with allPublic defaults
|
|
22
|
+
return { ...allPublic, ...option };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Normalize hooks option to granular config
|
|
26
|
+
*/
|
|
27
|
+
function normalizeHooks(option) {
|
|
28
|
+
const noHooks = {
|
|
29
|
+
beforeCreate: false,
|
|
30
|
+
afterCreate: false,
|
|
31
|
+
beforeUpdate: false,
|
|
32
|
+
afterUpdate: false,
|
|
33
|
+
beforeRemove: false,
|
|
34
|
+
afterRemove: false,
|
|
35
|
+
};
|
|
36
|
+
const allHooks = {
|
|
37
|
+
beforeCreate: true,
|
|
38
|
+
afterCreate: true,
|
|
39
|
+
beforeUpdate: true,
|
|
40
|
+
afterUpdate: true,
|
|
41
|
+
beforeRemove: true,
|
|
42
|
+
afterRemove: true,
|
|
43
|
+
};
|
|
44
|
+
if (option === undefined || option === false)
|
|
45
|
+
return noHooks;
|
|
46
|
+
if (option === true)
|
|
47
|
+
return allHooks;
|
|
48
|
+
// Granular config - merge with noHooks defaults
|
|
49
|
+
return { ...noHooks, ...option };
|
|
50
|
+
}
|
|
51
|
+
// Compile entity definition to IR
|
|
52
|
+
function compileEntity(name, definition) {
|
|
53
|
+
// Extract field configs from builders
|
|
54
|
+
const fields = {};
|
|
55
|
+
for (const [fieldName, builder] of Object.entries(definition.fields)) {
|
|
56
|
+
fields[fieldName] = builder._config;
|
|
57
|
+
}
|
|
58
|
+
// Extract relation configs from builders
|
|
59
|
+
const relations = {};
|
|
60
|
+
if (definition.relations) {
|
|
61
|
+
for (const [relationName, builder] of Object.entries(definition.relations)) {
|
|
62
|
+
relations[relationName] = builder._config;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
name,
|
|
67
|
+
fields,
|
|
68
|
+
relations,
|
|
69
|
+
behaviors: {
|
|
70
|
+
timestamps: true, // Default: true
|
|
71
|
+
softDelete: false,
|
|
72
|
+
audit: false,
|
|
73
|
+
...definition.behaviors,
|
|
74
|
+
},
|
|
75
|
+
auth: definition.auth || false,
|
|
76
|
+
protected: normalizeProtected(definition.protected),
|
|
77
|
+
source: definition.source,
|
|
78
|
+
hooks: normalizeHooks(definition.hooks),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Define an entity with fields, relations, and behaviors
|
|
83
|
+
*
|
|
84
|
+
* @param name - Entity name in PascalCase (e.g., 'User', 'BlogPost')
|
|
85
|
+
* @param definition - Entity configuration with fields, relations, and behaviors
|
|
86
|
+
* @returns Compiled EntityIR for use by generators
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const User = defineEntity('User', {
|
|
91
|
+
* fields: {
|
|
92
|
+
* email: text().required().unique().email(),
|
|
93
|
+
* name: text().required().min(2).max(100),
|
|
94
|
+
* age: number().optional().min(0).integer(),
|
|
95
|
+
* },
|
|
96
|
+
* relations: {
|
|
97
|
+
* posts: hasMany('Post'),
|
|
98
|
+
* },
|
|
99
|
+
* behaviors: {
|
|
100
|
+
* timestamps: true,
|
|
101
|
+
* softDelete: true,
|
|
102
|
+
* }
|
|
103
|
+
* })
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
function defineEntity(name, definition) {
|
|
107
|
+
return compileEntity(name, definition);
|
|
108
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field builders for entity definitions
|
|
3
|
+
*
|
|
4
|
+
* Each method returns a new immutable object (functional programming pattern).
|
|
5
|
+
* Chain methods to build field configurations fluently.
|
|
6
|
+
*
|
|
7
|
+
* @module fields
|
|
8
|
+
*/
|
|
9
|
+
export interface Validation {
|
|
10
|
+
type: string;
|
|
11
|
+
value?: unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface FieldConfig {
|
|
14
|
+
type: 'text' | 'number' | 'boolean' | 'date' | 'computed' | 'enum';
|
|
15
|
+
required: boolean;
|
|
16
|
+
unique: boolean;
|
|
17
|
+
default?: unknown;
|
|
18
|
+
label?: string;
|
|
19
|
+
validations: Validation[];
|
|
20
|
+
/** For computed fields: the return type */
|
|
21
|
+
returnType?: 'text' | 'number' | 'boolean' | 'date';
|
|
22
|
+
/** For computed fields: source fields used in computation */
|
|
23
|
+
sourceFields?: string[];
|
|
24
|
+
/** For computed fields: the computation expression */
|
|
25
|
+
expression?: string;
|
|
26
|
+
/** For enum fields: the allowed values */
|
|
27
|
+
enumValues?: readonly string[];
|
|
28
|
+
/** For enum fields: custom enum type name (optional) */
|
|
29
|
+
enumName?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface BaseFieldBuilder<T> {
|
|
32
|
+
/** @internal - Do not use directly. Use the fluent methods instead. */
|
|
33
|
+
readonly _config: FieldConfig;
|
|
34
|
+
required(): T;
|
|
35
|
+
optional(): T;
|
|
36
|
+
unique(): T;
|
|
37
|
+
default(value: unknown): T;
|
|
38
|
+
label(value: string): T;
|
|
39
|
+
}
|
|
40
|
+
export interface TextFieldBuilder extends BaseFieldBuilder<TextFieldBuilder> {
|
|
41
|
+
min(value: number): TextFieldBuilder;
|
|
42
|
+
max(value: number): TextFieldBuilder;
|
|
43
|
+
length(value: number): TextFieldBuilder;
|
|
44
|
+
email(): TextFieldBuilder;
|
|
45
|
+
url(): TextFieldBuilder;
|
|
46
|
+
regex(pattern: RegExp): TextFieldBuilder;
|
|
47
|
+
oneOf<V extends string>(values: readonly V[]): TextFieldBuilder;
|
|
48
|
+
trim(): TextFieldBuilder;
|
|
49
|
+
lowercase(): TextFieldBuilder;
|
|
50
|
+
uppercase(): TextFieldBuilder;
|
|
51
|
+
}
|
|
52
|
+
export interface NumberFieldBuilder extends BaseFieldBuilder<NumberFieldBuilder> {
|
|
53
|
+
min(value: number): NumberFieldBuilder;
|
|
54
|
+
max(value: number): NumberFieldBuilder;
|
|
55
|
+
integer(): NumberFieldBuilder;
|
|
56
|
+
positive(): NumberFieldBuilder;
|
|
57
|
+
}
|
|
58
|
+
export interface BooleanFieldBuilder extends BaseFieldBuilder<BooleanFieldBuilder> {
|
|
59
|
+
default(value: boolean): BooleanFieldBuilder;
|
|
60
|
+
}
|
|
61
|
+
export interface DateFieldBuilder extends BaseFieldBuilder<DateFieldBuilder> {
|
|
62
|
+
default(value: 'now' | Date): DateFieldBuilder;
|
|
63
|
+
}
|
|
64
|
+
export interface EnumFieldBuilder<T extends readonly string[]> extends BaseFieldBuilder<EnumFieldBuilder<T>> {
|
|
65
|
+
/** Set the default value (must be one of the enum values) */
|
|
66
|
+
default(value: T[number]): EnumFieldBuilder<T>;
|
|
67
|
+
}
|
|
68
|
+
export interface ComputedFieldBuilder {
|
|
69
|
+
readonly _config: FieldConfig;
|
|
70
|
+
/** Set a label for the field */
|
|
71
|
+
label(value: string): ComputedFieldBuilder;
|
|
72
|
+
}
|
|
73
|
+
export type FieldBuilder = TextFieldBuilder | NumberFieldBuilder | BooleanFieldBuilder | DateFieldBuilder | EnumFieldBuilder<readonly string[]> | ComputedFieldBuilder;
|
|
74
|
+
/**
|
|
75
|
+
* Create a text field builder
|
|
76
|
+
*
|
|
77
|
+
* @returns TextFieldBuilder with chainable methods
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* text()
|
|
82
|
+
* .required()
|
|
83
|
+
* .unique()
|
|
84
|
+
* .email()
|
|
85
|
+
* .min(5).max(255)
|
|
86
|
+
* .trim()
|
|
87
|
+
* .lowercase()
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function text(): TextFieldBuilder;
|
|
91
|
+
/**
|
|
92
|
+
* Create a number field builder
|
|
93
|
+
*
|
|
94
|
+
* @returns NumberFieldBuilder with chainable methods
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* number()
|
|
99
|
+
* .required()
|
|
100
|
+
* .min(0).max(100)
|
|
101
|
+
* .integer()
|
|
102
|
+
* .positive()
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function number(): NumberFieldBuilder;
|
|
106
|
+
/**
|
|
107
|
+
* Create a boolean field builder
|
|
108
|
+
*
|
|
109
|
+
* @returns BooleanFieldBuilder with chainable methods
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* boolean().default(false)
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function boolean(): BooleanFieldBuilder;
|
|
117
|
+
/**
|
|
118
|
+
* Create a date field builder
|
|
119
|
+
*
|
|
120
|
+
* @returns DateFieldBuilder with chainable methods
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* date().default('now')
|
|
125
|
+
* date().required()
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare function date(): DateFieldBuilder;
|
|
129
|
+
/**
|
|
130
|
+
* Create an enum field builder with type-safe values
|
|
131
|
+
*
|
|
132
|
+
* Enum fields create native database enum types (PostgreSQL) or
|
|
133
|
+
* CHECK constraints (SQLite/MySQL) and generate proper Zod enums.
|
|
134
|
+
*
|
|
135
|
+
* @param values - Array of allowed string values (use `as const` for type safety)
|
|
136
|
+
* @returns EnumFieldBuilder with chainable methods
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* // Basic enum
|
|
141
|
+
* status: enumField(['draft', 'published', 'archived'])
|
|
142
|
+
*
|
|
143
|
+
* // With type safety (recommended)
|
|
144
|
+
* status: enumField(['draft', 'published', 'archived'] as const)
|
|
145
|
+
* .required()
|
|
146
|
+
* .default('draft')
|
|
147
|
+
*
|
|
148
|
+
* // Order status with default
|
|
149
|
+
* orderStatus: enumField(['pending', 'processing', 'shipped', 'delivered'] as const)
|
|
150
|
+
* .required()
|
|
151
|
+
* .default('pending')
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare function enumField<T extends readonly string[]>(values: T): EnumFieldBuilder<T>;
|
|
155
|
+
/**
|
|
156
|
+
* Computed field configuration
|
|
157
|
+
*/
|
|
158
|
+
export interface ComputedOptions {
|
|
159
|
+
/** The return type of the computed field */
|
|
160
|
+
type: 'text' | 'number' | 'boolean' | 'date';
|
|
161
|
+
/** Source fields used in the computation */
|
|
162
|
+
from: string[];
|
|
163
|
+
/**
|
|
164
|
+
* The computation expression. Use field names as variables.
|
|
165
|
+
*
|
|
166
|
+
* For text concatenation: `"${firstName} ${lastName}"`
|
|
167
|
+
* For math: `"price * quantity"`
|
|
168
|
+
* For conditionals: `"stock > 0 ? 'In Stock' : 'Out of Stock'"`
|
|
169
|
+
*/
|
|
170
|
+
get: string;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Create a computed/virtual field
|
|
174
|
+
*
|
|
175
|
+
* Computed fields are derived from other fields at runtime.
|
|
176
|
+
* They are included in API responses but excluded from create/update inputs.
|
|
177
|
+
* They are NOT stored in the database.
|
|
178
|
+
*
|
|
179
|
+
* @param options - Configuration for the computed field
|
|
180
|
+
* @returns ComputedFieldBuilder
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* // Full name from first + last
|
|
185
|
+
* fullName: computed({
|
|
186
|
+
* type: 'text',
|
|
187
|
+
* from: ['firstName', 'lastName'],
|
|
188
|
+
* get: '`${firstName} ${lastName}`'
|
|
189
|
+
* })
|
|
190
|
+
*
|
|
191
|
+
* // Total price
|
|
192
|
+
* totalPrice: computed({
|
|
193
|
+
* type: 'number',
|
|
194
|
+
* from: ['price', 'quantity'],
|
|
195
|
+
* get: 'price * quantity'
|
|
196
|
+
* })
|
|
197
|
+
*
|
|
198
|
+
* // Stock status
|
|
199
|
+
* inStock: computed({
|
|
200
|
+
* type: 'boolean',
|
|
201
|
+
* from: ['quantity'],
|
|
202
|
+
* get: 'quantity > 0'
|
|
203
|
+
* })
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
export declare function computed(options: ComputedOptions): ComputedFieldBuilder;
|
|
207
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/fields.ts"],"names":[],"mappings":"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"}
|