@uniforge/core 0.1.0-alpha.2

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 (87) hide show
  1. package/dist/auth/index.d.cts +165 -0
  2. package/dist/auth/index.d.ts +165 -0
  3. package/dist/auth/index.js +443 -0
  4. package/dist/auth/index.js.map +1 -0
  5. package/dist/auth/index.mjs +406 -0
  6. package/dist/auth/index.mjs.map +1 -0
  7. package/dist/billing/index.d.cts +34 -0
  8. package/dist/billing/index.d.ts +34 -0
  9. package/dist/billing/index.js +254 -0
  10. package/dist/billing/index.js.map +1 -0
  11. package/dist/billing/index.mjs +225 -0
  12. package/dist/billing/index.mjs.map +1 -0
  13. package/dist/config/index.d.cts +12 -0
  14. package/dist/config/index.d.ts +12 -0
  15. package/dist/config/index.js +186 -0
  16. package/dist/config/index.js.map +1 -0
  17. package/dist/config/index.mjs +156 -0
  18. package/dist/config/index.mjs.map +1 -0
  19. package/dist/database/index.d.cts +33 -0
  20. package/dist/database/index.d.ts +33 -0
  21. package/dist/database/index.js +127 -0
  22. package/dist/database/index.js.map +1 -0
  23. package/dist/database/index.mjs +95 -0
  24. package/dist/database/index.mjs.map +1 -0
  25. package/dist/graphql/index.d.cts +36 -0
  26. package/dist/graphql/index.d.ts +36 -0
  27. package/dist/graphql/index.js +209 -0
  28. package/dist/graphql/index.js.map +1 -0
  29. package/dist/graphql/index.mjs +179 -0
  30. package/dist/graphql/index.mjs.map +1 -0
  31. package/dist/index.d.cts +16 -0
  32. package/dist/index.d.ts +16 -0
  33. package/dist/index.js +36 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/index.mjs +10 -0
  36. package/dist/index.mjs.map +1 -0
  37. package/dist/multi-store/index.d.cts +11 -0
  38. package/dist/multi-store/index.d.ts +11 -0
  39. package/dist/multi-store/index.js +473 -0
  40. package/dist/multi-store/index.js.map +1 -0
  41. package/dist/multi-store/index.mjs +447 -0
  42. package/dist/multi-store/index.mjs.map +1 -0
  43. package/dist/multi-tenant/index.d.cts +23 -0
  44. package/dist/multi-tenant/index.d.ts +23 -0
  45. package/dist/multi-tenant/index.js +69 -0
  46. package/dist/multi-tenant/index.js.map +1 -0
  47. package/dist/multi-tenant/index.mjs +41 -0
  48. package/dist/multi-tenant/index.mjs.map +1 -0
  49. package/dist/performance/index.d.cts +34 -0
  50. package/dist/performance/index.d.ts +34 -0
  51. package/dist/performance/index.js +319 -0
  52. package/dist/performance/index.js.map +1 -0
  53. package/dist/performance/index.mjs +290 -0
  54. package/dist/performance/index.mjs.map +1 -0
  55. package/dist/platform/index.d.cts +25 -0
  56. package/dist/platform/index.d.ts +25 -0
  57. package/dist/platform/index.js +91 -0
  58. package/dist/platform/index.js.map +1 -0
  59. package/dist/platform/index.mjs +62 -0
  60. package/dist/platform/index.mjs.map +1 -0
  61. package/dist/rbac/index.d.cts +24 -0
  62. package/dist/rbac/index.d.ts +24 -0
  63. package/dist/rbac/index.js +267 -0
  64. package/dist/rbac/index.js.map +1 -0
  65. package/dist/rbac/index.mjs +236 -0
  66. package/dist/rbac/index.mjs.map +1 -0
  67. package/dist/schema-CM7mHj_H.d.cts +53 -0
  68. package/dist/schema-CM7mHj_H.d.ts +53 -0
  69. package/dist/security/index.d.cts +47 -0
  70. package/dist/security/index.d.ts +47 -0
  71. package/dist/security/index.js +505 -0
  72. package/dist/security/index.js.map +1 -0
  73. package/dist/security/index.mjs +474 -0
  74. package/dist/security/index.mjs.map +1 -0
  75. package/dist/session-storage/index.d.cts +70 -0
  76. package/dist/session-storage/index.d.ts +70 -0
  77. package/dist/session-storage/index.js +271 -0
  78. package/dist/session-storage/index.js.map +1 -0
  79. package/dist/session-storage/index.mjs +242 -0
  80. package/dist/session-storage/index.mjs.map +1 -0
  81. package/dist/webhooks/index.d.cts +89 -0
  82. package/dist/webhooks/index.d.ts +89 -0
  83. package/dist/webhooks/index.js +380 -0
  84. package/dist/webhooks/index.js.map +1 -0
  85. package/dist/webhooks/index.mjs +348 -0
  86. package/dist/webhooks/index.mjs.map +1 -0
  87. package/package.json +119 -0
