@uniforge/testing 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.
- package/dist/auth/index.d.cts +177 -0
- package/dist/auth/index.d.ts +177 -0
- package/dist/auth/index.js +459 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +418 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/billing/index.d.cts +27 -0
- package/dist/billing/index.d.ts +27 -0
- package/dist/billing/index.js +208 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/billing/index.mjs +178 -0
- package/dist/billing/index.mjs.map +1 -0
- package/dist/database/index.d.cts +399 -0
- package/dist/database/index.d.ts +399 -0
- package/dist/database/index.js +19054 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/index.mjs +19046 -0
- package/dist/database/index.mjs.map +1 -0
- package/dist/graphql/index.d.cts +23 -0
- package/dist/graphql/index.d.ts +23 -0
- package/dist/graphql/index.js +18511 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/graphql/index.mjs +18505 -0
- package/dist/graphql/index.mjs.map +1 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -0
- package/dist/multi-store/index.d.cts +66 -0
- package/dist/multi-store/index.d.ts +66 -0
- package/dist/multi-store/index.js +319 -0
- package/dist/multi-store/index.js.map +1 -0
- package/dist/multi-store/index.mjs +287 -0
- package/dist/multi-store/index.mjs.map +1 -0
- package/dist/multi-tenant/index.d.cts +15 -0
- package/dist/multi-tenant/index.d.ts +15 -0
- package/dist/multi-tenant/index.js +87 -0
- package/dist/multi-tenant/index.js.map +1 -0
- package/dist/multi-tenant/index.mjs +57 -0
- package/dist/multi-tenant/index.mjs.map +1 -0
- package/dist/performance/index.d.cts +60 -0
- package/dist/performance/index.d.ts +60 -0
- package/dist/performance/index.js +280 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/performance/index.mjs +246 -0
- package/dist/performance/index.mjs.map +1 -0
- package/dist/platform/index.d.cts +71 -0
- package/dist/platform/index.d.ts +71 -0
- package/dist/platform/index.js +435 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/index.mjs +396 -0
- package/dist/platform/index.mjs.map +1 -0
- package/dist/rbac/index.d.cts +21 -0
- package/dist/rbac/index.d.ts +21 -0
- package/dist/rbac/index.js +178 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/index.mjs +150 -0
- package/dist/rbac/index.mjs.map +1 -0
- package/dist/security/index.d.cts +73 -0
- package/dist/security/index.d.ts +73 -0
- package/dist/security/index.js +246 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/index.mjs +211 -0
- package/dist/security/index.mjs.map +1 -0
- package/dist/shopify-api/index.d.cts +139 -0
- package/dist/shopify-api/index.d.ts +139 -0
- package/dist/shopify-api/index.js +469 -0
- package/dist/shopify-api/index.js.map +1 -0
- package/dist/shopify-api/index.mjs +439 -0
- package/dist/shopify-api/index.mjs.map +1 -0
- package/dist/shopify-compliance/index.d.cts +85 -0
- package/dist/shopify-compliance/index.d.ts +85 -0
- package/dist/shopify-compliance/index.js +287 -0
- package/dist/shopify-compliance/index.js.map +1 -0
- package/dist/shopify-compliance/index.mjs +259 -0
- package/dist/shopify-compliance/index.mjs.map +1 -0
- package/dist/webhooks/index.d.cts +127 -0
- package/dist/webhooks/index.d.ts +127 -0
- package/dist/webhooks/index.js +18934 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/index.mjs +18916 -0
- package/dist/webhooks/index.mjs.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// src/multi-store/factories.ts
|
|
2
|
+
function createTestAccount(overrides = {}) {
|
|
3
|
+
const now = /* @__PURE__ */ new Date();
|
|
4
|
+
return {
|
|
5
|
+
id: "acct_test_001",
|
|
6
|
+
name: "Test Enterprise Account",
|
|
7
|
+
type: "enterprise",
|
|
8
|
+
isActive: true,
|
|
9
|
+
createdAt: now,
|
|
10
|
+
updatedAt: now,
|
|
11
|
+
...overrides
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function createTestAccountStore(overrides = {}) {
|
|
15
|
+
const now = /* @__PURE__ */ new Date();
|
|
16
|
+
return {
|
|
17
|
+
id: "store_test_001",
|
|
18
|
+
accountId: "acct_test_001",
|
|
19
|
+
shopDomain: "test-shop.myshopify.com",
|
|
20
|
+
storeName: "Test Store",
|
|
21
|
+
region: null,
|
|
22
|
+
currency: null,
|
|
23
|
+
locale: null,
|
|
24
|
+
timezone: null,
|
|
25
|
+
storeSettings: {},
|
|
26
|
+
isActive: true,
|
|
27
|
+
isPrimary: true,
|
|
28
|
+
createdAt: now,
|
|
29
|
+
updatedAt: now,
|
|
30
|
+
...overrides
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function createTestAccountMember(overrides = {}) {
|
|
34
|
+
const now = /* @__PURE__ */ new Date();
|
|
35
|
+
return {
|
|
36
|
+
id: "member_test_001",
|
|
37
|
+
accountId: "acct_test_001",
|
|
38
|
+
userEmail: "owner@test.com",
|
|
39
|
+
role: "owner",
|
|
40
|
+
allStoresAccess: true,
|
|
41
|
+
allowedStoreIds: [],
|
|
42
|
+
permissions: [],
|
|
43
|
+
createdAt: now,
|
|
44
|
+
updatedAt: now,
|
|
45
|
+
...overrides
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function createTestAccountSharedSetting(overrides = {}) {
|
|
49
|
+
const now = /* @__PURE__ */ new Date();
|
|
50
|
+
return {
|
|
51
|
+
id: "setting_test_001",
|
|
52
|
+
accountId: "acct_test_001",
|
|
53
|
+
settingKey: "theme",
|
|
54
|
+
settingValue: "dark",
|
|
55
|
+
appliesToStores: null,
|
|
56
|
+
createdAt: now,
|
|
57
|
+
updatedAt: now,
|
|
58
|
+
...overrides
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/multi-store/mock-account-service.ts
|
|
63
|
+
import { ACCOUNT_ROLE_HIERARCHY } from "@uniforge/platform-core/multi-store";
|
|
64
|
+
var MockAccountService = class {
|
|
65
|
+
accounts = /* @__PURE__ */ new Map();
|
|
66
|
+
stores = /* @__PURE__ */ new Map();
|
|
67
|
+
storesByDomain = /* @__PURE__ */ new Map();
|
|
68
|
+
members = /* @__PURE__ */ new Map();
|
|
69
|
+
membersByKey = /* @__PURE__ */ new Map();
|
|
70
|
+
nextId = 1;
|
|
71
|
+
generateId() {
|
|
72
|
+
return `mock_${this.nextId++}`;
|
|
73
|
+
}
|
|
74
|
+
_reset() {
|
|
75
|
+
this.accounts.clear();
|
|
76
|
+
this.stores.clear();
|
|
77
|
+
this.storesByDomain.clear();
|
|
78
|
+
this.members.clear();
|
|
79
|
+
this.membersByKey.clear();
|
|
80
|
+
this.nextId = 1;
|
|
81
|
+
}
|
|
82
|
+
async createAccount(input) {
|
|
83
|
+
const now = /* @__PURE__ */ new Date();
|
|
84
|
+
const account = {
|
|
85
|
+
id: this.generateId(),
|
|
86
|
+
name: input.name,
|
|
87
|
+
type: input.type,
|
|
88
|
+
isActive: true,
|
|
89
|
+
createdAt: now,
|
|
90
|
+
updatedAt: now
|
|
91
|
+
};
|
|
92
|
+
this.accounts.set(account.id, account);
|
|
93
|
+
return account;
|
|
94
|
+
}
|
|
95
|
+
async getAccount(accountId) {
|
|
96
|
+
return this.accounts.get(accountId) ?? null;
|
|
97
|
+
}
|
|
98
|
+
async updateAccount(accountId, input) {
|
|
99
|
+
const account = this.accounts.get(accountId);
|
|
100
|
+
if (!account) throw new Error(`Account ${accountId} not found`);
|
|
101
|
+
const updated = { ...account, updatedAt: /* @__PURE__ */ new Date() };
|
|
102
|
+
if (input.name !== void 0) updated.name = input.name;
|
|
103
|
+
if (input.type !== void 0) updated.type = input.type;
|
|
104
|
+
if (input.isActive !== void 0) updated.isActive = input.isActive;
|
|
105
|
+
this.accounts.set(accountId, updated);
|
|
106
|
+
return updated;
|
|
107
|
+
}
|
|
108
|
+
async deleteAccount(accountId) {
|
|
109
|
+
this.accounts.delete(accountId);
|
|
110
|
+
}
|
|
111
|
+
async addStore(input) {
|
|
112
|
+
const now = /* @__PURE__ */ new Date();
|
|
113
|
+
const store = {
|
|
114
|
+
id: this.generateId(),
|
|
115
|
+
accountId: input.accountId,
|
|
116
|
+
shopDomain: input.shopDomain,
|
|
117
|
+
storeName: input.storeName,
|
|
118
|
+
region: input.region ?? null,
|
|
119
|
+
currency: input.currency ?? null,
|
|
120
|
+
locale: input.locale ?? null,
|
|
121
|
+
timezone: input.timezone ?? null,
|
|
122
|
+
storeSettings: input.storeSettings ?? {},
|
|
123
|
+
isActive: true,
|
|
124
|
+
isPrimary: input.isPrimary ?? false,
|
|
125
|
+
createdAt: now,
|
|
126
|
+
updatedAt: now
|
|
127
|
+
};
|
|
128
|
+
this.stores.set(store.id, store);
|
|
129
|
+
this.storesByDomain.set(store.shopDomain, store);
|
|
130
|
+
return store;
|
|
131
|
+
}
|
|
132
|
+
async getStore(storeId) {
|
|
133
|
+
return this.stores.get(storeId) ?? null;
|
|
134
|
+
}
|
|
135
|
+
async getStoreByDomain(shopDomain) {
|
|
136
|
+
return this.storesByDomain.get(shopDomain) ?? null;
|
|
137
|
+
}
|
|
138
|
+
async listStores(accountId) {
|
|
139
|
+
return [...this.stores.values()].filter((s) => s.accountId === accountId);
|
|
140
|
+
}
|
|
141
|
+
async updateStore(storeId, input) {
|
|
142
|
+
const store = this.stores.get(storeId);
|
|
143
|
+
if (!store) throw new Error(`Store ${storeId} not found`);
|
|
144
|
+
const updated = { ...store, updatedAt: /* @__PURE__ */ new Date() };
|
|
145
|
+
if (input.storeName !== void 0) updated.storeName = input.storeName;
|
|
146
|
+
if (input.region !== void 0) updated.region = input.region;
|
|
147
|
+
if (input.currency !== void 0) updated.currency = input.currency;
|
|
148
|
+
if (input.locale !== void 0) updated.locale = input.locale;
|
|
149
|
+
if (input.timezone !== void 0) updated.timezone = input.timezone;
|
|
150
|
+
if (input.storeSettings !== void 0) updated.storeSettings = input.storeSettings;
|
|
151
|
+
if (input.isActive !== void 0) updated.isActive = input.isActive;
|
|
152
|
+
if (input.isPrimary !== void 0) updated.isPrimary = input.isPrimary;
|
|
153
|
+
this.stores.set(storeId, updated);
|
|
154
|
+
this.storesByDomain.set(updated.shopDomain, updated);
|
|
155
|
+
return updated;
|
|
156
|
+
}
|
|
157
|
+
async removeStore(storeId) {
|
|
158
|
+
const store = this.stores.get(storeId);
|
|
159
|
+
if (store) {
|
|
160
|
+
this.storesByDomain.delete(store.shopDomain);
|
|
161
|
+
}
|
|
162
|
+
this.stores.delete(storeId);
|
|
163
|
+
}
|
|
164
|
+
async addMember(input) {
|
|
165
|
+
const now = /* @__PURE__ */ new Date();
|
|
166
|
+
const member = {
|
|
167
|
+
id: this.generateId(),
|
|
168
|
+
accountId: input.accountId,
|
|
169
|
+
userEmail: input.userEmail,
|
|
170
|
+
role: input.role,
|
|
171
|
+
allStoresAccess: input.allStoresAccess ?? false,
|
|
172
|
+
allowedStoreIds: input.allowedStoreIds ?? [],
|
|
173
|
+
permissions: input.permissions ?? [],
|
|
174
|
+
createdAt: now,
|
|
175
|
+
updatedAt: now
|
|
176
|
+
};
|
|
177
|
+
this.members.set(member.id, member);
|
|
178
|
+
this.membersByKey.set(`${member.accountId}:${member.userEmail}`, member);
|
|
179
|
+
return member;
|
|
180
|
+
}
|
|
181
|
+
async getMember(memberId) {
|
|
182
|
+
return this.members.get(memberId) ?? null;
|
|
183
|
+
}
|
|
184
|
+
async getMemberByEmail(accountId, userEmail) {
|
|
185
|
+
return this.membersByKey.get(`${accountId}:${userEmail}`) ?? null;
|
|
186
|
+
}
|
|
187
|
+
async listMembers(accountId) {
|
|
188
|
+
return [...this.members.values()].filter((m) => m.accountId === accountId);
|
|
189
|
+
}
|
|
190
|
+
async updateMember(memberId, input) {
|
|
191
|
+
const member = this.members.get(memberId);
|
|
192
|
+
if (!member) throw new Error(`Member ${memberId} not found`);
|
|
193
|
+
const updated = { ...member, updatedAt: /* @__PURE__ */ new Date() };
|
|
194
|
+
if (input.role !== void 0) updated.role = input.role;
|
|
195
|
+
if (input.allStoresAccess !== void 0) updated.allStoresAccess = input.allStoresAccess;
|
|
196
|
+
if (input.allowedStoreIds !== void 0) updated.allowedStoreIds = input.allowedStoreIds;
|
|
197
|
+
if (input.permissions !== void 0) updated.permissions = input.permissions;
|
|
198
|
+
this.members.set(memberId, updated);
|
|
199
|
+
this.membersByKey.set(`${updated.accountId}:${updated.userEmail}`, updated);
|
|
200
|
+
return updated;
|
|
201
|
+
}
|
|
202
|
+
async removeMember(memberId) {
|
|
203
|
+
const member = this.members.get(memberId);
|
|
204
|
+
if (member) {
|
|
205
|
+
this.membersByKey.delete(`${member.accountId}:${member.userEmail}`);
|
|
206
|
+
}
|
|
207
|
+
this.members.delete(memberId);
|
|
208
|
+
}
|
|
209
|
+
async canAccessStore(accountId, userEmail, storeId) {
|
|
210
|
+
const member = this.membersByKey.get(`${accountId}:${userEmail}`);
|
|
211
|
+
if (!member) return false;
|
|
212
|
+
if (member.role === "owner" || member.role === "admin") return true;
|
|
213
|
+
if (member.allStoresAccess) return true;
|
|
214
|
+
return member.allowedStoreIds.includes(storeId);
|
|
215
|
+
}
|
|
216
|
+
async isRoleAtLeast(accountId, userEmail, minimumRole) {
|
|
217
|
+
const member = this.membersByKey.get(`${accountId}:${userEmail}`);
|
|
218
|
+
if (!member) return false;
|
|
219
|
+
return ACCOUNT_ROLE_HIERARCHY[member.role] >= ACCOUNT_ROLE_HIERARCHY[minimumRole];
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// src/multi-store/mock-shared-settings-service.ts
|
|
224
|
+
var MockSharedSettingsService = class {
|
|
225
|
+
settings = /* @__PURE__ */ new Map();
|
|
226
|
+
storeSettings = /* @__PURE__ */ new Map();
|
|
227
|
+
nextId = 1;
|
|
228
|
+
key(accountId, settingKey) {
|
|
229
|
+
return `${accountId}:${settingKey}`;
|
|
230
|
+
}
|
|
231
|
+
_reset() {
|
|
232
|
+
this.settings.clear();
|
|
233
|
+
this.storeSettings.clear();
|
|
234
|
+
this.nextId = 1;
|
|
235
|
+
}
|
|
236
|
+
/** Helper to set store-level overrides for testing cascade logic. */
|
|
237
|
+
_setStoreSettings(storeId, settings) {
|
|
238
|
+
this.storeSettings.set(storeId, settings);
|
|
239
|
+
}
|
|
240
|
+
async set(input) {
|
|
241
|
+
const now = /* @__PURE__ */ new Date();
|
|
242
|
+
const k = this.key(input.accountId, input.settingKey);
|
|
243
|
+
const existing = this.settings.get(k);
|
|
244
|
+
const setting = {
|
|
245
|
+
id: existing?.id ?? `mock_setting_${this.nextId++}`,
|
|
246
|
+
accountId: input.accountId,
|
|
247
|
+
settingKey: input.settingKey,
|
|
248
|
+
settingValue: input.settingValue,
|
|
249
|
+
appliesToStores: input.appliesToStores ?? null,
|
|
250
|
+
createdAt: existing?.createdAt ?? now,
|
|
251
|
+
updatedAt: now
|
|
252
|
+
};
|
|
253
|
+
this.settings.set(k, setting);
|
|
254
|
+
return setting;
|
|
255
|
+
}
|
|
256
|
+
async get(accountId, settingKey) {
|
|
257
|
+
return this.settings.get(this.key(accountId, settingKey)) ?? null;
|
|
258
|
+
}
|
|
259
|
+
async list(accountId) {
|
|
260
|
+
return [...this.settings.values()].filter((s) => s.accountId === accountId);
|
|
261
|
+
}
|
|
262
|
+
async delete(accountId, settingKey) {
|
|
263
|
+
this.settings.delete(this.key(accountId, settingKey));
|
|
264
|
+
}
|
|
265
|
+
async resolve(accountId, storeId, settingKey, defaultValue) {
|
|
266
|
+
const storeOverrides = this.storeSettings.get(storeId);
|
|
267
|
+
if (storeOverrides && settingKey in storeOverrides) {
|
|
268
|
+
return storeOverrides[settingKey];
|
|
269
|
+
}
|
|
270
|
+
const shared = this.settings.get(this.key(accountId, settingKey));
|
|
271
|
+
if (shared) {
|
|
272
|
+
if (shared.appliesToStores === null || shared.appliesToStores.includes(storeId)) {
|
|
273
|
+
return shared.settingValue;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return defaultValue;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
export {
|
|
280
|
+
MockAccountService,
|
|
281
|
+
MockSharedSettingsService,
|
|
282
|
+
createTestAccount,
|
|
283
|
+
createTestAccountMember,
|
|
284
|
+
createTestAccountSharedSetting,
|
|
285
|
+
createTestAccountStore
|
|
286
|
+
};
|
|
287
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/multi-store/factories.ts","../../src/multi-store/mock-account-service.ts","../../src/multi-store/mock-shared-settings-service.ts"],"sourcesContent":["/**\n * Test data factories for multi-store types.\n *\n * Each factory provides sensible defaults that can be overridden.\n */\n\nimport type {\n Account,\n AccountStore,\n AccountMember,\n AccountSharedSetting,\n} from '@uniforge/platform-core/multi-store';\n\nexport function createTestAccount(overrides: Partial<Account> = {}): Account {\n const now = new Date();\n return {\n id: 'acct_test_001',\n name: 'Test Enterprise Account',\n type: 'enterprise',\n isActive: true,\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n\nexport function createTestAccountStore(\n overrides: Partial<AccountStore> = {},\n): AccountStore {\n const now = new Date();\n return {\n id: 'store_test_001',\n accountId: 'acct_test_001',\n shopDomain: 'test-shop.myshopify.com',\n storeName: 'Test Store',\n region: null,\n currency: null,\n locale: null,\n timezone: null,\n storeSettings: {},\n isActive: true,\n isPrimary: true,\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n\nexport function createTestAccountMember(\n overrides: Partial<AccountMember> = {},\n): AccountMember {\n const now = new Date();\n return {\n id: 'member_test_001',\n accountId: 'acct_test_001',\n userEmail: 'owner@test.com',\n role: 'owner',\n allStoresAccess: true,\n allowedStoreIds: [],\n permissions: [],\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n\nexport function createTestAccountSharedSetting(\n overrides: Partial<AccountSharedSetting> = {},\n): AccountSharedSetting {\n const now = new Date();\n return {\n id: 'setting_test_001',\n accountId: 'acct_test_001',\n settingKey: 'theme',\n settingValue: 'dark',\n appliesToStores: null,\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n","/**\n * In-memory mock AccountService for testing.\n */\n\nimport type {\n Account,\n AccountStore,\n AccountMember,\n AccountRole,\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\nexport class MockAccountService implements AccountService {\n private accounts = new Map<string, Account>();\n private stores = new Map<string, AccountStore>();\n private storesByDomain = new Map<string, AccountStore>();\n private members = new Map<string, AccountMember>();\n private membersByKey = new Map<string, AccountMember>();\n private nextId = 1;\n\n private generateId(): string {\n return `mock_${this.nextId++}`;\n }\n\n _reset(): void {\n this.accounts.clear();\n this.stores.clear();\n this.storesByDomain.clear();\n this.members.clear();\n this.membersByKey.clear();\n this.nextId = 1;\n }\n\n async createAccount(input: CreateAccountInput): Promise<Account> {\n const now = new Date();\n const account: Account = {\n id: this.generateId(),\n name: input.name,\n type: input.type,\n isActive: true,\n createdAt: now,\n updatedAt: now,\n };\n this.accounts.set(account.id, account);\n return account;\n }\n\n async getAccount(accountId: string): Promise<Account | null> {\n return this.accounts.get(accountId) ?? null;\n }\n\n async updateAccount(accountId: string, input: UpdateAccountInput): Promise<Account> {\n const account = this.accounts.get(accountId);\n if (!account) throw new Error(`Account ${accountId} not found`);\n const updated: Account = { ...account, updatedAt: new Date() };\n if (input.name !== undefined) updated.name = input.name;\n if (input.type !== undefined) updated.type = input.type;\n if (input.isActive !== undefined) updated.isActive = input.isActive;\n this.accounts.set(accountId, updated);\n return updated;\n }\n\n async deleteAccount(accountId: string): Promise<void> {\n this.accounts.delete(accountId);\n }\n\n async addStore(input: AddStoreInput): Promise<AccountStore> {\n const now = new Date();\n const store: AccountStore = {\n id: this.generateId(),\n accountId: input.accountId,\n shopDomain: input.shopDomain,\n storeName: input.storeName,\n region: input.region ?? null,\n currency: input.currency ?? null,\n locale: input.locale ?? null,\n timezone: input.timezone ?? null,\n storeSettings: input.storeSettings ?? {},\n isActive: true,\n isPrimary: input.isPrimary ?? false,\n createdAt: now,\n updatedAt: now,\n };\n this.stores.set(store.id, store);\n this.storesByDomain.set(store.shopDomain, store);\n return store;\n }\n\n async getStore(storeId: string): Promise<AccountStore | null> {\n return this.stores.get(storeId) ?? null;\n }\n\n async getStoreByDomain(shopDomain: string): Promise<AccountStore | null> {\n return this.storesByDomain.get(shopDomain) ?? null;\n }\n\n async listStores(accountId: string): Promise<AccountStore[]> {\n return [...this.stores.values()].filter((s) => s.accountId === accountId);\n }\n\n async updateStore(storeId: string, input: UpdateStoreInput): Promise<AccountStore> {\n const store = this.stores.get(storeId);\n if (!store) throw new Error(`Store ${storeId} not found`);\n const updated: AccountStore = { ...store, updatedAt: new Date() };\n if (input.storeName !== undefined) updated.storeName = input.storeName;\n if (input.region !== undefined) updated.region = input.region;\n if (input.currency !== undefined) updated.currency = input.currency;\n if (input.locale !== undefined) updated.locale = input.locale;\n if (input.timezone !== undefined) updated.timezone = input.timezone;\n if (input.storeSettings !== undefined) updated.storeSettings = input.storeSettings;\n if (input.isActive !== undefined) updated.isActive = input.isActive;\n if (input.isPrimary !== undefined) updated.isPrimary = input.isPrimary;\n this.stores.set(storeId, updated);\n this.storesByDomain.set(updated.shopDomain, updated);\n return updated;\n }\n\n async removeStore(storeId: string): Promise<void> {\n const store = this.stores.get(storeId);\n if (store) {\n this.storesByDomain.delete(store.shopDomain);\n }\n this.stores.delete(storeId);\n }\n\n async addMember(input: AddMemberInput): Promise<AccountMember> {\n const now = new Date();\n const member: AccountMember = {\n id: this.generateId(),\n accountId: input.accountId,\n userEmail: input.userEmail,\n role: input.role,\n allStoresAccess: input.allStoresAccess ?? false,\n allowedStoreIds: input.allowedStoreIds ?? [],\n permissions: input.permissions ?? [],\n createdAt: now,\n updatedAt: now,\n };\n this.members.set(member.id, member);\n this.membersByKey.set(`${member.accountId}:${member.userEmail}`, member);\n return member;\n }\n\n async getMember(memberId: string): Promise<AccountMember | null> {\n return this.members.get(memberId) ?? null;\n }\n\n async getMemberByEmail(accountId: string, userEmail: string): Promise<AccountMember | null> {\n return this.membersByKey.get(`${accountId}:${userEmail}`) ?? null;\n }\n\n async listMembers(accountId: string): Promise<AccountMember[]> {\n return [...this.members.values()].filter((m) => m.accountId === accountId);\n }\n\n async updateMember(memberId: string, input: UpdateMemberInput): Promise<AccountMember> {\n const member = this.members.get(memberId);\n if (!member) throw new Error(`Member ${memberId} not found`);\n const updated: AccountMember = { ...member, updatedAt: new Date() };\n if (input.role !== undefined) updated.role = input.role;\n if (input.allStoresAccess !== undefined) updated.allStoresAccess = input.allStoresAccess;\n if (input.allowedStoreIds !== undefined) updated.allowedStoreIds = input.allowedStoreIds;\n if (input.permissions !== undefined) updated.permissions = input.permissions;\n this.members.set(memberId, updated);\n this.membersByKey.set(`${updated.accountId}:${updated.userEmail}`, updated);\n return updated;\n }\n\n async removeMember(memberId: string): Promise<void> {\n const member = this.members.get(memberId);\n if (member) {\n this.membersByKey.delete(`${member.accountId}:${member.userEmail}`);\n }\n this.members.delete(memberId);\n }\n\n async canAccessStore(accountId: string, userEmail: string, storeId: string): Promise<boolean> {\n const member = this.membersByKey.get(`${accountId}:${userEmail}`);\n if (!member) return false;\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(accountId: string, userEmail: string, minimumRole: AccountRole): Promise<boolean> {\n const member = this.membersByKey.get(`${accountId}:${userEmail}`);\n if (!member) return false;\n return ACCOUNT_ROLE_HIERARCHY[member.role] >= ACCOUNT_ROLE_HIERARCHY[minimumRole];\n }\n}\n","/**\n * In-memory mock SharedSettingsService for testing.\n */\n\nimport type {\n AccountSharedSetting,\n SetSharedSettingInput,\n SharedSettingsService,\n} from '@uniforge/platform-core/multi-store';\n\nexport class MockSharedSettingsService implements SharedSettingsService {\n private settings = new Map<string, AccountSharedSetting>();\n private storeSettings = new Map<string, Record<string, unknown>>();\n private nextId = 1;\n\n private key(accountId: string, settingKey: string): string {\n return `${accountId}:${settingKey}`;\n }\n\n _reset(): void {\n this.settings.clear();\n this.storeSettings.clear();\n this.nextId = 1;\n }\n\n /** Helper to set store-level overrides for testing cascade logic. */\n _setStoreSettings(storeId: string, settings: Record<string, unknown>): void {\n this.storeSettings.set(storeId, settings);\n }\n\n async set(input: SetSharedSettingInput): Promise<AccountSharedSetting> {\n const now = new Date();\n const k = this.key(input.accountId, input.settingKey);\n const existing = this.settings.get(k);\n const setting: AccountSharedSetting = {\n id: existing?.id ?? `mock_setting_${this.nextId++}`,\n accountId: input.accountId,\n settingKey: input.settingKey,\n settingValue: input.settingValue,\n appliesToStores: input.appliesToStores ?? null,\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n };\n this.settings.set(k, setting);\n return setting;\n }\n\n async get(accountId: string, settingKey: string): Promise<AccountSharedSetting | null> {\n return this.settings.get(this.key(accountId, settingKey)) ?? null;\n }\n\n async list(accountId: string): Promise<AccountSharedSetting[]> {\n return [...this.settings.values()].filter((s) => s.accountId === accountId);\n }\n\n async delete(accountId: string, settingKey: string): Promise<void> {\n this.settings.delete(this.key(accountId, settingKey));\n }\n\n async resolve<T = unknown>(\n accountId: string,\n storeId: string,\n settingKey: string,\n defaultValue: T,\n ): Promise<T> {\n // 1. Store-specific override\n const storeOverrides = this.storeSettings.get(storeId);\n if (storeOverrides && settingKey in storeOverrides) {\n return storeOverrides[settingKey] as T;\n }\n\n // 2. Account shared setting\n const shared = this.settings.get(this.key(accountId, settingKey));\n if (shared) {\n if (shared.appliesToStores === null || shared.appliesToStores.includes(storeId)) {\n return shared.settingValue as T;\n }\n }\n\n // 3. Default value\n return defaultValue;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Session, ShopContext, Shop } from '@uniforge/platform-core/auth';
|
|
2
|
+
import { TenantContext } from '@uniforge/platform-core/multi-tenant';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test data factories for multi-tenant types.
|
|
6
|
+
*
|
|
7
|
+
* Each factory provides sensible defaults that can be overridden.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
declare function createTestSession(overrides?: Partial<Session>): Session;
|
|
11
|
+
declare function createTestShopContext(overrides?: Partial<ShopContext>): ShopContext;
|
|
12
|
+
declare function createTestTenantContext(overrides?: Partial<TenantContext>): TenantContext;
|
|
13
|
+
declare function createTestShop(overrides?: Partial<Shop>): Shop;
|
|
14
|
+
|
|
15
|
+
export { createTestSession, createTestShop, createTestShopContext, createTestTenantContext };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Session, ShopContext, Shop } from '@uniforge/platform-core/auth';
|
|
2
|
+
import { TenantContext } from '@uniforge/platform-core/multi-tenant';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test data factories for multi-tenant types.
|
|
6
|
+
*
|
|
7
|
+
* Each factory provides sensible defaults that can be overridden.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
declare function createTestSession(overrides?: Partial<Session>): Session;
|
|
11
|
+
declare function createTestShopContext(overrides?: Partial<ShopContext>): ShopContext;
|
|
12
|
+
declare function createTestTenantContext(overrides?: Partial<TenantContext>): TenantContext;
|
|
13
|
+
declare function createTestShop(overrides?: Partial<Shop>): Shop;
|
|
14
|
+
|
|
15
|
+
export { createTestSession, createTestShop, createTestShopContext, createTestTenantContext };
|
|
@@ -0,0 +1,87 @@
|
|
|
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
|
+
createTestSession: () => createTestSession,
|
|
24
|
+
createTestShop: () => createTestShop,
|
|
25
|
+
createTestShopContext: () => createTestShopContext,
|
|
26
|
+
createTestTenantContext: () => createTestTenantContext
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(multi_tenant_exports);
|
|
29
|
+
|
|
30
|
+
// src/multi-tenant/factories.ts
|
|
31
|
+
function createTestSession(overrides = {}) {
|
|
32
|
+
const now = /* @__PURE__ */ new Date();
|
|
33
|
+
return {
|
|
34
|
+
id: "offline_test-shop.myshopify.com",
|
|
35
|
+
shop: "test-shop.myshopify.com",
|
|
36
|
+
state: "test-state-nonce",
|
|
37
|
+
isOnline: false,
|
|
38
|
+
scope: "read_products,write_orders",
|
|
39
|
+
expires: null,
|
|
40
|
+
accessToken: "shpat_test_token",
|
|
41
|
+
createdAt: now,
|
|
42
|
+
updatedAt: now,
|
|
43
|
+
...overrides
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function createTestShopContext(overrides = {}) {
|
|
47
|
+
const session = createTestSession();
|
|
48
|
+
return {
|
|
49
|
+
shopDomain: "test-shop.myshopify.com",
|
|
50
|
+
accessToken: "shpat_test_token",
|
|
51
|
+
scopes: ["read_products", "write_orders"],
|
|
52
|
+
session,
|
|
53
|
+
...overrides
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function createTestTenantContext(overrides = {}) {
|
|
57
|
+
const session = createTestSession();
|
|
58
|
+
const shopContext = createTestShopContext({ session });
|
|
59
|
+
return {
|
|
60
|
+
shopDomain: "test-shop.myshopify.com",
|
|
61
|
+
session,
|
|
62
|
+
shopContext,
|
|
63
|
+
...overrides
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function createTestShop(overrides = {}) {
|
|
67
|
+
const now = /* @__PURE__ */ new Date();
|
|
68
|
+
return {
|
|
69
|
+
shopDomain: "test-shop.myshopify.com",
|
|
70
|
+
isInstalled: true,
|
|
71
|
+
installedAt: now,
|
|
72
|
+
uninstalledAt: null,
|
|
73
|
+
scopes: "read_products,write_orders",
|
|
74
|
+
shopifyPlan: "basic",
|
|
75
|
+
createdAt: now,
|
|
76
|
+
updatedAt: now,
|
|
77
|
+
...overrides
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
81
|
+
0 && (module.exports = {
|
|
82
|
+
createTestSession,
|
|
83
|
+
createTestShop,
|
|
84
|
+
createTestShopContext,
|
|
85
|
+
createTestTenantContext
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/multi-tenant/index.ts","../../src/multi-tenant/factories.ts"],"sourcesContent":["/**\n * @uniforge/testing - Multi-Tenant\n *\n * Test data factories for multi-tenant types.\n */\n\nexport {\n createTestSession,\n createTestShopContext,\n createTestTenantContext,\n createTestShop,\n} from './factories';\n","/**\n * Test data factories for multi-tenant types.\n *\n * Each factory provides sensible defaults that can be overridden.\n */\n\nimport type { Session, ShopContext, Shop } from '@uniforge/platform-core/auth';\nimport type { TenantContext } from '@uniforge/platform-core/multi-tenant';\n\nexport function createTestSession(overrides: Partial<Session> = {}): Session {\n const now = new Date();\n return {\n id: 'offline_test-shop.myshopify.com',\n shop: 'test-shop.myshopify.com',\n state: 'test-state-nonce',\n isOnline: false,\n scope: 'read_products,write_orders',\n expires: null,\n accessToken: 'shpat_test_token',\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n\nexport function createTestShopContext(\n overrides: Partial<ShopContext> = {},\n): ShopContext {\n const session = createTestSession();\n return {\n shopDomain: 'test-shop.myshopify.com',\n accessToken: 'shpat_test_token',\n scopes: ['read_products', 'write_orders'],\n session,\n ...overrides,\n };\n}\n\nexport function createTestTenantContext(\n overrides: Partial<TenantContext> = {},\n): TenantContext {\n const session = createTestSession();\n const shopContext = createTestShopContext({ session });\n return {\n shopDomain: 'test-shop.myshopify.com',\n session,\n shopContext,\n ...overrides,\n };\n}\n\nexport function createTestShop(overrides: Partial<Shop> = {}): Shop {\n const now = new Date();\n return {\n shopDomain: 'test-shop.myshopify.com',\n isInstalled: true,\n installedAt: now,\n uninstalledAt: null,\n scopes: 'read_products,write_orders',\n shopifyPlan: 'basic',\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACSO,SAAS,kBAAkB,YAA8B,CAAC,GAAY;AAC3E,QAAM,MAAM,oBAAI,KAAK;AACrB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,WAAW;AAAA,IACX,GAAG;AAAA,EACL;AACF;AAEO,SAAS,sBACd,YAAkC,CAAC,GACtB;AACb,QAAM,UAAU,kBAAkB;AAClC,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ,CAAC,iBAAiB,cAAc;AAAA,IACxC;AAAA,IACA,GAAG;AAAA,EACL;AACF;AAEO,SAAS,wBACd,YAAoC,CAAC,GACtB;AACf,QAAM,UAAU,kBAAkB;AAClC,QAAM,cAAc,sBAAsB,EAAE,QAAQ,CAAC;AACrD,SAAO;AAAA,IACL,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AACF;AAEO,SAAS,eAAe,YAA2B,CAAC,GAAS;AAClE,QAAM,MAAM,oBAAI,KAAK;AACrB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,WAAW;AAAA,IACX,WAAW;AAAA,IACX,GAAG;AAAA,EACL;AACF;","names":[]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/multi-tenant/factories.ts
|
|
2
|
+
function createTestSession(overrides = {}) {
|
|
3
|
+
const now = /* @__PURE__ */ new Date();
|
|
4
|
+
return {
|
|
5
|
+
id: "offline_test-shop.myshopify.com",
|
|
6
|
+
shop: "test-shop.myshopify.com",
|
|
7
|
+
state: "test-state-nonce",
|
|
8
|
+
isOnline: false,
|
|
9
|
+
scope: "read_products,write_orders",
|
|
10
|
+
expires: null,
|
|
11
|
+
accessToken: "shpat_test_token",
|
|
12
|
+
createdAt: now,
|
|
13
|
+
updatedAt: now,
|
|
14
|
+
...overrides
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function createTestShopContext(overrides = {}) {
|
|
18
|
+
const session = createTestSession();
|
|
19
|
+
return {
|
|
20
|
+
shopDomain: "test-shop.myshopify.com",
|
|
21
|
+
accessToken: "shpat_test_token",
|
|
22
|
+
scopes: ["read_products", "write_orders"],
|
|
23
|
+
session,
|
|
24
|
+
...overrides
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function createTestTenantContext(overrides = {}) {
|
|
28
|
+
const session = createTestSession();
|
|
29
|
+
const shopContext = createTestShopContext({ session });
|
|
30
|
+
return {
|
|
31
|
+
shopDomain: "test-shop.myshopify.com",
|
|
32
|
+
session,
|
|
33
|
+
shopContext,
|
|
34
|
+
...overrides
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function createTestShop(overrides = {}) {
|
|
38
|
+
const now = /* @__PURE__ */ new Date();
|
|
39
|
+
return {
|
|
40
|
+
shopDomain: "test-shop.myshopify.com",
|
|
41
|
+
isInstalled: true,
|
|
42
|
+
installedAt: now,
|
|
43
|
+
uninstalledAt: null,
|
|
44
|
+
scopes: "read_products,write_orders",
|
|
45
|
+
shopifyPlan: "basic",
|
|
46
|
+
createdAt: now,
|
|
47
|
+
updatedAt: now,
|
|
48
|
+
...overrides
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
createTestSession,
|
|
53
|
+
createTestShop,
|
|
54
|
+
createTestShopContext,
|
|
55
|
+
createTestTenantContext
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/multi-tenant/factories.ts"],"sourcesContent":["/**\n * Test data factories for multi-tenant types.\n *\n * Each factory provides sensible defaults that can be overridden.\n */\n\nimport type { Session, ShopContext, Shop } from '@uniforge/platform-core/auth';\nimport type { TenantContext } from '@uniforge/platform-core/multi-tenant';\n\nexport function createTestSession(overrides: Partial<Session> = {}): Session {\n const now = new Date();\n return {\n id: 'offline_test-shop.myshopify.com',\n shop: 'test-shop.myshopify.com',\n state: 'test-state-nonce',\n isOnline: false,\n scope: 'read_products,write_orders',\n expires: null,\n accessToken: 'shpat_test_token',\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n\nexport function createTestShopContext(\n overrides: Partial<ShopContext> = {},\n): ShopContext {\n const session = createTestSession();\n return {\n shopDomain: 'test-shop.myshopify.com',\n accessToken: 'shpat_test_token',\n scopes: ['read_products', 'write_orders'],\n session,\n ...overrides,\n };\n}\n\nexport function createTestTenantContext(\n overrides: Partial<TenantContext> = {},\n): TenantContext {\n const session = createTestSession();\n const shopContext = createTestShopContext({ session });\n return {\n shopDomain: 'test-shop.myshopify.com',\n session,\n shopContext,\n ...overrides,\n };\n}\n\nexport function createTestShop(overrides: Partial<Shop> = {}): Shop {\n const now = new Date();\n return {\n shopDomain: 'test-shop.myshopify.com',\n isInstalled: true,\n installedAt: now,\n uninstalledAt: null,\n scopes: 'read_products,write_orders',\n shopifyPlan: 'basic',\n createdAt: now,\n updatedAt: now,\n ...overrides,\n };\n}\n"],"mappings":";AASO,SAAS,kBAAkB,YAA8B,CAAC,GAAY;AAC3E,QAAM,MAAM,oBAAI,KAAK;AACrB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,WAAW;AAAA,IACX,GAAG;AAAA,EACL;AACF;AAEO,SAAS,sBACd,YAAkC,CAAC,GACtB;AACb,QAAM,UAAU,kBAAkB;AAClC,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,QAAQ,CAAC,iBAAiB,cAAc;AAAA,IACxC;AAAA,IACA,GAAG;AAAA,EACL;AACF;AAEO,SAAS,wBACd,YAAoC,CAAC,GACtB;AACf,QAAM,UAAU,kBAAkB;AAClC,QAAM,cAAc,sBAAsB,EAAE,QAAQ,CAAC;AACrD,SAAO;AAAA,IACL,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AACF;AAEO,SAAS,eAAe,YAA2B,CAAC,GAAS;AAClE,QAAM,MAAM,oBAAI,KAAK;AACrB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,WAAW;AAAA,IACX,WAAW;AAAA,IACX,GAAG;AAAA,EACL;AACF;","names":[]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CacheManagerConfig, CacheEntry, CacheMetrics, QueryCostConfig, QueryCostEntry, QueryCostReport, BatchConfig, CacheManager } from '@uniforge/platform-core/performance';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test data factories for performance types.
|
|
5
|
+
*
|
|
6
|
+
* Each factory provides sensible defaults that can be overridden.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
declare function createTestCacheConfig(overrides?: Partial<CacheManagerConfig>): CacheManagerConfig;
|
|
10
|
+
declare function createTestCacheEntry<T = string>(overrides?: Partial<CacheEntry<T>>): CacheEntry<T>;
|
|
11
|
+
declare function createTestCacheMetrics(overrides?: Partial<CacheMetrics>): CacheMetrics;
|
|
12
|
+
declare function createTestQueryCostConfig(overrides?: Partial<QueryCostConfig>): QueryCostConfig;
|
|
13
|
+
declare function createTestQueryCostEntry(overrides?: Partial<QueryCostEntry>): QueryCostEntry;
|
|
14
|
+
declare function createTestQueryCostReport(overrides?: Partial<QueryCostReport>): QueryCostReport;
|
|
15
|
+
declare function createTestBatchConfig(overrides?: Partial<BatchConfig>): BatchConfig;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Mock CacheManager for unit testing.
|
|
19
|
+
*
|
|
20
|
+
* Provides an in-memory implementation of CacheManager backed by
|
|
21
|
+
* a Map, with metrics tracking and call recording.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
declare class MockCacheManager implements CacheManager {
|
|
25
|
+
readonly config: CacheManagerConfig;
|
|
26
|
+
private store;
|
|
27
|
+
private _hits;
|
|
28
|
+
private _misses;
|
|
29
|
+
private _evictions;
|
|
30
|
+
/** Recorded keys for get() calls. */
|
|
31
|
+
getCalls: string[];
|
|
32
|
+
/** Recorded keys for set() calls. */
|
|
33
|
+
setCalls: Array<{
|
|
34
|
+
key: string;
|
|
35
|
+
value: unknown;
|
|
36
|
+
ttl?: number;
|
|
37
|
+
}>;
|
|
38
|
+
/** Recorded keys for delete() calls. */
|
|
39
|
+
deleteCalls: string[];
|
|
40
|
+
/** Recorded patterns for invalidate() calls. */
|
|
41
|
+
invalidateCalls: string[];
|
|
42
|
+
constructor(config?: Partial<CacheManagerConfig>);
|
|
43
|
+
get<T = unknown>(key: string): Promise<CacheEntry<T> | undefined>;
|
|
44
|
+
set<T = unknown>(key: string, value: T, ttl?: number): Promise<void>;
|
|
45
|
+
delete(key: string): Promise<boolean>;
|
|
46
|
+
invalidate(pattern: string): Promise<number>;
|
|
47
|
+
has(key: string): Promise<boolean>;
|
|
48
|
+
warm(entries: Array<{
|
|
49
|
+
key: string;
|
|
50
|
+
value: unknown;
|
|
51
|
+
ttl?: number;
|
|
52
|
+
}>): Promise<void>;
|
|
53
|
+
getMetrics(): CacheMetrics;
|
|
54
|
+
resetMetrics(): void;
|
|
55
|
+
clear(): Promise<void>;
|
|
56
|
+
/** Reset all state: store, metrics, and recorded calls. */
|
|
57
|
+
_reset(): void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { MockCacheManager, createTestBatchConfig, createTestCacheConfig, createTestCacheEntry, createTestCacheMetrics, createTestQueryCostConfig, createTestQueryCostEntry, createTestQueryCostReport };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CacheManagerConfig, CacheEntry, CacheMetrics, QueryCostConfig, QueryCostEntry, QueryCostReport, BatchConfig, CacheManager } from '@uniforge/platform-core/performance';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test data factories for performance types.
|
|
5
|
+
*
|
|
6
|
+
* Each factory provides sensible defaults that can be overridden.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
declare function createTestCacheConfig(overrides?: Partial<CacheManagerConfig>): CacheManagerConfig;
|
|
10
|
+
declare function createTestCacheEntry<T = string>(overrides?: Partial<CacheEntry<T>>): CacheEntry<T>;
|
|
11
|
+
declare function createTestCacheMetrics(overrides?: Partial<CacheMetrics>): CacheMetrics;
|
|
12
|
+
declare function createTestQueryCostConfig(overrides?: Partial<QueryCostConfig>): QueryCostConfig;
|
|
13
|
+
declare function createTestQueryCostEntry(overrides?: Partial<QueryCostEntry>): QueryCostEntry;
|
|
14
|
+
declare function createTestQueryCostReport(overrides?: Partial<QueryCostReport>): QueryCostReport;
|
|
15
|
+
declare function createTestBatchConfig(overrides?: Partial<BatchConfig>): BatchConfig;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Mock CacheManager for unit testing.
|
|
19
|
+
*
|
|
20
|
+
* Provides an in-memory implementation of CacheManager backed by
|
|
21
|
+
* a Map, with metrics tracking and call recording.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
declare class MockCacheManager implements CacheManager {
|
|
25
|
+
readonly config: CacheManagerConfig;
|
|
26
|
+
private store;
|
|
27
|
+
private _hits;
|
|
28
|
+
private _misses;
|
|
29
|
+
private _evictions;
|
|
30
|
+
/** Recorded keys for get() calls. */
|
|
31
|
+
getCalls: string[];
|
|
32
|
+
/** Recorded keys for set() calls. */
|
|
33
|
+
setCalls: Array<{
|
|
34
|
+
key: string;
|
|
35
|
+
value: unknown;
|
|
36
|
+
ttl?: number;
|
|
37
|
+
}>;
|
|
38
|
+
/** Recorded keys for delete() calls. */
|
|
39
|
+
deleteCalls: string[];
|
|
40
|
+
/** Recorded patterns for invalidate() calls. */
|
|
41
|
+
invalidateCalls: string[];
|
|
42
|
+
constructor(config?: Partial<CacheManagerConfig>);
|
|
43
|
+
get<T = unknown>(key: string): Promise<CacheEntry<T> | undefined>;
|
|
44
|
+
set<T = unknown>(key: string, value: T, ttl?: number): Promise<void>;
|
|
45
|
+
delete(key: string): Promise<boolean>;
|
|
46
|
+
invalidate(pattern: string): Promise<number>;
|
|
47
|
+
has(key: string): Promise<boolean>;
|
|
48
|
+
warm(entries: Array<{
|
|
49
|
+
key: string;
|
|
50
|
+
value: unknown;
|
|
51
|
+
ttl?: number;
|
|
52
|
+
}>): Promise<void>;
|
|
53
|
+
getMetrics(): CacheMetrics;
|
|
54
|
+
resetMetrics(): void;
|
|
55
|
+
clear(): Promise<void>;
|
|
56
|
+
/** Reset all state: store, metrics, and recorded calls. */
|
|
57
|
+
_reset(): void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { MockCacheManager, createTestBatchConfig, createTestCacheConfig, createTestCacheEntry, createTestCacheMetrics, createTestQueryCostConfig, createTestQueryCostEntry, createTestQueryCostReport };
|