schemock 0.0.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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/dist/adapters/index.d.mts +1364 -0
  4. package/dist/adapters/index.d.ts +1364 -0
  5. package/dist/adapters/index.js +36988 -0
  6. package/dist/adapters/index.js.map +1 -0
  7. package/dist/adapters/index.mjs +36972 -0
  8. package/dist/adapters/index.mjs.map +1 -0
  9. package/dist/cli/index.d.mts +831 -0
  10. package/dist/cli/index.d.ts +831 -0
  11. package/dist/cli/index.js +4425 -0
  12. package/dist/cli/index.js.map +1 -0
  13. package/dist/cli/index.mjs +4401 -0
  14. package/dist/cli/index.mjs.map +1 -0
  15. package/dist/cli.js +6776 -0
  16. package/dist/index.d.mts +8 -0
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.js +39439 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/index.mjs +39367 -0
  21. package/dist/index.mjs.map +1 -0
  22. package/dist/middleware/index.d.mts +688 -0
  23. package/dist/middleware/index.d.ts +688 -0
  24. package/dist/middleware/index.js +921 -0
  25. package/dist/middleware/index.js.map +1 -0
  26. package/dist/middleware/index.mjs +899 -0
  27. package/dist/middleware/index.mjs.map +1 -0
  28. package/dist/react/index.d.mts +316 -0
  29. package/dist/react/index.d.ts +316 -0
  30. package/dist/react/index.js +466 -0
  31. package/dist/react/index.js.map +1 -0
  32. package/dist/react/index.mjs +456 -0
  33. package/dist/react/index.mjs.map +1 -0
  34. package/dist/runtime/index.d.mts +814 -0
  35. package/dist/runtime/index.d.ts +814 -0
  36. package/dist/runtime/index.js +1270 -0
  37. package/dist/runtime/index.js.map +1 -0
  38. package/dist/runtime/index.mjs +1246 -0
  39. package/dist/runtime/index.mjs.map +1 -0
  40. package/dist/schema/index.d.mts +838 -0
  41. package/dist/schema/index.d.ts +838 -0
  42. package/dist/schema/index.js +696 -0
  43. package/dist/schema/index.js.map +1 -0
  44. package/dist/schema/index.mjs +681 -0
  45. package/dist/schema/index.mjs.map +1 -0
  46. package/dist/types-C1MiZh1d.d.ts +96 -0
  47. package/dist/types-C2bd2vgy.d.mts +773 -0
  48. package/dist/types-C2bd2vgy.d.ts +773 -0
  49. package/dist/types-C9VMgu3E.d.mts +289 -0
  50. package/dist/types-DV2DS7wj.d.mts +96 -0
  51. package/dist/types-c2AN3vky.d.ts +289 -0
  52. package/package.json +116 -0