@@ -0,0 +1,447 @@
1
+ // src/multi-store/account-service.ts
2
+ import { ACCOUNT_ROLE_HIERARCHY } from "@uniforge/platform-core/multi-store";
3
+ function mapAccount(row) {
4
+ return {
5
+ id: row.id,
6
+ name: row.name,
7
+ type: row.type,
8
+ isActive: row.isActive,
9
+ createdAt: row.createdAt,
10
+ updatedAt: row.updatedAt
11
+ };
12
+ }
13
+ function mapAccountStore(row) {
14
+ return {
15
+ id: row.id,
16
+ accountId: row.accountId,
17
+ shopDomain: row.shopDomain,
18
+ storeName: row.storeName,
19
+ region: row.region ?? null,
20
+ currency: row.currency ?? null,
21
+ locale: row.locale ?? null,
22
+ timezone: row.timezone ?? null,
23
+ storeSettings: row.storeSettings && typeof row.storeSettings === "object" ? row.storeSettings : {},
24
+ isActive: row.isActive,
25
+ isPrimary: row.isPrimary,
26
+ createdAt: row.createdAt,
27
+ updatedAt: row.updatedAt
28
+ };
29
+ }
30
+ function mapAccountMember(row) {
31
+ return {
32
+ id: row.id,
33
+ accountId: row.accountId,
34
+ userEmail: row.userEmail,
35
+ role: row.role,
36
+ allStoresAccess: row.allStoresAccess,
37
+ allowedStoreIds: Array.isArray(row.allowedStoreIds) ? row.allowedStoreIds : [],
38
+ permissions: Array.isArray(row.permissions) ? row.permissions : [],
39
+ createdAt: row.createdAt,
40
+ updatedAt: row.updatedAt
41
+ };
42
+ }
43
+ function createAccountService(prisma) {
44
+ return {
45
+ async createAccount(input) {
46
+ const row = await prisma.account.create({
47
+ data: {
48
+ name: input.name,
49
+ type: input.type
50
+ }
51
+ });
52
+ return mapAccount(row);
53
+ },
54
+ async getAccount(accountId) {
55
+ const row = await prisma.account.findUnique({
56
+ where: { id: accountId }
57
+ });
58
+ if (!row) return null;
59
+ return mapAccount(row);
60
+ },
61
+ async updateAccount(accountId, input) {
62
+ const data = {};
63
+ if (input.name !== void 0) {
64
+ data.name = input.name;
65
+ }
66
+ if (input.type !== void 0) {
67
+ data.type = input.type;
68
+ }
69
+ if (input.isActive !== void 0) {
70
+ data.isActive = input.isActive;
71
+ }
72
+ const row = await prisma.account.update({
73
+ where: { id: accountId },
74
+ data
75
+ });
76
+ return mapAccount(row);
77
+ },
78
+ async deleteAccount(accountId) {
79
+ await prisma.account.delete({ where: { id: accountId } });
80
+ },
81
+ async addStore(input) {
82
+ const data = {
83
+ accountId: input.accountId,
84
+ shopDomain: input.shopDomain,
85
+ storeName: input.storeName
86
+ };
87
+ if (input.region !== void 0) {
88
+ data.region = input.region;
89
+ }
90
+ if (input.currency !== void 0) {
91
+ data.currency = input.currency;
92
+ }
93
+ if (input.locale !== void 0) {
94
+ data.locale = input.locale;
95
+ }
96
+ if (input.timezone !== void 0) {
97
+ data.timezone = input.timezone;
98
+ }
99
+ if (input.storeSettings !== void 0) {
100
+ data.storeSettings = input.storeSettings;
101
+ }
102
+ if (input.isPrimary !== void 0) {
103
+ data.isPrimary = input.isPrimary;
104
+ }
105
+ const row = await prisma.accountStore.create({ data });
106
+ return mapAccountStore(row);
107
+ },
108
+ async getStore(storeId) {
109
+ const row = await prisma.accountStore.findUnique({
110
+ where: { id: storeId }
111
+ });
112
+ if (!row) return null;
113
+ return mapAccountStore(row);
114
+ },
115
+ async getStoreByDomain(shopDomain) {
116
+ const row = await prisma.accountStore.findUnique({
117
+ where: { shopDomain }
118
+ });
119
+ if (!row) return null;
120
+ return mapAccountStore(row);
121
+ },
122
+ async listStores(accountId) {
123
+ const rows = await prisma.accountStore.findMany({
124
+ where: { accountId }
125
+ });
126
+ return rows.map(mapAccountStore);
127
+ },
128
+ async updateStore(storeId, input) {
129
+ const data = {};
130
+ if (input.storeName !== void 0) {
131
+ data.storeName = input.storeName;
132
+ }
133
+ if (input.region !== void 0) {
134
+ data.region = input.region;
135
+ }
136
+ if (input.currency !== void 0) {
137
+ data.currency = input.currency;
138
+ }
139
+ if (input.locale !== void 0) {
140
+ data.locale = input.locale;
141
+ }
142
+ if (input.timezone !== void 0) {
143
+ data.timezone = input.timezone;
144
+ }
145
+ if (input.storeSettings !== void 0) {
146
+ data.storeSettings = input.storeSettings;
147
+ }
148
+ if (input.isActive !== void 0) {
149
+ data.isActive = input.isActive;
150
+ }
151
+ if (input.isPrimary !== void 0) {
152
+ data.isPrimary = input.isPrimary;
153
+ }
154
+ const row = await prisma.accountStore.update({
155
+ where: { id: storeId },
156
+ data
157
+ });
158
+ return mapAccountStore(row);
159
+ },
160
+ async removeStore(storeId) {
161
+ await prisma.accountStore.delete({ where: { id: storeId } });
162
+ },
163
+ async addMember(input) {
164
+ const data = {
165
+ accountId: input.accountId,
166
+ userEmail: input.userEmail,
167
+ role: input.role
168
+ };
169
+ if (input.allStoresAccess !== void 0) {
170
+ data.allStoresAccess = input.allStoresAccess;
171
+ }
172
+ if (input.allowedStoreIds !== void 0) {
173
+ data.allowedStoreIds = JSON.stringify(input.allowedStoreIds);
174
+ }
175
+ if (input.permissions !== void 0) {
176
+ data.permissions = JSON.stringify(input.permissions);
177
+ }
178
+ const row = await prisma.accountMember.create({ data });
179
+ return mapAccountMember(row);
180
+ },
181
+ async getMember(memberId) {
182
+ const row = await prisma.accountMember.findUnique({
183
+ where: { id: memberId }
184
+ });
185
+ if (!row) return null;
186
+ return mapAccountMember(row);
187
+ },
188
+ async getMemberByEmail(accountId, userEmail) {
189
+ const row = await prisma.accountMember.findUnique({
190
+ where: { accountId_userEmail: { accountId, userEmail } }
191
+ });
192
+ if (!row) return null;
193
+ return mapAccountMember(row);
194
+ },
195
+ async listMembers(accountId) {
196
+ const rows = await prisma.accountMember.findMany({
197
+ where: { accountId }
198
+ });
199
+ return rows.map(mapAccountMember);
200
+ },
201
+ async updateMember(memberId, input) {
202
+ const data = {};
203
+ if (input.role !== void 0) {
204
+ data.role = input.role;
205
+ }
206
+ if (input.allStoresAccess !== void 0) {
207
+ data.allStoresAccess = input.allStoresAccess;
208
+ }
209
+ if (input.allowedStoreIds !== void 0) {
210
+ data.allowedStoreIds = JSON.stringify(input.allowedStoreIds);
211
+ }
212
+ if (input.permissions !== void 0) {
213
+ data.permissions = JSON.stringify(input.permissions);
214
+ }
215
+ const row = await prisma.accountMember.update({
216
+ where: { id: memberId },
217
+ data
218
+ });
219
+ return mapAccountMember(row);
220
+ },
221
+ async removeMember(memberId) {
222
+ await prisma.accountMember.delete({ where: { id: memberId } });
223
+ },
224
+ async canAccessStore(accountId, userEmail, storeId) {
225
+ const row = await prisma.accountMember.findUnique({
226
+ where: { accountId_userEmail: { accountId, userEmail } }
227
+ });
228
+ if (!row) return false;
229
+ const member = mapAccountMember(row);
230
+ if (member.role === "owner" || member.role === "admin") return true;
231
+ if (member.allStoresAccess) return true;
232
+ return member.allowedStoreIds.includes(storeId);
233
+ },
234
+ async isRoleAtLeast(accountId, userEmail, minimumRole) {
235
+ const row = await prisma.accountMember.findUnique({
236
+ where: { accountId_userEmail: { accountId, userEmail } }
237
+ });
238
+ if (!row) return false;
239
+ const member = mapAccountMember(row);
240
+ return ACCOUNT_ROLE_HIERARCHY[member.role] >= ACCOUNT_ROLE_HIERARCHY[minimumRole];
241
+ }
242
+ };
243
+ }
244
+
245
+ // src/multi-store/shared-settings-service.ts
246
+ function mapSharedSetting(row) {
247
+ return {
248
+ id: row.id,
249
+ accountId: row.accountId,
250
+ settingKey: row.settingKey,
251
+ settingValue: row.settingValue,
252
+ appliesToStores: Array.isArray(row.appliesToStores) ? row.appliesToStores : null,
253
+ createdAt: row.createdAt,
254
+ updatedAt: row.updatedAt
255
+ };
256
+ }
257
+ function createSharedSettingsService(prisma) {
258
+ return {
259
+ async set(input) {
260
+ const data = {
261
+ settingValue: input.settingValue
262
+ };
263
+ if (input.appliesToStores !== void 0) {
264
+ data.appliesToStores = input.appliesToStores === null ? null : JSON.stringify(input.appliesToStores);
265
+ }
266
+ const row = await prisma.accountSharedSetting.upsert({
267
+ where: {
268
+ accountId_settingKey: {
269
+ accountId: input.accountId,
270
+ settingKey: input.settingKey
271
+ }
272
+ },
273
+ create: {
274
+ accountId: input.accountId,
275
+ settingKey: input.settingKey,
276
+ settingValue: input.settingValue,
277
+ ...input.appliesToStores !== void 0 ? {
278
+ appliesToStores: input.appliesToStores === null ? null : JSON.stringify(input.appliesToStores)
279
+ } : {}
280
+ },
281
+ update: data
282
+ });
283
+ return mapSharedSetting(row);
284
+ },
285
+ async get(accountId, settingKey) {
286
+ const row = await prisma.accountSharedSetting.findUnique({
287
+ where: { accountId_settingKey: { accountId, settingKey } }
288
+ });
289
+ if (!row) return null;
290
+ return mapSharedSetting(row);
291
+ },
292
+ async list(accountId) {
293
+ const rows = await prisma.accountSharedSetting.findMany({
294
+ where: { accountId }
295
+ });
296
+ return rows.map(mapSharedSetting);
297
+ },
298
+ async delete(accountId, settingKey) {
299
+ await prisma.accountSharedSetting.delete({
300
+ where: { accountId_settingKey: { accountId, settingKey } }
301
+ });
302
+ },
303
+ async resolve(accountId, storeId, settingKey, defaultValue) {
304
+ const store = await prisma.accountStore.findUnique({
305
+ where: { id: storeId }
306
+ });
307
+ if (store) {
308
+ const storeSettings = store.storeSettings && typeof store.storeSettings === "object" ? store.storeSettings : {};
309
+ if (settingKey in storeSettings) {
310
+ return storeSettings[settingKey];
311
+ }
312
+ }
313
+ const shared = await prisma.accountSharedSetting.findUnique({
314
+ where: { accountId_settingKey: { accountId, settingKey } }
315
+ });
316
+ if (shared) {
317
+ const appliesToStores = Array.isArray(shared.appliesToStores) ? shared.appliesToStores : null;
318
+ if (appliesToStores === null || appliesToStores.includes(storeId)) {
319
+ return shared.settingValue;
320
+ }
321
+ }
322
+ return defaultValue;
323
+ }
324
+ };
325
+ }
326
+
327
+ // src/multi-store/account-middleware.ts
328
+ function mapAccountStore2(row) {
329
+ return {
330
+ id: row.id,
331
+ accountId: row.accountId,
332
+ shopDomain: row.shopDomain,
333
+ storeName: row.storeName,
334
+ region: row.region ?? null,
335
+ currency: row.currency ?? null,
336
+ locale: row.locale ?? null,
337
+ timezone: row.timezone ?? null,
338
+ storeSettings: row.storeSettings && typeof row.storeSettings === "object" ? row.storeSettings : {},
339
+ isActive: row.isActive,
340
+ isPrimary: row.isPrimary,
341
+ createdAt: row.createdAt,
342
+ updatedAt: row.updatedAt
343
+ };
344
+ }
345
+ function mapAccount2(row) {
346
+ return {
347
+ id: row.id,
348
+ name: row.name,
349
+ type: row.type,
350
+ isActive: row.isActive,
351
+ createdAt: row.createdAt,
352
+ updatedAt: row.updatedAt
353
+ };
354
+ }
355
+ function mapAccountMember2(row) {
356
+ return {
357
+ id: row.id,
358
+ accountId: row.accountId,
359
+ userEmail: row.userEmail,
360
+ role: row.role,
361
+ allStoresAccess: row.allStoresAccess,
362
+ allowedStoreIds: Array.isArray(row.allowedStoreIds) ? row.allowedStoreIds : [],
363
+ permissions: Array.isArray(row.permissions) ? row.permissions : [],
364
+ createdAt: row.createdAt,
365
+ updatedAt: row.updatedAt
366
+ };
367
+ }
368
+ function createAccountMiddleware(prisma) {
369
+ return {
370
+ async getAccountContext(shopDomain, userEmail) {
371
+ const storeRow = await prisma.accountStore.findUnique({
372
+ where: { shopDomain },
373
+ include: { account: true }
374
+ });
375
+ if (!storeRow) return null;
376
+ const account = mapAccount2(storeRow.account);
377
+ const currentStore = mapAccountStore2(storeRow);
378
+ const storeRows = await prisma.accountStore.findMany({
379
+ where: { accountId: account.id }
380
+ });
381
+ const stores = storeRows.map(mapAccountStore2);
382
+ let member = null;
383
+ if (userEmail) {
384
+ const memberRow = await prisma.accountMember.findUnique({
385
+ where: {
386
+ accountId_userEmail: { accountId: account.id, userEmail }
387
+ }
388
+ });
389
+ if (memberRow) {
390
+ member = mapAccountMember2(memberRow);
391
+ }
392
+ }
393
+ return { account, currentStore, member, stores };
394
+ },
395
+ async validateStoreAccess(accountId, userEmail, storeId) {
396
+ const memberRow = await prisma.accountMember.findUnique({
397
+ where: { accountId_userEmail: { accountId, userEmail } }
398
+ });
399
+ if (!memberRow) return false;
400
+ const member = mapAccountMember2(memberRow);
401
+ if (member.role === "owner" || member.role === "admin") return true;
402
+ if (member.allStoresAccess) return true;
403
+ return member.allowedStoreIds.includes(storeId);
404
+ }
405
+ };
406
+ }
407
+
408
+ // src/multi-store/pricing.ts
409
+ import {
410
+ DEFAULT_PRICING_TIERS,
411
+ DEFAULT_BASE_PRICE,
412
+ DEFAULT_INCLUDED_STORES
413
+ } from "@uniforge/platform-core/multi-store";
414
+ function calculateAccountPricing(storeCount, tiers, basePrice) {
415
+ const effectiveTiers = tiers ?? DEFAULT_PRICING_TIERS;
416
+ const effectiveBasePrice = basePrice ?? DEFAULT_BASE_PRICE;
417
+ const includedStores = DEFAULT_INCLUDED_STORES;
418
+ const tierBreakdown = [];
419
+ let additionalStoreCost = 0;
420
+ for (const tier of effectiveTiers) {
421
+ const tierMax = tier.maxStores ?? storeCount;
422
+ const tierStart = tier.minStores;
423
+ const tierEnd = Math.min(tierMax, storeCount);
424
+ if (tierStart > storeCount) {
425
+ tierBreakdown.push({ tier, storeCount: 0, cost: 0 });
426
+ continue;
427
+ }
428
+ const storesInTier = tierEnd - tierStart + 1;
429
+ const cost = storesInTier * tier.pricePerStore;
430
+ tierBreakdown.push({ tier, storeCount: storesInTier, cost });
431
+ additionalStoreCost += cost;
432
+ }
433
+ return {
434
+ basePrice: effectiveBasePrice,
435
+ includedStores,
436
+ additionalStoreCost,
437
+ totalMonthlyPrice: effectiveBasePrice + additionalStoreCost,
438
+ tierBreakdown
439
+ };
440
+ }
441
+ export {
442
+ calculateAccountPricing,
443
+ createAccountMiddleware,
444
+ createAccountService,
445
+ createSharedSettingsService
446
+ };
447
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/multi-store/account-service.ts","../../src/multi-store/shared-settings-service.ts","../../src/multi-store/account-middleware.ts","../../src/multi-store/pricing.ts"],"sourcesContent":["import type {\n Account,\n AccountStore,\n AccountMember,\n AccountRole,\n AccountType,\n AccountService,\n CreateAccountInput,\n UpdateAccountInput,\n AddStoreInput,\n UpdateStoreInput,\n AddMemberInput,\n UpdateMemberInput,\n} from '@uniforge/platform-core/multi-store';\nimport { ACCOUNT_ROLE_HIERARCHY } from '@uniforge/platform-core/multi-store';\n\nfunction mapAccount(row: any): Account {\n return {\n id: row.id,\n name: row.name,\n type: row.type as AccountType,\n isActive: row.isActive,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction mapAccountStore(row: any): AccountStore {\n return {\n id: row.id,\n accountId: row.accountId,\n shopDomain: row.shopDomain,\n storeName: row.storeName,\n region: row.region ?? null,\n currency: row.currency ?? null,\n locale: row.locale ?? null,\n timezone: row.timezone ?? null,\n storeSettings:\n row.storeSettings && typeof row.storeSettings === 'object'\n ? (row.storeSettings as Record<string, unknown>)\n : {},\n isActive: row.isActive,\n isPrimary: row.isPrimary,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction mapAccountMember(row: any): AccountMember {\n return {\n id: row.id,\n accountId: row.accountId,\n userEmail: row.userEmail,\n role: row.role as AccountRole,\n allStoresAccess: row.allStoresAccess,\n allowedStoreIds: Array.isArray(row.allowedStoreIds)\n ? (row.allowedStoreIds as string[])\n : [],\n permissions: Array.isArray(row.permissions)\n ? (row.permissions as string[])\n : [],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nexport function createAccountService(prisma: any): AccountService {\n return {\n async createAccount(input: CreateAccountInput): Promise<Account> {\n const row = await prisma.account.create({\n data: {\n name: input.name,\n type: input.type,\n },\n });\n return mapAccount(row);\n },\n\n async getAccount(accountId: string): Promise<Account | null> {\n const row = await prisma.account.findUnique({\n where: { id: accountId },\n });\n if (!row) return null;\n return mapAccount(row);\n },\n\n async updateAccount(\n accountId: string,\n input: UpdateAccountInput,\n ): Promise<Account> {\n const data: Record<string, unknown> = {};\n if (input.name !== undefined) {\n data.name = input.name;\n }\n if (input.type !== undefined) {\n data.type = input.type;\n }\n if (input.isActive !== undefined) {\n data.isActive = input.isActive;\n }\n const row = await prisma.account.update({\n where: { id: accountId },\n data,\n });\n return mapAccount(row);\n },\n\n async deleteAccount(accountId: string): Promise<void> {\n await prisma.account.delete({ where: { id: accountId } });\n },\n\n async addStore(input: AddStoreInput): Promise<AccountStore> {\n const data: Record<string, unknown> = {\n accountId: input.accountId,\n shopDomain: input.shopDomain,\n storeName: input.storeName,\n };\n if (input.region !== undefined) {\n data.region = input.region;\n }\n if (input.currency !== undefined) {\n data.currency = input.currency;\n }\n if (input.locale !== undefined) {\n data.locale = input.locale;\n }\n if (input.timezone !== undefined) {\n data.timezone = input.timezone;\n }\n if (input.storeSettings !== undefined) {\n data.storeSettings = input.storeSettings;\n }\n if (input.isPrimary !== undefined) {\n data.isPrimary = input.isPrimary;\n }\n const row = await prisma.accountStore.create({ data });\n return mapAccountStore(row);\n },\n\n async getStore(storeId: string): Promise<AccountStore | null> {\n const row = await prisma.accountStore.findUnique({\n where: { id: storeId },\n });\n if (!row) return null;\n return mapAccountStore(row);\n },\n\n async getStoreByDomain(shopDomain: string): Promise<AccountStore | null> {\n const row = await prisma.accountStore.findUnique({\n where: { shopDomain },\n });\n if (!row) return null;\n return mapAccountStore(row);\n },\n\n async listStores(accountId: string): Promise<AccountStore[]> {\n const rows = await prisma.accountStore.findMany({\n where: { accountId },\n });\n return rows.map(mapAccountStore);\n },\n\n async updateStore(\n storeId: string,\n input: UpdateStoreInput,\n ): Promise<AccountStore> {\n const data: Record<string, unknown> = {};\n if (input.storeName !== undefined) {\n data.storeName = input.storeName;\n }\n if (input.region !== undefined) {\n data.region = input.region;\n }\n if (input.currency !== undefined) {\n data.currency = input.currency;\n }\n if (input.locale !== undefined) {\n data.locale = input.locale;\n }\n if (input.timezone !== undefined) {\n data.timezone = input.timezone;\n }\n if (input.storeSettings !== undefined) {\n data.storeSettings = input.storeSettings;\n }\n if (input.isActive !== undefined) {\n data.isActive = input.isActive;\n }\n if (input.isPrimary !== undefined) {\n data.isPrimary = input.isPrimary;\n }\n const row = await prisma.accountStore.update({\n where: { id: storeId },\n data,\n });\n return mapAccountStore(row);\n },\n\n async removeStore(storeId: string): Promise<void> {\n await prisma.accountStore.delete({ where: { id: storeId } });\n },\n\n async addMember(input: AddMemberInput): Promise<AccountMember> {\n const data: Record<string, unknown> = {\n accountId: input.accountId,\n userEmail: input.userEmail,\n role: input.role,\n };\n if (input.allStoresAccess !== undefined) {\n data.allStoresAccess = input.allStoresAccess;\n }\n if (input.allowedStoreIds !== undefined) {\n data.allowedStoreIds = JSON.stringify(input.allowedStoreIds);\n }\n if (input.permissions !== undefined) {\n data.permissions = JSON.stringify(input.permissions);\n }\n const row = await prisma.accountMember.create({ data });\n return mapAccountMember(row);\n },\n\n async getMember(memberId: string): Promise<AccountMember | null> {\n const row = await prisma.accountMember.findUnique({\n where: { id: memberId },\n });\n if (!row) return null;\n return mapAccountMember(row);\n },\n\n async getMemberByEmail(\n accountId: string,\n userEmail: string,\n ): Promise<AccountMember | null> {\n const row = await prisma.accountMember.findUnique({\n where: { accountId_userEmail: { accountId, userEmail } },\n });\n if (!row) return null;\n return mapAccountMember(row);\n },\n\n async listMembers(accountId: string): Promise<AccountMember[]> {\n const rows = await prisma.accountMember.findMany({\n where: { accountId },\n });\n return rows.map(mapAccountMember);\n },\n\n async updateMember(\n memberId: string,\n input: UpdateMemberInput,\n ): Promise<AccountMember> {\n const data: Record<string, unknown> = {};\n if (input.role !== undefined) {\n data.role = input.role;\n }\n if (input.allStoresAccess !== undefined) {\n data.allStoresAccess = input.allStoresAccess;\n }\n if (input.allowedStoreIds !== undefined) {\n data.allowedStoreIds = JSON.stringify(input.allowedStoreIds);\n }\n if (input.permissions !== undefined) {\n data.permissions = JSON.stringify(input.permissions);\n }\n const row = await prisma.accountMember.update({\n where: { id: memberId },\n data,\n });\n return mapAccountMember(row);\n },\n\n async removeMember(memberId: string): Promise<void> {\n await prisma.accountMember.delete({ where: { id: memberId } });\n },\n\n async canAccessStore(\n accountId: string,\n userEmail: string,\n storeId: string,\n ): Promise<boolean> {\n const row = await prisma.accountMember.findUnique({\n where: { accountId_userEmail: { accountId, userEmail } },\n });\n if (!row) return false;\n const member = mapAccountMember(row);\n if (member.role === 'owner' || member.role === 'admin') return true;\n if (member.allStoresAccess) return true;\n return member.allowedStoreIds.includes(storeId);\n },\n\n async isRoleAtLeast(\n accountId: string,\n userEmail: string,\n minimumRole: AccountRole,\n ): Promise<boolean> {\n const row = await prisma.accountMember.findUnique({\n where: { accountId_userEmail: { accountId, userEmail } },\n });\n if (!row) return false;\n const member = mapAccountMember(row);\n return (\n ACCOUNT_ROLE_HIERARCHY[member.role] >=\n ACCOUNT_ROLE_HIERARCHY[minimumRole]\n );\n },\n };\n}\n","import type {\n AccountSharedSetting,\n SetSharedSettingInput,\n SharedSettingsService,\n} from '@uniforge/platform-core/multi-store';\n\nfunction mapSharedSetting(row: any): AccountSharedSetting {\n return {\n id: row.id,\n accountId: row.accountId,\n settingKey: row.settingKey,\n settingValue: row.settingValue,\n appliesToStores: Array.isArray(row.appliesToStores)\n ? (row.appliesToStores as string[])\n : null,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nexport function createSharedSettingsService(\n prisma: any,\n): SharedSettingsService {\n return {\n async set(input: SetSharedSettingInput): Promise<AccountSharedSetting> {\n const data: Record<string, unknown> = {\n settingValue: input.settingValue,\n };\n if (input.appliesToStores !== undefined) {\n data.appliesToStores =\n input.appliesToStores === null\n ? null\n : JSON.stringify(input.appliesToStores);\n }\n const row = await prisma.accountSharedSetting.upsert({\n where: {\n accountId_settingKey: {\n accountId: input.accountId,\n settingKey: input.settingKey,\n },\n },\n create: {\n accountId: input.accountId,\n settingKey: input.settingKey,\n settingValue: input.settingValue,\n ...(input.appliesToStores !== undefined\n ? {\n appliesToStores:\n input.appliesToStores === null\n ? null\n : JSON.stringify(input.appliesToStores),\n }\n : {}),\n },\n update: data,\n });\n return mapSharedSetting(row);\n },\n\n async get(\n accountId: string,\n settingKey: string,\n ): Promise<AccountSharedSetting | null> {\n const row = await prisma.accountSharedSetting.findUnique({\n where: { accountId_settingKey: { accountId, settingKey } },\n });\n if (!row) return null;\n return mapSharedSetting(row);\n },\n\n async list(accountId: string): Promise<AccountSharedSetting[]> {\n const rows = await prisma.accountSharedSetting.findMany({\n where: { accountId },\n });\n return rows.map(mapSharedSetting);\n },\n\n async delete(accountId: string, settingKey: string): Promise<void> {\n await prisma.accountSharedSetting.delete({\n where: { accountId_settingKey: { accountId, settingKey } },\n });\n },\n\n async resolve<T = unknown>(\n accountId: string,\n storeId: string,\n settingKey: string,\n defaultValue: T,\n ): Promise<T> {\n // 1. Check store-specific override\n const store = await prisma.accountStore.findUnique({\n where: { id: storeId },\n });\n if (store) {\n const storeSettings =\n store.storeSettings && typeof store.storeSettings === 'object'\n ? (store.storeSettings as Record<string, unknown>)\n : {};\n if (settingKey in storeSettings) {\n return storeSettings[settingKey] as T;\n }\n }\n\n // 2. Check account shared setting\n const shared = await prisma.accountSharedSetting.findUnique({\n where: { accountId_settingKey: { accountId, settingKey } },\n });\n if (shared) {\n const appliesToStores = Array.isArray(shared.appliesToStores)\n ? (shared.appliesToStores as string[])\n : null;\n if (\n appliesToStores === null ||\n appliesToStores.includes(storeId)\n ) {\n return shared.settingValue as T;\n }\n }\n\n // 3. Return default\n return defaultValue;\n },\n };\n}\n","import type {\n AccountContext,\n AccountMiddleware,\n AccountRole,\n} from '@uniforge/platform-core/multi-store';\n\nfunction mapAccountStore(row: any) {\n return {\n id: row.id,\n accountId: row.accountId,\n shopDomain: row.shopDomain,\n storeName: row.storeName,\n region: row.region ?? null,\n currency: row.currency ?? null,\n locale: row.locale ?? null,\n timezone: row.timezone ?? null,\n storeSettings:\n row.storeSettings && typeof row.storeSettings === 'object'\n ? (row.storeSettings as Record<string, unknown>)\n : {},\n isActive: row.isActive,\n isPrimary: row.isPrimary,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction mapAccount(row: any) {\n return {\n id: row.id,\n name: row.name,\n type: row.type as 'individual' | 'enterprise',\n isActive: row.isActive,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nfunction mapAccountMember(row: any) {\n return {\n id: row.id,\n accountId: row.accountId,\n userEmail: row.userEmail,\n role: row.role as AccountRole,\n allStoresAccess: row.allStoresAccess,\n allowedStoreIds: Array.isArray(row.allowedStoreIds)\n ? (row.allowedStoreIds as string[])\n : [],\n permissions: Array.isArray(row.permissions)\n ? (row.permissions as string[])\n : [],\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n\nexport function createAccountMiddleware(prisma: any): AccountMiddleware {\n return {\n async getAccountContext(\n shopDomain: string,\n userEmail?: string,\n ): Promise<AccountContext | null> {\n // 1. Find the store by shopDomain, include account\n const storeRow = await prisma.accountStore.findUnique({\n where: { shopDomain },\n include: { account: true },\n });\n if (!storeRow) return null;\n\n const account = mapAccount(storeRow.account);\n const currentStore = mapAccountStore(storeRow);\n\n // 2. Get all stores for the account\n const storeRows = await prisma.accountStore.findMany({\n where: { accountId: account.id },\n });\n const stores = storeRows.map(mapAccountStore);\n\n // 3. Get member if userEmail provided\n let member = null;\n if (userEmail) {\n const memberRow = await prisma.accountMember.findUnique({\n where: {\n accountId_userEmail: { accountId: account.id, userEmail },\n },\n });\n if (memberRow) {\n member = mapAccountMember(memberRow);\n }\n }\n\n return { account, currentStore, member, stores };\n },\n\n async validateStoreAccess(\n accountId: string,\n userEmail: string,\n storeId: string,\n ): Promise<boolean> {\n const memberRow = await prisma.accountMember.findUnique({\n where: { accountId_userEmail: { accountId, userEmail } },\n });\n if (!memberRow) return false;\n\n const member = mapAccountMember(memberRow);\n if (member.role === 'owner' || member.role === 'admin') return true;\n if (member.allStoresAccess) return true;\n return member.allowedStoreIds.includes(storeId);\n },\n };\n}\n","import type {\n AccountPricingTier,\n AccountPricingResult,\n} from '@uniforge/platform-core/multi-store';\nimport {\n DEFAULT_PRICING_TIERS,\n DEFAULT_BASE_PRICE,\n DEFAULT_INCLUDED_STORES,\n} from '@uniforge/platform-core/multi-store';\n\nexport function calculateAccountPricing(\n storeCount: number,\n tiers?: AccountPricingTier[],\n basePrice?: number,\n): AccountPricingResult {\n const effectiveTiers = tiers ?? DEFAULT_PRICING_TIERS;\n const effectiveBasePrice = basePrice ?? DEFAULT_BASE_PRICE;\n const includedStores = DEFAULT_INCLUDED_STORES;\n\n const tierBreakdown: Array<{\n tier: AccountPricingTier;\n storeCount: number;\n cost: number;\n }> = [];\n let additionalStoreCost = 0;\n\n for (const tier of effectiveTiers) {\n const tierMax = tier.maxStores ?? storeCount;\n const tierStart = tier.minStores;\n const tierEnd = Math.min(tierMax, storeCount);\n\n if (tierStart > storeCount) {\n tierBreakdown.push({ tier, storeCount: 0, cost: 0 });\n continue;\n }\n\n const storesInTier = tierEnd - tierStart + 1;\n const cost = storesInTier * tier.pricePerStore;\n\n tierBreakdown.push({ tier, storeCount: storesInTier, cost });\n additionalStoreCost += cost;\n }\n\n return {\n basePrice: effectiveBasePrice,\n includedStores,\n additionalStoreCost,\n totalMonthlyPrice: effectiveBasePrice + additionalStoreCost,\n tierBreakdown,\n };\n}\n"],"mappings":"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","names":["mapAccountStore","mapAccount","mapAccountMember"]}
@@ -0,0 +1,23 @@
1
+ import { TenantMiddlewareConfig, TenantMiddleware, QueryScopeFilter } from '@uniforge/platform-core/multi-tenant';
2
+
3
+ /**
4
+ * Multi-tenant middleware implementation.
5
+ *
6
+ * Extracts tenant context from an authenticated session and provides
7
+ * tenant validation for cross-tenant access prevention.
8
+ */
9
+
10
+ /** Create a TenantMiddleware instance with optional configuration. */
11
+ declare function createTenantMiddleware(config?: TenantMiddlewareConfig): TenantMiddleware;
12
+
13
+ /**
14
+ * Query scoping implementation for multi-tenant data access.
15
+ *
16
+ * Automatically adds shopDomain filters to database queries
17
+ * and validates record ownership.
18
+ */
19
+
20
+ /** Create a QueryScopeFilter that injects shopDomain into where clauses. */
21
+ declare function createQueryScopeFilter(): QueryScopeFilter;
22
+
23
+ export { createQueryScopeFilter, createTenantMiddleware };
@@ -0,0 +1,23 @@
1
+ import { TenantMiddlewareConfig, TenantMiddleware, QueryScopeFilter } from '@uniforge/platform-core/multi-tenant';
2
+
3
+ /**
4
+ * Multi-tenant middleware implementation.
5
+ *
6
+ * Extracts tenant context from an authenticated session and provides
7
+ * tenant validation for cross-tenant access prevention.
8
+ */
9
+
10
+ /** Create a TenantMiddleware instance with optional configuration. */
11
+ declare function createTenantMiddleware(config?: TenantMiddlewareConfig): TenantMiddleware;
12
+
13
+ /**
14
+ * Query scoping implementation for multi-tenant data access.
15
+ *
16
+ * Automatically adds shopDomain filters to database queries
17
+ * and validates record ownership.
18
+ */
19
+
20
+ /** Create a QueryScopeFilter that injects shopDomain into where clauses. */
21
+ declare function createQueryScopeFilter(): QueryScopeFilter;
22
+
23
+ export { createQueryScopeFilter, createTenantMiddleware };
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/multi-tenant/index.ts
21
+ var multi_tenant_exports = {};
22
+ __export(multi_tenant_exports, {
23
+ createQueryScopeFilter: () => createQueryScopeFilter,
24
+ createTenantMiddleware: () => createTenantMiddleware
25
+ });
26
+ module.exports = __toCommonJS(multi_tenant_exports);
27
+
28
+ // src/multi-tenant/middleware.ts
29
+ function createTenantMiddleware(config) {
30
+ const extractor = config?.extractor;
31
+ return {
32
+ getTenantContext(session, shopContext) {
33
+ if (extractor) {
34
+ return extractor.extract(session, shopContext);
35
+ }
36
+ return {
37
+ shopDomain: shopContext.shopDomain,
38
+ session,
39
+ shopContext
40
+ };
41
+ },
42
+ validateTenant(tenantContext, shopDomain) {
43
+ return tenantContext.shopDomain === shopDomain;
44
+ }
45
+ };
46
+ }
47
+
48
+ // src/multi-tenant/query-scoping.ts
49
+ function createQueryScopeFilter() {
50
+ return {
51
+ applyScope(where, options) {
52
+ return {
53
+ where: {
54
+ ...where,
55
+ shopDomain: options.shopDomain
56
+ }
57
+ };
58
+ },
59
+ validateOwnership(record, expectedShopDomain) {
60
+ return record.shopDomain === expectedShopDomain;
61
+ }
62
+ };
63
+ }
64
+ // Annotate the CommonJS export names for ESM import in node:
65
+ 0 && (module.exports = {
66
+ createQueryScopeFilter,
67
+ createTenantMiddleware
68
+ });
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/multi-tenant/index.ts","../../src/multi-tenant/middleware.ts","../../src/multi-tenant/query-scoping.ts"],"sourcesContent":["/**\n * @uniforge/core - Multi-Tenant\n *\n * Tenant isolation middleware and query scoping implementations.\n */\n\nexport { createTenantMiddleware } from './middleware';\nexport { createQueryScopeFilter } from './query-scoping';\n","/**\n * Multi-tenant middleware implementation.\n *\n * Extracts tenant context from an authenticated session and provides\n * tenant validation for cross-tenant access prevention.\n */\n\nimport type {\n Session,\n ShopContext,\n} from '@uniforge/platform-core/auth';\nimport type {\n TenantContext,\n TenantMiddleware,\n TenantMiddlewareConfig,\n} from '@uniforge/platform-core/multi-tenant';\n\n/** Create a TenantMiddleware instance with optional configuration. */\nexport function createTenantMiddleware(\n config?: TenantMiddlewareConfig,\n): TenantMiddleware {\n const extractor = config?.extractor;\n\n return {\n getTenantContext(session: Session, shopContext: ShopContext): TenantContext {\n if (extractor) {\n return extractor.extract(session, shopContext);\n }\n return {\n shopDomain: shopContext.shopDomain,\n session,\n shopContext,\n };\n },\n\n validateTenant(tenantContext: TenantContext, shopDomain: string): boolean {\n return tenantContext.shopDomain === shopDomain;\n },\n };\n}\n","/**\n * Query scoping implementation for multi-tenant data access.\n *\n * Automatically adds shopDomain filters to database queries\n * and validates record ownership.\n */\n\nimport type {\n QueryScopeFilter,\n QueryScopeOptions,\n ScopedQuery,\n} from '@uniforge/platform-core/multi-tenant';\n\n/** Create a QueryScopeFilter that injects shopDomain into where clauses. */\nexport function createQueryScopeFilter(): QueryScopeFilter {\n return {\n applyScope<T extends Record<string, unknown>>(\n where: T,\n options: QueryScopeOptions,\n ): ScopedQuery<T> {\n return {\n where: {\n ...where,\n shopDomain: options.shopDomain,\n },\n };\n },\n\n validateOwnership(\n record: { shopDomain: string },\n expectedShopDomain: string,\n ): boolean {\n return record.shopDomain === expectedShopDomain;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACkBO,SAAS,uBACd,QACkB;AAClB,QAAM,YAAY,QAAQ;AAE1B,SAAO;AAAA,IACL,iBAAiB,SAAkB,aAAyC;AAC1E,UAAI,WAAW;AACb,eAAO,UAAU,QAAQ,SAAS,WAAW;AAAA,MAC/C;AACA,aAAO;AAAA,QACL,YAAY,YAAY;AAAA,QACxB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IAEA,eAAe,eAA8B,YAA6B;AACxE,aAAO,cAAc,eAAe;AAAA,IACtC;AAAA,EACF;AACF;;;ACzBO,SAAS,yBAA2C;AACzD,SAAO;AAAA,IACL,WACE,OACA,SACgB;AAChB,aAAO;AAAA,QACL,OAAO;AAAA,UACL,GAAG;AAAA,UACH,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,IAEA,kBACE,QACA,oBACS;AACT,aAAO,OAAO,eAAe;AAAA,IAC/B;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,41 @@
1
+ // src/multi-tenant/middleware.ts
2
+ function createTenantMiddleware(config) {
3
+ const extractor = config?.extractor;
4
+ return {
5
+ getTenantContext(session, shopContext) {
6
+ if (extractor) {
7
+ return extractor.extract(session, shopContext);
8
+ }
9
+ return {
10
+ shopDomain: shopContext.shopDomain,
11
+ session,
12
+ shopContext
13
+ };
14
+ },
15
+ validateTenant(tenantContext, shopDomain) {
16
+ return tenantContext.shopDomain === shopDomain;
17
+ }
18
+ };
19
+ }
20
+
21
+ // src/multi-tenant/query-scoping.ts
22
+ function createQueryScopeFilter() {
23
+ return {
24
+ applyScope(where, options) {
25
+ return {
26
+ where: {
27
+ ...where,
28
+ shopDomain: options.shopDomain
29
+ }
30
+ };
31
+ },
32
+ validateOwnership(record, expectedShopDomain) {
33
+ return record.shopDomain === expectedShopDomain;
34
+ }
35
+ };
36
+ }
37
+ export {
38
+ createQueryScopeFilter,
39
+ createTenantMiddleware
40
+ };
41
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/multi-tenant/middleware.ts","../../src/multi-tenant/query-scoping.ts"],"sourcesContent":["/**\n * Multi-tenant middleware implementation.\n *\n * Extracts tenant context from an authenticated session and provides\n * tenant validation for cross-tenant access prevention.\n */\n\nimport type {\n Session,\n ShopContext,\n} from '@uniforge/platform-core/auth';\nimport type {\n TenantContext,\n TenantMiddleware,\n TenantMiddlewareConfig,\n} from '@uniforge/platform-core/multi-tenant';\n\n/** Create a TenantMiddleware instance with optional configuration. */\nexport function createTenantMiddleware(\n config?: TenantMiddlewareConfig,\n): TenantMiddleware {\n const extractor = config?.extractor;\n\n return {\n getTenantContext(session: Session, shopContext: ShopContext): TenantContext {\n if (extractor) {\n return extractor.extract(session, shopContext);\n }\n return {\n shopDomain: shopContext.shopDomain,\n session,\n shopContext,\n };\n },\n\n validateTenant(tenantContext: TenantContext, shopDomain: string): boolean {\n return tenantContext.shopDomain === shopDomain;\n },\n };\n}\n","/**\n * Query scoping implementation for multi-tenant data access.\n *\n * Automatically adds shopDomain filters to database queries\n * and validates record ownership.\n */\n\nimport type {\n QueryScopeFilter,\n QueryScopeOptions,\n ScopedQuery,\n} from '@uniforge/platform-core/multi-tenant';\n\n/** Create a QueryScopeFilter that injects shopDomain into where clauses. */\nexport function createQueryScopeFilter(): QueryScopeFilter {\n return {\n applyScope<T extends Record<string, unknown>>(\n where: T,\n options: QueryScopeOptions,\n ): ScopedQuery<T> {\n return {\n where: {\n ...where,\n shopDomain: options.shopDomain,\n },\n };\n },\n\n validateOwnership(\n record: { shopDomain: string },\n expectedShopDomain: string,\n ): boolean {\n return record.shopDomain === expectedShopDomain;\n },\n };\n}\n"],"mappings":";AAkBO,SAAS,uBACd,QACkB;AAClB,QAAM,YAAY,QAAQ;AAE1B,SAAO;AAAA,IACL,iBAAiB,SAAkB,aAAyC;AAC1E,UAAI,WAAW;AACb,eAAO,UAAU,QAAQ,SAAS,WAAW;AAAA,MAC/C;AACA,aAAO;AAAA,QACL,YAAY,YAAY;AAAA,QACxB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IAEA,eAAe,eAA8B,YAA6B;AACxE,aAAO,cAAc,eAAe;AAAA,IACtC;AAAA,EACF;AACF;;;ACzBO,SAAS,yBAA2C;AACzD,SAAO;AAAA,IACL,WACE,OACA,SACgB;AAChB,aAAO;AAAA,QACL,OAAO;AAAA,UACL,GAAG;AAAA,UACH,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,IAEA,kBACE,QACA,oBACS;AACT,aAAO,OAAO,eAAe;AAAA,IAC/B;AAAA,EACF;AACF;","names":[]}