@cimplify/sdk 0.82.0 → 0.83.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.
@@ -5899,6 +5899,14 @@ function createLinkService({ clock, ids }) {
5899
5899
  };
5900
5900
  }
5901
5901
 
5902
+ // src/mock/state/snapshot.ts
5903
+ function applySnapshot(reg, data) {
5904
+ for (const [k, v] of Object.entries(data)) {
5905
+ const store = reg[k];
5906
+ if (store) store.loadJSON(v);
5907
+ }
5908
+ }
5909
+
5902
5910
  // src/mock/seeds/image.ts
5903
5911
  var CDN_BASE_URL = "https://static-tmp.cimplify.io";
5904
5912
  function seedImage(industry, slug) {
@@ -10266,15 +10274,217 @@ function applySeed(registry, name) {
10266
10274
  return fn(registry);
10267
10275
  }
10268
10276
 
10277
+ // src/mock/seeds/context.ts
10278
+ var SEED_ISO = "2026-01-01T00:00:00.000Z";
10279
+ var ID_PREFIX = {
10280
+ business: "bus_",
10281
+ category: "cat_",
10282
+ collection: "col_",
10283
+ product: "prod_",
10284
+ service: "svc_"
10285
+ };
10286
+ var DEFAULT_CURRENCY = "GHS";
10287
+ function slugify(value) {
10288
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10289
+ }
10290
+ function makeSeedContext(registry) {
10291
+ let current;
10292
+ const requireBusiness = () => {
10293
+ if (current) return current;
10294
+ const sole = registry.businesses.list();
10295
+ if (sole.length === 1) {
10296
+ current = sole[0];
10297
+ return current;
10298
+ }
10299
+ throw new Error("Seed must create a business (ctx.business) before adding child records.");
10300
+ };
10301
+ const resolveCategoryId = (cat) => {
10302
+ if (!cat) return void 0;
10303
+ if (typeof cat !== "string") return cat.id;
10304
+ if (registry.categories.get(cat)) return cat;
10305
+ return registry.categories.list().find((c) => c.slug === cat)?.id;
10306
+ };
10307
+ const resolveCollectionId = (col) => {
10308
+ if (!col) return void 0;
10309
+ if (typeof col !== "string") return col.id;
10310
+ if (registry.collections.get(col)) return col;
10311
+ return registry.collections.list().find((c) => c.slug === col)?.id;
10312
+ };
10313
+ return {
10314
+ registry,
10315
+ business(input) {
10316
+ const handle = input.handle ?? slugify(input.name);
10317
+ const id = `${ID_PREFIX.business}${slugify(handle)}`;
10318
+ const business = {
10319
+ business_type: "other",
10320
+ email: `hello@${handle}.test`,
10321
+ default_currency: DEFAULT_CURRENCY,
10322
+ default_offers_table_service: false,
10323
+ default_accepts_online_orders: true,
10324
+ status: "active",
10325
+ created_by: "seed",
10326
+ preferences: {},
10327
+ is_online_only: true,
10328
+ enabled_payment_types: ["mobile_money"],
10329
+ default_location_settings: {},
10330
+ country_code: "GH",
10331
+ timezone: "Africa/Accra",
10332
+ ...input,
10333
+ id,
10334
+ handle,
10335
+ created_at: input.created_at ?? SEED_ISO,
10336
+ updated_at: input.updated_at ?? SEED_ISO
10337
+ };
10338
+ registry.businesses.put(id, business);
10339
+ current = business;
10340
+ return business;
10341
+ },
10342
+ category(input) {
10343
+ const business = requireBusiness();
10344
+ const slug = input.slug ?? slugify(input.name);
10345
+ const id = `${ID_PREFIX.category}${slug}`;
10346
+ const category = {
10347
+ id,
10348
+ business_id: business.id,
10349
+ name: input.name,
10350
+ slug,
10351
+ description: input.description,
10352
+ image: input.image,
10353
+ product_ids: [],
10354
+ display_order: input.displayOrder ?? 0,
10355
+ is_active: true,
10356
+ created_at: SEED_ISO,
10357
+ updated_at: SEED_ISO
10358
+ };
10359
+ registry.categories.put(id, category);
10360
+ return category;
10361
+ },
10362
+ collection(input) {
10363
+ const business = requireBusiness();
10364
+ const slug = input.slug ?? slugify(input.name);
10365
+ const id = `${ID_PREFIX.collection}${slug}`;
10366
+ const collection = {
10367
+ id,
10368
+ business_id: business.id,
10369
+ name: input.name,
10370
+ slug,
10371
+ description: input.description,
10372
+ product_ids: [],
10373
+ is_active: true,
10374
+ created_at: SEED_ISO,
10375
+ updated_at: SEED_ISO
10376
+ };
10377
+ registry.collections.put(id, collection);
10378
+ return collection;
10379
+ },
10380
+ product(input) {
10381
+ const business = requireBusiness();
10382
+ const slug = input.slug ?? slugify(input.name);
10383
+ const id = `${ID_PREFIX.product}${slug}`;
10384
+ const categoryId = resolveCategoryId(input.category);
10385
+ const collectionId = resolveCollectionId(input.collection);
10386
+ const product = {
10387
+ id,
10388
+ business_id: business.id,
10389
+ name: input.name,
10390
+ slug,
10391
+ description: input.description,
10392
+ product_type: input.productType ?? "product",
10393
+ base_price: input.price,
10394
+ currency: input.currency ?? business.default_currency,
10395
+ image: input.image,
10396
+ images: input.images ?? (input.image ? [input.image] : []),
10397
+ is_available: true,
10398
+ category_ids: categoryId ? [categoryId] : [],
10399
+ collection_ids: collectionId ? [collectionId] : [],
10400
+ add_on_ids: [],
10401
+ variant_ids: [],
10402
+ tags: input.tags ?? [],
10403
+ calories: input.calories,
10404
+ allergies: input.allergies ?? [],
10405
+ ingredients: input.ingredients ?? [],
10406
+ pairings: [],
10407
+ is_signature: input.isSignature ?? false,
10408
+ is_new: input.isNew ?? false,
10409
+ duration_minutes: input.durationMinutes,
10410
+ metadata: input.metadata,
10411
+ created_at: SEED_ISO,
10412
+ updated_at: SEED_ISO
10413
+ };
10414
+ registry.products.put(id, product);
10415
+ if (categoryId) {
10416
+ const cat = registry.categories.get(categoryId);
10417
+ if (cat && !cat.product_ids.includes(id)) cat.product_ids.push(id);
10418
+ }
10419
+ if (collectionId) {
10420
+ const col = registry.collections.get(collectionId);
10421
+ if (col && !col.product_ids.includes(id)) col.product_ids.push(id);
10422
+ }
10423
+ return product;
10424
+ },
10425
+ service(input) {
10426
+ const business = requireBusiness();
10427
+ const id = `${ID_PREFIX.service}${slugify(input.name)}`;
10428
+ const service = {
10429
+ id,
10430
+ business_id: business.id,
10431
+ name: input.name,
10432
+ description: input.description,
10433
+ duration_minutes: input.durationMinutes,
10434
+ price: input.price,
10435
+ is_available: true
10436
+ };
10437
+ registry.services.put(id, service);
10438
+ return service;
10439
+ },
10440
+ image: seedImage,
10441
+ extend(name) {
10442
+ const result = applySeed(registry, name);
10443
+ current = registry.businesses.get(result.businessId) ?? current;
10444
+ return result;
10445
+ }
10446
+ };
10447
+ }
10448
+ function defineSeed(seed) {
10449
+ return seed;
10450
+ }
10451
+
10452
+ // src/mock/seeds/source.ts
10453
+ var SNAPSHOT_META_KEY = "__meta";
10454
+ function loadSnapshot(registry, data, businessId) {
10455
+ applySnapshot(registry, data);
10456
+ if (businessId) return { businessId };
10457
+ const meta = data[SNAPSHOT_META_KEY];
10458
+ if (meta?.defaultBusinessId) return { businessId: meta.defaultBusinessId };
10459
+ const businesses = registry.businesses.list();
10460
+ if (businesses.length === 1) return { businessId: businesses[0].id };
10461
+ if (businesses.length === 0) {
10462
+ throw new Error("Seed snapshot has no business. Add one, or set __meta.defaultBusinessId.");
10463
+ }
10464
+ throw new Error(
10465
+ `Seed snapshot has ${businesses.length} businesses; set __meta.defaultBusinessId to pick one.`
10466
+ );
10467
+ }
10468
+ function resolveSeed(registry, source) {
10469
+ if (typeof source === "string") return applySeed(registry, source);
10470
+ switch (source.kind) {
10471
+ case "builtin":
10472
+ return applySeed(registry, source.name);
10473
+ case "json":
10474
+ return loadSnapshot(registry, source.data, source.businessId);
10475
+ case "fn":
10476
+ return source.seed(makeSeedContext(registry));
10477
+ }
10478
+ }
10479
+
10269
10480
  // src/mock/deps.ts
10270
10481
  function createDeps(options = {}) {
10271
10482
  const clock = createClock({ frozenAt: options.frozenAt });
10272
10483
  const ids = createIdGen(options.rngSeed);
10273
10484
  const bus = createBus({ idGen: () => ids.raw("evt"), clock: () => clock.now() });
10274
10485
  const registry = createStateRegistry();
10275
- const seedName = options.seed ?? "default";
10276
- const seedResult = applySeed(registry, seedName);
10277
- let defaultBusinessId = seedResult.businessId;
10486
+ const seedSource = options.seed ?? "default";
10487
+ let defaultBusinessId = resolveSeed(registry, seedSource).businessId;
10278
10488
  const auth = createAuthService({
10279
10489
  registry,
10280
10490
  clock,
@@ -10328,11 +10538,10 @@ function createDeps(options = {}) {
10328
10538
  return defaultBusinessId;
10329
10539
  },
10330
10540
  chaos,
10331
- resetAll(newSeed) {
10541
+ resetAll(next) {
10332
10542
  for (const store of Object.values(registry)) store.reset();
10333
10543
  bus.clear();
10334
- const r = applySeed(registry, newSeed ?? seedName);
10335
- defaultBusinessId = r.businessId;
10544
+ defaultBusinessId = resolveSeed(registry, next ?? seedSource).businessId;
10336
10545
  return defaultBusinessId;
10337
10546
  }
10338
10547
  };
@@ -10435,4 +10644,4 @@ function setupWebhooks(bus, opts) {
10435
10644
  });
10436
10645
  }
10437
10646
 
10438
- export { applySeed, createDeps, createMockApp, setupWebhooks, signPayload, verifySignature };
10647
+ export { SEED_ISO, SNAPSHOT_META_KEY, applySeed, applySnapshot, createDeps, createMockApp, defineSeed, loadSnapshot, makeSeedContext, resolveSeed, setupWebhooks, signPayload, slugify, verifySignature };
package/dist/mock/msw.js CHANGED
@@ -5899,6 +5899,14 @@ function createLinkService({ clock, ids }) {
5899
5899
  };
5900
5900
  }
5901
5901
 
5902
+ // src/mock/state/snapshot.ts
5903
+ function applySnapshot(reg, data) {
5904
+ for (const [k, v] of Object.entries(data)) {
5905
+ const store = reg[k];
5906
+ if (store) store.loadJSON(v);
5907
+ }
5908
+ }
5909
+
5902
5910
  // src/mock/seeds/image.ts
5903
5911
  var CDN_BASE_URL = "https://static-tmp.cimplify.io";
5904
5912
  function seedImage(industry, slug) {
@@ -10266,15 +10274,214 @@ function applySeed(registry, name) {
10266
10274
  return fn(registry);
10267
10275
  }
10268
10276
 
10277
+ // src/mock/seeds/context.ts
10278
+ var SEED_ISO = "2026-01-01T00:00:00.000Z";
10279
+ var ID_PREFIX = {
10280
+ business: "bus_",
10281
+ category: "cat_",
10282
+ collection: "col_",
10283
+ product: "prod_",
10284
+ service: "svc_"
10285
+ };
10286
+ var DEFAULT_CURRENCY = "GHS";
10287
+ function slugify(value) {
10288
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10289
+ }
10290
+ function makeSeedContext(registry) {
10291
+ let current;
10292
+ const requireBusiness = () => {
10293
+ if (current) return current;
10294
+ const sole = registry.businesses.list();
10295
+ if (sole.length === 1) {
10296
+ current = sole[0];
10297
+ return current;
10298
+ }
10299
+ throw new Error("Seed must create a business (ctx.business) before adding child records.");
10300
+ };
10301
+ const resolveCategoryId = (cat) => {
10302
+ if (!cat) return void 0;
10303
+ if (typeof cat !== "string") return cat.id;
10304
+ if (registry.categories.get(cat)) return cat;
10305
+ return registry.categories.list().find((c) => c.slug === cat)?.id;
10306
+ };
10307
+ const resolveCollectionId = (col) => {
10308
+ if (!col) return void 0;
10309
+ if (typeof col !== "string") return col.id;
10310
+ if (registry.collections.get(col)) return col;
10311
+ return registry.collections.list().find((c) => c.slug === col)?.id;
10312
+ };
10313
+ return {
10314
+ registry,
10315
+ business(input) {
10316
+ const handle = input.handle ?? slugify(input.name);
10317
+ const id = `${ID_PREFIX.business}${slugify(handle)}`;
10318
+ const business = {
10319
+ business_type: "other",
10320
+ email: `hello@${handle}.test`,
10321
+ default_currency: DEFAULT_CURRENCY,
10322
+ default_offers_table_service: false,
10323
+ default_accepts_online_orders: true,
10324
+ status: "active",
10325
+ created_by: "seed",
10326
+ preferences: {},
10327
+ is_online_only: true,
10328
+ enabled_payment_types: ["mobile_money"],
10329
+ default_location_settings: {},
10330
+ country_code: "GH",
10331
+ timezone: "Africa/Accra",
10332
+ ...input,
10333
+ id,
10334
+ handle,
10335
+ created_at: input.created_at ?? SEED_ISO,
10336
+ updated_at: input.updated_at ?? SEED_ISO
10337
+ };
10338
+ registry.businesses.put(id, business);
10339
+ current = business;
10340
+ return business;
10341
+ },
10342
+ category(input) {
10343
+ const business = requireBusiness();
10344
+ const slug = input.slug ?? slugify(input.name);
10345
+ const id = `${ID_PREFIX.category}${slug}`;
10346
+ const category = {
10347
+ id,
10348
+ business_id: business.id,
10349
+ name: input.name,
10350
+ slug,
10351
+ description: input.description,
10352
+ image: input.image,
10353
+ product_ids: [],
10354
+ display_order: input.displayOrder ?? 0,
10355
+ is_active: true,
10356
+ created_at: SEED_ISO,
10357
+ updated_at: SEED_ISO
10358
+ };
10359
+ registry.categories.put(id, category);
10360
+ return category;
10361
+ },
10362
+ collection(input) {
10363
+ const business = requireBusiness();
10364
+ const slug = input.slug ?? slugify(input.name);
10365
+ const id = `${ID_PREFIX.collection}${slug}`;
10366
+ const collection = {
10367
+ id,
10368
+ business_id: business.id,
10369
+ name: input.name,
10370
+ slug,
10371
+ description: input.description,
10372
+ product_ids: [],
10373
+ is_active: true,
10374
+ created_at: SEED_ISO,
10375
+ updated_at: SEED_ISO
10376
+ };
10377
+ registry.collections.put(id, collection);
10378
+ return collection;
10379
+ },
10380
+ product(input) {
10381
+ const business = requireBusiness();
10382
+ const slug = input.slug ?? slugify(input.name);
10383
+ const id = `${ID_PREFIX.product}${slug}`;
10384
+ const categoryId = resolveCategoryId(input.category);
10385
+ const collectionId = resolveCollectionId(input.collection);
10386
+ const product = {
10387
+ id,
10388
+ business_id: business.id,
10389
+ name: input.name,
10390
+ slug,
10391
+ description: input.description,
10392
+ product_type: input.productType ?? "product",
10393
+ base_price: input.price,
10394
+ currency: input.currency ?? business.default_currency,
10395
+ image: input.image,
10396
+ images: input.images ?? (input.image ? [input.image] : []),
10397
+ is_available: true,
10398
+ category_ids: categoryId ? [categoryId] : [],
10399
+ collection_ids: collectionId ? [collectionId] : [],
10400
+ add_on_ids: [],
10401
+ variant_ids: [],
10402
+ tags: input.tags ?? [],
10403
+ calories: input.calories,
10404
+ allergies: input.allergies ?? [],
10405
+ ingredients: input.ingredients ?? [],
10406
+ pairings: [],
10407
+ is_signature: input.isSignature ?? false,
10408
+ is_new: input.isNew ?? false,
10409
+ duration_minutes: input.durationMinutes,
10410
+ metadata: input.metadata,
10411
+ created_at: SEED_ISO,
10412
+ updated_at: SEED_ISO
10413
+ };
10414
+ registry.products.put(id, product);
10415
+ if (categoryId) {
10416
+ const cat = registry.categories.get(categoryId);
10417
+ if (cat && !cat.product_ids.includes(id)) cat.product_ids.push(id);
10418
+ }
10419
+ if (collectionId) {
10420
+ const col = registry.collections.get(collectionId);
10421
+ if (col && !col.product_ids.includes(id)) col.product_ids.push(id);
10422
+ }
10423
+ return product;
10424
+ },
10425
+ service(input) {
10426
+ const business = requireBusiness();
10427
+ const id = `${ID_PREFIX.service}${slugify(input.name)}`;
10428
+ const service = {
10429
+ id,
10430
+ business_id: business.id,
10431
+ name: input.name,
10432
+ description: input.description,
10433
+ duration_minutes: input.durationMinutes,
10434
+ price: input.price,
10435
+ is_available: true
10436
+ };
10437
+ registry.services.put(id, service);
10438
+ return service;
10439
+ },
10440
+ image: seedImage,
10441
+ extend(name) {
10442
+ const result = applySeed(registry, name);
10443
+ current = registry.businesses.get(result.businessId) ?? current;
10444
+ return result;
10445
+ }
10446
+ };
10447
+ }
10448
+
10449
+ // src/mock/seeds/source.ts
10450
+ var SNAPSHOT_META_KEY = "__meta";
10451
+ function loadSnapshot(registry, data, businessId) {
10452
+ applySnapshot(registry, data);
10453
+ if (businessId) return { businessId };
10454
+ const meta = data[SNAPSHOT_META_KEY];
10455
+ if (meta?.defaultBusinessId) return { businessId: meta.defaultBusinessId };
10456
+ const businesses = registry.businesses.list();
10457
+ if (businesses.length === 1) return { businessId: businesses[0].id };
10458
+ if (businesses.length === 0) {
10459
+ throw new Error("Seed snapshot has no business. Add one, or set __meta.defaultBusinessId.");
10460
+ }
10461
+ throw new Error(
10462
+ `Seed snapshot has ${businesses.length} businesses; set __meta.defaultBusinessId to pick one.`
10463
+ );
10464
+ }
10465
+ function resolveSeed(registry, source) {
10466
+ if (typeof source === "string") return applySeed(registry, source);
10467
+ switch (source.kind) {
10468
+ case "builtin":
10469
+ return applySeed(registry, source.name);
10470
+ case "json":
10471
+ return loadSnapshot(registry, source.data, source.businessId);
10472
+ case "fn":
10473
+ return source.seed(makeSeedContext(registry));
10474
+ }
10475
+ }
10476
+
10269
10477
  // src/mock/deps.ts
10270
10478
  function createDeps(options = {}) {
10271
10479
  const clock = createClock({ frozenAt: options.frozenAt });
10272
10480
  const ids = createIdGen(options.rngSeed);
10273
10481
  const bus = createBus({ idGen: () => ids.raw("evt"), clock: () => clock.now() });
10274
10482
  const registry = createStateRegistry();
10275
- const seedName = options.seed ?? "default";
10276
- const seedResult = applySeed(registry, seedName);
10277
- let defaultBusinessId = seedResult.businessId;
10483
+ const seedSource = options.seed ?? "default";
10484
+ let defaultBusinessId = resolveSeed(registry, seedSource).businessId;
10278
10485
  const auth = createAuthService({
10279
10486
  registry,
10280
10487
  clock,
@@ -10328,11 +10535,10 @@ function createDeps(options = {}) {
10328
10535
  return defaultBusinessId;
10329
10536
  },
10330
10537
  chaos,
10331
- resetAll(newSeed) {
10538
+ resetAll(next) {
10332
10539
  for (const store of Object.values(registry)) store.reset();
10333
10540
  bus.clear();
10334
- const r = applySeed(registry, newSeed ?? seedName);
10335
- defaultBusinessId = r.businessId;
10541
+ defaultBusinessId = resolveSeed(registry, next ?? seedSource).businessId;
10336
10542
  return defaultBusinessId;
10337
10543
  }
10338
10544
  };