@reactionary/provider-fake 0.0.31 → 0.0.33

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/index.js CHANGED
@@ -1,245 +1,15 @@
1
1
  // core/src/cache/redis-cache.ts
2
2
  import { Redis } from "@upstash/redis";
3
3
 
4
- // otel/src/trpc-middleware.ts
5
- import { TRPCError } from "@trpc/server";
6
- import {
7
- SpanKind as SpanKind2,
8
- SpanStatusCode as SpanStatusCode3
9
- } from "@opentelemetry/api";
10
-
11
- // otel/src/tracer.ts
12
- import {
13
- trace,
14
- SpanStatusCode,
15
- context as otelContext
16
- } from "@opentelemetry/api";
17
-
18
- // otel/src/sdk.ts
19
- import { NodeSDK } from "@opentelemetry/sdk-node";
20
- var sdk = null;
21
- var isInitialized = false;
22
- var initializationPromise = null;
23
- function isBrowser() {
24
- return typeof window !== "undefined" && typeof process === "undefined";
25
- }
26
- function ensureInitialized() {
27
- if (isInitialized || initializationPromise) {
28
- return;
29
- }
30
- if (isBrowser()) {
31
- isInitialized = true;
32
- return;
33
- }
34
- initializationPromise = Promise.resolve().then(() => {
35
- sdk = new NodeSDK();
36
- sdk.start();
37
- isInitialized = true;
38
- process.on("SIGTERM", async () => {
39
- try {
40
- await shutdownOtel();
41
- if (process.env["OTEL_LOG_LEVEL"] === "debug") {
42
- console.log("OpenTelemetry terminated successfully");
43
- }
44
- } catch (error) {
45
- console.error("Error terminating OpenTelemetry", error);
46
- }
47
- });
48
- });
49
- }
50
- async function shutdownOtel() {
51
- if (sdk) {
52
- await sdk.shutdown();
53
- sdk = null;
54
- isInitialized = false;
55
- }
56
- }
57
- function isOtelInitialized() {
58
- ensureInitialized();
59
- return isInitialized;
60
- }
61
-
62
- // otel/src/tracer.ts
63
- import { SpanKind, SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
64
- var TRACER_NAME = "@reactionary/otel";
65
- var TRACER_VERSION = "0.0.1";
66
- var globalTracer = null;
67
- function getTracer() {
68
- if (!globalTracer) {
69
- isOtelInitialized();
70
- globalTracer = trace.getTracer(TRACER_NAME, TRACER_VERSION);
71
- }
72
- return globalTracer;
73
- }
74
- function withSpan(name, fn, options) {
75
- const tracer = getTracer();
76
- return tracer.startActiveSpan(name, options || {}, async (span) => {
77
- try {
78
- const result = await fn(span);
79
- span.setStatus({ code: SpanStatusCode.OK });
80
- return result;
81
- } catch (error) {
82
- span.setStatus({
83
- code: SpanStatusCode.ERROR,
84
- message: error instanceof Error ? error.message : String(error)
85
- });
86
- if (error instanceof Error) {
87
- span.recordException(error);
88
- }
89
- throw error;
90
- } finally {
91
- span.end();
92
- }
93
- });
94
- }
95
- function setSpanAttributes(span, attributes) {
96
- Object.entries(attributes).forEach(([key, value]) => {
97
- if (value !== void 0 && value !== null) {
98
- span.setAttribute(key, value);
99
- }
100
- });
101
- }
102
-
103
- // otel/src/metrics.ts
104
- import { metrics } from "@opentelemetry/api";
105
- var METER_NAME = "@reactionary/otel";
106
- var METER_VERSION = "0.0.1";
107
- var globalMeter = null;
108
- function getMeter() {
109
- if (!globalMeter) {
110
- isOtelInitialized();
111
- globalMeter = metrics.getMeter(METER_NAME, METER_VERSION);
112
- }
113
- return globalMeter;
114
- }
115
- var metricsInstance = null;
116
- function initializeMetrics() {
117
- if (metricsInstance) {
118
- return metricsInstance;
119
- }
120
- const meter = getMeter();
121
- metricsInstance = {
122
- requestCounter: meter.createCounter("reactionary.requests", {
123
- description: "Total number of requests"
124
- }),
125
- requestDuration: meter.createHistogram("reactionary.request.duration", {
126
- description: "Request duration in milliseconds",
127
- unit: "ms"
128
- }),
129
- activeRequests: meter.createUpDownCounter("reactionary.requests.active", {
130
- description: "Number of active requests"
131
- }),
132
- errorCounter: meter.createCounter("reactionary.errors", {
133
- description: "Total number of errors"
134
- }),
135
- providerCallCounter: meter.createCounter("reactionary.provider.calls", {
136
- description: "Total number of provider calls"
137
- }),
138
- providerCallDuration: meter.createHistogram("reactionary.provider.duration", {
139
- description: "Provider call duration in milliseconds",
140
- unit: "ms"
141
- }),
142
- cacheHitCounter: meter.createCounter("reactionary.cache.hits", {
143
- description: "Total number of cache hits"
144
- }),
145
- cacheMissCounter: meter.createCounter("reactionary.cache.misses", {
146
- description: "Total number of cache misses"
147
- })
148
- };
149
- return metricsInstance;
150
- }
151
- function getMetrics() {
152
- if (!metricsInstance) {
153
- return initializeMetrics();
154
- }
155
- return metricsInstance;
156
- }
157
-
158
- // otel/src/provider-instrumentation.ts
159
- import { SpanKind as SpanKind3 } from "@opentelemetry/api";
160
- async function withProviderSpan(options, fn) {
161
- const { providerName, operationType, operationName, attributes = {} } = options;
162
- const metrics2 = getMetrics();
163
- const spanName = `provider.${providerName}.${operationType}${operationName ? `.${operationName}` : ""}`;
164
- const startTime = Date.now();
165
- metrics2.providerCallCounter.add(1, {
166
- "provider.name": providerName,
167
- "provider.operation.type": operationType,
168
- "provider.operation.name": operationName || "unknown"
169
- });
170
- return withSpan(
171
- spanName,
172
- async (span) => {
173
- setSpanAttributes(span, {
174
- "provider.name": providerName,
175
- "provider.operation.type": operationType,
176
- "provider.operation.name": operationName,
177
- ...attributes
178
- });
179
- try {
180
- const result = await fn(span);
181
- const duration = Date.now() - startTime;
182
- metrics2.providerCallDuration.record(duration, {
183
- "provider.name": providerName,
184
- "provider.operation.type": operationType,
185
- "provider.operation.name": operationName || "unknown",
186
- "status": "success"
187
- });
188
- return result;
189
- } catch (error) {
190
- const duration = Date.now() - startTime;
191
- metrics2.providerCallDuration.record(duration, {
192
- "provider.name": providerName,
193
- "provider.operation.type": operationType,
194
- "provider.operation.name": operationName || "unknown",
195
- "status": "error"
196
- });
197
- metrics2.errorCounter.add(1, {
198
- "provider.name": providerName,
199
- "provider.operation.type": operationType,
200
- "provider.operation.name": operationName || "unknown"
201
- });
202
- throw error;
203
- }
204
- },
205
- { kind: SpanKind3.CLIENT }
206
- );
207
- }
208
- function createProviderInstrumentation(providerName) {
209
- return {
210
- traceQuery: (operationName, fn, attributes) => {
211
- return withProviderSpan(
212
- {
213
- providerName,
214
- operationType: "query",
215
- operationName,
216
- attributes
217
- },
218
- fn
219
- );
220
- },
221
- traceMutation: (operationName, fn, attributes) => {
222
- return withProviderSpan(
223
- {
224
- providerName,
225
- operationType: "mutation",
226
- operationName,
227
- attributes
228
- },
229
- fn
230
- );
231
- }
232
- };
233
- }
4
+ // core/src/decorators/trpc.decorators.ts
5
+ import "reflect-metadata";
6
+ var TRPC_QUERY_METADATA_KEY = Symbol("trpc:query");
7
+ var TRPC_MUTATION_METADATA_KEY = Symbol("trpc:mutation");
234
8
 
235
9
  // core/src/providers/base.provider.ts
236
- import * as crypto from "crypto";
237
10
  var BaseProvider = class {
238
- constructor(schema, querySchema, mutationSchema, cache) {
11
+ constructor(schema, cache) {
239
12
  this.schema = schema;
240
- this.querySchema = querySchema;
241
- this.mutationSchema = mutationSchema;
242
- this.instrumentation = createProviderInstrumentation(this.constructor.name);
243
13
  this.cache = cache;
244
14
  }
245
15
  /**
@@ -256,144 +26,41 @@ var BaseProvider = class {
256
26
  return this.schema.parse({});
257
27
  }
258
28
  /**
259
- * Retrieves a set of entities matching the list of queries. The size of
260
- * the resulting list WILL always match the size of the query list. The
261
- * result list will never contain nulls or undefined. The order
262
- * of the results will match the order of the queries.
29
+ * Handler for parsing a response from a remote provider and converting it
30
+ * into the typed domain model.
263
31
  */
264
- async query(queries, session) {
265
- return this.instrumentation.traceQuery(
266
- "query",
267
- async (span) => {
268
- span.setAttribute("provider.query.count", queries.length);
269
- let cacheHits = 0;
270
- let cacheMisses = 0;
271
- const results = [];
272
- for (const query of queries) {
273
- let result = null;
274
- const cacheInfo = this.getCacheEvaluation(query, session);
275
- if (cacheInfo.canCache && cacheInfo.key) {
276
- try {
277
- result = await this.cache.get(cacheInfo.key, this.schema);
278
- if (result) {
279
- cacheHits++;
280
- span.setAttribute("provider.cache.hit", true);
281
- }
282
- } catch (error) {
283
- console.warn(`Cache get error for ${this.constructor.name}:`, error);
284
- }
285
- }
286
- if (!result) {
287
- const singleResult = await this.fetch([query], session);
288
- result = singleResult[0];
289
- cacheMisses++;
290
- if (result && cacheInfo.canCache && cacheInfo.key) {
291
- try {
292
- await this.cache.put(cacheInfo.key, result, cacheInfo.cacheDurationInSeconds);
293
- } catch (error) {
294
- console.warn(`Cache put error for ${this.constructor.name}:`, error);
295
- }
296
- }
297
- }
298
- if (result) {
299
- this.assert(result);
300
- results.push(result);
301
- }
302
- }
303
- span.setAttribute("provider.result.count", results.length);
304
- span.setAttribute("provider.cache.hits", cacheHits);
305
- span.setAttribute("provider.cache.misses", cacheMisses);
306
- span.setAttribute("provider.cache.hit_ratio", cacheHits / (cacheHits + cacheMisses));
307
- return results;
308
- },
309
- { queryCount: queries.length }
310
- );
311
- }
312
- /**
313
- * Executes the listed mutations in order and returns the final state
314
- * resulting from that set of operations.
315
- */
316
- async mutate(mutations, session) {
317
- return this.instrumentation.traceMutation(
318
- "mutate",
319
- async (span) => {
320
- span.setAttribute("provider.mutation.count", mutations.length);
321
- const result = await this.process(mutations, session);
322
- this.assert(result);
323
- return result;
324
- },
325
- { mutationCount: mutations.length }
326
- );
327
- }
328
- /**
329
- * Provider-specific cache evaluation logic.
330
- * Returns information about how this query should be cached.
331
- * Override this method to enable caching with custom keys and TTL.
332
- * Default implementation returns no caching.
333
- */
334
- getCacheEvaluation(query, session) {
335
- const providerName = this.constructor.name.toLowerCase();
336
- const userId = session.identity?.id || "anonymous";
337
- const queryHash = crypto.createHash("md5").update(JSON.stringify(query)).digest("hex").substring(0, 12);
338
- const key = `${providerName}:${userId}:${queryHash}`;
339
- return {
340
- key,
341
- cacheDurationInSeconds: 0,
342
- canCache: false
343
- };
32
+ parseSingle(_body) {
33
+ const model = this.newModel();
34
+ return this.assert(model);
344
35
  }
345
36
  };
346
37
 
38
+ // core/src/providers/analytics.provider.ts
39
+ var AnalyticsProvider = class extends BaseProvider {
40
+ };
41
+
42
+ // core/src/providers/cart.provider.ts
43
+ var CartProvider = class extends BaseProvider {
44
+ };
45
+
347
46
  // core/src/providers/identity.provider.ts
348
47
  var IdentityProvider = class extends BaseProvider {
349
- getCacheEvaluation(_query, session) {
350
- const providerName = this.constructor.name.toLowerCase();
351
- const userId = session.identity?.id;
352
- const key = userId ? `${providerName}:identity:${userId}` : `${providerName}:identity:anonymous`;
353
- return {
354
- key,
355
- cacheDurationInSeconds: 0,
356
- canCache: false
357
- };
358
- }
48
+ };
49
+
50
+ // core/src/providers/inventory.provider.ts
51
+ var InventoryProvider = class extends BaseProvider {
52
+ };
53
+
54
+ // core/src/providers/price.provider.ts
55
+ var PriceProvider = class extends BaseProvider {
359
56
  };
360
57
 
361
58
  // core/src/providers/product.provider.ts
362
- import * as crypto2 from "crypto";
363
59
  var ProductProvider = class extends BaseProvider {
364
- getCacheEvaluation(query, _session) {
365
- const providerName = this.constructor.name.toLowerCase();
366
- let key;
367
- if (query.query === "slug") {
368
- key = `${providerName}:product:slug:${query.slug}`;
369
- } else if (query.query === "id") {
370
- key = `${providerName}:product:id:${query.id}`;
371
- } else {
372
- const queryHash = crypto2.createHash("md5").update(JSON.stringify(query)).digest("hex").substring(0, 12);
373
- key = `${providerName}:product:${queryHash}`;
374
- }
375
- return {
376
- key,
377
- cacheDurationInSeconds: 300,
378
- // Products are moderately stable - 5 minutes
379
- canCache: true
380
- };
381
- }
382
60
  };
383
61
 
384
62
  // core/src/providers/search.provider.ts
385
- import * as crypto3 from "crypto";
386
63
  var SearchProvider = class extends BaseProvider {
387
- getCacheEvaluation(query, _session) {
388
- const providerName = this.constructor.name.toLowerCase();
389
- const searchHash = crypto3.createHash("md5").update(JSON.stringify(query.search)).digest("hex").substring(0, 12);
390
- const key = `${providerName}:search:${searchHash}`;
391
- return {
392
- key,
393
- cacheDurationInSeconds: 0,
394
- canCache: false
395
- };
396
- }
397
64
  };
398
65
 
399
66
  // core/src/schemas/capabilities.schema.ts
@@ -741,42 +408,32 @@ var SearchResultSchema = BaseModelSchema.extend({
741
408
 
742
409
  // core/src/schemas/mutations/base.mutation.ts
743
410
  import { z as z12 } from "zod";
744
- var BaseMutationSchema = z12.looseInterface({
745
- mutation: z12.ZodLiteral
746
- });
411
+ var BaseMutationSchema = z12.looseInterface({});
747
412
 
748
413
  // core/src/schemas/mutations/cart.mutation.ts
749
414
  import { z as z13 } from "zod";
750
415
  var CartMutationItemAddSchema = BaseMutationSchema.extend({
751
- mutation: z13.literal("add"),
752
416
  cart: CartIdentifierSchema.required(),
753
417
  product: ProductIdentifierSchema.required(),
754
418
  quantity: z13.number()
755
419
  });
756
420
  var CartMutationItemRemoveSchema = BaseMutationSchema.extend({
757
- mutation: z13.literal("remove"),
758
421
  cart: CartIdentifierSchema.required(),
759
422
  item: CartItemIdentifierSchema.required()
760
423
  });
761
424
  var CartMutationItemQuantityChangeSchema = BaseMutationSchema.extend({
762
- mutation: z13.literal("adjustQuantity"),
763
425
  cart: CartIdentifierSchema.required(),
764
426
  item: CartItemIdentifierSchema.required(),
765
427
  quantity: z13.number()
766
428
  });
767
- var CartMutationSchema = z13.union([CartMutationItemAddSchema, CartMutationItemRemoveSchema, CartMutationItemQuantityChangeSchema]);
768
429
 
769
430
  // core/src/schemas/mutations/identity.mutation.ts
770
431
  import { z as z14 } from "zod";
771
432
  var IdentityMutationLoginSchema = BaseMutationSchema.extend({
772
- mutation: z14.literal("login"),
773
433
  username: z14.string(),
774
434
  password: z14.string()
775
435
  });
776
- var IdentityMutationLogoutSchema = BaseMutationSchema.extend({
777
- mutation: z14.literal("logout")
778
- });
779
- var IdentityMutationSchema = z14.union([IdentityMutationLoginSchema, IdentityMutationLogoutSchema]);
436
+ var IdentityMutationLogoutSchema = BaseMutationSchema.extend({});
780
437
 
781
438
  // core/src/schemas/mutations/inventory.mutation.ts
782
439
  import { z as z15 } from "zod";
@@ -796,104 +453,324 @@ var SearchMutationSchema = z18.union([]);
796
453
 
797
454
  // core/src/schemas/queries/base.query.ts
798
455
  import { z as z19 } from "zod";
799
- var BaseQuerySchema = z19.looseInterface({
800
- query: z19.ZodLiteral
801
- });
456
+ var BaseQuerySchema = z19.looseInterface({});
802
457
 
803
458
  // core/src/schemas/queries/cart.query.ts
804
459
  import { z as z20 } from "zod";
805
460
  var CartQueryByIdSchema = BaseQuerySchema.extend({
806
- query: z20.literal("id"),
807
461
  cart: CartIdentifierSchema.required()
808
462
  });
809
463
  var CartQuerySchema = z20.union([CartQueryByIdSchema]);
810
464
 
811
465
  // core/src/schemas/queries/identity.query.ts
812
- import { z as z21 } from "zod";
813
- var IdentityQuerySelfSchema = BaseQuerySchema.extend({
814
- query: z21.literal("self")
815
- });
816
- var IdentityQuerySchema = z21.union([IdentityQuerySelfSchema]);
466
+ var IdentityQuerySelfSchema = BaseQuerySchema.extend({});
817
467
 
818
468
  // core/src/schemas/queries/inventory.query.ts
819
- import { z as z22 } from "zod";
469
+ import { z as z21 } from "zod";
820
470
  var InventoryQuerySchema = BaseQuerySchema.extend({
821
- query: z22.literal("sku"),
822
- sku: z22.string()
471
+ sku: z21.string()
823
472
  });
824
473
 
825
474
  // core/src/schemas/queries/price.query.ts
826
- import { z as z23 } from "zod";
827
475
  var PriceQueryBySkuSchema = BaseQuerySchema.extend({
828
- query: z23.literal("sku"),
829
476
  sku: SKUIdentifierSchema.required()
830
477
  });
831
- var PriceQuerySchema = z23.union([PriceQueryBySkuSchema]);
832
478
 
833
479
  // core/src/schemas/queries/product.query.ts
834
- import { z as z24 } from "zod";
480
+ import { z as z22 } from "zod";
835
481
  var ProductQueryBySlugSchema = BaseQuerySchema.extend({
836
- query: z24.literal("slug"),
837
- slug: z24.string()
482
+ slug: z22.string()
838
483
  });
839
484
  var ProductQueryByIdSchema = BaseQuerySchema.extend({
840
- query: z24.literal("id"),
841
- id: z24.string()
485
+ id: z22.string()
842
486
  });
843
- var ProductQuerySchema = z24.union([ProductQueryBySlugSchema, ProductQueryByIdSchema]);
844
487
 
845
488
  // core/src/schemas/queries/search.query.ts
846
- import { z as z25 } from "zod";
847
489
  var SearchQueryByTermSchema = BaseQuerySchema.extend({
848
- query: z25.literal("term"),
849
490
  search: SearchIdentifierSchema.required()
850
491
  });
851
- var SearchQuerySchema = z25.union([SearchQueryByTermSchema]);
852
492
 
853
493
  // providers/fake/src/providers/product.provider.ts
854
494
  import { base, en, Faker } from "@faker-js/faker";
495
+
496
+ // otel/src/trpc-middleware.ts
497
+ import { TRPCError } from "@trpc/server";
498
+ import {
499
+ SpanKind as SpanKind2,
500
+ SpanStatusCode as SpanStatusCode3
501
+ } from "@opentelemetry/api";
502
+
503
+ // otel/src/tracer.ts
504
+ import {
505
+ trace,
506
+ SpanStatusCode,
507
+ context as otelContext
508
+ } from "@opentelemetry/api";
509
+
510
+ // otel/src/sdk.ts
511
+ import { NodeSDK } from "@opentelemetry/sdk-node";
512
+ var sdk = null;
513
+ var isInitialized = false;
514
+ var initializationPromise = null;
515
+ function isBrowser() {
516
+ return typeof window !== "undefined" && typeof process === "undefined";
517
+ }
518
+ function ensureInitialized() {
519
+ if (isInitialized || initializationPromise) {
520
+ return;
521
+ }
522
+ if (isBrowser()) {
523
+ isInitialized = true;
524
+ return;
525
+ }
526
+ initializationPromise = Promise.resolve().then(() => {
527
+ sdk = new NodeSDK();
528
+ sdk.start();
529
+ isInitialized = true;
530
+ process.on("SIGTERM", async () => {
531
+ try {
532
+ await shutdownOtel();
533
+ if (process.env["OTEL_LOG_LEVEL"] === "debug") {
534
+ console.log("OpenTelemetry terminated successfully");
535
+ }
536
+ } catch (error) {
537
+ console.error("Error terminating OpenTelemetry", error);
538
+ }
539
+ });
540
+ });
541
+ }
542
+ async function shutdownOtel() {
543
+ if (sdk) {
544
+ await sdk.shutdown();
545
+ sdk = null;
546
+ isInitialized = false;
547
+ }
548
+ }
549
+ function isOtelInitialized() {
550
+ ensureInitialized();
551
+ return isInitialized;
552
+ }
553
+
554
+ // otel/src/tracer.ts
555
+ import { SpanKind, SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
556
+ var TRACER_NAME = "@reactionary/otel";
557
+ var TRACER_VERSION = "0.0.1";
558
+ var globalTracer = null;
559
+ function getTracer() {
560
+ if (!globalTracer) {
561
+ isOtelInitialized();
562
+ globalTracer = trace.getTracer(TRACER_NAME, TRACER_VERSION);
563
+ }
564
+ return globalTracer;
565
+ }
566
+
567
+ // otel/src/metrics.ts
568
+ import { metrics } from "@opentelemetry/api";
569
+
570
+ // otel/src/provider-instrumentation.ts
571
+ import { SpanKind as SpanKind3 } from "@opentelemetry/api";
572
+
573
+ // otel/src/trace-decorator.ts
574
+ import { SpanKind as SpanKind4, SpanStatusCode as SpanStatusCode4 } from "@opentelemetry/api";
575
+ function safeSerialize(value, maxDepth = 3, currentDepth = 0) {
576
+ if (currentDepth >= maxDepth) {
577
+ return "[Max depth reached]";
578
+ }
579
+ if (value === null)
580
+ return "null";
581
+ if (value === void 0)
582
+ return "undefined";
583
+ const type = typeof value;
584
+ if (type === "string" || type === "number" || type === "boolean") {
585
+ return String(value);
586
+ }
587
+ if (type === "function") {
588
+ return `[Function: ${value.name || "anonymous"}]`;
589
+ }
590
+ if (value instanceof Date) {
591
+ return value.toISOString();
592
+ }
593
+ if (value instanceof Error) {
594
+ return `[Error: ${value.message}]`;
595
+ }
596
+ if (Array.isArray(value)) {
597
+ if (value.length > 10) {
598
+ return `[Array(${value.length})]`;
599
+ }
600
+ try {
601
+ return JSON.stringify(value.map(
602
+ (item) => safeSerialize(item, maxDepth, currentDepth + 1)
603
+ ));
604
+ } catch {
605
+ return "[Array - circular reference]";
606
+ }
607
+ }
608
+ if (type === "object") {
609
+ try {
610
+ const keys = Object.keys(value);
611
+ if (keys.length > 20) {
612
+ return `[Object with ${keys.length} keys]`;
613
+ }
614
+ const simplified = {};
615
+ for (const key of keys.slice(0, 10)) {
616
+ simplified[key] = safeSerialize(
617
+ value[key],
618
+ maxDepth,
619
+ currentDepth + 1
620
+ );
621
+ }
622
+ return JSON.stringify(simplified);
623
+ } catch {
624
+ return "[Object - circular reference]";
625
+ }
626
+ }
627
+ return String(value);
628
+ }
629
+ function traced(options = {}) {
630
+ const {
631
+ captureArgs = true,
632
+ captureResult = true,
633
+ spanName,
634
+ spanKind = SpanKind4.INTERNAL
635
+ } = options;
636
+ return function(target, propertyKey, descriptor) {
637
+ if (typeof propertyKey === "object" && propertyKey && "kind" in propertyKey) {
638
+ const context = propertyKey;
639
+ const originalMethod = target;
640
+ const methodName = String(context.name);
641
+ return createTracedMethod(originalMethod, methodName, {
642
+ captureArgs,
643
+ captureResult,
644
+ spanName,
645
+ spanKind
646
+ });
647
+ }
648
+ if (descriptor && typeof descriptor.value === "function") {
649
+ const originalMethod = descriptor.value;
650
+ const methodName = String(propertyKey);
651
+ descriptor.value = createTracedMethod(originalMethod, methodName, {
652
+ captureArgs,
653
+ captureResult,
654
+ spanName,
655
+ spanKind
656
+ });
657
+ return descriptor;
658
+ }
659
+ return target;
660
+ };
661
+ }
662
+ function createTracedMethod(originalMethod, methodName, options) {
663
+ const { captureArgs, captureResult, spanName, spanKind } = options;
664
+ function tracedMethod(...args) {
665
+ const tracer = getTracer();
666
+ const className = this?.constructor?.name || "Unknown";
667
+ const effectiveSpanName = spanName || `${className}.${methodName}`;
668
+ const span = tracer.startSpan(effectiveSpanName, {
669
+ kind: spanKind,
670
+ attributes: {
671
+ "function.name": methodName,
672
+ "function.class": className
673
+ }
674
+ });
675
+ if (captureArgs && args.length > 0) {
676
+ args.forEach((arg, index) => {
677
+ try {
678
+ span.setAttribute(`function.args.${index}`, safeSerialize(arg));
679
+ } catch {
680
+ span.setAttribute(`function.args.${index}`, "[Serialization error]");
681
+ }
682
+ });
683
+ span.setAttribute("function.args.count", args.length);
684
+ }
685
+ const finalizeSpan = (result, isError = false) => {
686
+ if (!isError && captureResult && result !== void 0) {
687
+ try {
688
+ span.setAttribute("function.result", safeSerialize(result));
689
+ } catch {
690
+ span.setAttribute("function.result", "[Serialization error]");
691
+ }
692
+ }
693
+ if (isError) {
694
+ span.setStatus({
695
+ code: SpanStatusCode4.ERROR,
696
+ message: result instanceof Error ? result.message : String(result)
697
+ });
698
+ if (result instanceof Error) {
699
+ span.recordException(result);
700
+ }
701
+ } else {
702
+ span.setStatus({ code: SpanStatusCode4.OK });
703
+ }
704
+ span.end();
705
+ };
706
+ try {
707
+ const result = originalMethod.apply(this, args);
708
+ if (result instanceof Promise) {
709
+ return result.then((value) => {
710
+ finalizeSpan(value);
711
+ return value;
712
+ }).catch((error) => {
713
+ finalizeSpan(error, true);
714
+ throw error;
715
+ });
716
+ }
717
+ finalizeSpan(result);
718
+ return result;
719
+ } catch (error) {
720
+ finalizeSpan(error, true);
721
+ throw error;
722
+ }
723
+ }
724
+ Object.defineProperty(tracedMethod, "name", {
725
+ value: methodName,
726
+ configurable: true
727
+ });
728
+ return tracedMethod;
729
+ }
730
+
731
+ // providers/fake/src/providers/product.provider.ts
855
732
  var FakeProductProvider = class extends ProductProvider {
856
- constructor(config, schema, querySchema, mutationSchema, cache) {
857
- super(schema, querySchema, mutationSchema, cache);
733
+ constructor(config, schema, cache) {
734
+ super(schema, cache);
858
735
  this.config = config;
859
736
  }
860
- async fetch(queries, session) {
861
- const results = new Array();
862
- for (const query of queries) {
863
- const generator = new Faker({
864
- seed: 42,
865
- locale: [en, base]
866
- });
867
- const key = query.id || generator.commerce.isbn();
868
- const slug = query.slug || generator.lorem.slug();
869
- const product = {
870
- identifier: {
737
+ @traced()
738
+ async getById(payload, _session) {
739
+ return this.parseSingle(payload);
740
+ }
741
+ async getBySlug(payload, _session) {
742
+ return this.parseSingle(payload);
743
+ }
744
+ parseSingle(body) {
745
+ const generator = new Faker({
746
+ seed: 42,
747
+ locale: [en, base]
748
+ });
749
+ const key = body.slug || body.id;
750
+ const model = this.newModel();
751
+ Object.assign(model, {
752
+ identifier: {
753
+ key
754
+ },
755
+ name: generator.commerce.productName(),
756
+ slug: key,
757
+ attributes: [],
758
+ description: generator.commerce.productDescription(),
759
+ image: generator.image.urlPicsumPhotos({
760
+ width: 600,
761
+ height: 600
762
+ }),
763
+ images: [],
764
+ meta: {
765
+ cache: {
766
+ hit: false,
871
767
  key
872
768
  },
873
- name: generator.commerce.productName(),
874
- slug,
875
- attributes: [],
876
- description: generator.commerce.productDescription(),
877
- image: generator.image.urlPicsumPhotos({
878
- width: 600,
879
- height: 600
880
- }),
881
- images: [],
882
- meta: {
883
- cache: {
884
- hit: false,
885
- key
886
- },
887
- placeholder: false
888
- },
889
- skus: []
890
- };
891
- results.push(product);
892
- }
893
- return results;
894
- }
895
- process(mutation, session) {
896
- throw new Error("Method not implemented.");
769
+ placeholder: false
770
+ },
771
+ skus: []
772
+ });
773
+ return this.assert(model);
897
774
  }
898
775
  };
899
776
 
@@ -908,32 +785,19 @@ async function jitter(duration, deviation) {
908
785
  function gaussianRandom(mean, deviation) {
909
786
  const u = 1 - Math.random();
910
787
  const v = Math.random();
911
- const z27 = Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
912
- return z27 * deviation + mean;
788
+ const z24 = Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
789
+ return z24 * deviation + mean;
913
790
  }
914
791
 
915
792
  // providers/fake/src/providers/search.provider.ts
916
793
  var FakeSearchProvider = class extends SearchProvider {
917
- constructor(config, schema, querySchema, mutationSchema, cache) {
918
- super(schema, querySchema, mutationSchema, cache);
794
+ constructor(config, schema, cache) {
795
+ super(schema, cache);
919
796
  this.config = config;
920
797
  }
921
- async fetch(queries, session) {
922
- const results = [];
923
- for (const query of queries) {
924
- const result = await this.get(query.search);
925
- results.push(result);
926
- }
927
- return results;
928
- }
929
- process(mutations, session) {
930
- throw new Error("Method not implemented.");
931
- }
932
- async get(identifier) {
798
+ async queryByTerm(payload, _session) {
933
799
  await jitter(this.config.jitter.mean, this.config.jitter.deviation);
934
- return this.parse({}, identifier);
935
- }
936
- parse(data, query) {
800
+ const query = payload.search;
937
801
  const querySpecificity = 20 - query.term.length - query.page - query.facets.length;
938
802
  const totalProducts = 10 * querySpecificity;
939
803
  const totalPages = Math.ceil(totalProducts / query.pageSize);
@@ -964,12 +828,12 @@ var FakeSearchProvider = class extends SearchProvider {
964
828
  });
965
829
  }
966
830
  const facetBase = ["color", "size"];
967
- for (const base3 of facetBase) {
831
+ for (const base6 of facetBase) {
968
832
  const facet = {
969
833
  identifier: {
970
- key: base3
834
+ key: base6
971
835
  },
972
- name: base3,
836
+ name: base6,
973
837
  values: []
974
838
  };
975
839
  for (let i = 0; i < 10; i++) {
@@ -1013,71 +877,238 @@ var FakeSearchProvider = class extends SearchProvider {
1013
877
  }
1014
878
  };
1015
879
 
880
+ // providers/fake/src/core/initialize.ts
881
+ function withFakeCapabilities(configuration, capabilities) {
882
+ return (cache) => {
883
+ const client = {};
884
+ if (capabilities.product) {
885
+ client.product = new FakeProductProvider(configuration, ProductSchema, cache);
886
+ }
887
+ if (capabilities.search) {
888
+ client.search = new FakeSearchProvider(configuration, SearchResultSchema, cache);
889
+ }
890
+ return client;
891
+ };
892
+ }
893
+
894
+ // providers/fake/src/providers/analytics.provider.ts
895
+ var FakeAnalyticsProvider = class extends AnalyticsProvider {
896
+ constructor(config, schema, cache) {
897
+ super(schema, cache);
898
+ this.config = config;
899
+ }
900
+ };
901
+
902
+ // providers/fake/src/providers/cart.provider.ts
903
+ var FakeCartProvider = class extends CartProvider {
904
+ constructor(config, schema, cache) {
905
+ super(schema, cache);
906
+ this.carts = /* @__PURE__ */ new Map();
907
+ this.config = config;
908
+ }
909
+ async getById(payload, _session) {
910
+ const cartId = payload.cart.key;
911
+ if (!this.carts.has(cartId)) {
912
+ const model = this.newModel();
913
+ Object.assign(model, {
914
+ identifier: { key: cartId },
915
+ items: [],
916
+ meta: {
917
+ cache: {
918
+ hit: false,
919
+ key: cartId
920
+ },
921
+ placeholder: false
922
+ }
923
+ });
924
+ this.carts.set(cartId, this.assert(model));
925
+ }
926
+ const cart = this.carts.get(cartId);
927
+ if (!cart) {
928
+ throw new Error(`Cart with id ${cartId} not found`);
929
+ }
930
+ return cart;
931
+ }
932
+ async add(payload, session) {
933
+ const cart = await this.getById({ cart: payload.cart }, session);
934
+ const existingItemIndex = cart.items.findIndex(
935
+ (item) => item.product.key === payload.product.key
936
+ );
937
+ if (existingItemIndex >= 0) {
938
+ cart.items[existingItemIndex].quantity += payload.quantity;
939
+ } else {
940
+ cart.items.push({
941
+ identifier: { key: `item-${Date.now()}` },
942
+ product: payload.product,
943
+ quantity: payload.quantity
944
+ });
945
+ }
946
+ return this.assert(cart);
947
+ }
948
+ async remove(payload, session) {
949
+ const cart = await this.getById({ cart: payload.cart }, session);
950
+ cart.items = cart.items.filter(
951
+ (item) => item.identifier.key !== payload.item.key
952
+ );
953
+ return this.assert(cart);
954
+ }
955
+ async changeQuantity(payload, session) {
956
+ const cart = await this.getById({ cart: payload.cart }, session);
957
+ const item = cart.items.find(
958
+ (item2) => item2.identifier.key === payload.item.key
959
+ );
960
+ if (item) {
961
+ item.quantity = payload.quantity;
962
+ }
963
+ return this.assert(cart);
964
+ }
965
+ };
966
+
1016
967
  // providers/fake/src/providers/identity.provider.ts
1017
- import { faker } from "@faker-js/faker";
968
+ import { base as base3, en as en3, Faker as Faker3 } from "@faker-js/faker";
1018
969
  var FakeIdentityProvider = class extends IdentityProvider {
1019
- constructor(config, schema, querySchema, mutationSchema, cache) {
1020
- super(schema, querySchema, mutationSchema, cache);
970
+ constructor(config, schema, cache) {
971
+ super(schema, cache);
972
+ this.currentIdentity = null;
1021
973
  this.config = config;
1022
974
  }
1023
- async fetch(queries, session) {
1024
- const results = [];
1025
- for (const query of queries) {
1026
- const result = await this.get(session);
1027
- results.push(result);
975
+ async getSelf(_payload, _session) {
976
+ if (!this.currentIdentity) {
977
+ const model = this.newModel();
978
+ Object.assign(model, {
979
+ id: "anonymous",
980
+ type: "Anonymous",
981
+ issued: /* @__PURE__ */ new Date(),
982
+ expiry: new Date(Date.now() + 24 * 60 * 60 * 1e3),
983
+ // 24 hours from now
984
+ meta: {
985
+ cache: {
986
+ hit: false,
987
+ key: "anonymous"
988
+ },
989
+ placeholder: false
990
+ }
991
+ });
992
+ this.currentIdentity = this.assert(model);
1028
993
  }
1029
- return results;
994
+ return this.currentIdentity;
1030
995
  }
1031
- async process(mutations, session) {
1032
- let result = this.newModel();
1033
- for (const mutation of mutations) {
1034
- switch (mutation.mutation) {
1035
- case "login":
1036
- result = await this.login(mutation, session);
1037
- break;
1038
- case "logout":
1039
- result = await this.logout(session);
1040
- break;
996
+ async login(payload, _session) {
997
+ const generator = new Faker3({
998
+ seed: 42,
999
+ locale: [en3, base3]
1000
+ });
1001
+ const model = this.newModel();
1002
+ Object.assign(model, {
1003
+ id: generator.string.uuid(),
1004
+ type: "Registered",
1005
+ token: generator.string.alphanumeric(32),
1006
+ issued: /* @__PURE__ */ new Date(),
1007
+ expiry: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3),
1008
+ // 7 days from now
1009
+ meta: {
1010
+ cache: {
1011
+ hit: false,
1012
+ key: payload.username
1013
+ },
1014
+ placeholder: false
1041
1015
  }
1042
- }
1043
- return result;
1016
+ });
1017
+ this.currentIdentity = this.assert(model);
1018
+ return this.currentIdentity;
1044
1019
  }
1045
- async login(payload, session) {
1046
- const base3 = this.newModel();
1047
- base3.id = faker.string.uuid();
1048
- base3.token = faker.string.uuid();
1049
- base3.issued = faker.date.recent();
1050
- base3.issued = faker.date.soon();
1051
- base3.type = "Registered";
1052
- return base3;
1020
+ async logout(_payload, _session) {
1021
+ const model = this.newModel();
1022
+ Object.assign(model, {
1023
+ id: "anonymous",
1024
+ type: "Anonymous",
1025
+ issued: /* @__PURE__ */ new Date(),
1026
+ expiry: new Date(Date.now() + 24 * 60 * 60 * 1e3),
1027
+ // 24 hours from now
1028
+ meta: {
1029
+ cache: {
1030
+ hit: false,
1031
+ key: "anonymous"
1032
+ },
1033
+ placeholder: false
1034
+ }
1035
+ });
1036
+ this.currentIdentity = this.assert(model);
1037
+ return this.currentIdentity;
1053
1038
  }
1054
- async get(session) {
1055
- const base3 = this.schema.parse(session.identity);
1056
- return base3;
1039
+ };
1040
+
1041
+ // providers/fake/src/providers/inventory.provider.ts
1042
+ import { base as base4, en as en4, Faker as Faker4 } from "@faker-js/faker";
1043
+ var FakeInventoryProvider = class extends InventoryProvider {
1044
+ constructor(config, schema, cache) {
1045
+ super(schema, cache);
1046
+ this.config = config;
1057
1047
  }
1058
- async logout(session) {
1059
- const base3 = this.newModel();
1060
- session.identity = base3;
1061
- return base3;
1048
+ async getBySKU(payload, _session) {
1049
+ let hash = 0;
1050
+ const skuString = payload.sku;
1051
+ for (let i = 0; i < skuString.length; i++) {
1052
+ hash = (hash << 5) - hash + skuString.charCodeAt(i);
1053
+ hash = hash & hash;
1054
+ }
1055
+ const generator = new Faker4({
1056
+ seed: hash || 42,
1057
+ locale: [en4, base4]
1058
+ });
1059
+ const model = this.newModel();
1060
+ Object.assign(model, {
1061
+ quantity: generator.number.int({ min: 0, max: 100 }),
1062
+ meta: {
1063
+ cache: {
1064
+ hit: false,
1065
+ key: payload.sku
1066
+ },
1067
+ placeholder: false
1068
+ }
1069
+ });
1070
+ return this.assert(model);
1062
1071
  }
1063
1072
  };
1064
1073
 
1065
- // providers/fake/src/core/initialize.ts
1066
- function withFakeCapabilities(configuration, capabilities) {
1067
- return (cache) => {
1068
- const client = {};
1069
- if (capabilities.product) {
1070
- client.product = new FakeProductProvider(configuration, ProductSchema, ProductQuerySchema, ProductMutationSchema, cache);
1071
- }
1072
- if (capabilities.search) {
1073
- client.search = new FakeSearchProvider(configuration, SearchResultSchema, SearchQuerySchema, SearchMutationSchema, cache);
1074
- }
1075
- if (capabilities.identity) {
1076
- client.identity = new FakeIdentityProvider(configuration, IdentitySchema, IdentityQuerySchema, IdentityMutationSchema, cache);
1074
+ // providers/fake/src/providers/price.provider.ts
1075
+ import { base as base5, en as en5, Faker as Faker5 } from "@faker-js/faker";
1076
+ var FakePriceProvider = class extends PriceProvider {
1077
+ constructor(config, schema, cache) {
1078
+ super(schema, cache);
1079
+ this.config = config;
1080
+ }
1081
+ async getBySKU(payload, _session) {
1082
+ let hash = 0;
1083
+ const skuString = payload.sku.key;
1084
+ for (let i = 0; i < skuString.length; i++) {
1085
+ hash = (hash << 5) - hash + skuString.charCodeAt(i);
1086
+ hash = hash & hash;
1077
1087
  }
1078
- return client;
1079
- };
1080
- }
1088
+ const generator = new Faker5({
1089
+ seed: hash || 42,
1090
+ locale: [en5, base5]
1091
+ });
1092
+ const model = this.newModel();
1093
+ Object.assign(model, {
1094
+ identifier: {
1095
+ sku: payload.sku
1096
+ },
1097
+ value: {
1098
+ cents: generator.number.int({ min: 100, max: 1e5 }),
1099
+ currency: "USD"
1100
+ },
1101
+ meta: {
1102
+ cache: {
1103
+ hit: false,
1104
+ key: payload.sku
1105
+ },
1106
+ placeholder: false
1107
+ }
1108
+ });
1109
+ return this.assert(model);
1110
+ }
1111
+ };
1081
1112
 
1082
1113
  // providers/fake/src/schema/capabilities.schema.ts
1083
1114
  var FakeCapabilitiesSchema = CapabilitiesSchema.pick({
@@ -1087,20 +1118,24 @@ var FakeCapabilitiesSchema = CapabilitiesSchema.pick({
1087
1118
  }).partial();
1088
1119
 
1089
1120
  // providers/fake/src/schema/configuration.schema.ts
1090
- import { z as z26 } from "zod";
1091
- var FakeConfigurationSchema = z26.looseInterface({
1092
- jitter: z26.looseInterface({
1093
- mean: z26.number().min(0).max(1e4),
1094
- deviation: z26.number().min(0).max(5e3)
1121
+ import { z as z23 } from "zod";
1122
+ var FakeConfigurationSchema = z23.looseInterface({
1123
+ jitter: z23.looseInterface({
1124
+ mean: z23.number().min(0).max(1e4),
1125
+ deviation: z23.number().min(0).max(5e3)
1095
1126
  }).default({
1096
1127
  mean: 0,
1097
1128
  deviation: 0
1098
1129
  })
1099
1130
  });
1100
1131
  export {
1132
+ FakeAnalyticsProvider,
1101
1133
  FakeCapabilitiesSchema,
1134
+ FakeCartProvider,
1102
1135
  FakeConfigurationSchema,
1103
1136
  FakeIdentityProvider,
1137
+ FakeInventoryProvider,
1138
+ FakePriceProvider,
1104
1139
  FakeProductProvider,
1105
1140
  FakeSearchProvider,
1106
1141
  withFakeCapabilities