@@ -0,0 +1,1270 @@
1
+ 'use strict';
2
+
3
+ var msw = require('msw');
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+
15
+ // src/runtime/handlers.ts
16
+ var handlers_exports = {};
17
+ __export(handlers_exports, {
18
+ createHandlers: () => createHandlers
19
+ });
20
+ function createHandlers(schemas, adapter, options) {
21
+ const handlers = [];
22
+ const baseUrl = options?.baseUrl ?? "/api";
23
+ for (const schema of schemas) {
24
+ const entityPath = getEntityPath(schema, baseUrl);
25
+ handlers.push(createListHandler(schema, entityPath, adapter));
26
+ handlers.push(createGetHandler(schema, entityPath, adapter));
27
+ handlers.push(createCreateHandler(schema, entityPath, adapter));
28
+ handlers.push(createUpdateHandler(schema, entityPath, adapter, "PUT"));
29
+ handlers.push(createUpdateHandler(schema, entityPath, adapter, "PATCH"));
30
+ handlers.push(createDeleteHandler(schema, entityPath, adapter));
31
+ if (schema.api?.operations) {
32
+ handlers.push(
33
+ ...createCustomHandlers(schema, entityPath, adapter)
34
+ );
35
+ }
36
+ }
37
+ return handlers;
38
+ }
39
+ function getEntityPath(schema, baseUrl) {
40
+ if (schema.api?.basePath) {
41
+ return schema.api.basePath;
42
+ }
43
+ const plural = schema.name.endsWith("s") ? schema.name : `${schema.name}s`;
44
+ return `${baseUrl}/${plural}`;
45
+ }
46
+ function createListHandler(schema, path, adapter) {
47
+ return msw.http.get(path, async ({ request }) => {
48
+ const url = new URL(request.url);
49
+ const ctx = {
50
+ entity: schema.name,
51
+ endpoint: path,
52
+ params: {},
53
+ filter: parseQueryFilter(url.searchParams),
54
+ limit: parseNumber(url.searchParams.get("limit")),
55
+ offset: parseNumber(url.searchParams.get("offset")),
56
+ orderBy: parseOrderBy(url.searchParams.get("orderBy"))
57
+ };
58
+ const result = await adapter.findMany(ctx);
59
+ if (result.error) {
60
+ return msw.HttpResponse.json(
61
+ { error: result.error.message },
62
+ { status: 500 }
63
+ );
64
+ }
65
+ return msw.HttpResponse.json({
66
+ data: result.data,
67
+ meta: result.meta
68
+ });
69
+ });
70
+ }
71
+ function createGetHandler(schema, path, adapter) {
72
+ return msw.http.get(`${path}/:id`, async ({ params }) => {
73
+ const ctx = {
74
+ entity: schema.name,
75
+ endpoint: path,
76
+ params: { id: params.id }
77
+ };
78
+ const result = await adapter.findOne(ctx);
79
+ if (result.error) {
80
+ return msw.HttpResponse.json(
81
+ { error: result.error.message },
82
+ { status: 404 }
83
+ );
84
+ }
85
+ if (!result.data) {
86
+ return msw.HttpResponse.json(
87
+ { error: `${schema.name} not found` },
88
+ { status: 404 }
89
+ );
90
+ }
91
+ return msw.HttpResponse.json({ data: result.data });
92
+ });
93
+ }
94
+ function createCreateHandler(schema, path, adapter) {
95
+ return msw.http.post(path, async ({ request }) => {
96
+ const body = await request.json();
97
+ const ctx = {
98
+ entity: schema.name,
99
+ endpoint: path,
100
+ data: body
101
+ };
102
+ const result = await adapter.create(ctx);
103
+ if (result.error) {
104
+ return msw.HttpResponse.json(
105
+ { error: result.error.message },
106
+ { status: 400 }
107
+ );
108
+ }
109
+ return msw.HttpResponse.json({ data: result.data }, { status: 201 });
110
+ });
111
+ }
112
+ function createUpdateHandler(schema, path, adapter, method) {
113
+ const handler = method === "PUT" ? msw.http.put : msw.http.patch;
114
+ return handler(`${path}/:id`, async ({ params, request }) => {
115
+ const body = await request.json();
116
+ const ctx = {
117
+ entity: schema.name,
118
+ endpoint: path,
119
+ params: { id: params.id },
120
+ data: body
121
+ };
122
+ const result = await adapter.update(ctx);
123
+ if (result.error) {
124
+ return msw.HttpResponse.json(
125
+ { error: result.error.message },
126
+ { status: 400 }
127
+ );
128
+ }
129
+ if (!result.data) {
130
+ return msw.HttpResponse.json(
131
+ { error: `${schema.name} not found` },
132
+ { status: 404 }
133
+ );
134
+ }
135
+ return msw.HttpResponse.json({ data: result.data });
136
+ });
137
+ }
138
+ function createDeleteHandler(schema, path, adapter) {
139
+ return msw.http.delete(`${path}/:id`, async ({ params }) => {
140
+ const ctx = {
141
+ entity: schema.name,
142
+ endpoint: path,
143
+ params: { id: params.id }
144
+ };
145
+ const result = await adapter.delete(ctx);
146
+ if (result.error) {
147
+ return msw.HttpResponse.json(
148
+ { error: result.error.message },
149
+ { status: 400 }
150
+ );
151
+ }
152
+ return new msw.HttpResponse(null, { status: 204 });
153
+ });
154
+ }
155
+ function createCustomHandlers(schema, basePath, adapter) {
156
+ const handlers = [];
157
+ const operations = schema.api?.operations || {};
158
+ for (const [name, config] of Object.entries(operations)) {
159
+ if (typeof config === "boolean") continue;
160
+ if (!config || typeof config !== "object") continue;
161
+ const customConfig = config;
162
+ const method = customConfig.method?.toLowerCase() || "get";
163
+ const path = `${basePath}${customConfig.path || `/${name}`}`;
164
+ const httpMethod = msw.http[method];
165
+ if (typeof httpMethod !== "function") continue;
166
+ handlers.push(
167
+ httpMethod(path, async ({ request, params }) => {
168
+ const ctx = {
169
+ entity: schema.name,
170
+ endpoint: path,
171
+ operation: name,
172
+ params
173
+ };
174
+ if (method === "post" || method === "put" || method === "patch") {
175
+ ctx.data = await request.json();
176
+ }
177
+ if (adapter.custom) {
178
+ const result = await adapter.custom(ctx);
179
+ if (result.error) {
180
+ return msw.HttpResponse.json(
181
+ { error: result.error.message },
182
+ { status: 400 }
183
+ );
184
+ }
185
+ return msw.HttpResponse.json({ data: result.data });
186
+ }
187
+ return msw.HttpResponse.json(
188
+ { error: "Custom operations not supported by adapter" },
189
+ { status: 501 }
190
+ );
191
+ })
192
+ );
193
+ }
194
+ return handlers;
195
+ }
196
+ function parseQueryFilter(params) {
197
+ const filter = {};
198
+ let hasFilter = false;
199
+ for (const [key, value] of params.entries()) {
200
+ if (["limit", "offset", "orderBy", "select"].includes(key)) continue;
201
+ if (key.startsWith("filter[") && key.endsWith("]")) {
202
+ const field = key.slice(7, -1);
203
+ filter[field] = parseValue(value);
204
+ hasFilter = true;
205
+ } else if (!key.includes("[")) {
206
+ filter[key] = parseValue(value);
207
+ hasFilter = true;
208
+ }
209
+ }
210
+ return hasFilter ? filter : void 0;
211
+ }
212
+ function parseOrderBy(value) {
213
+ if (!value) return void 0;
214
+ const orderBy = {};
215
+ for (const part of value.split(",")) {
216
+ const [field, direction] = part.split(":");
217
+ if (field) {
218
+ orderBy[field] = direction === "desc" ? "desc" : "asc";
219
+ }
220
+ }
221
+ return Object.keys(orderBy).length > 0 ? orderBy : void 0;
222
+ }
223
+ function parseNumber(value) {
224
+ if (!value) return void 0;
225
+ const num = parseInt(value, 10);
226
+ return isNaN(num) ? void 0 : num;
227
+ }
228
+ function parseValue(value) {
229
+ if (value === "true") return true;
230
+ if (value === "false") return false;
231
+ const num = Number(value);
232
+ if (!isNaN(num)) return num;
233
+ return value;
234
+ }
235
+ var init_handlers = __esm({
236
+ "src/runtime/handlers.ts"() {
237
+ }
238
+ });
239
+
240
+ // src/runtime/resolver/registry.ts
241
+ var SchemaRegistry = class {
242
+ entities = /* @__PURE__ */ new Map();
243
+ views = /* @__PURE__ */ new Map();
244
+ /**
245
+ * Register an entity schema
246
+ * @param schema - The entity schema to register
247
+ */
248
+ register(schema) {
249
+ if (this.entities.has(schema.name)) {
250
+ console.warn(`Schema '${schema.name}' is already registered. Overwriting.`);
251
+ }
252
+ this.entities.set(schema.name, schema);
253
+ }
254
+ /**
255
+ * Register a view schema
256
+ * @param view - The view schema to register
257
+ */
258
+ registerView(view) {
259
+ if (this.views.has(view.name)) {
260
+ console.warn(`View '${view.name}' is already registered. Overwriting.`);
261
+ }
262
+ this.views.set(view.name, view);
263
+ }
264
+ /**
265
+ * Get an entity schema by name
266
+ * @param entityName - The entity name
267
+ * @returns EntitySchema or undefined if not found
268
+ */
269
+ get(entityName) {
270
+ return this.entities.get(entityName);
271
+ }
272
+ /**
273
+ * Get an entity schema by name, throws if not found
274
+ * @param entityName - The entity name
275
+ * @returns EntitySchema
276
+ * @throws Error if entity not found
277
+ */
278
+ getOrThrow(entityName) {
279
+ const schema = this.entities.get(entityName);
280
+ if (!schema) {
281
+ throw new Error(`Entity schema '${entityName}' not found. Did you forget to register it?`);
282
+ }
283
+ return schema;
284
+ }
285
+ /**
286
+ * Get a view schema by name
287
+ * @param viewName - The view name
288
+ * @returns ViewSchema or undefined if not found
289
+ */
290
+ getView(viewName) {
291
+ return this.views.get(viewName);
292
+ }
293
+ /**
294
+ * Get a view schema by name, throws if not found
295
+ * @param viewName - The view name
296
+ * @returns ViewSchema
297
+ * @throws Error if view not found
298
+ */
299
+ getViewOrThrow(viewName) {
300
+ const view = this.views.get(viewName);
301
+ if (!view) {
302
+ throw new Error(`View schema '${viewName}' not found. Did you forget to register it?`);
303
+ }
304
+ return view;
305
+ }
306
+ /**
307
+ * Get all registered entity schemas
308
+ * @returns Array of all entity schemas
309
+ */
310
+ getAll() {
311
+ return Array.from(this.entities.values());
312
+ }
313
+ /**
314
+ * Get all registered view schemas
315
+ * @returns Array of all view schemas
316
+ */
317
+ getAllViews() {
318
+ return Array.from(this.views.values());
319
+ }
320
+ /**
321
+ * Check if an entity schema is registered
322
+ * @param entityName - The entity name
323
+ * @returns true if registered
324
+ */
325
+ has(entityName) {
326
+ return this.entities.has(entityName);
327
+ }
328
+ /**
329
+ * Check if a view schema is registered
330
+ * @param viewName - The view name
331
+ * @returns true if registered
332
+ */
333
+ hasView(viewName) {
334
+ return this.views.has(viewName);
335
+ }
336
+ /**
337
+ * Get all relations for an entity
338
+ * @param entityName - The entity name
339
+ * @returns Array of relation definitions with their names
340
+ */
341
+ getRelationsFor(entityName) {
342
+ const schema = this.entities.get(entityName);
343
+ if (!schema || !schema.relations) {
344
+ return [];
345
+ }
346
+ return Object.entries(schema.relations).map(([name, relation]) => ({
347
+ name,
348
+ relation
349
+ }));
350
+ }
351
+ /**
352
+ * Get all entities that have a relation to a target entity
353
+ * @param targetEntityName - The target entity name
354
+ * @returns Array of entity names that reference the target
355
+ */
356
+ getEntitiesReferencingEntity(targetEntityName) {
357
+ const result = [];
358
+ for (const [entityName, schema] of this.entities) {
359
+ if (schema.relations) {
360
+ for (const relation of Object.values(schema.relations)) {
361
+ if (relation.target === targetEntityName) {
362
+ result.push(entityName);
363
+ break;
364
+ }
365
+ }
366
+ }
367
+ }
368
+ return result;
369
+ }
370
+ /**
371
+ * Get entity names in dependency order (topological sort)
372
+ * Entities with no dependencies come first
373
+ * @returns Array of entity names in order
374
+ */
375
+ getEntityOrder() {
376
+ const visited = /* @__PURE__ */ new Set();
377
+ const result = [];
378
+ const visit = (entityName) => {
379
+ if (visited.has(entityName)) return;
380
+ visited.add(entityName);
381
+ const schema = this.entities.get(entityName);
382
+ if (schema?.relations) {
383
+ for (const relation of Object.values(schema.relations)) {
384
+ if (this.entities.has(relation.target)) {
385
+ visit(relation.target);
386
+ }
387
+ }
388
+ }
389
+ result.push(entityName);
390
+ };
391
+ for (const entityName of this.entities.keys()) {
392
+ visit(entityName);
393
+ }
394
+ return result;
395
+ }
396
+ /**
397
+ * Clear all registered schemas
398
+ */
399
+ clear() {
400
+ this.entities.clear();
401
+ this.views.clear();
402
+ }
403
+ /**
404
+ * Get entity count
405
+ */
406
+ get entityCount() {
407
+ return this.entities.size;
408
+ }
409
+ /**
410
+ * Get view count
411
+ */
412
+ get viewCount() {
413
+ return this.views.size;
414
+ }
415
+ };
416
+ var registry = new SchemaRegistry();
417
+
418
+ // src/runtime/resolver/computed.ts
419
+ function topologicalSort(fields, allComputed) {
420
+ const result = [];
421
+ const visited = /* @__PURE__ */ new Set();
422
+ const visiting = /* @__PURE__ */ new Set();
423
+ const fieldNames = new Set(fields.map(([name]) => name));
424
+ function visit(name) {
425
+ if (visited.has(name)) return;
426
+ if (visiting.has(name)) {
427
+ throw new Error(`Circular dependency detected in computed fields: ${name}`);
428
+ }
429
+ visiting.add(name);
430
+ const computed = allComputed[name];
431
+ if (computed?.dependsOn) {
432
+ for (const dep of computed.dependsOn) {
433
+ if (allComputed[dep] && fieldNames.has(dep)) {
434
+ visit(dep);
435
+ }
436
+ }
437
+ }
438
+ visiting.delete(name);
439
+ visited.add(name);
440
+ const field = fields.find(([n]) => n === name);
441
+ if (field) {
442
+ result.push(field);
443
+ }
444
+ }
445
+ for (const [name] of fields) {
446
+ visit(name);
447
+ }
448
+ return result;
449
+ }
450
+ var computeCache = /* @__PURE__ */ new Map();
451
+ function clearComputeCache() {
452
+ computeCache.clear();
453
+ }
454
+ function resolveComputedField(entity, fieldName, computed, db, context) {
455
+ const entityId = entity.id;
456
+ const cacheKey = `${entityId}:${fieldName}`;
457
+ if (computeCache.has(cacheKey)) {
458
+ return computeCache.get(cacheKey);
459
+ }
460
+ let value;
461
+ if (context.mode === "seed" && computed.mock) {
462
+ value = computed.mock();
463
+ } else {
464
+ value = computed.resolve(entity, db, context);
465
+ }
466
+ if (value instanceof Promise) {
467
+ return value.then((resolved) => {
468
+ computeCache.set(cacheKey, resolved);
469
+ return resolved;
470
+ });
471
+ }
472
+ computeCache.set(cacheKey, value);
473
+ return value;
474
+ }
475
+ async function resolveComputedFields(entity, schema, db, context) {
476
+ if (!schema.computed || Object.keys(schema.computed).length === 0) {
477
+ return entity;
478
+ }
479
+ const computedFields = Object.entries(schema.computed);
480
+ const sorted = topologicalSort(computedFields, schema.computed);
481
+ for (const [fieldName, computed] of sorted) {
482
+ const value = await resolveComputedField(entity, fieldName, computed, db, context);
483
+ entity[fieldName] = value;
484
+ }
485
+ return entity;
486
+ }
487
+ function resolveComputedFieldsSync(entity, schema, context) {
488
+ if (!schema.computed || Object.keys(schema.computed).length === 0) {
489
+ return entity;
490
+ }
491
+ const computedFields = Object.entries(schema.computed);
492
+ const sorted = topologicalSort(computedFields, schema.computed);
493
+ for (const [fieldName, computed] of sorted) {
494
+ if (computed.mock) {
495
+ entity[fieldName] = computed.mock();
496
+ }
497
+ }
498
+ return entity;
499
+ }
500
+
501
+ // src/runtime/resolver/relation.ts
502
+ var DEFAULT_MAX_DEPTH = 3;
503
+ async function resolveRelation(entity, relationName, relation, db, registry2, options = {}, currentDepth = 0) {
504
+ const maxDepth = options.depth ?? DEFAULT_MAX_DEPTH;
505
+ if (currentDepth >= maxDepth) {
506
+ return relation.type === "hasMany" ? [] : null;
507
+ }
508
+ switch (relation.type) {
509
+ case "hasOne":
510
+ return resolveHasOne(entity, relation, db, registry2, options, currentDepth);
511
+ case "hasMany":
512
+ return resolveHasMany(entity, relation, db, registry2, options, currentDepth);
513
+ case "belongsTo":
514
+ return resolveBelongsTo(entity, relation, db, registry2, options, currentDepth);
515
+ default:
516
+ throw new Error(`Unknown relation type: ${relation.type}`);
517
+ }
518
+ }
519
+ async function resolveHasOne(entity, relation, db, registry2, options, currentDepth) {
520
+ const targetDb = db[relation.target];
521
+ if (!targetDb) {
522
+ throw new Error(`Target entity '${relation.target}' not found in database`);
523
+ }
524
+ const foreignKey = relation.foreignKey || `${entity.constructor.name.toLowerCase()}Id`;
525
+ const entityId = entity.id;
526
+ const related = targetDb.findFirst({
527
+ where: {
528
+ [foreignKey]: { equals: entityId }
529
+ }
530
+ });
531
+ if (!related) return null;
532
+ const targetSchema = registry2.get(relation.target);
533
+ if (targetSchema) {
534
+ await resolveNestedRelations(
535
+ related,
536
+ targetSchema,
537
+ db,
538
+ registry2,
539
+ options,
540
+ currentDepth + 1
541
+ );
542
+ }
543
+ return related;
544
+ }
545
+ async function resolveHasMany(entity, relation, db, registry2, options, currentDepth) {
546
+ const targetDb = db[relation.target];
547
+ if (!targetDb) {
548
+ throw new Error(`Target entity '${relation.target}' not found in database`);
549
+ }
550
+ const foreignKey = relation.foreignKey || `${entity.constructor.name.toLowerCase()}Id`;
551
+ const entityId = entity.id;
552
+ const query = {
553
+ where: {
554
+ [foreignKey]: { equals: entityId }
555
+ }
556
+ };
557
+ const limit = options.limit ?? relation.limit;
558
+ if (limit) {
559
+ query.take = limit;
560
+ }
561
+ const orderBy = options.orderBy ?? relation.orderBy;
562
+ if (orderBy) {
563
+ query.orderBy = orderBy;
564
+ }
565
+ const results = targetDb.findMany(query);
566
+ const targetSchema = registry2.get(relation.target);
567
+ if (targetSchema) {
568
+ for (const item of results) {
569
+ await resolveNestedRelations(
570
+ item,
571
+ targetSchema,
572
+ db,
573
+ registry2,
574
+ options,
575
+ currentDepth + 1
576
+ );
577
+ }
578
+ }
579
+ return results;
580
+ }
581
+ async function resolveBelongsTo(entity, relation, db, registry2, options, currentDepth) {
582
+ const foreignKey = relation.foreignKey || `${relation.target}Id`;
583
+ const foreignKeyValue = entity[foreignKey];
584
+ if (!foreignKeyValue) return null;
585
+ const targetDb = db[relation.target];
586
+ if (!targetDb) {
587
+ throw new Error(`Target entity '${relation.target}' not found in database`);
588
+ }
589
+ const related = targetDb.findFirst({
590
+ where: { id: { equals: foreignKeyValue } }
591
+ });
592
+ if (!related) return null;
593
+ const targetSchema = registry2.get(relation.target);
594
+ if (targetSchema) {
595
+ await resolveNestedRelations(
596
+ related,
597
+ targetSchema,
598
+ db,
599
+ registry2,
600
+ options,
601
+ currentDepth + 1
602
+ );
603
+ }
604
+ return related;
605
+ }
606
+ async function resolveNestedRelations(entity, schema, db, registry2, options, currentDepth) {
607
+ if (!schema.relations) return;
608
+ const include = options.include ?? [];
609
+ for (const [relationName, relation] of Object.entries(schema.relations)) {
610
+ const shouldLoad = relation.eager || include.includes(relationName) || include.some((inc) => inc.startsWith(`${relationName}.`));
611
+ if (shouldLoad) {
612
+ const nestedIncludes = include.filter((inc) => inc.startsWith(`${relationName}.`)).map((inc) => inc.replace(`${relationName}.`, ""));
613
+ entity[relationName] = await resolveRelation(
614
+ entity,
615
+ relationName,
616
+ relation,
617
+ db,
618
+ registry2,
619
+ { ...options, include: nestedIncludes },
620
+ currentDepth
621
+ );
622
+ }
623
+ }
624
+ }
625
+ async function resolveRelations(entity, schema, db, registry2, options = {}) {
626
+ await resolveNestedRelations(entity, schema, db, registry2, options, 0);
627
+ return entity;
628
+ }
629
+ async function eagerLoadRelations(entities, schema, db, registry2, options = {}) {
630
+ if (!schema.relations || entities.length === 0) {
631
+ return entities;
632
+ }
633
+ const include = options.include ?? [];
634
+ for (const [relationName, relation] of Object.entries(schema.relations)) {
635
+ const shouldLoad = relation.eager || include.includes(relationName) || include.some((inc) => inc.startsWith(`${relationName}.`));
636
+ if (!shouldLoad) continue;
637
+ if (relation.type === "belongsTo") {
638
+ await batchLoadBelongsTo(entities, relationName, relation, db, registry2, options);
639
+ } else if (relation.type === "hasOne") {
640
+ await batchLoadHasOne(entities, relationName, relation, db, registry2, options);
641
+ } else if (relation.type === "hasMany") {
642
+ for (const entity of entities) {
643
+ entity[relationName] = await resolveRelation(entity, relationName, relation, db, registry2, options);
644
+ }
645
+ }
646
+ }
647
+ return entities;
648
+ }
649
+ async function batchLoadBelongsTo(entities, relationName, relation, db, registry2, options) {
650
+ const foreignKey = relation.foreignKey || `${relation.target}Id`;
651
+ const targetDb = db[relation.target];
652
+ const foreignKeyValues = [...new Set(entities.map((e) => e[foreignKey]).filter(Boolean))];
653
+ if (foreignKeyValues.length === 0) {
654
+ entities.forEach((e) => e[relationName] = null);
655
+ return;
656
+ }
657
+ const relatedEntities = targetDb.findMany({
658
+ where: {
659
+ id: { in: foreignKeyValues }
660
+ }
661
+ });
662
+ const lookup = new Map(relatedEntities.map((r) => [r.id, r]));
663
+ for (const entity of entities) {
664
+ const fkValue = entity[foreignKey];
665
+ entity[relationName] = fkValue ? lookup.get(fkValue) ?? null : null;
666
+ }
667
+ const targetSchema = registry2.get(relation.target);
668
+ if (targetSchema) {
669
+ const nestedIncludes = (options.include ?? []).filter((inc) => inc.startsWith(`${relationName}.`)).map((inc) => inc.replace(`${relationName}.`, ""));
670
+ if (nestedIncludes.length > 0) {
671
+ await eagerLoadRelations(relatedEntities, targetSchema, db, registry2, {
672
+ ...options,
673
+ include: nestedIncludes
674
+ });
675
+ }
676
+ }
677
+ }
678
+ async function batchLoadHasOne(entities, relationName, relation, db, registry2, options) {
679
+ const foreignKey = relation.foreignKey || "id";
680
+ const targetDb = db[relation.target];
681
+ const entityIds = entities.map((e) => e.id).filter(Boolean);
682
+ if (entityIds.length === 0) {
683
+ entities.forEach((e) => e[relationName] = null);
684
+ return;
685
+ }
686
+ const relatedEntities = targetDb.findMany({
687
+ where: {
688
+ [foreignKey]: { in: entityIds }
689
+ }
690
+ });
691
+ const lookup = new Map(relatedEntities.map((r) => [r[foreignKey], r]));
692
+ for (const entity of entities) {
693
+ entity[relationName] = lookup.get(entity.id) ?? null;
694
+ }
695
+ const targetSchema = registry2.get(relation.target);
696
+ if (targetSchema) {
697
+ const nestedIncludes = (options.include ?? []).filter((inc) => inc.startsWith(`${relationName}.`)).map((inc) => inc.replace(`${relationName}.`, ""));
698
+ if (nestedIncludes.length > 0) {
699
+ await eagerLoadRelations(relatedEntities, targetSchema, db, registry2, {
700
+ ...options,
701
+ include: nestedIncludes
702
+ });
703
+ }
704
+ }
705
+ }
706
+
707
+ // src/schema/types.ts
708
+ function isComputedField(field) {
709
+ return typeof field === "object" && field !== null && "_computed" in field && field._computed === true;
710
+ }
711
+
712
+ // src/runtime/resolver/view.ts
713
+ function isEmbedDefinition(value) {
714
+ return typeof value === "object" && value !== null && "_embed" in value && value._embed === true;
715
+ }
716
+ var ViewResolver = class {
717
+ constructor(registry2, db) {
718
+ this.registry = registry2;
719
+ this.db = db;
720
+ }
721
+ /**
722
+ * Resolves a view schema with given parameters.
723
+ *
724
+ * @param view - The view schema to resolve
725
+ * @param params - URL parameters for the view
726
+ * @param context - Optional resolver context
727
+ * @returns The resolved view data
728
+ *
729
+ * @example
730
+ * ```typescript
731
+ * const userData = await viewResolver.resolve(UserFullView, { id: 'user-123' });
732
+ * ```
733
+ */
734
+ async resolve(view, params, context) {
735
+ clearComputeCache();
736
+ const resolverContext = {
737
+ mode: "resolve",
738
+ params,
739
+ ...context
740
+ };
741
+ return this.buildViewResult(view, { params, context: resolverContext });
742
+ }
743
+ /**
744
+ * Builds the view result by resolving all fields
745
+ */
746
+ async buildViewResult(view, options) {
747
+ const result = {};
748
+ for (const [fieldName, fieldDef] of Object.entries(view.fields)) {
749
+ if (isEmbedDefinition(fieldDef)) {
750
+ result[fieldName] = await this.resolveEmbed(fieldDef, result, options);
751
+ } else if (isComputedField(fieldDef)) {
752
+ result[fieldName] = await this.resolveViewComputedField(fieldDef, result, options);
753
+ } else if (this.isNestedObjectField(fieldDef)) {
754
+ result[fieldName] = await this.resolveNestedObject(fieldDef, result, options);
755
+ } else {
756
+ const paramValue = options.params[fieldName];
757
+ if (paramValue !== void 0) {
758
+ result[fieldName] = paramValue;
759
+ }
760
+ }
761
+ }
762
+ return result;
763
+ }
764
+ /**
765
+ * Check if a field definition is a nested object
766
+ */
767
+ isNestedObjectField(fieldDef) {
768
+ return typeof fieldDef === "object" && fieldDef !== null && !("type" in fieldDef) && !("_computed" in fieldDef) && !("_embed" in fieldDef);
769
+ }
770
+ /**
771
+ * Resolves an embedded entity field
772
+ */
773
+ async resolveEmbed(embed, parentData, options) {
774
+ const targetDb = this.db[embed.entity.name];
775
+ if (!targetDb) {
776
+ throw new Error(`Target entity '${embed.entity.name}' not found in database`);
777
+ }
778
+ const query = { where: {} };
779
+ const idParam = options.params.id;
780
+ if (idParam) {
781
+ const possibleForeignKeys = [
782
+ `${this.guessParentEntityName(options)}Id`,
783
+ "userId",
784
+ "authorId",
785
+ "parentId"
786
+ ];
787
+ for (const fk of possibleForeignKeys) {
788
+ if (embed.entity.fields && fk in embed.entity.fields) {
789
+ query.where[fk] = { equals: idParam };
790
+ break;
791
+ }
792
+ }
793
+ }
794
+ if (embed.config?.limit) {
795
+ query.take = embed.config.limit;
796
+ }
797
+ if (embed.config?.orderBy) {
798
+ query.orderBy = embed.config.orderBy;
799
+ }
800
+ const shouldReturnArray = !embed.config?.limit || embed.config.limit > 1;
801
+ if (shouldReturnArray) {
802
+ const results = targetDb.findMany(query);
803
+ return results;
804
+ } else {
805
+ const result = targetDb.findFirst(query);
806
+ return result;
807
+ }
808
+ }
809
+ /**
810
+ * Guess the parent entity name from the view endpoint
811
+ */
812
+ guessParentEntityName(options) {
813
+ return "user";
814
+ }
815
+ /**
816
+ * Resolves a computed field within a view context
817
+ */
818
+ async resolveViewComputedField(computed, currentData, options) {
819
+ if (options.context.mode === "seed" && computed.mock) {
820
+ return computed.mock();
821
+ }
822
+ return computed.resolve(currentData, this.db, options.context);
823
+ }
824
+ /**
825
+ * Resolves a nested object containing fields and computed values
826
+ */
827
+ async resolveNestedObject(nestedDef, parentData, options) {
828
+ const result = {};
829
+ for (const [fieldName, fieldDef] of Object.entries(nestedDef)) {
830
+ if (isComputedField(fieldDef)) {
831
+ result[fieldName] = await this.resolveViewComputedField(fieldDef, parentData, options);
832
+ } else {
833
+ result[fieldName] = fieldDef;
834
+ }
835
+ }
836
+ return result;
837
+ }
838
+ /**
839
+ * Resolves a view with mock data (for seeding)
840
+ */
841
+ async resolveMock(view, params) {
842
+ return this.resolve(view, params, { mode: "seed" });
843
+ }
844
+ };
845
+ function createViewResolver(registry2, db) {
846
+ return new ViewResolver(registry2, db);
847
+ }
848
+
849
+ // src/runtime/resolver/resolver.ts
850
+ var Resolver = class _Resolver {
851
+ constructor(registry2, db, context) {
852
+ this.registry = registry2;
853
+ this.db = db;
854
+ this.context = { mode: "resolve", ...context };
855
+ this.viewResolver = new ViewResolver(registry2, db);
856
+ }
857
+ context;
858
+ viewResolver;
859
+ /**
860
+ * Find a single entity by ID
861
+ *
862
+ * @param entityName - The entity type to find
863
+ * @param id - The entity ID
864
+ * @param options - Query options (relations, computed fields)
865
+ * @returns The entity or null if not found
866
+ *
867
+ * @example
868
+ * ```typescript
869
+ * const user = await resolver.findOne('user', '123', {
870
+ * include: ['profile'],
871
+ * computed: ['postCount'],
872
+ * });
873
+ * ```
874
+ */
875
+ async findOne(entityName, id, options = {}) {
876
+ clearComputeCache();
877
+ const schema = this.registry.getOrThrow(entityName);
878
+ const entityDb = this.db[entityName];
879
+ if (!entityDb) {
880
+ throw new Error(`Entity '${entityName}' not found in database`);
881
+ }
882
+ const entity = entityDb.findFirst({
883
+ where: { id: { equals: id } }
884
+ });
885
+ if (!entity) return null;
886
+ await resolveRelations(entity, schema, this.db, this.registry, options);
887
+ await resolveComputedFields(entity, schema, this.db, this.context);
888
+ return entity;
889
+ }
890
+ /**
891
+ * Find multiple entities with filtering and pagination
892
+ *
893
+ * @param entityName - The entity type to find
894
+ * @param options - Query options (filters, pagination, relations)
895
+ * @returns Array of entities
896
+ *
897
+ * @example
898
+ * ```typescript
899
+ * const users = await resolver.findMany('user', {
900
+ * where: { role: 'admin' },
901
+ * limit: 20,
902
+ * offset: 0,
903
+ * include: ['profile'],
904
+ * });
905
+ * ```
906
+ */
907
+ async findMany(entityName, options = {}) {
908
+ clearComputeCache();
909
+ const schema = this.registry.getOrThrow(entityName);
910
+ const entityDb = this.db[entityName];
911
+ if (!entityDb) {
912
+ throw new Error(`Entity '${entityName}' not found in database`);
913
+ }
914
+ const query = {};
915
+ if (options.where) {
916
+ query.where = this.buildWhereClause(options.where);
917
+ }
918
+ if (options.limit) {
919
+ query.take = options.limit;
920
+ }
921
+ if (options.offset) {
922
+ query.skip = options.offset;
923
+ }
924
+ if (options.orderBy) {
925
+ query.orderBy = options.orderBy;
926
+ }
927
+ const entities = entityDb.findMany(query);
928
+ await eagerLoadRelations(entities, schema, this.db, this.registry, options);
929
+ for (const entity of entities) {
930
+ await resolveComputedFields(entity, schema, this.db, this.context);
931
+ }
932
+ return entities;
933
+ }
934
+ /**
935
+ * Create a new entity
936
+ *
937
+ * @param entityName - The entity type to create
938
+ * @param data - The entity data
939
+ * @param options - Query options for the returned entity
940
+ * @returns The created entity with relations and computed fields
941
+ *
942
+ * @example
943
+ * ```typescript
944
+ * const user = await resolver.create('user', {
945
+ * name: 'John Doe',
946
+ * email: 'john@example.com',
947
+ * });
948
+ * ```
949
+ */
950
+ async create(entityName, data, options = {}) {
951
+ const schema = this.registry.getOrThrow(entityName);
952
+ const entityDb = this.db[entityName];
953
+ if (!entityDb) {
954
+ throw new Error(`Entity '${entityName}' not found in database`);
955
+ }
956
+ if (!entityDb.create) {
957
+ throw new Error(`Entity '${entityName}' does not support create operation`);
958
+ }
959
+ const entity = entityDb.create(data);
960
+ await resolveRelations(entity, schema, this.db, this.registry, options);
961
+ await resolveComputedFields(entity, schema, this.db, this.context);
962
+ return entity;
963
+ }
964
+ /**
965
+ * Update an existing entity
966
+ *
967
+ * @param entityName - The entity type to update
968
+ * @param id - The entity ID
969
+ * @param data - The update data
970
+ * @param options - Query options for the returned entity
971
+ * @returns The updated entity or null if not found
972
+ *
973
+ * @example
974
+ * ```typescript
975
+ * const user = await resolver.update('user', '123', {
976
+ * name: 'Jane Doe',
977
+ * });
978
+ * ```
979
+ */
980
+ async update(entityName, id, data, options = {}) {
981
+ const schema = this.registry.getOrThrow(entityName);
982
+ const entityDb = this.db[entityName];
983
+ if (!entityDb) {
984
+ throw new Error(`Entity '${entityName}' not found in database`);
985
+ }
986
+ if (!entityDb.update) {
987
+ throw new Error(`Entity '${entityName}' does not support update operation`);
988
+ }
989
+ const entity = entityDb.update({
990
+ where: { id: { equals: id } },
991
+ data
992
+ });
993
+ if (!entity) return null;
994
+ await resolveRelations(entity, schema, this.db, this.registry, options);
995
+ await resolveComputedFields(entity, schema, this.db, this.context);
996
+ return entity;
997
+ }
998
+ /**
999
+ * Delete an entity by ID
1000
+ *
1001
+ * @param entityName - The entity type to delete
1002
+ * @param id - The entity ID
1003
+ * @returns true if deleted, false if not found
1004
+ *
1005
+ * @example
1006
+ * ```typescript
1007
+ * const deleted = await resolver.delete('user', '123');
1008
+ * ```
1009
+ */
1010
+ delete(entityName, id) {
1011
+ const entityDb = this.db[entityName];
1012
+ if (!entityDb) {
1013
+ throw new Error(`Entity '${entityName}' not found in database`);
1014
+ }
1015
+ if (!entityDb.delete) {
1016
+ throw new Error(`Entity '${entityName}' does not support delete operation`);
1017
+ }
1018
+ const deleted = entityDb.delete({
1019
+ where: { id: { equals: id } }
1020
+ });
1021
+ return deleted !== null;
1022
+ }
1023
+ /**
1024
+ * Count entities matching a filter
1025
+ *
1026
+ * @param entityName - The entity type to count
1027
+ * @param options - Count options (filters)
1028
+ * @returns The count
1029
+ *
1030
+ * @example
1031
+ * ```typescript
1032
+ * const adminCount = await resolver.count('user', {
1033
+ * where: { role: 'admin' },
1034
+ * });
1035
+ * ```
1036
+ */
1037
+ count(entityName, options = {}) {
1038
+ const entityDb = this.db[entityName];
1039
+ if (!entityDb) {
1040
+ throw new Error(`Entity '${entityName}' not found in database`);
1041
+ }
1042
+ const query = options.where ? { where: this.buildWhereClause(options.where) } : {};
1043
+ return entityDb.count(query);
1044
+ }
1045
+ /**
1046
+ * Resolve a view with parameters
1047
+ *
1048
+ * @param viewName - The view name
1049
+ * @param params - View parameters
1050
+ * @returns The resolved view data
1051
+ *
1052
+ * @example
1053
+ * ```typescript
1054
+ * const userFull = await resolver.view('user-full', { id: '123' });
1055
+ * ```
1056
+ */
1057
+ async view(viewName, params) {
1058
+ clearComputeCache();
1059
+ const viewSchema = this.registry.getViewOrThrow(viewName);
1060
+ return this.viewResolver.resolve(viewSchema, params, this.context);
1061
+ }
1062
+ /**
1063
+ * Build a where clause from simple object to database format
1064
+ */
1065
+ buildWhereClause(where) {
1066
+ const clause = {};
1067
+ for (const [key, value] of Object.entries(where)) {
1068
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
1069
+ clause[key] = value;
1070
+ } else if (Array.isArray(value)) {
1071
+ clause[key] = { in: value };
1072
+ } else {
1073
+ clause[key] = { equals: value };
1074
+ }
1075
+ }
1076
+ return clause;
1077
+ }
1078
+ /**
1079
+ * Get the current resolver context
1080
+ */
1081
+ getContext() {
1082
+ return { ...this.context };
1083
+ }
1084
+ /**
1085
+ * Create a new resolver with updated context
1086
+ */
1087
+ withContext(context) {
1088
+ return new _Resolver(this.registry, this.db, { ...this.context, ...context });
1089
+ }
1090
+ };
1091
+ function createResolver(registry2, db, context) {
1092
+ return new Resolver(registry2, db, context);
1093
+ }
1094
+
1095
+ // src/runtime/setup.ts
1096
+ var state = {
1097
+ initialized: false,
1098
+ adapter: null,
1099
+ schemas: [],
1100
+ worker: null,
1101
+ server: null
1102
+ };
1103
+ async function setup(options) {
1104
+ if (state.initialized) {
1105
+ console.warn("Schemock runtime already initialized");
1106
+ return;
1107
+ }
1108
+ if (options) {
1109
+ state.adapter = options.adapter;
1110
+ state.schemas = options.schemas;
1111
+ }
1112
+ if (options?.startMsw && typeof window !== "undefined" && options.schemas.length > 0) {
1113
+ await startMswWorker(options);
1114
+ }
1115
+ state.initialized = true;
1116
+ }
1117
+ async function startMswWorker(options) {
1118
+ try {
1119
+ const { setupWorker } = await import('msw/browser');
1120
+ const { createHandlers: createHandlers2 } = await Promise.resolve().then(() => (init_handlers(), handlers_exports));
1121
+ const handlers = createHandlers2(
1122
+ options.schemas,
1123
+ state.adapter,
1124
+ options.mswOptions
1125
+ );
1126
+ state.worker = setupWorker(...handlers);
1127
+ await state.worker.start({
1128
+ quiet: options.mswOptions?.quiet ?? true
1129
+ });
1130
+ } catch (error) {
1131
+ console.warn("MSW setup failed:", error);
1132
+ }
1133
+ }
1134
+ async function teardown() {
1135
+ if (state.worker) {
1136
+ await state.worker.stop();
1137
+ state.worker = null;
1138
+ }
1139
+ state.adapter = null;
1140
+ state.schemas = [];
1141
+ state.initialized = false;
1142
+ }
1143
+ function isInitialized() {
1144
+ return state.initialized;
1145
+ }
1146
+ function getAdapter() {
1147
+ return state.adapter;
1148
+ }
1149
+ function setAdapter(adapter) {
1150
+ state.adapter = adapter;
1151
+ }
1152
+
1153
+ // src/runtime/seed.ts
1154
+ function seed(counts) {
1155
+ const adapter = getAdapter();
1156
+ if (!adapter) {
1157
+ throw new Error(
1158
+ "No adapter configured. Call setup() first or use adapter.seed() directly."
1159
+ );
1160
+ }
1161
+ if (adapter.name !== "mock") {
1162
+ throw new Error(
1163
+ `seed() only works with MockAdapter. Current adapter: ${adapter.name}`
1164
+ );
1165
+ }
1166
+ adapter.seed(counts);
1167
+ }
1168
+ function reset() {
1169
+ const adapter = getAdapter();
1170
+ if (!adapter) {
1171
+ throw new Error("No adapter configured. Call setup() first.");
1172
+ }
1173
+ if (adapter.name !== "mock") {
1174
+ throw new Error(
1175
+ `reset() only works with MockAdapter. Current adapter: ${adapter.name}`
1176
+ );
1177
+ }
1178
+ adapter.reset();
1179
+ }
1180
+ function seedWithRelations(counts, relations) {
1181
+ const adapter = getAdapter();
1182
+ if (!adapter || adapter.name !== "mock") {
1183
+ throw new Error("seedWithRelations() requires MockAdapter");
1184
+ }
1185
+ const deps = /* @__PURE__ */ new Map();
1186
+ for (const entity of Object.keys(counts)) {
1187
+ deps.set(entity, /* @__PURE__ */ new Set());
1188
+ }
1189
+ for (const [entity, fks] of Object.entries(relations)) {
1190
+ for (const targetEntity of Object.values(fks)) {
1191
+ deps.get(entity)?.add(targetEntity);
1192
+ }
1193
+ }
1194
+ const sorted = [];
1195
+ const visited = /* @__PURE__ */ new Set();
1196
+ const visiting = /* @__PURE__ */ new Set();
1197
+ function visit(entity) {
1198
+ if (visited.has(entity)) return;
1199
+ if (visiting.has(entity)) {
1200
+ throw new Error(`Circular dependency detected: ${entity}`);
1201
+ }
1202
+ visiting.add(entity);
1203
+ for (const dep of deps.get(entity) || []) {
1204
+ visit(dep);
1205
+ }
1206
+ visiting.delete(entity);
1207
+ visited.add(entity);
1208
+ sorted.push(entity);
1209
+ }
1210
+ for (const entity of Object.keys(counts)) {
1211
+ visit(entity);
1212
+ }
1213
+ const entityIds = {};
1214
+ for (const entity of sorted) {
1215
+ const count = counts[entity];
1216
+ if (count === void 0) continue;
1217
+ const fks = relations[entity] || {};
1218
+ const parentIds = {};
1219
+ for (const [fkField, parentEntity] of Object.entries(fks)) {
1220
+ parentIds[fkField] = entityIds[parentEntity] || [];
1221
+ }
1222
+ entityIds[entity] = [];
1223
+ for (let i = 0; i < count; i++) {
1224
+ const data = {};
1225
+ for (const [fkField, ids] of Object.entries(parentIds)) {
1226
+ if (ids.length > 0) {
1227
+ data[fkField] = ids[Math.floor(Math.random() * ids.length)];
1228
+ }
1229
+ }
1230
+ const result = adapter.create({
1231
+ entity,
1232
+ data
1233
+ });
1234
+ result.then((res) => {
1235
+ if (res.data?.id) {
1236
+ entityIds[entity].push(res.data.id);
1237
+ }
1238
+ });
1239
+ }
1240
+ }
1241
+ }
1242
+
1243
+ // src/runtime/index.ts
1244
+ init_handlers();
1245
+
1246
+ exports.Resolver = Resolver;
1247
+ exports.SchemaRegistry = SchemaRegistry;
1248
+ exports.ViewResolver = ViewResolver;
1249
+ exports.clearComputeCache = clearComputeCache;
1250
+ exports.createHandlers = createHandlers;
1251
+ exports.createResolver = createResolver;
1252
+ exports.createViewResolver = createViewResolver;
1253
+ exports.eagerLoadRelations = eagerLoadRelations;
1254
+ exports.getAdapter = getAdapter;
1255
+ exports.isInitialized = isInitialized;
1256
+ exports.registry = registry;
1257
+ exports.reset = reset;
1258
+ exports.resolveComputedField = resolveComputedField;
1259
+ exports.resolveComputedFields = resolveComputedFields;
1260
+ exports.resolveComputedFieldsSync = resolveComputedFieldsSync;
1261
+ exports.resolveRelation = resolveRelation;
1262
+ exports.resolveRelations = resolveRelations;
1263
+ exports.seed = seed;
1264
+ exports.seedWithRelations = seedWithRelations;
1265
+ exports.setAdapter = setAdapter;
1266
+ exports.setup = setup;
1267
+ exports.teardown = teardown;
1268
+ exports.topologicalSort = topologicalSort;
1269
+ //# sourceMappingURL=index.js.map
1270
+ //# sourceMappingURL=index.js.map