@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,290 @@
1
+ // src/performance/cache-manager.ts
2
+ function createCacheManager(config) {
3
+ const store = /* @__PURE__ */ new Map();
4
+ let hits = 0;
5
+ let misses = 0;
6
+ let evictions = 0;
7
+ function resolveTTL(key, ttlOverride) {
8
+ if (ttlOverride !== void 0) return ttlOverride;
9
+ if (config.strategies !== void 0) {
10
+ for (const strategy of config.strategies) {
11
+ if (key.startsWith(strategy.pattern)) {
12
+ return strategy.ttl;
13
+ }
14
+ }
15
+ }
16
+ return config.defaultTTL;
17
+ }
18
+ function prefixKey(key) {
19
+ if (config.keyPrefix !== void 0) {
20
+ return `${config.keyPrefix}:${key}`;
21
+ }
22
+ return key;
23
+ }
24
+ function isExpired(entry) {
25
+ return Date.now() >= entry.expiresAt;
26
+ }
27
+ function evictOldest() {
28
+ let oldestKey;
29
+ let oldestTime = Infinity;
30
+ for (const [k, v] of store) {
31
+ if (v.createdAt < oldestTime) {
32
+ oldestTime = v.createdAt;
33
+ oldestKey = k;
34
+ }
35
+ }
36
+ if (oldestKey !== void 0) {
37
+ store.delete(oldestKey);
38
+ evictions++;
39
+ }
40
+ }
41
+ const manager = {
42
+ config,
43
+ async get(key) {
44
+ const fullKey = prefixKey(key);
45
+ const entry = store.get(fullKey);
46
+ if (!entry) {
47
+ misses++;
48
+ return void 0;
49
+ }
50
+ if (isExpired(entry)) {
51
+ store.delete(fullKey);
52
+ misses++;
53
+ return void 0;
54
+ }
55
+ entry.hits++;
56
+ hits++;
57
+ return {
58
+ key: entry.key,
59
+ value: entry.value,
60
+ createdAt: entry.createdAt,
61
+ expiresAt: entry.expiresAt,
62
+ hits: entry.hits
63
+ };
64
+ },
65
+ async set(key, value, ttl) {
66
+ const fullKey = prefixKey(key);
67
+ const resolvedTTL = resolveTTL(key, ttl);
68
+ const now = Date.now();
69
+ if (!store.has(fullKey) && store.size >= config.maxEntries) {
70
+ evictOldest();
71
+ }
72
+ const entry = {
73
+ key,
74
+ value,
75
+ createdAt: now,
76
+ expiresAt: now + resolvedTTL,
77
+ hits: 0
78
+ };
79
+ store.set(fullKey, entry);
80
+ },
81
+ async delete(key) {
82
+ const fullKey = prefixKey(key);
83
+ return store.delete(fullKey);
84
+ },
85
+ async invalidate(pattern) {
86
+ let count = 0;
87
+ const prefixed = prefixKey(pattern);
88
+ for (const key of [...store.keys()]) {
89
+ if (key.startsWith(prefixed)) {
90
+ store.delete(key);
91
+ count++;
92
+ }
93
+ }
94
+ return count;
95
+ },
96
+ async has(key) {
97
+ const fullKey = prefixKey(key);
98
+ const entry = store.get(fullKey);
99
+ if (!entry) return false;
100
+ if (isExpired(entry)) {
101
+ store.delete(fullKey);
102
+ return false;
103
+ }
104
+ return true;
105
+ },
106
+ async warm(entries) {
107
+ for (const entry of entries) {
108
+ await manager.set(entry.key, entry.value, entry.ttl);
109
+ }
110
+ },
111
+ getMetrics() {
112
+ const total = hits + misses;
113
+ return {
114
+ hits,
115
+ misses,
116
+ hitRate: total === 0 ? 0 : hits / total,
117
+ totalEntries: store.size,
118
+ evictions
119
+ };
120
+ },
121
+ resetMetrics() {
122
+ hits = 0;
123
+ misses = 0;
124
+ evictions = 0;
125
+ },
126
+ async clear() {
127
+ store.clear();
128
+ }
129
+ };
130
+ return manager;
131
+ }
132
+
133
+ // src/performance/query-cost-tracker.ts
134
+ function createQueryCostTracker(config) {
135
+ let entries = [];
136
+ function pruneExpired() {
137
+ const cutoff = Date.now() - config.trackingWindowMs;
138
+ entries = entries.filter((e) => e.timestamp >= cutoff);
139
+ }
140
+ function computeCostPerSecond() {
141
+ if (entries.length === 0) return 0;
142
+ let totalCost = 0;
143
+ for (const entry of entries) {
144
+ totalCost += entry.actualCost;
145
+ }
146
+ const windowSeconds = config.trackingWindowMs / 1e3;
147
+ return totalCost / windowSeconds;
148
+ }
149
+ const tracker = {
150
+ config,
151
+ track(query, actualCost, requestedCost) {
152
+ entries.push({
153
+ query,
154
+ actualCost,
155
+ requestedCost,
156
+ timestamp: Date.now()
157
+ });
158
+ pruneExpired();
159
+ },
160
+ getReport() {
161
+ pruneExpired();
162
+ if (entries.length === 0) {
163
+ return {
164
+ totalCost: 0,
165
+ averageCost: 0,
166
+ maxCost: 0,
167
+ queryCount: 0,
168
+ costPerSecond: 0,
169
+ topQueries: [],
170
+ isOverBudget: false
171
+ };
172
+ }
173
+ let totalCost = 0;
174
+ let maxCost = 0;
175
+ for (const entry of entries) {
176
+ totalCost += entry.actualCost;
177
+ if (entry.actualCost > maxCost) {
178
+ maxCost = entry.actualCost;
179
+ }
180
+ }
181
+ const queryCount = entries.length;
182
+ const averageCost = totalCost / queryCount;
183
+ const costPerSecond = computeCostPerSecond();
184
+ const topQueries = [...entries].sort((a, b) => b.actualCost - a.actualCost).slice(0, 10);
185
+ return {
186
+ totalCost,
187
+ averageCost,
188
+ maxCost,
189
+ queryCount,
190
+ costPerSecond,
191
+ topQueries,
192
+ isOverBudget: costPerSecond > config.maxCostPerSecond
193
+ };
194
+ },
195
+ isWithinBudget() {
196
+ pruneExpired();
197
+ return computeCostPerSecond() <= config.maxCostPerSecond;
198
+ },
199
+ getCostPerSecond() {
200
+ pruneExpired();
201
+ return computeCostPerSecond();
202
+ },
203
+ reset() {
204
+ entries = [];
205
+ }
206
+ };
207
+ return tracker;
208
+ }
209
+
210
+ // src/performance/query-batcher.ts
211
+ function createQueryBatcher(config, executor) {
212
+ let pending = [];
213
+ let timer;
214
+ function scheduleFlush() {
215
+ if (timer !== void 0) return;
216
+ const delay = config.maxDelayMs !== void 0 ? Math.min(config.delayMs, config.maxDelayMs) : config.delayMs;
217
+ timer = setTimeout(() => {
218
+ timer = void 0;
219
+ void batcher.flush();
220
+ }, delay);
221
+ }
222
+ function clearTimer() {
223
+ if (timer !== void 0) {
224
+ clearTimeout(timer);
225
+ timer = void 0;
226
+ }
227
+ }
228
+ const batcher = {
229
+ config,
230
+ add(query) {
231
+ return new Promise((resolve, reject) => {
232
+ pending.push({ query, resolve, reject });
233
+ if (pending.length >= config.maxBatchSize) {
234
+ clearTimer();
235
+ void batcher.flush();
236
+ } else {
237
+ scheduleFlush();
238
+ }
239
+ });
240
+ },
241
+ async flush() {
242
+ clearTimer();
243
+ const batch = pending;
244
+ pending = [];
245
+ if (batch.length === 0) {
246
+ return {
247
+ results: [],
248
+ batchSize: 0,
249
+ executionTimeMs: 0
250
+ };
251
+ }
252
+ const queries = batch.map((p) => p.query);
253
+ const startTime = Date.now();
254
+ try {
255
+ const results = await executor(queries);
256
+ const executionTimeMs = Date.now() - startTime;
257
+ for (let i = 0; i < batch.length; i++) {
258
+ const item = batch[i];
259
+ if (item) {
260
+ item.resolve(results[i]);
261
+ }
262
+ }
263
+ return {
264
+ results,
265
+ batchSize: batch.length,
266
+ executionTimeMs
267
+ };
268
+ } catch (error) {
269
+ for (const item of batch) {
270
+ item.reject(error);
271
+ }
272
+ return {
273
+ results: [],
274
+ batchSize: batch.length,
275
+ executionTimeMs: Date.now() - startTime
276
+ };
277
+ }
278
+ },
279
+ pending() {
280
+ return pending.length;
281
+ }
282
+ };
283
+ return batcher;
284
+ }
285
+ export {
286
+ createCacheManager,
287
+ createQueryBatcher,
288
+ createQueryCostTracker
289
+ };
290
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/performance/cache-manager.ts","../../src/performance/query-cost-tracker.ts","../../src/performance/query-batcher.ts"],"sourcesContent":["/**\n * In-memory cache manager implementation.\n *\n * Provides TTL-based caching with strategy-based TTL matching,\n * LRU-style eviction, and performance metrics tracking.\n */\n\nimport type {\n CacheManagerConfig,\n CacheEntry,\n CacheMetrics,\n} from '@uniforge/platform-core/performance';\nimport type { CacheManager } from '@uniforge/platform-core/performance';\n\ninterface InternalEntry<T = unknown> {\n key: string;\n value: T;\n createdAt: number;\n expiresAt: number;\n hits: number;\n}\n\n/** Create an in-memory CacheManager. */\nexport function createCacheManager(config: CacheManagerConfig): CacheManager {\n const store = new Map<string, InternalEntry>();\n\n let hits = 0;\n let misses = 0;\n let evictions = 0;\n\n function resolveTTL(key: string, ttlOverride?: number): number {\n if (ttlOverride !== undefined) return ttlOverride;\n\n if (config.strategies !== undefined) {\n for (const strategy of config.strategies) {\n if (key.startsWith(strategy.pattern)) {\n return strategy.ttl;\n }\n }\n }\n\n return config.defaultTTL;\n }\n\n function prefixKey(key: string): string {\n if (config.keyPrefix !== undefined) {\n return `${config.keyPrefix}:${key}`;\n }\n return key;\n }\n\n function isExpired(entry: InternalEntry): boolean {\n return Date.now() >= entry.expiresAt;\n }\n\n function evictOldest(): void {\n // Evict the oldest entry by createdAt\n let oldestKey: string | undefined;\n let oldestTime = Infinity;\n\n for (const [k, v] of store) {\n if (v.createdAt < oldestTime) {\n oldestTime = v.createdAt;\n oldestKey = k;\n }\n }\n\n if (oldestKey !== undefined) {\n store.delete(oldestKey);\n evictions++;\n }\n }\n\n const manager: CacheManager = {\n config,\n\n async get<T = unknown>(key: string): Promise<CacheEntry<T> | undefined> {\n const fullKey = prefixKey(key);\n const entry = store.get(fullKey) as InternalEntry<T> | undefined;\n\n if (!entry) {\n misses++;\n return undefined;\n }\n\n if (isExpired(entry)) {\n store.delete(fullKey);\n misses++;\n return undefined;\n }\n\n entry.hits++;\n hits++;\n\n return {\n key: entry.key,\n value: entry.value,\n createdAt: entry.createdAt,\n expiresAt: entry.expiresAt,\n hits: entry.hits,\n };\n },\n\n async set<T = unknown>(key: string, value: T, ttl?: number): Promise<void> {\n const fullKey = prefixKey(key);\n const resolvedTTL = resolveTTL(key, ttl);\n const now = Date.now();\n\n // If the key already exists, update in place (no eviction needed)\n if (!store.has(fullKey) && store.size >= config.maxEntries) {\n evictOldest();\n }\n\n const entry: InternalEntry<T> = {\n key,\n value,\n createdAt: now,\n expiresAt: now + resolvedTTL,\n hits: 0,\n };\n\n store.set(fullKey, entry as InternalEntry);\n },\n\n async delete(key: string): Promise<boolean> {\n const fullKey = prefixKey(key);\n return store.delete(fullKey);\n },\n\n async invalidate(pattern: string): Promise<number> {\n let count = 0;\n const prefixed = prefixKey(pattern);\n\n for (const key of [...store.keys()]) {\n if (key.startsWith(prefixed)) {\n store.delete(key);\n count++;\n }\n }\n\n return count;\n },\n\n async has(key: string): Promise<boolean> {\n const fullKey = prefixKey(key);\n const entry = store.get(fullKey);\n\n if (!entry) return false;\n\n if (isExpired(entry)) {\n store.delete(fullKey);\n return false;\n }\n\n return true;\n },\n\n async warm(entries: Array<{ key: string; value: unknown; ttl?: number }>): Promise<void> {\n for (const entry of entries) {\n await manager.set(entry.key, entry.value, entry.ttl);\n }\n },\n\n getMetrics(): CacheMetrics {\n const total = hits + misses;\n return {\n hits,\n misses,\n hitRate: total === 0 ? 0 : hits / total,\n totalEntries: store.size,\n evictions,\n };\n },\n\n resetMetrics(): void {\n hits = 0;\n misses = 0;\n evictions = 0;\n },\n\n async clear(): Promise<void> {\n store.clear();\n },\n };\n\n return manager;\n}\n","/**\n * Query cost tracker implementation.\n *\n * Tracks GraphQL query costs within a sliding time window\n * and provides budget monitoring to prevent API throttling.\n */\n\nimport type {\n QueryCostConfig,\n QueryCostEntry,\n QueryCostReport,\n} from '@uniforge/platform-core/performance';\nimport type { QueryCostTracker } from '@uniforge/platform-core/performance';\n\n/** Create a QueryCostTracker that monitors query costs within a sliding window. */\nexport function createQueryCostTracker(config: QueryCostConfig): QueryCostTracker {\n let entries: QueryCostEntry[] = [];\n\n function pruneExpired(): void {\n const cutoff = Date.now() - config.trackingWindowMs;\n entries = entries.filter((e) => e.timestamp >= cutoff);\n }\n\n function computeCostPerSecond(): number {\n if (entries.length === 0) return 0;\n\n let totalCost = 0;\n for (const entry of entries) {\n totalCost += entry.actualCost;\n }\n\n const windowSeconds = config.trackingWindowMs / 1000;\n return totalCost / windowSeconds;\n }\n\n const tracker: QueryCostTracker = {\n config,\n\n track(query: string, actualCost: number, requestedCost: number): void {\n entries.push({\n query,\n actualCost,\n requestedCost,\n timestamp: Date.now(),\n });\n\n pruneExpired();\n },\n\n getReport(): QueryCostReport {\n pruneExpired();\n\n if (entries.length === 0) {\n return {\n totalCost: 0,\n averageCost: 0,\n maxCost: 0,\n queryCount: 0,\n costPerSecond: 0,\n topQueries: [],\n isOverBudget: false,\n };\n }\n\n let totalCost = 0;\n let maxCost = 0;\n\n for (const entry of entries) {\n totalCost += entry.actualCost;\n if (entry.actualCost > maxCost) {\n maxCost = entry.actualCost;\n }\n }\n\n const queryCount = entries.length;\n const averageCost = totalCost / queryCount;\n const costPerSecond = computeCostPerSecond();\n\n // Top queries sorted by actualCost descending, take top 10\n const topQueries = [...entries]\n .sort((a, b) => b.actualCost - a.actualCost)\n .slice(0, 10);\n\n return {\n totalCost,\n averageCost,\n maxCost,\n queryCount,\n costPerSecond,\n topQueries,\n isOverBudget: costPerSecond > config.maxCostPerSecond,\n };\n },\n\n isWithinBudget(): boolean {\n pruneExpired();\n return computeCostPerSecond() <= config.maxCostPerSecond;\n },\n\n getCostPerSecond(): number {\n pruneExpired();\n return computeCostPerSecond();\n },\n\n reset(): void {\n entries = [];\n },\n };\n\n return tracker;\n}\n","/**\n * Query batcher implementation.\n *\n * Collects individual queries into batches and executes them together,\n * reducing the number of API round-trips. Batches are flushed either\n * when they reach the configured size or after a delay timeout.\n */\n\nimport type { BatchConfig, BatchResult } from '@uniforge/platform-core/performance';\nimport type { QueryBatcher } from '@uniforge/platform-core/performance';\n\ninterface PendingQuery<TQuery, TResult> {\n query: TQuery;\n resolve: (result: TResult) => void;\n reject: (error: unknown) => void;\n}\n\n/** Create a QueryBatcher that groups queries and executes them in batches. */\nexport function createQueryBatcher<TQuery, TResult>(\n config: BatchConfig,\n executor: (queries: TQuery[]) => Promise<TResult[]>,\n): QueryBatcher<TQuery, TResult> {\n let pending: Array<PendingQuery<TQuery, TResult>> = [];\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n function scheduleFlush(): void {\n if (timer !== undefined) return;\n\n const delay = config.maxDelayMs !== undefined\n ? Math.min(config.delayMs, config.maxDelayMs)\n : config.delayMs;\n\n timer = setTimeout(() => {\n timer = undefined;\n void batcher.flush();\n }, delay);\n }\n\n function clearTimer(): void {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n }\n\n const batcher: QueryBatcher<TQuery, TResult> = {\n config,\n\n add(query: TQuery): Promise<TResult> {\n return new Promise<TResult>((resolve, reject) => {\n pending.push({ query, resolve, reject });\n\n if (pending.length >= config.maxBatchSize) {\n clearTimer();\n void batcher.flush();\n } else {\n scheduleFlush();\n }\n });\n },\n\n async flush(): Promise<BatchResult<TResult>> {\n clearTimer();\n\n const batch = pending;\n pending = [];\n\n if (batch.length === 0) {\n return {\n results: [],\n batchSize: 0,\n executionTimeMs: 0,\n };\n }\n\n const queries = batch.map((p) => p.query);\n const startTime = Date.now();\n\n try {\n const results = await executor(queries);\n const executionTimeMs = Date.now() - startTime;\n\n for (let i = 0; i < batch.length; i++) {\n const item = batch[i];\n if (item) {\n item.resolve(results[i] as TResult);\n }\n }\n\n return {\n results,\n batchSize: batch.length,\n executionTimeMs,\n };\n } catch (error) {\n for (const item of batch) {\n item.reject(error);\n }\n\n return {\n results: [],\n batchSize: batch.length,\n executionTimeMs: Date.now() - startTime,\n };\n }\n },\n\n pending(): number {\n return pending.length;\n },\n };\n\n return batcher;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,25 @@
1
+ import { PlatformRegistry, PlatformProvider, PlatformValidationResult } from '@uniforge/platform-core/platform';
2
+ import { U as UniforgeConfig } from '../schema-CM7mHj_H.cjs';
3
+
4
+ /**
5
+ * Create an in-memory platform registry.
6
+ *
7
+ * Stores platform providers keyed by their unique ID.
8
+ * Throws if a duplicate provider ID is registered.
9
+ */
10
+ declare function createPlatformRegistry(): PlatformRegistry;
11
+
12
+ /**
13
+ * Resolve the active platform provider from config.
14
+ *
15
+ * Reads `config.platform?.id` and looks it up in the registry.
16
+ * Returns `undefined` if no platform is configured or the ID is not found.
17
+ */
18
+ declare function resolvePlatformFromConfig(config: UniforgeConfig, registry: PlatformRegistry): PlatformProvider | undefined;
19
+ /**
20
+ * Validate that the UniforgeConfig has the required fields for
21
+ * the given provider's capabilities.
22
+ */
23
+ declare function validatePlatformConfig(config: UniforgeConfig, provider: PlatformProvider): PlatformValidationResult;
24
+
25
+ export { createPlatformRegistry, resolvePlatformFromConfig, validatePlatformConfig };
@@ -0,0 +1,25 @@
1
+ import { PlatformRegistry, PlatformProvider, PlatformValidationResult } from '@uniforge/platform-core/platform';
2
+ import { U as UniforgeConfig } from '../schema-CM7mHj_H.js';
3
+
4
+ /**
5
+ * Create an in-memory platform registry.
6
+ *
7
+ * Stores platform providers keyed by their unique ID.
8
+ * Throws if a duplicate provider ID is registered.
9
+ */
10
+ declare function createPlatformRegistry(): PlatformRegistry;
11
+
12
+ /**
13
+ * Resolve the active platform provider from config.
14
+ *
15
+ * Reads `config.platform?.id` and looks it up in the registry.
16
+ * Returns `undefined` if no platform is configured or the ID is not found.
17
+ */
18
+ declare function resolvePlatformFromConfig(config: UniforgeConfig, registry: PlatformRegistry): PlatformProvider | undefined;
19
+ /**
20
+ * Validate that the UniforgeConfig has the required fields for
21
+ * the given provider's capabilities.
22
+ */
23
+ declare function validatePlatformConfig(config: UniforgeConfig, provider: PlatformProvider): PlatformValidationResult;
24
+
25
+ export { createPlatformRegistry, resolvePlatformFromConfig, validatePlatformConfig };
@@ -0,0 +1,91 @@
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/platform/index.ts
21
+ var platform_exports = {};
22
+ __export(platform_exports, {
23
+ createPlatformRegistry: () => createPlatformRegistry,
24
+ resolvePlatformFromConfig: () => resolvePlatformFromConfig,
25
+ validatePlatformConfig: () => validatePlatformConfig
26
+ });
27
+ module.exports = __toCommonJS(platform_exports);
28
+
29
+ // src/platform/registry.ts
30
+ function createPlatformRegistry() {
31
+ const providers = /* @__PURE__ */ new Map();
32
+ return {
33
+ register(provider) {
34
+ if (providers.has(provider.id)) {
35
+ throw new Error(
36
+ `Platform provider "${provider.id}" is already registered`
37
+ );
38
+ }
39
+ providers.set(provider.id, provider);
40
+ },
41
+ get(platformId) {
42
+ return providers.get(platformId);
43
+ },
44
+ has(platformId) {
45
+ return providers.has(platformId);
46
+ },
47
+ list() {
48
+ return Array.from(providers.keys());
49
+ },
50
+ getAll() {
51
+ return Array.from(providers.values());
52
+ }
53
+ };
54
+ }
55
+
56
+ // src/platform/config.ts
57
+ function resolvePlatformFromConfig(config, registry) {
58
+ const platformId = config.platform?.id;
59
+ if (!platformId) {
60
+ return void 0;
61
+ }
62
+ return registry.get(platformId);
63
+ }
64
+ function validatePlatformConfig(config, provider) {
65
+ const errors = [];
66
+ if (provider.supportsBilling() && !config.billing) {
67
+ errors.push({
68
+ field: "billing",
69
+ message: "Billing configuration is required when billing is supported",
70
+ code: "MISSING_BILLING_CONFIG"
71
+ });
72
+ }
73
+ if (provider.supportsMultiStore() && !config.multiStore) {
74
+ errors.push({
75
+ field: "multiStore",
76
+ message: "Multi-store configuration is required when multi-store is supported",
77
+ code: "MISSING_MULTI_STORE_CONFIG"
78
+ });
79
+ }
80
+ return {
81
+ valid: errors.length === 0,
82
+ errors
83
+ };
84
+ }
85
+ // Annotate the CommonJS export names for ESM import in node:
86
+ 0 && (module.exports = {
87
+ createPlatformRegistry,
88
+ resolvePlatformFromConfig,
89
+ validatePlatformConfig
90
+ });
91
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/platform/index.ts","../../src/platform/registry.ts","../../src/platform/config.ts"],"sourcesContent":["export { createPlatformRegistry } from './registry';\nexport { resolvePlatformFromConfig, validatePlatformConfig } from './config';\n","import type {\n PlatformRegistry,\n PlatformProvider,\n PlatformId,\n} from '@uniforge/platform-core/platform';\n\n/**\n * Create an in-memory platform registry.\n *\n * Stores platform providers keyed by their unique ID.\n * Throws if a duplicate provider ID is registered.\n */\nexport function createPlatformRegistry(): PlatformRegistry {\n const providers = new Map<PlatformId, PlatformProvider>();\n\n return {\n register(provider: PlatformProvider): void {\n if (providers.has(provider.id)) {\n throw new Error(\n `Platform provider \"${provider.id}\" is already registered`,\n );\n }\n providers.set(provider.id, provider);\n },\n\n get(platformId: PlatformId): PlatformProvider | undefined {\n return providers.get(platformId);\n },\n\n has(platformId: PlatformId): boolean {\n return providers.has(platformId);\n },\n\n list(): PlatformId[] {\n return Array.from(providers.keys());\n },\n\n getAll(): PlatformProvider[] {\n return Array.from(providers.values());\n },\n };\n}\n","import type {\n PlatformRegistry,\n PlatformProvider,\n PlatformValidationResult,\n PlatformValidationError,\n} from '@uniforge/platform-core/platform';\nimport type { UniforgeConfig } from '../config/schema';\n\n/**\n * Resolve the active platform provider from config.\n *\n * Reads `config.platform?.id` and looks it up in the registry.\n * Returns `undefined` if no platform is configured or the ID is not found.\n */\nexport function resolvePlatformFromConfig(\n config: UniforgeConfig,\n registry: PlatformRegistry,\n): PlatformProvider | undefined {\n const platformId = config.platform?.id;\n if (!platformId) {\n return undefined;\n }\n return registry.get(platformId);\n}\n\n/**\n * Validate that the UniforgeConfig has the required fields for\n * the given provider's capabilities.\n */\nexport function validatePlatformConfig(\n config: UniforgeConfig,\n provider: PlatformProvider,\n): PlatformValidationResult {\n const errors: PlatformValidationError[] = [];\n\n if (provider.supportsBilling() && !config.billing) {\n errors.push({\n field: 'billing',\n message: 'Billing configuration is required when billing is supported',\n code: 'MISSING_BILLING_CONFIG',\n });\n }\n\n if (provider.supportsMultiStore() && !config.multiStore) {\n errors.push({\n field: 'multiStore',\n message:\n 'Multi-store configuration is required when multi-store is supported',\n code: 'MISSING_MULTI_STORE_CONFIG',\n });\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACYO,SAAS,yBAA2C;AACzD,QAAM,YAAY,oBAAI,IAAkC;AAExD,SAAO;AAAA,IACL,SAAS,UAAkC;AACzC,UAAI,UAAU,IAAI,SAAS,EAAE,GAAG;AAC9B,cAAM,IAAI;AAAA,UACR,sBAAsB,SAAS,EAAE;AAAA,QACnC;AAAA,MACF;AACA,gBAAU,IAAI,SAAS,IAAI,QAAQ;AAAA,IACrC;AAAA,IAEA,IAAI,YAAsD;AACxD,aAAO,UAAU,IAAI,UAAU;AAAA,IACjC;AAAA,IAEA,IAAI,YAAiC;AACnC,aAAO,UAAU,IAAI,UAAU;AAAA,IACjC;AAAA,IAEA,OAAqB;AACnB,aAAO,MAAM,KAAK,UAAU,KAAK,CAAC;AAAA,IACpC;AAAA,IAEA,SAA6B;AAC3B,aAAO,MAAM,KAAK,UAAU,OAAO,CAAC;AAAA,IACtC;AAAA,EACF;AACF;;;AC3BO,SAAS,0BACd,QACA,UAC8B;AAC9B,QAAM,aAAa,OAAO,UAAU;AACpC,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AACA,SAAO,SAAS,IAAI,UAAU;AAChC;AAMO,SAAS,uBACd,QACA,UAC0B;AAC1B,QAAM,SAAoC,CAAC;AAE3C,MAAI,SAAS,gBAAgB,KAAK,CAAC,OAAO,SAAS;AACjD,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,MAAI,SAAS,mBAAmB,KAAK,CAAC,OAAO,YAAY;AACvD,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,62 @@
1
+ // src/platform/registry.ts
2
+ function createPlatformRegistry() {
3
+ const providers = /* @__PURE__ */ new Map();
4
+ return {
5
+ register(provider) {
6
+ if (providers.has(provider.id)) {
7
+ throw new Error(
8
+ `Platform provider "${provider.id}" is already registered`
9
+ );
10
+ }
11
+ providers.set(provider.id, provider);
12
+ },
13
+ get(platformId) {
14
+ return providers.get(platformId);
15
+ },
16
+ has(platformId) {
17
+ return providers.has(platformId);
18
+ },
19
+ list() {
20
+ return Array.from(providers.keys());
21
+ },
22
+ getAll() {
23
+ return Array.from(providers.values());
24
+ }
25
+ };
26
+ }
27
+
28
+ // src/platform/config.ts
29
+ function resolvePlatformFromConfig(config, registry) {
30
+ const platformId = config.platform?.id;
31
+ if (!platformId) {
32
+ return void 0;
33
+ }
34
+ return registry.get(platformId);
35
+ }
36
+ function validatePlatformConfig(config, provider) {
37
+ const errors = [];
38
+ if (provider.supportsBilling() && !config.billing) {
39
+ errors.push({
40
+ field: "billing",
41
+ message: "Billing configuration is required when billing is supported",
42
+ code: "MISSING_BILLING_CONFIG"
43
+ });
44
+ }
45
+ if (provider.supportsMultiStore() && !config.multiStore) {
46
+ errors.push({
47
+ field: "multiStore",
48
+ message: "Multi-store configuration is required when multi-store is supported",
49
+ code: "MISSING_MULTI_STORE_CONFIG"
50
+ });
51
+ }
52
+ return {
53
+ valid: errors.length === 0,
54
+ errors
55
+ };
56
+ }
57
+ export {
58
+ createPlatformRegistry,
59
+ resolvePlatformFromConfig,
60
+ validatePlatformConfig
61
+ };
62
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/platform/registry.ts","../../src/platform/config.ts"],"sourcesContent":["import type {\n PlatformRegistry,\n PlatformProvider,\n PlatformId,\n} from '@uniforge/platform-core/platform';\n\n/**\n * Create an in-memory platform registry.\n *\n * Stores platform providers keyed by their unique ID.\n * Throws if a duplicate provider ID is registered.\n */\nexport function createPlatformRegistry(): PlatformRegistry {\n const providers = new Map<PlatformId, PlatformProvider>();\n\n return {\n register(provider: PlatformProvider): void {\n if (providers.has(provider.id)) {\n throw new Error(\n `Platform provider \"${provider.id}\" is already registered`,\n );\n }\n providers.set(provider.id, provider);\n },\n\n get(platformId: PlatformId): PlatformProvider | undefined {\n return providers.get(platformId);\n },\n\n has(platformId: PlatformId): boolean {\n return providers.has(platformId);\n },\n\n list(): PlatformId[] {\n return Array.from(providers.keys());\n },\n\n getAll(): PlatformProvider[] {\n return Array.from(providers.values());\n },\n };\n}\n","import type {\n PlatformRegistry,\n PlatformProvider,\n PlatformValidationResult,\n PlatformValidationError,\n} from '@uniforge/platform-core/platform';\nimport type { UniforgeConfig } from '../config/schema';\n\n/**\n * Resolve the active platform provider from config.\n *\n * Reads `config.platform?.id` and looks it up in the registry.\n * Returns `undefined` if no platform is configured or the ID is not found.\n */\nexport function resolvePlatformFromConfig(\n config: UniforgeConfig,\n registry: PlatformRegistry,\n): PlatformProvider | undefined {\n const platformId = config.platform?.id;\n if (!platformId) {\n return undefined;\n }\n return registry.get(platformId);\n}\n\n/**\n * Validate that the UniforgeConfig has the required fields for\n * the given provider's capabilities.\n */\nexport function validatePlatformConfig(\n config: UniforgeConfig,\n provider: PlatformProvider,\n): PlatformValidationResult {\n const errors: PlatformValidationError[] = [];\n\n if (provider.supportsBilling() && !config.billing) {\n errors.push({\n field: 'billing',\n message: 'Billing configuration is required when billing is supported',\n code: 'MISSING_BILLING_CONFIG',\n });\n }\n\n if (provider.supportsMultiStore() && !config.multiStore) {\n errors.push({\n field: 'multiStore',\n message:\n 'Multi-store configuration is required when multi-store is supported',\n code: 'MISSING_MULTI_STORE_CONFIG',\n });\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n"],"mappings":";AAYO,SAAS,yBAA2C;AACzD,QAAM,YAAY,oBAAI,IAAkC;AAExD,SAAO;AAAA,IACL,SAAS,UAAkC;AACzC,UAAI,UAAU,IAAI,SAAS,EAAE,GAAG;AAC9B,cAAM,IAAI;AAAA,UACR,sBAAsB,SAAS,EAAE;AAAA,QACnC;AAAA,MACF;AACA,gBAAU,IAAI,SAAS,IAAI,QAAQ;AAAA,IACrC;AAAA,IAEA,IAAI,YAAsD;AACxD,aAAO,UAAU,IAAI,UAAU;AAAA,IACjC;AAAA,IAEA,IAAI,YAAiC;AACnC,aAAO,UAAU,IAAI,UAAU;AAAA,IACjC;AAAA,IAEA,OAAqB;AACnB,aAAO,MAAM,KAAK,UAAU,KAAK,CAAC;AAAA,IACpC;AAAA,IAEA,SAA6B;AAC3B,aAAO,MAAM,KAAK,UAAU,OAAO,CAAC;AAAA,IACtC;AAAA,EACF;AACF;;;AC3BO,SAAS,0BACd,QACA,UAC8B;AAC9B,QAAM,aAAa,OAAO,UAAU;AACpC,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AACA,SAAO,SAAS,IAAI,UAAU;AAChC;AAMO,SAAS,uBACd,QACA,UAC0B;AAC1B,QAAM,SAAoC,CAAC;AAE3C,MAAI,SAAS,gBAAgB,KAAK,CAAC,OAAO,SAAS;AACjD,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,MAAI,SAAS,mBAAmB,KAAK,CAAC,OAAO,YAAY;AACvD,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,SACE;AAAA,MACF,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,24 @@
1
+ import { RolePermissionMap, Role, RBACService, RBACMiddlewareConfig, RBACMiddleware } from '@uniforge/platform-core/rbac';
2
+ import { PrismaClient } from '@prisma/client';
3
+
4
+ /**
5
+ * Default role permissions and permission resolution.
6
+ */
7
+
8
+ declare const DEFAULT_ROLE_PERMISSIONS: RolePermissionMap;
9
+ declare function resolvePermissions(role: Role, customPermissions?: string[] | null): string[];
10
+ declare function isRoleAtLeast(role: Role, minimumRole: Role): boolean;
11
+
12
+ /**
13
+ * Prisma-backed RBAC service for shop member management and permission checks.
14
+ */
15
+
16
+ declare function createRBACService(prisma: PrismaClient): RBACService;
17
+
18
+ /**
19
+ * RBAC middleware for route-level permission enforcement.
20
+ */
21
+
22
+ declare function createRBACMiddleware(config: RBACMiddlewareConfig): RBACMiddleware;
23
+
24
+ export { DEFAULT_ROLE_PERMISSIONS, createRBACMiddleware, createRBACService, isRoleAtLeast, resolvePermissions };
@@ -0,0 +1,24 @@
1
+ import { RolePermissionMap, Role, RBACService, RBACMiddlewareConfig, RBACMiddleware } from '@uniforge/platform-core/rbac';
2
+ import { PrismaClient } from '@prisma/client';
3
+
4
+ /**
5
+ * Default role permissions and permission resolution.
6
+ */
7
+
8
+ declare const DEFAULT_ROLE_PERMISSIONS: RolePermissionMap;
9
+ declare function resolvePermissions(role: Role, customPermissions?: string[] | null): string[];
10
+ declare function isRoleAtLeast(role: Role, minimumRole: Role): boolean;
11
+
12
+ /**
13
+ * Prisma-backed RBAC service for shop member management and permission checks.
14
+ */
15
+
16
+ declare function createRBACService(prisma: PrismaClient): RBACService;
17
+
18
+ /**
19
+ * RBAC middleware for route-level permission enforcement.
20
+ */
21
+
22
+ declare function createRBACMiddleware(config: RBACMiddlewareConfig): RBACMiddleware;
23
+
24
+ export { DEFAULT_ROLE_PERMISSIONS, createRBACMiddleware, createRBACService, isRoleAtLeast, resolvePermissions };