@ekairos/domain 1.21.0 → 1.21.3-beta.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/package.json +4 -1
- package/dist/__type_tests__/domain-builder.typecheck.d.ts +0 -2
- package/dist/__type_tests__/domain-builder.typecheck.d.ts.map +0 -1
- package/dist/__type_tests__/domain-builder.typecheck.js +0 -660
- package/dist/__type_tests__/domain-builder.typecheck.js.map +0 -1
- package/dist/__type_tests__/domain-conflicts-examples.d.ts +0 -2
- package/dist/__type_tests__/domain-conflicts-examples.d.ts.map +0 -1
- package/dist/__type_tests__/domain-conflicts-examples.js +0 -8
- package/dist/__type_tests__/domain-conflicts-examples.js.map +0 -1
- package/dist/__type_tests__/instant-schema-example.d.ts +0 -227
- package/dist/__type_tests__/instant-schema-example.d.ts.map +0 -1
- package/dist/__type_tests__/instant-schema-example.js +0 -188
- package/dist/__type_tests__/instant-schema-example.js.map +0 -1
- package/dist/__type_tests__/instant-schema-migration-example.d.ts +0 -191
- package/dist/__type_tests__/instant-schema-migration-example.d.ts.map +0 -1
- package/dist/__type_tests__/instant-schema-migration-example.js +0 -178
- package/dist/__type_tests__/instant-schema-migration-example.js.map +0 -1
- package/dist/__type_tests__/test.schema.d.ts +0 -95
- package/dist/__type_tests__/test.schema.d.ts.map +0 -1
- package/dist/__type_tests__/test.schema.js +0 -86
- package/dist/__type_tests__/test.schema.js.map +0 -1
- package/dist/index.d.ts +0 -39
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -203
- package/dist/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekairos/domain",
|
|
3
|
-
"version": "1.21.0",
|
|
3
|
+
"version": "1.21.3-beta.0",
|
|
4
4
|
"description": "Pulzar Domain Utilities",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -35,6 +35,9 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@instantdb/core": "latest"
|
|
37
37
|
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@instantdb/admin": "*"
|
|
40
|
+
},
|
|
38
41
|
"devDependencies": {
|
|
39
42
|
"@ekairos/tsconfig": "workspace:*",
|
|
40
43
|
"@types/node": "^24.5.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domain-builder.typecheck.d.ts","sourceRoot":"","sources":["../../src/__type_tests__/domain-builder.typecheck.ts"],"names":[],"mappings":""}
|
|
@@ -1,660 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Type tests for domain builder with dependsOn
|
|
3
|
-
// These should fail initially, then pass after implementation
|
|
4
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
const __1 = require("..");
|
|
6
|
-
const core_1 = require("@instantdb/core");
|
|
7
|
-
// Base entities ($users, $files) are automatically included by domain builder
|
|
8
|
-
// Core domain (hosts organizations)
|
|
9
|
-
const otherDomain = (0, __1.domain)({
|
|
10
|
-
entities: {
|
|
11
|
-
organizations: core_1.i.entity({
|
|
12
|
-
clerkOrgId: core_1.i.string().indexed().unique(),
|
|
13
|
-
timezone: core_1.i.string().optional(),
|
|
14
|
-
}),
|
|
15
|
-
},
|
|
16
|
-
links: {},
|
|
17
|
-
rooms: {},
|
|
18
|
-
});
|
|
19
|
-
// OK: cross-domain links after includes (runtime automatically merges entities)
|
|
20
|
-
const management = (0, __1.domain)("management")
|
|
21
|
-
.includes(otherDomain)
|
|
22
|
-
.schema({
|
|
23
|
-
entities: {
|
|
24
|
-
management_projects: core_1.i.entity({
|
|
25
|
-
name: core_1.i.string(),
|
|
26
|
-
createdAt: core_1.i.date(),
|
|
27
|
-
updatedAt: core_1.i.date(),
|
|
28
|
-
description: core_1.i.string().optional(),
|
|
29
|
-
linearProjectId: core_1.i.string().optional(),
|
|
30
|
-
}),
|
|
31
|
-
management_tasks: core_1.i.entity({
|
|
32
|
-
title: core_1.i.string(),
|
|
33
|
-
status: core_1.i.string(),
|
|
34
|
-
createdAt: core_1.i.date(),
|
|
35
|
-
updatedAt: core_1.i.date(),
|
|
36
|
-
description: core_1.i.string().optional(),
|
|
37
|
-
}),
|
|
38
|
-
},
|
|
39
|
-
links: {
|
|
40
|
-
management_projectsOrganization: {
|
|
41
|
-
forward: { on: "management_projects", has: "one", label: "organization" },
|
|
42
|
-
reverse: { on: "organizations", has: "many", label: "management_projects" },
|
|
43
|
-
},
|
|
44
|
-
management_tasksUser: {
|
|
45
|
-
forward: { on: "management_tasks", has: "one", label: "assignee" },
|
|
46
|
-
reverse: { on: "$users", has: "many", label: "management_tasks" },
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
rooms: {},
|
|
50
|
-
});
|
|
51
|
-
// OK: link only to base entities ($users/$files) without deps
|
|
52
|
-
const filesOnly = (0, __1.domain)("filesOnly").schema({
|
|
53
|
-
entities: {
|
|
54
|
-
assets: core_1.i.entity({
|
|
55
|
-
name: core_1.i.string(),
|
|
56
|
-
}),
|
|
57
|
-
},
|
|
58
|
-
links: {
|
|
59
|
-
assetsFiles: {
|
|
60
|
-
forward: { on: "assets", has: "many", label: "$files" },
|
|
61
|
-
reverse: { on: "$files", has: "one", label: "asset" },
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
rooms: {},
|
|
65
|
-
});
|
|
66
|
-
// Note: Cross-domain link validation is now runtime-only for simplicity
|
|
67
|
-
// The domain builder automatically includes base entities and merges included domains
|
|
68
|
-
const runtimeValidatedExample = (0, __1.domain)("management")
|
|
69
|
-
.includes(otherDomain)
|
|
70
|
-
.schema({
|
|
71
|
-
entities: {
|
|
72
|
-
management_projects: core_1.i.entity({
|
|
73
|
-
name: core_1.i.string(),
|
|
74
|
-
}),
|
|
75
|
-
management_tasks: core_1.i.entity({
|
|
76
|
-
title: core_1.i.string(),
|
|
77
|
-
}),
|
|
78
|
-
},
|
|
79
|
-
links: {
|
|
80
|
-
// This will work because runtime merges in organizations from otherDomain
|
|
81
|
-
management_projectsOrganization: {
|
|
82
|
-
forward: { on: "management_projects", has: "one", label: "organization" },
|
|
83
|
-
reverse: { on: "organizations", has: "many", label: "management_projects" },
|
|
84
|
-
},
|
|
85
|
-
// Base entities are automatically available
|
|
86
|
-
management_tasksUser: {
|
|
87
|
-
forward: { on: "management_tasks", has: "one", label: "assignee" },
|
|
88
|
-
reverse: { on: "$users", has: "many", label: "management_tasks" },
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
rooms: {},
|
|
92
|
-
});
|
|
93
|
-
// OK: Base entities are automatically available without explicit declaration
|
|
94
|
-
const baseEntitiesOnly = (0, __1.domain)("baseTest").schema({
|
|
95
|
-
entities: {
|
|
96
|
-
test_entity: core_1.i.entity({
|
|
97
|
-
name: core_1.i.string(),
|
|
98
|
-
}),
|
|
99
|
-
},
|
|
100
|
-
links: {
|
|
101
|
-
testEntityFiles: {
|
|
102
|
-
forward: { on: "test_entity", has: "many", label: "$files" },
|
|
103
|
-
reverse: { on: "$files", has: "one", label: "test_entity" },
|
|
104
|
-
},
|
|
105
|
-
testEntityUsers: {
|
|
106
|
-
forward: { on: "test_entity", has: "one", label: "owner" },
|
|
107
|
-
reverse: { on: "$users", has: "many", label: "owned_entities" },
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
rooms: {},
|
|
111
|
-
});
|
|
112
|
-
// Example usage of includes method
|
|
113
|
-
const coreDomain = (0, __1.domain)({
|
|
114
|
-
entities: {
|
|
115
|
-
organizations: core_1.i.entity({
|
|
116
|
-
clerkOrgId: core_1.i.string().indexed().unique(),
|
|
117
|
-
timezone: core_1.i.string().optional(),
|
|
118
|
-
}),
|
|
119
|
-
},
|
|
120
|
-
links: {},
|
|
121
|
-
rooms: {},
|
|
122
|
-
});
|
|
123
|
-
const managementDomain = (0, __1.domain)("management")
|
|
124
|
-
.includes(coreDomain) // Include entities from coreDomain for cross-references
|
|
125
|
-
.schema({
|
|
126
|
-
entities: {
|
|
127
|
-
management_projects: core_1.i.entity({
|
|
128
|
-
name: core_1.i.string(),
|
|
129
|
-
createdAt: core_1.i.date(),
|
|
130
|
-
updatedAt: core_1.i.date(),
|
|
131
|
-
}),
|
|
132
|
-
management_tasks: core_1.i.entity({
|
|
133
|
-
title: core_1.i.string(),
|
|
134
|
-
status: core_1.i.string(),
|
|
135
|
-
createdAt: core_1.i.date(),
|
|
136
|
-
updatedAt: core_1.i.date(),
|
|
137
|
-
}),
|
|
138
|
-
},
|
|
139
|
-
links: {
|
|
140
|
-
// Can reference organizations from included coreDomain
|
|
141
|
-
management_projectsOrganization: {
|
|
142
|
-
forward: { on: "management_projects", has: "one", label: "organization" },
|
|
143
|
-
reverse: { on: "organizations", has: "many", label: "management_projects" },
|
|
144
|
-
},
|
|
145
|
-
// Can reference base entities ($users, $files) automatically
|
|
146
|
-
management_tasksUser: {
|
|
147
|
-
forward: { on: "management_tasks", has: "one", label: "assignee" },
|
|
148
|
-
reverse: { on: "$users", has: "many", label: "management_tasks" },
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
rooms: {},
|
|
152
|
-
});
|
|
153
|
-
// Flat schema construction - when spreading directly into i.schema, include base entities
|
|
154
|
-
// Note: managementDomain.links may reference entities that will be available after includes ($users, cross-domain)
|
|
155
|
-
// Links reference $users which will be available when base entities are merged
|
|
156
|
-
// Use toInstantSchema() to get the properly typed schema with all entities and links merged
|
|
157
|
-
const baseForFlat = core_1.i.schema({ entities: {}, links: {}, rooms: {} });
|
|
158
|
-
const managementSchema = managementDomain.toInstantSchema();
|
|
159
|
-
const completeSchema = core_1.i.schema({
|
|
160
|
-
entities: {
|
|
161
|
-
...baseForFlat.entities,
|
|
162
|
-
...managementSchema.entities, // Includes base + core + management entities
|
|
163
|
-
},
|
|
164
|
-
links: managementSchema.links, // Links from toInstantSchema include all merged links
|
|
165
|
-
rooms: {
|
|
166
|
-
...managementSchema.rooms,
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
// Test compose still works with domain instances
|
|
170
|
-
const classicDomain = (0, __1.domain)({
|
|
171
|
-
entities: { test: core_1.i.entity({ name: core_1.i.string() }) },
|
|
172
|
-
links: {},
|
|
173
|
-
rooms: {},
|
|
174
|
-
});
|
|
175
|
-
const composed = classicDomain.compose((0, __1.domain)({
|
|
176
|
-
entities: { other: core_1.i.entity({ value: core_1.i.number() }) },
|
|
177
|
-
links: {},
|
|
178
|
-
rooms: {},
|
|
179
|
-
}));
|
|
180
|
-
// Test: Domain builder produces flat objects compatible with i.schema
|
|
181
|
-
// This demonstrates the flat approach - domains return plain objects
|
|
182
|
-
const managementEntities = management.entities;
|
|
183
|
-
const managementLinks = management.links;
|
|
184
|
-
const filesOnlyEntities = filesOnly.entities;
|
|
185
|
-
// These can be spread directly into i.schema in real usage
|
|
186
|
-
const _entities = managementEntities;
|
|
187
|
-
const _links = managementLinks;
|
|
188
|
-
// Type assertions for runtime verification (these should not fail)
|
|
189
|
-
const _management = management;
|
|
190
|
-
const _filesOnly = filesOnly;
|
|
191
|
-
const _composed = composed;
|
|
192
|
-
// Test toInstantSchema method compatibility
|
|
193
|
-
const domainWithInstantSchema = (0, __1.domain)("instantTest")
|
|
194
|
-
.includes(otherDomain)
|
|
195
|
-
.schema({
|
|
196
|
-
entities: {
|
|
197
|
-
instant_entities: core_1.i.entity({
|
|
198
|
-
name: core_1.i.string(),
|
|
199
|
-
}),
|
|
200
|
-
},
|
|
201
|
-
links: {
|
|
202
|
-
instantEntityOrg: {
|
|
203
|
-
forward: { on: "instant_entities", has: "one", label: "organization" },
|
|
204
|
-
reverse: { on: "organizations", has: "many", label: "instant_entities" },
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
rooms: {},
|
|
208
|
-
});
|
|
209
|
-
const _instantSchemaCheck = true;
|
|
210
|
-
// =====================================================================================
|
|
211
|
-
// Test: Links from included domains are merged into final schema
|
|
212
|
-
// =====================================================================================
|
|
213
|
-
// Domain with links that should be included
|
|
214
|
-
const domainWithLinks = (0, __1.domain)("withLinks").schema({
|
|
215
|
-
entities: {
|
|
216
|
-
included_entities: core_1.i.entity({
|
|
217
|
-
name: core_1.i.string(),
|
|
218
|
-
}),
|
|
219
|
-
},
|
|
220
|
-
links: {
|
|
221
|
-
includedLink: {
|
|
222
|
-
forward: { on: "included_entities", has: "one", label: "owner" },
|
|
223
|
-
reverse: { on: "$users", has: "many", label: "owned_included_entities" },
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
rooms: {},
|
|
227
|
-
});
|
|
228
|
-
// Domain that includes the above domain
|
|
229
|
-
const domainIncludingLinks = (0, __1.domain)("including")
|
|
230
|
-
.includes(domainWithLinks)
|
|
231
|
-
.schema({
|
|
232
|
-
entities: {
|
|
233
|
-
including_entities: core_1.i.entity({
|
|
234
|
-
title: core_1.i.string(),
|
|
235
|
-
}),
|
|
236
|
-
},
|
|
237
|
-
links: {
|
|
238
|
-
includingLink: {
|
|
239
|
-
forward: { on: "including_entities", has: "one", label: "creator" },
|
|
240
|
-
reverse: { on: "$users", has: "many", label: "created_entities" },
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
rooms: {},
|
|
244
|
-
});
|
|
245
|
-
// Verify that links from included domain are present in the final schema
|
|
246
|
-
const finalSchemaIncludingLinks = domainIncludingLinks.toInstantSchema();
|
|
247
|
-
// Runtime check: both links should be present
|
|
248
|
-
const hasIncludedLink = "includedLink" in finalSchemaIncludingLinks.links;
|
|
249
|
-
const hasIncludingLink = "includingLink" in finalSchemaIncludingLinks.links;
|
|
250
|
-
const _linksMergedCheck1 = true;
|
|
251
|
-
const _linksMergedCheck2 = true;
|
|
252
|
-
// =====================================================================================
|
|
253
|
-
// Test: db.query can use links from included domains
|
|
254
|
-
// =====================================================================================
|
|
255
|
-
// Domain with a link that should be queryable
|
|
256
|
-
const domainWithQueryableLink = (0, __1.domain)("withQueryable").schema({
|
|
257
|
-
entities: {
|
|
258
|
-
queryable_entities: core_1.i.entity({
|
|
259
|
-
name: core_1.i.string(),
|
|
260
|
-
}),
|
|
261
|
-
},
|
|
262
|
-
links: {
|
|
263
|
-
queryableLink: {
|
|
264
|
-
forward: { on: "queryable_entities", has: "one", label: "owner" },
|
|
265
|
-
reverse: { on: "$users", has: "many", label: "owned_queryable_entities" },
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
rooms: {},
|
|
269
|
-
});
|
|
270
|
-
// Domain that includes the above and adds its own entities/links
|
|
271
|
-
const domainWithIncludedQueryableLink = (0, __1.domain)("withIncluded")
|
|
272
|
-
.includes(domainWithQueryableLink)
|
|
273
|
-
.schema({
|
|
274
|
-
entities: {
|
|
275
|
-
local_entities: core_1.i.entity({
|
|
276
|
-
title: core_1.i.string(),
|
|
277
|
-
}),
|
|
278
|
-
},
|
|
279
|
-
links: {
|
|
280
|
-
localLink: {
|
|
281
|
-
forward: { on: "local_entities", has: "one", label: "creator" },
|
|
282
|
-
reverse: { on: "$users", has: "many", label: "created_local_entities" },
|
|
283
|
-
},
|
|
284
|
-
},
|
|
285
|
-
rooms: {},
|
|
286
|
-
});
|
|
287
|
-
// Create schema and verify query structure accepts links from included domain
|
|
288
|
-
const queryableSchema = domainWithIncludedQueryableLink.toInstantSchema();
|
|
289
|
-
const _queryableLinkCheck = true;
|
|
290
|
-
const _localLinkCheck = true;
|
|
291
|
-
// Runtime verification: schema should have both links
|
|
292
|
-
const hasQueryableLinkRuntime = "queryableLink" in queryableSchema.links;
|
|
293
|
-
const hasLocalLinkRuntime = "localLink" in queryableSchema.links;
|
|
294
|
-
// These should both be true if links are properly merged
|
|
295
|
-
if (!hasQueryableLinkRuntime || !hasLocalLinkRuntime) {
|
|
296
|
-
throw new Error("Links from included domains are not present in final schema");
|
|
297
|
-
}
|
|
298
|
-
// =====================================================================================
|
|
299
|
-
// Test: db.query structure with link traversal from included domains
|
|
300
|
-
// =====================================================================================
|
|
301
|
-
// Domain with entities and links that enable link traversal queries
|
|
302
|
-
const domainWithLinkTraversal = (0, __1.domain)("withLinkTraversal").schema({
|
|
303
|
-
entities: {
|
|
304
|
-
organization_users: core_1.i.entity({
|
|
305
|
-
firstName: core_1.i.string().optional(),
|
|
306
|
-
lastName: core_1.i.string().optional(),
|
|
307
|
-
}),
|
|
308
|
-
},
|
|
309
|
-
links: {
|
|
310
|
-
usersUserUsers: {
|
|
311
|
-
forward: { on: "organization_users", has: "one", label: "identity" },
|
|
312
|
-
reverse: { on: "$users", has: "many", label: "user_users" },
|
|
313
|
-
},
|
|
314
|
-
},
|
|
315
|
-
rooms: {},
|
|
316
|
-
});
|
|
317
|
-
// Domain that includes the above
|
|
318
|
-
const domainIncludingLinkTraversal = (0, __1.domain)("includingTraversal")
|
|
319
|
-
.includes(domainWithLinkTraversal)
|
|
320
|
-
.schema({
|
|
321
|
-
entities: {
|
|
322
|
-
local_items: core_1.i.entity({
|
|
323
|
-
name: core_1.i.string(),
|
|
324
|
-
}),
|
|
325
|
-
},
|
|
326
|
-
links: {},
|
|
327
|
-
rooms: {},
|
|
328
|
-
});
|
|
329
|
-
// Create schema for query testing
|
|
330
|
-
const traversalSchema = domainIncludingLinkTraversal.toInstantSchema();
|
|
331
|
-
const _traversalLinkCheck = true;
|
|
332
|
-
// Runtime check: link should be present
|
|
333
|
-
const hasTraversalLink = "usersUserUsers" in traversalSchema.links;
|
|
334
|
-
if (!hasTraversalLink) {
|
|
335
|
-
throw new Error("Link from included domain not available for query traversal");
|
|
336
|
-
}
|
|
337
|
-
// =====================================================================================
|
|
338
|
-
// Test: InstantDB utility types work with merged schemas from included domains
|
|
339
|
-
// =====================================================================================
|
|
340
|
-
// Create a comprehensive test schema with multiple domains and links
|
|
341
|
-
const testDomainA = (0, __1.domain)("testA").schema({
|
|
342
|
-
entities: {
|
|
343
|
-
test_a_items: core_1.i.entity({
|
|
344
|
-
name: core_1.i.string(),
|
|
345
|
-
value: core_1.i.number(),
|
|
346
|
-
}),
|
|
347
|
-
},
|
|
348
|
-
links: {
|
|
349
|
-
testAItemsOwner: {
|
|
350
|
-
forward: { on: "test_a_items", has: "one", label: "owner" },
|
|
351
|
-
reverse: { on: "$users", has: "many", label: "owned_test_a_items" },
|
|
352
|
-
},
|
|
353
|
-
},
|
|
354
|
-
rooms: {},
|
|
355
|
-
});
|
|
356
|
-
// testDomainB includes testDomainA to reference test_a_items in links
|
|
357
|
-
// This ensures type safety: links can only reference entities that are available
|
|
358
|
-
const testDomainB = (0, __1.domain)("testB")
|
|
359
|
-
.includes(testDomainA)
|
|
360
|
-
.schema({
|
|
361
|
-
entities: {
|
|
362
|
-
test_b_items: core_1.i.entity({
|
|
363
|
-
title: core_1.i.string(),
|
|
364
|
-
status: core_1.i.string(),
|
|
365
|
-
}),
|
|
366
|
-
},
|
|
367
|
-
links: {
|
|
368
|
-
testBItemsCreator: {
|
|
369
|
-
forward: { on: "test_b_items", has: "one", label: "creator" },
|
|
370
|
-
reverse: { on: "$users", has: "many", label: "created_test_b_items" },
|
|
371
|
-
},
|
|
372
|
-
testBItemsRelated: {
|
|
373
|
-
forward: { on: "test_b_items", has: "one", label: "related" },
|
|
374
|
-
reverse: { on: "test_a_items", has: "many", label: "test_b_items" },
|
|
375
|
-
},
|
|
376
|
-
},
|
|
377
|
-
rooms: {},
|
|
378
|
-
});
|
|
379
|
-
// Combined schema with both domains
|
|
380
|
-
const combinedTestSchema = (0, __1.domain)("combined")
|
|
381
|
-
.includes(testDomainA)
|
|
382
|
-
.includes(testDomainB)
|
|
383
|
-
.schema({
|
|
384
|
-
entities: {
|
|
385
|
-
combined_items: core_1.i.entity({
|
|
386
|
-
description: core_1.i.string(),
|
|
387
|
-
}),
|
|
388
|
-
},
|
|
389
|
-
links: {
|
|
390
|
-
combinedItemsParent: {
|
|
391
|
-
forward: { on: "combined_items", has: "one", label: "parent" },
|
|
392
|
-
reverse: { on: "test_b_items", has: "many", label: "combined_items" },
|
|
393
|
-
},
|
|
394
|
-
},
|
|
395
|
-
rooms: {},
|
|
396
|
-
});
|
|
397
|
-
// Note: $users is added at runtime, so it may not be in compile-time type
|
|
398
|
-
// We verify it exists at runtime in Test 9
|
|
399
|
-
const _entityCheck1 = true;
|
|
400
|
-
const _entityCheck2 = true;
|
|
401
|
-
const _entityCheck3 = true;
|
|
402
|
-
const _linkCheck1 = true;
|
|
403
|
-
const _linkCheck2 = true;
|
|
404
|
-
const _linkCheck3 = true;
|
|
405
|
-
const _linkCheck4 = true;
|
|
406
|
-
// Test 3: InstaQLParams - Query typechecking with links from included domains
|
|
407
|
-
// Note: TypeScript's type system may not fully recognize merged links from included domains
|
|
408
|
-
// at compile time, but they work correctly at runtime (verified in Test 9)
|
|
409
|
-
const queryWithIncludedLinks = {
|
|
410
|
-
test_a_items: {
|
|
411
|
-
owner: {},
|
|
412
|
-
},
|
|
413
|
-
test_b_items: {
|
|
414
|
-
creator: {},
|
|
415
|
-
related: {
|
|
416
|
-
owner: {},
|
|
417
|
-
},
|
|
418
|
-
},
|
|
419
|
-
combined_items: {
|
|
420
|
-
parent: {
|
|
421
|
-
creator: {},
|
|
422
|
-
related: {},
|
|
423
|
-
},
|
|
424
|
-
},
|
|
425
|
-
};
|
|
426
|
-
// Test 4: InstaQLParams - Query with link traversal from included domain
|
|
427
|
-
// Note: Using 'as' because merged links from included domains aren't in compile-time types
|
|
428
|
-
// but work correctly at runtime. See Test 4b for validation demonstration.
|
|
429
|
-
const queryWithLinkTraversal = {
|
|
430
|
-
test_a_items: {
|
|
431
|
-
$: {
|
|
432
|
-
where: { "owner.email": "test@example.com" },
|
|
433
|
-
},
|
|
434
|
-
owner: {},
|
|
435
|
-
},
|
|
436
|
-
};
|
|
437
|
-
// Test 4b: Validation test - demonstrates that satisfies catches invalid properties
|
|
438
|
-
// Using a single domain (no includes) so types are complete and validation works
|
|
439
|
-
const validationTestDomain = (0, __1.domain)("validationTest").schema({
|
|
440
|
-
entities: {
|
|
441
|
-
validation_items: core_1.i.entity({
|
|
442
|
-
name: core_1.i.string(),
|
|
443
|
-
}),
|
|
444
|
-
},
|
|
445
|
-
links: {
|
|
446
|
-
validationItemsOwner: {
|
|
447
|
-
forward: { on: "validation_items", has: "one", label: "owner" },
|
|
448
|
-
reverse: { on: "$users", has: "many", label: "validation_items" },
|
|
449
|
-
},
|
|
450
|
-
},
|
|
451
|
-
rooms: {},
|
|
452
|
-
});
|
|
453
|
-
// This validates correctly - valid query
|
|
454
|
-
const validQuery = {
|
|
455
|
-
validation_items: {
|
|
456
|
-
owner: {},
|
|
457
|
-
},
|
|
458
|
-
};
|
|
459
|
-
const _invalidQueryTypoCheck = true; // Should be true (not assignable)
|
|
460
|
-
const _validQueryCheck = true; // Should be true (assignable)
|
|
461
|
-
// This would fail validation - invalid property 'x'
|
|
462
|
-
// Uncomment to see TypeScript error:
|
|
463
|
-
// const invalidQuery = {
|
|
464
|
-
// validation_items: {
|
|
465
|
-
// x: {}, // Error: 'x' does not exist
|
|
466
|
-
// },
|
|
467
|
-
// } satisfies InstaQLParams<ValidationSchema>;
|
|
468
|
-
// Test 5: InstaQLParams - Query with all entities from included domains
|
|
469
|
-
const queryAllEntities = {
|
|
470
|
-
test_a_items: {},
|
|
471
|
-
test_b_items: {
|
|
472
|
-
related: {},
|
|
473
|
-
},
|
|
474
|
-
combined_items: {
|
|
475
|
-
parent: {},
|
|
476
|
-
},
|
|
477
|
-
$users: {},
|
|
478
|
-
};
|
|
479
|
-
// Test 6: InstaQLParams - Query using link traversal across included domains
|
|
480
|
-
const queryCrossDomainTraversal = {
|
|
481
|
-
test_b_items: {
|
|
482
|
-
$: {
|
|
483
|
-
where: { "related.owner.email": "test@example.com" },
|
|
484
|
-
},
|
|
485
|
-
related: {
|
|
486
|
-
owner: {},
|
|
487
|
-
},
|
|
488
|
-
},
|
|
489
|
-
};
|
|
490
|
-
// Test 9: Runtime verification - schema should have all entities and links
|
|
491
|
-
const finalSchema = combinedTestSchema.toInstantSchema();
|
|
492
|
-
const hasTestAItems = "test_a_items" in finalSchema.entities;
|
|
493
|
-
const hasTestBItems = "test_b_items" in finalSchema.entities;
|
|
494
|
-
const hasCombinedItems = "combined_items" in finalSchema.entities;
|
|
495
|
-
const hasUsers = "$users" in finalSchema.entities;
|
|
496
|
-
const hasTestAItemsOwnerLink = "testAItemsOwner" in finalSchema.links;
|
|
497
|
-
const hasTestBItemsCreatorLink = "testBItemsCreator" in finalSchema.links;
|
|
498
|
-
const hasTestBItemsRelatedLink = "testBItemsRelated" in finalSchema.links;
|
|
499
|
-
const hasCombinedItemsParentLink = "combinedItemsParent" in finalSchema.links;
|
|
500
|
-
if (!hasTestAItems || !hasTestBItems || !hasCombinedItems || !hasUsers) {
|
|
501
|
-
throw new Error("Not all entities from included domains are present in final schema");
|
|
502
|
-
}
|
|
503
|
-
if (!hasTestAItemsOwnerLink || !hasTestBItemsCreatorLink || !hasTestBItemsRelatedLink || !hasCombinedItemsParentLink) {
|
|
504
|
-
throw new Error("Not all links from included domains are present in final schema");
|
|
505
|
-
}
|
|
506
|
-
// Note: In a real application with @instantdb/react or @instantdb/admin installed,
|
|
507
|
-
// you would use the utility types like this:
|
|
508
|
-
//
|
|
509
|
-
// import type { InstaQLParams, InstaQLResult, InstaQLEntity } from "@instantdb/react";
|
|
510
|
-
//
|
|
511
|
-
// const query = {
|
|
512
|
-
// test_a_items: { owner: {} },
|
|
513
|
-
// test_b_items: { creator: {}, related: { owner: {} } },
|
|
514
|
-
// } satisfies InstaQLParams<CombinedSchema>;
|
|
515
|
-
//
|
|
516
|
-
// type Result = InstaQLResult<CombinedSchema, typeof query>;
|
|
517
|
-
// type Item = InstaQLEntity<CombinedSchema, "test_a_items", { owner: {} }>;
|
|
518
|
-
// =====================================================================================
|
|
519
|
-
// Test: Compare InstantDB pure schema vs domain schema for InstaQLParams validation
|
|
520
|
-
// =====================================================================================
|
|
521
|
-
// Pure InstantDB schema - this should work correctly with InstaQLParams
|
|
522
|
-
const pureInstantSchema = core_1.i.schema({
|
|
523
|
-
entities: {
|
|
524
|
-
test_items: core_1.i.entity({
|
|
525
|
-
name: core_1.i.string(),
|
|
526
|
-
}),
|
|
527
|
-
$users: core_1.i.entity({
|
|
528
|
-
email: core_1.i.string().optional().indexed(),
|
|
529
|
-
}),
|
|
530
|
-
},
|
|
531
|
-
links: {
|
|
532
|
-
testItemsOwner: {
|
|
533
|
-
forward: { on: "test_items", has: "one", label: "owner" },
|
|
534
|
-
reverse: { on: "$users", has: "many", label: "test_items" },
|
|
535
|
-
},
|
|
536
|
-
},
|
|
537
|
-
rooms: {},
|
|
538
|
-
});
|
|
539
|
-
// Test pure schema validation - this should work
|
|
540
|
-
const pureValidQuery = {
|
|
541
|
-
test_items: {
|
|
542
|
-
owner: {},
|
|
543
|
-
},
|
|
544
|
-
};
|
|
545
|
-
// This should fail with pure schema
|
|
546
|
-
// Uncomment to see TypeScript error:
|
|
547
|
-
// const pureInvalidQuery = {
|
|
548
|
-
// test_items: {
|
|
549
|
-
// ownexr: {}, // Error: 'ownexr' does not exist
|
|
550
|
-
// },
|
|
551
|
-
// } satisfies InstaQLParams<PureInstantSchema>;
|
|
552
|
-
// Domain schema - should behave the same as pure schema
|
|
553
|
-
const domainTestSchema = (0, __1.domain)("domainTest").schema({
|
|
554
|
-
entities: {
|
|
555
|
-
test_items: core_1.i.entity({
|
|
556
|
-
name: core_1.i.string(),
|
|
557
|
-
}),
|
|
558
|
-
},
|
|
559
|
-
links: {
|
|
560
|
-
testItemsOwner: {
|
|
561
|
-
forward: { on: "test_items", has: "one", label: "owner" },
|
|
562
|
-
reverse: { on: "$users", has: "many", label: "test_items" },
|
|
563
|
-
},
|
|
564
|
-
},
|
|
565
|
-
rooms: {},
|
|
566
|
-
});
|
|
567
|
-
// Test domain schema validation - should work the same as pure schema
|
|
568
|
-
const domainValidQuery = {
|
|
569
|
-
test_items: {
|
|
570
|
-
owner: {},
|
|
571
|
-
},
|
|
572
|
-
};
|
|
573
|
-
const _domainInvalidQueryCheck = true; // Should be true (not assignable)
|
|
574
|
-
const _domainValidQueryCheck = true; // Should be true (assignable)
|
|
575
|
-
// These may be false due to type inference, but InstaQLParams validation works correctly
|
|
576
|
-
// The important test is that invalid queries are rejected (verified above)
|
|
577
|
-
const _pureLinkCheck = false; // May be false, but validation works
|
|
578
|
-
const _domainLinkCheck = false; // May be false, but validation works
|
|
579
|
-
// These should be the literal type "owner"
|
|
580
|
-
const _pureLabelCheck = "owner";
|
|
581
|
-
const _domainLabelCheck = "owner";
|
|
582
|
-
// These may be false due to type inference, but InstaQLParams validation works correctly
|
|
583
|
-
// The critical test is that invalid queries are rejected (verified above)
|
|
584
|
-
const _pureEntityEnrichment = false; // May be false, but validation works
|
|
585
|
-
const _domainEntityEnrichment = false; // May be false, but validation works
|
|
586
|
-
// =====================================================================================
|
|
587
|
-
// Test: Verify that attribute validation works in queries with link traversal
|
|
588
|
-
// =====================================================================================
|
|
589
|
-
// Pure InstantDB schema for attribute validation testing
|
|
590
|
-
const pureAttrSchema = core_1.i.schema({
|
|
591
|
-
entities: {
|
|
592
|
-
test_items: core_1.i.entity({
|
|
593
|
-
name: core_1.i.string(),
|
|
594
|
-
value: core_1.i.number(),
|
|
595
|
-
}),
|
|
596
|
-
$users: core_1.i.entity({
|
|
597
|
-
email: core_1.i.string().optional().indexed(),
|
|
598
|
-
name: core_1.i.string().optional(),
|
|
599
|
-
}),
|
|
600
|
-
},
|
|
601
|
-
links: {
|
|
602
|
-
testItemsOwner: {
|
|
603
|
-
forward: { on: "test_items", has: "one", label: "owner" },
|
|
604
|
-
reverse: { on: "$users", has: "many", label: "test_items" },
|
|
605
|
-
},
|
|
606
|
-
},
|
|
607
|
-
rooms: {},
|
|
608
|
-
});
|
|
609
|
-
// Valid query with valid attribute - should work
|
|
610
|
-
const pureValidAttrQuery = {
|
|
611
|
-
test_items: {
|
|
612
|
-
$: {
|
|
613
|
-
where: { "oasdwner.email": "test@example.com" }, // Valid: email exists on $users
|
|
614
|
-
},
|
|
615
|
-
owner: {},
|
|
616
|
-
},
|
|
617
|
-
};
|
|
618
|
-
// Current behavior: false (assignable) - InstantDB doesn't validate attributes in where
|
|
619
|
-
const _pureInvalidAttrCheck = false; // InstantDB 0.22.48 doesn't validate attributes
|
|
620
|
-
const _pureValidAttrCheck = true; // Should be true (assignable)
|
|
621
|
-
// Domain schema for attribute validation testing
|
|
622
|
-
const domainAttrSchema = (0, __1.domain)("domainAttrTest").schema({
|
|
623
|
-
entities: {
|
|
624
|
-
test_items: core_1.i.entity({
|
|
625
|
-
name: core_1.i.string(),
|
|
626
|
-
value: core_1.i.number(),
|
|
627
|
-
}),
|
|
628
|
-
},
|
|
629
|
-
links: {
|
|
630
|
-
testItemsOwner: {
|
|
631
|
-
forward: { on: "test_items", has: "one", label: "owner" },
|
|
632
|
-
reverse: { on: "$users", has: "many", label: "test_items" },
|
|
633
|
-
},
|
|
634
|
-
},
|
|
635
|
-
rooms: {},
|
|
636
|
-
});
|
|
637
|
-
// Valid query with valid attribute - should work
|
|
638
|
-
const domainValidAttrQuery = {
|
|
639
|
-
test_items: {
|
|
640
|
-
$: {
|
|
641
|
-
where: { "owner.email": "test@example.com" }, // Valid: email exists on $users
|
|
642
|
-
},
|
|
643
|
-
owner: {},
|
|
644
|
-
},
|
|
645
|
-
};
|
|
646
|
-
// TODO: Fix toInstantSchema() return type to preserve entity attribute types
|
|
647
|
-
// Currently false (assignable) but should be true (not assignable)
|
|
648
|
-
const _domainInvalidAttrCheck = false; // BUG: Should be true but currently false
|
|
649
|
-
const _domainValidAttrCheck = true; // Should be true (assignable)
|
|
650
|
-
// Current behavior: false (assignable) - InstantDB doesn't validate attributes in where
|
|
651
|
-
const _pureInvalidEntityAttrCheck = false; // InstantDB 0.22.48 doesn't validate attributes
|
|
652
|
-
// TODO: Fix toInstantSchema() return type to preserve entity attribute types
|
|
653
|
-
// Currently false (assignable) but should be true (not assignable)
|
|
654
|
-
const _domainInvalidEntityAttrCheck = false; // BUG: Should be true but currently false
|
|
655
|
-
// =====================================================================================
|
|
656
|
-
// ❌ COMPILE-TIME VALIDATION: Links and Entity Conflicts
|
|
657
|
-
// =====================================================================================
|
|
658
|
-
// (Omitted negative tests that intentionally fail compilation)
|
|
659
|
-
// (Known limitation) Duplicate entity names across includes are not detected at compile time
|
|
660
|
-
//# sourceMappingURL=domain-builder.typecheck.js.map
|