@vibeorm/dsl 0.3.0 → 2.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -471
- package/dist/column.d.ts +150 -0
- package/dist/column.d.ts.map +1 -0
- package/dist/enum.d.ts +27 -0
- package/dist/enum.d.ts.map +1 -0
- package/dist/generator/index.d.ts +5 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/prisma.d.ts +19 -0
- package/dist/generator/prisma.d.ts.map +1 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1546 -0
- package/dist/index.js.map +22 -0
- package/dist/model.d.ts +44 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/naming.d.ts +23 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/relation-plan.d.ts +101 -0
- package/dist/relation-plan.d.ts.map +1 -0
- package/dist/relation.d.ts +23 -0
- package/dist/relation.d.ts.map +1 -0
- package/dist/relations.d.ts +29 -0
- package/dist/relations.d.ts.map +1 -0
- package/dist/schema.d.ts +38 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/templates.d.ts +79 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/to-ir.d.ts +41 -0
- package/dist/to-ir.d.ts.map +1 -0
- package/dist/types.d.ts +286 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/validate.d.ts +22 -0
- package/dist/validate.d.ts.map +1 -0
- package/package.json +29 -26
- package/src/column.ts +0 -389
- package/src/enum.ts +0 -71
- package/src/generator/index.ts +0 -5
- package/src/generator/prisma.ts +0 -728
- package/src/index.ts +0 -247
- package/src/model.ts +0 -330
- package/src/relation.ts +0 -75
- package/src/relations.ts +0 -293
- package/src/schema.ts +0 -184
- package/src/templates.ts +0 -134
- package/src/types.ts +0 -381
- package/src/validate.ts +0 -141
package/src/relations.ts
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Drizzle-style centralized relations for @vibeorm/dsl
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* const relations = dsl.defineRelations({ User, Post }, (r) => ({
|
|
6
|
-
* User: {
|
|
7
|
-
* posts: r.many.Post({
|
|
8
|
-
* from: r.User.id,
|
|
9
|
-
* to: r.Post.authorId,
|
|
10
|
-
* }),
|
|
11
|
-
* },
|
|
12
|
-
* Post: {
|
|
13
|
-
* author: r.one.User({
|
|
14
|
-
* from: r.Post.authorId,
|
|
15
|
-
* to: r.User.id,
|
|
16
|
-
* }),
|
|
17
|
-
* },
|
|
18
|
-
* }));
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import type {
|
|
22
|
-
ColumnRef,
|
|
23
|
-
ManyRelationDefConfig,
|
|
24
|
-
ModelDef,
|
|
25
|
-
OneRelationDefConfig,
|
|
26
|
-
RelationsBuilder,
|
|
27
|
-
RelationsMap,
|
|
28
|
-
RelationsOutput,
|
|
29
|
-
StoredRelationDef,
|
|
30
|
-
ThroughRef,
|
|
31
|
-
} from "./types.ts";
|
|
32
|
-
|
|
33
|
-
// ─── Column Ref Factory ─────────────────────
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Creates a ColumnRef with the through() method for many-to-many relations
|
|
37
|
-
*/
|
|
38
|
-
function createColumnRef<TModel extends string, TColumn extends string>(
|
|
39
|
-
model: TModel,
|
|
40
|
-
column: TColumn
|
|
41
|
-
): ColumnRef<TModel, TColumn> {
|
|
42
|
-
return {
|
|
43
|
-
__type: "columnRef",
|
|
44
|
-
__model: model,
|
|
45
|
-
__column: column,
|
|
46
|
-
through<TJunction extends string, TJunctionCol extends string>(
|
|
47
|
-
junction: ColumnRef<TJunction, TJunctionCol>
|
|
48
|
-
): ThroughRef<TModel, TColumn, TJunction, TJunctionCol> {
|
|
49
|
-
return {
|
|
50
|
-
__type: "throughRef",
|
|
51
|
-
__model: model,
|
|
52
|
-
__column: column,
|
|
53
|
-
__junction: junction.__model,
|
|
54
|
-
__junctionColumn: junction.__column,
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ─── Ref Extraction ─────────────────────
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Extracts info from a ColumnRef or ThroughRef
|
|
64
|
-
*/
|
|
65
|
-
function extractRefInfo(ref: ColumnRef | ThroughRef): {
|
|
66
|
-
model: string;
|
|
67
|
-
column: string;
|
|
68
|
-
junction?: string;
|
|
69
|
-
junctionColumn?: string;
|
|
70
|
-
} {
|
|
71
|
-
if (ref.__type === "throughRef") {
|
|
72
|
-
return {
|
|
73
|
-
model: ref.__model,
|
|
74
|
-
column: ref.__column,
|
|
75
|
-
junction: ref.__junction,
|
|
76
|
-
junctionColumn: ref.__junctionColumn,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
model: ref.__model,
|
|
81
|
-
column: ref.__column,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ─── Relation Factory ─────────────────────
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Creates a relation builder factory for one() or many()
|
|
89
|
-
*/
|
|
90
|
-
function createRelationFactory(
|
|
91
|
-
relationType: "one" | "many",
|
|
92
|
-
targetModelName: string
|
|
93
|
-
): (config: OneRelationDefConfig | ManyRelationDefConfig) => StoredRelationDef {
|
|
94
|
-
return (config) => {
|
|
95
|
-
const from = extractRefInfo(config.from);
|
|
96
|
-
const to = extractRefInfo(config.to);
|
|
97
|
-
|
|
98
|
-
// Determine through junction info (for many-to-many)
|
|
99
|
-
let throughJunction: string | undefined;
|
|
100
|
-
let throughFromCol: string | undefined;
|
|
101
|
-
let throughToCol: string | undefined;
|
|
102
|
-
|
|
103
|
-
if (config.from.__type === "throughRef") {
|
|
104
|
-
throughJunction = config.from.__junction;
|
|
105
|
-
throughFromCol = config.from.__junctionColumn;
|
|
106
|
-
}
|
|
107
|
-
if (config.to.__type === "throughRef") {
|
|
108
|
-
// If both have through, they should use the same junction
|
|
109
|
-
if (!throughJunction) {
|
|
110
|
-
throughJunction = config.to.__junction;
|
|
111
|
-
}
|
|
112
|
-
throughToCol = config.to.__junctionColumn;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
__type: "storedRelation",
|
|
117
|
-
__relationType: relationType,
|
|
118
|
-
__targetModel: targetModelName,
|
|
119
|
-
__fromModel: from.model,
|
|
120
|
-
__fromColumn: from.column,
|
|
121
|
-
__toModel: to.model,
|
|
122
|
-
__toColumn: to.column,
|
|
123
|
-
__throughJunction: throughJunction,
|
|
124
|
-
__throughFromCol: throughFromCol,
|
|
125
|
-
__throughToCol: throughToCol,
|
|
126
|
-
__optional: config.optional ?? (relationType === "one" ? false : true),
|
|
127
|
-
__alias: config.alias,
|
|
128
|
-
__onDelete: config.onDelete,
|
|
129
|
-
__onUpdate: config.onUpdate,
|
|
130
|
-
};
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// ─── Relations Builder ─────────────────────
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Creates the relations builder with r.one, r.many, and r.ModelName.columnName
|
|
138
|
-
*/
|
|
139
|
-
function createRelationsBuilder<TSchema extends Record<string, ModelDef>>(
|
|
140
|
-
schema: TSchema
|
|
141
|
-
): RelationsBuilder<TSchema> {
|
|
142
|
-
const builder = {} as RelationsBuilder<TSchema>;
|
|
143
|
-
|
|
144
|
-
// Create r.one and r.many objects
|
|
145
|
-
const oneObj: Record<string, (config: OneRelationDefConfig) => StoredRelationDef> = {};
|
|
146
|
-
const manyObj: Record<string, (config: ManyRelationDefConfig) => StoredRelationDef> = {};
|
|
147
|
-
|
|
148
|
-
for (const modelName of Object.keys(schema)) {
|
|
149
|
-
// r.one.ModelName
|
|
150
|
-
oneObj[modelName] = createRelationFactory("one", modelName);
|
|
151
|
-
// r.many.ModelName
|
|
152
|
-
manyObj[modelName] = createRelationFactory("many", modelName);
|
|
153
|
-
|
|
154
|
-
// r.ModelName.columnName - create column references
|
|
155
|
-
const model = schema[modelName];
|
|
156
|
-
if (!model) continue;
|
|
157
|
-
|
|
158
|
-
const columnRefs: Record<string, ColumnRef> = {};
|
|
159
|
-
|
|
160
|
-
// Get column names from the model's __columns Map
|
|
161
|
-
for (const [colName] of model.__columns) {
|
|
162
|
-
columnRefs[colName] = createColumnRef(modelName, colName);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Also add column names from children if they have auto-generated FKs
|
|
166
|
-
for (const [, childModel] of model.__children) {
|
|
167
|
-
// Child models have parentId FK - we might want to expose this
|
|
168
|
-
// For now, children are separate models so we don't add them here
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Assign column refs to builder (r.ModelName)
|
|
172
|
-
(builder as Record<string, unknown>)[modelName] = columnRefs;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
(builder as Record<string, unknown>).one = oneObj;
|
|
176
|
-
(builder as Record<string, unknown>).many = manyObj;
|
|
177
|
-
|
|
178
|
-
return builder;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// ─── Relations Processing ─────────────────────
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Processes the callback output into a RelationsMap
|
|
185
|
-
*/
|
|
186
|
-
function processRelationsOutput<TSchema extends Record<string, ModelDef>>(
|
|
187
|
-
output: RelationsOutput<TSchema>
|
|
188
|
-
): RelationsMap {
|
|
189
|
-
const result: RelationsMap = {};
|
|
190
|
-
|
|
191
|
-
for (const [modelName, relations] of Object.entries(output)) {
|
|
192
|
-
if (relations) {
|
|
193
|
-
result[modelName] = relations;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return result;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// ─── Public API ─────────────────────
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Define all relations for a schema in one place
|
|
204
|
-
*
|
|
205
|
-
* @example
|
|
206
|
-
* const relations = dsl.defineRelations({ User, Post, Comment }, (r) => ({
|
|
207
|
-
* User: {
|
|
208
|
-
* posts: r.many.Post({
|
|
209
|
-
* from: r.User.id,
|
|
210
|
-
* to: r.Post.authorId,
|
|
211
|
-
* }),
|
|
212
|
-
* },
|
|
213
|
-
* Post: {
|
|
214
|
-
* author: r.one.User({
|
|
215
|
-
* from: r.Post.authorId,
|
|
216
|
-
* to: r.User.id,
|
|
217
|
-
* }),
|
|
218
|
-
* comments: r.many.Comment({
|
|
219
|
-
* from: r.Post.id,
|
|
220
|
-
* to: r.Comment.postId,
|
|
221
|
-
* }),
|
|
222
|
-
* },
|
|
223
|
-
* Comment: {
|
|
224
|
-
* post: r.one.Post({
|
|
225
|
-
* from: r.Comment.postId,
|
|
226
|
-
* to: r.Post.id,
|
|
227
|
-
* }),
|
|
228
|
-
* },
|
|
229
|
-
* }));
|
|
230
|
-
*/
|
|
231
|
-
export function defineRelations<TSchema extends Record<string, ModelDef>>(
|
|
232
|
-
schema: TSchema,
|
|
233
|
-
callback: (r: RelationsBuilder<TSchema>) => RelationsOutput<TSchema>
|
|
234
|
-
): RelationsMap {
|
|
235
|
-
const builder = createRelationsBuilder(schema);
|
|
236
|
-
const output = callback(builder);
|
|
237
|
-
return processRelationsOutput(output);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Define a partial set of relations (for splitting into multiple files)
|
|
242
|
-
*
|
|
243
|
-
* @example
|
|
244
|
-
* // user-relations.ts
|
|
245
|
-
* export const userRelations = dsl.defineRelationsPart({ User, Post }, (r) => ({
|
|
246
|
-
* User: {
|
|
247
|
-
* posts: r.many.Post({ from: r.User.id, to: r.Post.authorId }),
|
|
248
|
-
* },
|
|
249
|
-
* }));
|
|
250
|
-
*
|
|
251
|
-
* // post-relations.ts
|
|
252
|
-
* export const postRelations = dsl.defineRelationsPart({ User, Post }, (r) => ({
|
|
253
|
-
* Post: {
|
|
254
|
-
* author: r.one.User({ from: r.Post.authorId, to: r.User.id }),
|
|
255
|
-
* },
|
|
256
|
-
* }));
|
|
257
|
-
*
|
|
258
|
-
* // Merge in main file
|
|
259
|
-
* const allRelations = { ...userRelations, ...postRelations };
|
|
260
|
-
*/
|
|
261
|
-
export function defineRelationsPart<TSchema extends Record<string, ModelDef>>(
|
|
262
|
-
schema: TSchema,
|
|
263
|
-
callback: (r: RelationsBuilder<TSchema>) => Partial<RelationsOutput<TSchema>>
|
|
264
|
-
): RelationsMap {
|
|
265
|
-
const builder = createRelationsBuilder(schema);
|
|
266
|
-
const output = callback(builder);
|
|
267
|
-
return processRelationsOutput(output as RelationsOutput<TSchema>);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Merge multiple relation parts into a single RelationsMap
|
|
272
|
-
*
|
|
273
|
-
* @example
|
|
274
|
-
* const allRelations = dsl.mergeRelations(
|
|
275
|
-
* userRelations,
|
|
276
|
-
* postRelations,
|
|
277
|
-
* commentRelations,
|
|
278
|
-
* );
|
|
279
|
-
*/
|
|
280
|
-
export function mergeRelations(...parts: RelationsMap[]): RelationsMap {
|
|
281
|
-
const result: RelationsMap = {};
|
|
282
|
-
|
|
283
|
-
for (const part of parts) {
|
|
284
|
-
for (const [modelName, relations] of Object.entries(part)) {
|
|
285
|
-
if (!result[modelName]) {
|
|
286
|
-
result[modelName] = {};
|
|
287
|
-
}
|
|
288
|
-
Object.assign(result[modelName], relations);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
return result;
|
|
293
|
-
}
|
package/src/schema.ts
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema composer for combining models and relations
|
|
3
|
-
*
|
|
4
|
-
* v3: Relations are now passed separately via options
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* // Define models
|
|
8
|
-
* const models = { Workspace, User, Printer };
|
|
9
|
-
*
|
|
10
|
-
* // Define relations separately
|
|
11
|
-
* const relations = dsl.defineRelations(models, (r) => ({
|
|
12
|
-
* User: {
|
|
13
|
-
* workspace: r.one.Workspace({ from: r.User.workspaceId, to: r.Workspace.id }),
|
|
14
|
-
* },
|
|
15
|
-
* }));
|
|
16
|
-
*
|
|
17
|
-
* // Create schema with relations
|
|
18
|
-
* const schema = dsl.schema(models, { relations });
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* // Grouped by domain
|
|
22
|
-
* const schema = dsl.schema({
|
|
23
|
-
* Workspace,
|
|
24
|
-
* shipping: { Carrier, CarrierService },
|
|
25
|
-
* printing: { Account: PrintingAccount, Job: PrintJob },
|
|
26
|
-
* }, { relations });
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* // With standalone enums
|
|
30
|
-
* const Status = dsl.enum({ name: "Status", options: ["active", "inactive"] });
|
|
31
|
-
* const schema = dsl.schema({
|
|
32
|
-
* Status, // Standalone enums can be included
|
|
33
|
-
* User,
|
|
34
|
-
* }, { relations });
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
import type { EnumDef, ModelDef, RelationsMap, SchemaDef, SchemaInput } from "./types.ts";
|
|
38
|
-
|
|
39
|
-
// ─── Types ─────────────────────────────────
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Options for schema creation
|
|
43
|
-
*/
|
|
44
|
-
export type SchemaOptions = {
|
|
45
|
-
/** Relations defined via dsl.defineRelations() */
|
|
46
|
-
relations?: RelationsMap;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// ─── Type Guards ─────────────────────────────────
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Checks if a value is a ModelDef
|
|
53
|
-
*/
|
|
54
|
-
function isModelDef(value: unknown): value is ModelDef {
|
|
55
|
-
return (
|
|
56
|
-
typeof value === "object" &&
|
|
57
|
-
value !== null &&
|
|
58
|
-
"__type" in value &&
|
|
59
|
-
value.__type === "model"
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Checks if a value is an EnumDef (standalone enum)
|
|
65
|
-
*/
|
|
66
|
-
function isEnumDef(value: unknown): value is EnumDef {
|
|
67
|
-
return (
|
|
68
|
-
typeof value === "object" &&
|
|
69
|
-
value !== null &&
|
|
70
|
-
"__type" in value &&
|
|
71
|
-
value.__type === "enum"
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ─── Extraction Helpers ─────────────────────────────────
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Recursively extracts all models and standalone enums from schema input
|
|
79
|
-
*/
|
|
80
|
-
function extractModelsAndEnums(params: {
|
|
81
|
-
input: SchemaInput;
|
|
82
|
-
models: Map<string, ModelDef>;
|
|
83
|
-
standaloneEnums: Map<string, readonly string[]>;
|
|
84
|
-
}): void {
|
|
85
|
-
const { input, models, standaloneEnums } = params;
|
|
86
|
-
|
|
87
|
-
for (const [key, value] of Object.entries(input)) {
|
|
88
|
-
if (isModelDef(value)) {
|
|
89
|
-
models.set(value.__name, value);
|
|
90
|
-
|
|
91
|
-
// Also add any child models
|
|
92
|
-
for (const [childKey, childModel] of value.__children) {
|
|
93
|
-
models.set(childModel.__name, childModel);
|
|
94
|
-
}
|
|
95
|
-
} else if (isEnumDef(value)) {
|
|
96
|
-
// Standalone enum
|
|
97
|
-
standaloneEnums.set(value.__name, value.__options);
|
|
98
|
-
} else if (typeof value === "object" && value !== null) {
|
|
99
|
-
// Nested group
|
|
100
|
-
extractModelsAndEnums({
|
|
101
|
-
input: value as SchemaInput,
|
|
102
|
-
models,
|
|
103
|
-
standaloneEnums,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Extracts all unique enum values from models (for inline enums)
|
|
111
|
-
*/
|
|
112
|
-
function extractInlineEnums(params: {
|
|
113
|
-
models: Map<string, ModelDef>;
|
|
114
|
-
standaloneEnums: Map<string, readonly string[]>;
|
|
115
|
-
}): Map<string, readonly string[]> {
|
|
116
|
-
const { models, standaloneEnums } = params;
|
|
117
|
-
const enums = new Map<string, readonly string[]>(standaloneEnums);
|
|
118
|
-
|
|
119
|
-
for (const [modelName, model] of models) {
|
|
120
|
-
for (const [colName, column] of model.__columns) {
|
|
121
|
-
if (column.__columnType === "enum" && column.__enumValues) {
|
|
122
|
-
// Check if this is a standalone enum reference
|
|
123
|
-
if (column.__enumName) {
|
|
124
|
-
// Already has a name (standalone enum) - ensure it's in the map
|
|
125
|
-
if (!enums.has(column.__enumName)) {
|
|
126
|
-
enums.set(column.__enumName, column.__enumValues);
|
|
127
|
-
}
|
|
128
|
-
} else {
|
|
129
|
-
// Inline enum - generate name: ModelNameColumnName
|
|
130
|
-
const enumName = `${modelName}${colName.charAt(0).toUpperCase()}${colName.slice(1)}`;
|
|
131
|
-
enums.set(enumName, column.__enumValues);
|
|
132
|
-
|
|
133
|
-
// Store enum name reference on column for generator
|
|
134
|
-
column.__enumName = enumName;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return enums;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// ─── Public API ─────────────────────────────────
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Creates a schema from models and relations
|
|
147
|
-
*
|
|
148
|
-
* @param input - Models to include (can be nested/grouped)
|
|
149
|
-
* @param options - Options including relations from defineRelations()
|
|
150
|
-
*/
|
|
151
|
-
export function schema(input: SchemaInput, options?: SchemaOptions): SchemaDef {
|
|
152
|
-
const models = new Map<string, ModelDef>();
|
|
153
|
-
const standaloneEnums = new Map<string, readonly string[]>();
|
|
154
|
-
|
|
155
|
-
extractModelsAndEnums({ input, models, standaloneEnums });
|
|
156
|
-
|
|
157
|
-
const enums = extractInlineEnums({ models, standaloneEnums });
|
|
158
|
-
|
|
159
|
-
return {
|
|
160
|
-
__type: "schema",
|
|
161
|
-
__models: models,
|
|
162
|
-
__enums: enums,
|
|
163
|
-
__relations: options?.relations ?? {},
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Creates a domain group for organizing models
|
|
169
|
-
*
|
|
170
|
-
* @example
|
|
171
|
-
* const shippingDomain = dsl.domain({
|
|
172
|
-
* name: "Shipping",
|
|
173
|
-
* models: { Carrier, CarrierService },
|
|
174
|
-
* });
|
|
175
|
-
*/
|
|
176
|
-
export function domain(params: {
|
|
177
|
-
name: string;
|
|
178
|
-
models: Record<string, ModelDef>;
|
|
179
|
-
}): { name: string; models: Record<string, ModelDef> } {
|
|
180
|
-
return {
|
|
181
|
-
name: params.name,
|
|
182
|
-
models: params.models,
|
|
183
|
-
};
|
|
184
|
-
}
|
package/src/templates.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Built-in templates for common schema patterns
|
|
3
|
-
*
|
|
4
|
-
* Templates use getters so that each spread produces fresh column instances,
|
|
5
|
-
* preventing shared mutable state across models.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* import { dsl } from "@vibeorm/dsl";
|
|
9
|
-
*
|
|
10
|
-
* const User = dsl.create({
|
|
11
|
-
* name: "User",
|
|
12
|
-
* schema: {
|
|
13
|
-
* ...dsl.templates.base,
|
|
14
|
-
* ...dsl.templates.withMetadata,
|
|
15
|
-
* email: dsl.string({ unique: true }),
|
|
16
|
-
* },
|
|
17
|
-
* });
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { boolean, datetime, id, json, string } from "./column.ts";
|
|
21
|
-
|
|
22
|
-
// ─── Base Templates ─────────────────────
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Standard base fields for all models
|
|
26
|
-
* - id: ULID primary key
|
|
27
|
-
* - createdAt: Creation timestamp
|
|
28
|
-
* - updatedAt: Last update timestamp
|
|
29
|
-
* - deletedAt: Soft delete timestamp (optional)
|
|
30
|
-
*
|
|
31
|
-
* Uses getters to return fresh instances on each spread.
|
|
32
|
-
*/
|
|
33
|
-
export const base = {
|
|
34
|
-
get id() { return id({ type: "ulid" }); },
|
|
35
|
-
get createdAt() { return datetime({ default: "now", tz: true, index: true }); },
|
|
36
|
-
get updatedAt() { return datetime({ default: "now", updatedAt: true, tz: true, index: true }); },
|
|
37
|
-
get deletedAt() { return datetime({ optional: true, index: true }); },
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Base fields with workspace association
|
|
42
|
-
*/
|
|
43
|
-
export const baseWithWorkspace = {
|
|
44
|
-
get id() { return id({ type: "ulid" }); },
|
|
45
|
-
get createdAt() { return datetime({ default: "now", tz: true, index: true }); },
|
|
46
|
-
get updatedAt() { return datetime({ default: "now", updatedAt: true, tz: true, index: true }); },
|
|
47
|
-
get deletedAt() { return datetime({ optional: true, index: true }); },
|
|
48
|
-
get workspaceId() { return string({ index: true }); },
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// ─── Mixin Templates ─────────────────────
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Metadata fields for storing arbitrary JSON data
|
|
55
|
-
*/
|
|
56
|
-
export const withMetadata = {
|
|
57
|
-
get metadata() { return json({ optional: true }); },
|
|
58
|
-
get settings() { return json({ optional: true }); },
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Active/inactive status field
|
|
63
|
-
*/
|
|
64
|
-
export const withActive = {
|
|
65
|
-
get isActive() { return boolean({ default: true }); },
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Audit fields for tracking who created/updated
|
|
70
|
-
*/
|
|
71
|
-
export const withAudit = {
|
|
72
|
-
get createdById() { return string({ optional: true, index: true }); },
|
|
73
|
-
get updatedById() { return string({ optional: true, index: true }); },
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* External ID field for integrations
|
|
78
|
-
*/
|
|
79
|
-
export const withExternalId = {
|
|
80
|
-
get externalId() { return string({ index: true }); },
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Name and description fields
|
|
85
|
-
*/
|
|
86
|
-
export const withNameDescription = {
|
|
87
|
-
get name() { return string(); },
|
|
88
|
-
get description() { return string({ optional: true }); },
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// ─── Common Field Definitions ─────────────────────
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Pre-defined field definitions for common use cases.
|
|
95
|
-
* Uses getters for fresh instances.
|
|
96
|
-
*/
|
|
97
|
-
export const fields = {
|
|
98
|
-
/** Standard datetime with now default and timezone */
|
|
99
|
-
get datetime() { return datetime({ default: "now", updatedAt: true, tz: true, index: true }); },
|
|
100
|
-
|
|
101
|
-
/** ULID primary key */
|
|
102
|
-
get id() { return id({ type: "ulid" }); },
|
|
103
|
-
|
|
104
|
-
/** Standard title/name field */
|
|
105
|
-
get title() { return string(); },
|
|
106
|
-
|
|
107
|
-
/** Optional description field */
|
|
108
|
-
get description() { return string({ optional: true }); },
|
|
109
|
-
|
|
110
|
-
/** External ID with index */
|
|
111
|
-
get externalId() { return string({ index: true }); },
|
|
112
|
-
|
|
113
|
-
/** Optional metadata JSON */
|
|
114
|
-
get metadata() { return json({ optional: true }); },
|
|
115
|
-
|
|
116
|
-
/** Optional settings JSON */
|
|
117
|
-
get settings() { return json({ optional: true }); },
|
|
118
|
-
|
|
119
|
-
/** Active status with default true */
|
|
120
|
-
get isActive() { return boolean({ default: true }); },
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
// ─── Template Namespace Export ─────────────────────
|
|
124
|
-
|
|
125
|
-
export const templates = {
|
|
126
|
-
base,
|
|
127
|
-
baseWithWorkspace,
|
|
128
|
-
withMetadata,
|
|
129
|
-
withActive,
|
|
130
|
-
withAudit,
|
|
131
|
-
withExternalId,
|
|
132
|
-
withNameDescription,
|
|
133
|
-
fields,
|
|
134
|
-
};
|