@reactionary/provider-commercetools 0.0.30 → 0.0.32

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
@@ -113,283 +113,19 @@ var CommercetoolsClient = class {
113
113
  }
114
114
  };
115
115
 
116
- // core/src/cache/caching-strategy.ts
117
- var BaseCachingStrategy = class {
118
- get(query, session) {
119
- const q = query;
120
- return {
121
- key: q.sku,
122
- cacheDurationInSeconds: 300,
123
- canCache: true
124
- };
125
- }
126
- };
127
-
128
116
  // core/src/cache/redis-cache.ts
129
117
  import { Redis } from "@upstash/redis";
130
- var RedisCache = class {
131
- constructor(strategy) {
132
- this.strategy = strategy;
133
- this.redis = Redis.fromEnv();
134
- }
135
- async get(query, session, schema) {
136
- let result = null;
137
- const cacheInformation = this.strategy.get(query, session);
138
- if (cacheInformation.canCache && cacheInformation.key) {
139
- const unvalidated = await this.redis.get(cacheInformation.key);
140
- const parsed = schema.safeParse(unvalidated);
141
- if (parsed.success) {
142
- result = parsed.data;
143
- }
144
- }
145
- return result;
146
- }
147
- put(query, session, value) {
148
- const cacheInformation = this.strategy.get(query, session);
149
- if (cacheInformation.canCache && cacheInformation.key) {
150
- this.redis.set(cacheInformation.key, value, { ex: cacheInformation.cacheDurationInSeconds });
151
- }
152
- }
153
- };
154
-
155
- // otel/src/trpc-middleware.ts
156
- import { TRPCError } from "@trpc/server";
157
- import {
158
- SpanKind as SpanKind2,
159
- SpanStatusCode as SpanStatusCode3
160
- } from "@opentelemetry/api";
161
-
162
- // otel/src/tracer.ts
163
- import {
164
- trace,
165
- SpanStatusCode,
166
- context as otelContext
167
- } from "@opentelemetry/api";
168
-
169
- // otel/src/sdk.ts
170
- import { NodeSDK } from "@opentelemetry/sdk-node";
171
- var sdk = null;
172
- var isInitialized = false;
173
- var initializationPromise = null;
174
- function isBrowser() {
175
- return typeof window !== "undefined" && typeof process === "undefined";
176
- }
177
- function ensureInitialized() {
178
- if (isInitialized || initializationPromise) {
179
- return;
180
- }
181
- if (isBrowser()) {
182
- isInitialized = true;
183
- return;
184
- }
185
- initializationPromise = Promise.resolve().then(() => {
186
- sdk = new NodeSDK();
187
- sdk.start();
188
- isInitialized = true;
189
- process.on("SIGTERM", async () => {
190
- try {
191
- await shutdownOtel();
192
- if (process.env["OTEL_LOG_LEVEL"] === "debug") {
193
- console.log("OpenTelemetry terminated successfully");
194
- }
195
- } catch (error) {
196
- console.error("Error terminating OpenTelemetry", error);
197
- }
198
- });
199
- });
200
- }
201
- async function shutdownOtel() {
202
- if (sdk) {
203
- await sdk.shutdown();
204
- sdk = null;
205
- isInitialized = false;
206
- }
207
- }
208
- function isOtelInitialized() {
209
- ensureInitialized();
210
- return isInitialized;
211
- }
212
118
 
213
- // otel/src/tracer.ts
214
- import { SpanKind, SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
215
- var TRACER_NAME = "@reactionary/otel";
216
- var TRACER_VERSION = "0.0.1";
217
- var globalTracer = null;
218
- function getTracer() {
219
- if (!globalTracer) {
220
- isOtelInitialized();
221
- globalTracer = trace.getTracer(TRACER_NAME, TRACER_VERSION);
222
- }
223
- return globalTracer;
224
- }
225
- function withSpan(name, fn, options) {
226
- const tracer = getTracer();
227
- return tracer.startActiveSpan(name, options || {}, async (span) => {
228
- try {
229
- const result = await fn(span);
230
- span.setStatus({ code: SpanStatusCode.OK });
231
- return result;
232
- } catch (error) {
233
- span.setStatus({
234
- code: SpanStatusCode.ERROR,
235
- message: error instanceof Error ? error.message : String(error)
236
- });
237
- if (error instanceof Error) {
238
- span.recordException(error);
239
- }
240
- throw error;
241
- } finally {
242
- span.end();
243
- }
244
- });
245
- }
246
- function setSpanAttributes(span, attributes) {
247
- Object.entries(attributes).forEach(([key, value]) => {
248
- if (value !== void 0 && value !== null) {
249
- span.setAttribute(key, value);
250
- }
251
- });
252
- }
253
-
254
- // otel/src/metrics.ts
255
- import { metrics } from "@opentelemetry/api";
256
- var METER_NAME = "@reactionary/otel";
257
- var METER_VERSION = "0.0.1";
258
- var globalMeter = null;
259
- function getMeter() {
260
- if (!globalMeter) {
261
- isOtelInitialized();
262
- globalMeter = metrics.getMeter(METER_NAME, METER_VERSION);
263
- }
264
- return globalMeter;
265
- }
266
- var metricsInstance = null;
267
- function initializeMetrics() {
268
- if (metricsInstance) {
269
- return metricsInstance;
270
- }
271
- const meter = getMeter();
272
- metricsInstance = {
273
- requestCounter: meter.createCounter("reactionary.requests", {
274
- description: "Total number of requests"
275
- }),
276
- requestDuration: meter.createHistogram("reactionary.request.duration", {
277
- description: "Request duration in milliseconds",
278
- unit: "ms"
279
- }),
280
- activeRequests: meter.createUpDownCounter("reactionary.requests.active", {
281
- description: "Number of active requests"
282
- }),
283
- errorCounter: meter.createCounter("reactionary.errors", {
284
- description: "Total number of errors"
285
- }),
286
- providerCallCounter: meter.createCounter("reactionary.provider.calls", {
287
- description: "Total number of provider calls"
288
- }),
289
- providerCallDuration: meter.createHistogram("reactionary.provider.duration", {
290
- description: "Provider call duration in milliseconds",
291
- unit: "ms"
292
- }),
293
- cacheHitCounter: meter.createCounter("reactionary.cache.hits", {
294
- description: "Total number of cache hits"
295
- }),
296
- cacheMissCounter: meter.createCounter("reactionary.cache.misses", {
297
- description: "Total number of cache misses"
298
- })
299
- };
300
- return metricsInstance;
301
- }
302
- function getMetrics() {
303
- if (!metricsInstance) {
304
- return initializeMetrics();
305
- }
306
- return metricsInstance;
307
- }
308
-
309
- // otel/src/provider-instrumentation.ts
310
- import { SpanKind as SpanKind3 } from "@opentelemetry/api";
311
- async function withProviderSpan(options, fn) {
312
- const { providerName, operationType, operationName, attributes = {} } = options;
313
- const metrics2 = getMetrics();
314
- const spanName = `provider.${providerName}.${operationType}${operationName ? `.${operationName}` : ""}`;
315
- const startTime = Date.now();
316
- metrics2.providerCallCounter.add(1, {
317
- "provider.name": providerName,
318
- "provider.operation.type": operationType,
319
- "provider.operation.name": operationName || "unknown"
320
- });
321
- return withSpan(
322
- spanName,
323
- async (span) => {
324
- setSpanAttributes(span, {
325
- "provider.name": providerName,
326
- "provider.operation.type": operationType,
327
- "provider.operation.name": operationName,
328
- ...attributes
329
- });
330
- try {
331
- const result = await fn(span);
332
- const duration = Date.now() - startTime;
333
- metrics2.providerCallDuration.record(duration, {
334
- "provider.name": providerName,
335
- "provider.operation.type": operationType,
336
- "provider.operation.name": operationName || "unknown",
337
- "status": "success"
338
- });
339
- return result;
340
- } catch (error) {
341
- const duration = Date.now() - startTime;
342
- metrics2.providerCallDuration.record(duration, {
343
- "provider.name": providerName,
344
- "provider.operation.type": operationType,
345
- "provider.operation.name": operationName || "unknown",
346
- "status": "error"
347
- });
348
- metrics2.errorCounter.add(1, {
349
- "provider.name": providerName,
350
- "provider.operation.type": operationType,
351
- "provider.operation.name": operationName || "unknown"
352
- });
353
- throw error;
354
- }
355
- },
356
- { kind: SpanKind3.CLIENT }
357
- );
358
- }
359
- function createProviderInstrumentation(providerName) {
360
- return {
361
- traceQuery: (operationName, fn, attributes) => {
362
- return withProviderSpan(
363
- {
364
- providerName,
365
- operationType: "query",
366
- operationName,
367
- attributes
368
- },
369
- fn
370
- );
371
- },
372
- traceMutation: (operationName, fn, attributes) => {
373
- return withProviderSpan(
374
- {
375
- providerName,
376
- operationType: "mutation",
377
- operationName,
378
- attributes
379
- },
380
- fn
381
- );
382
- }
383
- };
384
- }
119
+ // core/src/decorators/trpc.decorators.ts
120
+ import "reflect-metadata";
121
+ var TRPC_QUERY_METADATA_KEY = Symbol("trpc:query");
122
+ var TRPC_MUTATION_METADATA_KEY = Symbol("trpc:mutation");
385
123
 
386
124
  // core/src/providers/base.provider.ts
387
125
  var BaseProvider = class {
388
- constructor(schema, querySchema, mutationSchema) {
126
+ constructor(schema, cache) {
389
127
  this.schema = schema;
390
- this.querySchema = querySchema;
391
- this.mutationSchema = mutationSchema;
392
- this.instrumentation = createProviderInstrumentation(this.constructor.name);
128
+ this.cache = cache;
393
129
  }
394
130
  /**
395
131
  * Validates that the final domain model constructed by the provider
@@ -405,41 +141,12 @@ var BaseProvider = class {
405
141
  return this.schema.parse({});
406
142
  }
407
143
  /**
408
- * Retrieves a set of entities matching the list of queries. The size of
409
- * the resulting list WILL always match the size of the query list. The
410
- * result list will never contain nulls or undefined. The order
411
- * of the results will match the order of the queries.
144
+ * Handler for parsing a response from a remote provider and converting it
145
+ * into the typed domain model.
412
146
  */
413
- async query(queries, session) {
414
- return this.instrumentation.traceQuery(
415
- "query",
416
- async (span) => {
417
- span.setAttribute("provider.query.count", queries.length);
418
- const results = await this.fetch(queries, session);
419
- for (const result of results) {
420
- this.assert(result);
421
- }
422
- span.setAttribute("provider.result.count", results.length);
423
- return results;
424
- },
425
- { queryCount: queries.length }
426
- );
427
- }
428
- /**
429
- * Executes the listed mutations in order and returns the final state
430
- * resulting from that set of operations.
431
- */
432
- async mutate(mutations, session) {
433
- return this.instrumentation.traceMutation(
434
- "mutate",
435
- async (span) => {
436
- span.setAttribute("provider.mutation.count", mutations.length);
437
- const result = await this.process(mutations, session);
438
- this.assert(result);
439
- return result;
440
- },
441
- { mutationCount: mutations.length }
442
- );
147
+ parseSingle(_body) {
148
+ const model = this.newModel();
149
+ return this.assert(model);
443
150
  }
444
151
  };
445
152
 
@@ -812,42 +519,32 @@ var SearchResultSchema = BaseModelSchema.extend({
812
519
 
813
520
  // core/src/schemas/mutations/base.mutation.ts
814
521
  import { z as z12 } from "zod";
815
- var BaseMutationSchema = z12.looseInterface({
816
- mutation: z12.ZodLiteral
817
- });
522
+ var BaseMutationSchema = z12.looseInterface({});
818
523
 
819
524
  // core/src/schemas/mutations/cart.mutation.ts
820
525
  import { z as z13 } from "zod";
821
526
  var CartMutationItemAddSchema = BaseMutationSchema.extend({
822
- mutation: z13.literal("add"),
823
527
  cart: CartIdentifierSchema.required(),
824
528
  product: ProductIdentifierSchema.required(),
825
529
  quantity: z13.number()
826
530
  });
827
531
  var CartMutationItemRemoveSchema = BaseMutationSchema.extend({
828
- mutation: z13.literal("remove"),
829
532
  cart: CartIdentifierSchema.required(),
830
533
  item: CartItemIdentifierSchema.required()
831
534
  });
832
535
  var CartMutationItemQuantityChangeSchema = BaseMutationSchema.extend({
833
- mutation: z13.literal("adjustQuantity"),
834
536
  cart: CartIdentifierSchema.required(),
835
537
  item: CartItemIdentifierSchema.required(),
836
538
  quantity: z13.number()
837
539
  });
838
- var CartMutationSchema = z13.union([CartMutationItemAddSchema, CartMutationItemRemoveSchema, CartMutationItemQuantityChangeSchema]);
839
540
 
840
541
  // core/src/schemas/mutations/identity.mutation.ts
841
542
  import { z as z14 } from "zod";
842
543
  var IdentityMutationLoginSchema = BaseMutationSchema.extend({
843
- mutation: z14.literal("login"),
844
544
  username: z14.string(),
845
545
  password: z14.string()
846
546
  });
847
- var IdentityMutationLogoutSchema = BaseMutationSchema.extend({
848
- mutation: z14.literal("logout")
849
- });
850
- var IdentityMutationSchema = z14.union([IdentityMutationLoginSchema, IdentityMutationLogoutSchema]);
547
+ var IdentityMutationLogoutSchema = BaseMutationSchema.extend({});
851
548
 
852
549
  // core/src/schemas/mutations/inventory.mutation.ts
853
550
  import { z as z15 } from "zod";
@@ -867,185 +564,143 @@ var SearchMutationSchema = z18.union([]);
867
564
 
868
565
  // core/src/schemas/queries/base.query.ts
869
566
  import { z as z19 } from "zod";
870
- var BaseQuerySchema = z19.looseInterface({
871
- query: z19.ZodLiteral
872
- });
567
+ var BaseQuerySchema = z19.looseInterface({});
873
568
 
874
569
  // core/src/schemas/queries/cart.query.ts
875
570
  import { z as z20 } from "zod";
876
571
  var CartQueryByIdSchema = BaseQuerySchema.extend({
877
- query: z20.literal("id"),
878
572
  cart: CartIdentifierSchema.required()
879
573
  });
880
574
  var CartQuerySchema = z20.union([CartQueryByIdSchema]);
881
575
 
882
576
  // core/src/schemas/queries/identity.query.ts
883
- import { z as z21 } from "zod";
884
- var IdentityQuerySelfSchema = BaseQuerySchema.extend({
885
- query: z21.literal("self")
886
- });
887
- var IdentityQuerySchema = z21.union([IdentityQuerySelfSchema]);
577
+ var IdentityQuerySelfSchema = BaseQuerySchema.extend({});
888
578
 
889
579
  // core/src/schemas/queries/inventory.query.ts
890
- import { z as z22 } from "zod";
580
+ import { z as z21 } from "zod";
891
581
  var InventoryQuerySchema = BaseQuerySchema.extend({
892
- query: z22.literal("sku"),
893
- sku: z22.string()
582
+ sku: z21.string()
894
583
  });
895
584
 
896
585
  // core/src/schemas/queries/price.query.ts
897
- import { z as z23 } from "zod";
898
586
  var PriceQueryBySkuSchema = BaseQuerySchema.extend({
899
- query: z23.literal("sku"),
900
587
  sku: SKUIdentifierSchema.required()
901
588
  });
902
- var PriceQuerySchema = z23.union([PriceQueryBySkuSchema]);
903
589
 
904
590
  // core/src/schemas/queries/product.query.ts
905
- import { z as z24 } from "zod";
591
+ import { z as z22 } from "zod";
906
592
  var ProductQueryBySlugSchema = BaseQuerySchema.extend({
907
- query: z24.literal("slug"),
908
- slug: z24.string()
593
+ slug: z22.string()
909
594
  });
910
595
  var ProductQueryByIdSchema = BaseQuerySchema.extend({
911
- query: z24.literal("id"),
912
- id: z24.string()
596
+ id: z22.string()
913
597
  });
914
- var ProductQuerySchema = z24.union([ProductQueryBySlugSchema, ProductQueryByIdSchema]);
915
598
 
916
599
  // core/src/schemas/queries/search.query.ts
917
- import { z as z25 } from "zod";
918
600
  var SearchQueryByTermSchema = BaseQuerySchema.extend({
919
- query: z25.literal("term"),
920
601
  search: SearchIdentifierSchema.required()
921
602
  });
922
- var SearchQuerySchema = z25.union([SearchQueryByTermSchema]);
923
603
 
924
604
  // providers/commercetools/src/providers/search.provider.ts
925
605
  var CommercetoolsSearchProvider = class extends SearchProvider {
926
- constructor(config, schema, querySchema, mutationSchema) {
927
- super(schema, querySchema, mutationSchema);
606
+ constructor(config, schema, cache) {
607
+ super(schema, cache);
928
608
  this.config = config;
929
609
  }
930
- async fetch(queries, session) {
931
- const results = [];
932
- for (const query of queries) {
933
- const result = await this.get(query.search);
934
- results.push(result);
935
- }
936
- return results;
937
- }
938
- process(mutations, session) {
939
- throw new Error("Method not implemented.");
940
- }
941
- async get(identifier) {
610
+ async queryByTerm(payload, _session) {
942
611
  const client = new CommercetoolsClient(this.config).createAnonymousClient();
943
612
  const remote = await client.withProjectKey({ projectKey: this.config.projectKey }).productProjections().search().get({
944
613
  queryArgs: {
945
- limit: identifier.pageSize,
946
- offset: identifier.pageSize * identifier.page,
947
- ["text.en-US"]: identifier.term
614
+ limit: payload.search.pageSize,
615
+ offset: payload.search.pageSize * payload.search.page,
616
+ ["text.en-US"]: payload.search.term
948
617
  }
949
618
  }).execute();
950
- const parsed = this.parse(remote, identifier);
951
- return parsed;
619
+ return this.parseSearchResult(remote, payload);
952
620
  }
953
- parse(remote, query) {
954
- const result = super.newModel();
955
- result.identifier = query;
956
- for (const p of remote.body.results) {
957
- const product = SearchResultProductSchema.parse({});
958
- product.identifier.key = p.id;
959
- product.name = p.name["en-US"];
960
- if (p.masterVariant.images) {
961
- product.image = p.masterVariant.images[0].url;
962
- }
621
+ parseSearchResult(remote, payload) {
622
+ const result = this.newModel();
623
+ const remoteData = remote;
624
+ result.identifier = payload.search;
625
+ for (const p of remoteData.body.results) {
626
+ const product = {
627
+ identifier: { key: p.id },
628
+ name: p.name["en-US"],
629
+ slug: p.slug?.["en-US"] || p.id,
630
+ image: p.masterVariant.images?.[0]?.url || "https://placehold.co/400"
631
+ };
963
632
  result.products.push(product);
964
633
  }
965
- result.pages = Math.ceil((remote.body.total || 0) / query.pageSize);
966
- return result;
634
+ result.pages = Math.ceil((remoteData.body.total || 0) / payload.search.pageSize);
635
+ result.meta = {
636
+ cache: { hit: false, key: payload.search.term },
637
+ placeholder: false
638
+ };
639
+ return this.assert(result);
967
640
  }
968
641
  };
969
642
 
970
643
  // providers/commercetools/src/providers/product.provider.ts
971
644
  var CommercetoolsProductProvider = class extends ProductProvider {
972
- constructor(config, schema, querySchema, mutationSchema) {
973
- super(schema, querySchema, mutationSchema);
645
+ constructor(config, schema, cache) {
646
+ super(schema, cache);
974
647
  this.config = config;
975
648
  }
976
- async fetch(queries, session) {
977
- const ids = queries.filter((x) => x.query === "id").map((x) => x.id);
978
- const slugs = queries.filter((x) => x.query === "slug").map((x) => x.slug);
649
+ async getById(payload, _session) {
650
+ const client = new CommercetoolsClient(this.config).createAnonymousClient();
651
+ const remote = await client.withProjectKey({ projectKey: this.config.projectKey }).productProjections().withId({ ID: payload.id }).get().execute();
652
+ return this.parse(remote.body);
653
+ }
654
+ async getBySlug(payload, _session) {
979
655
  const client = new CommercetoolsClient(this.config).createAnonymousClient();
980
656
  const remote = await client.withProjectKey({ projectKey: this.config.projectKey }).productProjections().get({
981
657
  queryArgs: {
982
- where: "slug(en-US in :slugs)",
983
- "var.slugs": slugs
658
+ where: "slug(en-US = :slug)",
659
+ "var.slug": payload.slug
984
660
  }
985
661
  }).execute();
986
- console.log("remote: ", remote);
987
- const results = new Array();
988
- for (const r of remote.body.results) {
989
- const result = this.parse(r);
990
- results.push(result);
662
+ if (remote.body.results.length === 0) {
663
+ throw new Error(`Product with slug '${payload.slug}' not found`);
991
664
  }
992
- return results;
993
- }
994
- process(mutation, session) {
995
- throw new Error("Method not implemented.");
665
+ return this.parse(remote.body.results[0]);
996
666
  }
997
667
  parse(data) {
998
668
  const base = this.newModel();
999
- base.identifier.key = data.id;
669
+ base.identifier = { key: data.id };
1000
670
  base.name = data.name["en-US"];
1001
671
  base.slug = data.slug["en-US"];
1002
672
  if (data.description) {
1003
673
  base.description = data.description["en-US"];
1004
674
  }
1005
- if (data.masterVariant.images) {
675
+ if (data.masterVariant.images && data.masterVariant.images.length > 0) {
1006
676
  base.image = data.masterVariant.images[0].url;
1007
677
  }
678
+ base.images = [];
679
+ base.attributes = [];
680
+ base.skus = [];
1008
681
  const variants = [data.masterVariant, ...data.variants];
1009
682
  for (const variant of variants) {
1010
- base.skus.push({
1011
- identifier: {
1012
- key: variant.sku || ""
1013
- }
1014
- });
683
+ if (variant.sku) {
684
+ base.skus.push({
685
+ identifier: { key: variant.sku }
686
+ });
687
+ }
1015
688
  }
1016
- return base;
689
+ base.meta = {
690
+ cache: { hit: false, key: data.id },
691
+ placeholder: false
692
+ };
693
+ return this.assert(base);
1017
694
  }
1018
695
  };
1019
696
 
1020
697
  // providers/commercetools/src/providers/identity.provider.ts
1021
698
  var CommercetoolsIdentityProvider = class extends IdentityProvider {
1022
- constructor(config, schema, querySchema, mutationSchema) {
1023
- super(schema, querySchema, mutationSchema);
699
+ constructor(config, schema, cache) {
700
+ super(schema, cache);
1024
701
  this.config = config;
1025
702
  }
1026
- async fetch(queries, session) {
1027
- const results = [];
1028
- for (const query of queries) {
1029
- const result = await this.get(session);
1030
- results.push(result);
1031
- }
1032
- return results;
1033
- }
1034
- async process(mutations, session) {
1035
- let result = this.newModel();
1036
- for (const mutation of mutations) {
1037
- switch (mutation.mutation) {
1038
- case "login":
1039
- result = await this.login(mutation, session);
1040
- break;
1041
- case "logout":
1042
- result = await this.logout(session);
1043
- break;
1044
- }
1045
- }
1046
- return result;
1047
- }
1048
- async get(session) {
703
+ async getSelf(payload, session) {
1049
704
  const client = new CommercetoolsClient(this.config);
1050
705
  const base = this.newModel();
1051
706
  if (session.identity.token) {
@@ -1053,12 +708,20 @@ var CommercetoolsIdentityProvider = class extends IdentityProvider {
1053
708
  if (remote.active) {
1054
709
  const current = this.schema.safeParse(session.identity);
1055
710
  if (current.success) {
711
+ current.data.meta = {
712
+ cache: { hit: false, key: session.identity.id || "anonymous" },
713
+ placeholder: false
714
+ };
1056
715
  return current.data;
1057
716
  }
1058
717
  }
1059
718
  }
719
+ base.meta = {
720
+ cache: { hit: false, key: "anonymous" },
721
+ placeholder: false
722
+ };
1060
723
  session.identity = base;
1061
- return base;
724
+ return this.assert(base);
1062
725
  }
1063
726
  async login(payload, session) {
1064
727
  const client = new CommercetoolsClient(this.config);
@@ -1072,17 +735,25 @@ var CommercetoolsIdentityProvider = class extends IdentityProvider {
1072
735
  base.token = remote.access_token;
1073
736
  base.type = "Registered";
1074
737
  }
738
+ base.meta = {
739
+ cache: { hit: false, key: base.id || "anonymous" },
740
+ placeholder: false
741
+ };
1075
742
  session.identity = base;
1076
- return base;
743
+ return this.assert(base);
1077
744
  }
1078
- async logout(session) {
745
+ async logout(payload, session) {
1079
746
  const client = new CommercetoolsClient(this.config);
1080
747
  const base = this.newModel();
1081
748
  if (session.identity.token) {
1082
- const remote = await client.logout(session.identity.token);
749
+ await client.logout(session.identity.token);
1083
750
  }
751
+ base.meta = {
752
+ cache: { hit: false, key: "anonymous" },
753
+ placeholder: false
754
+ };
1084
755
  session.identity = base;
1085
- return base;
756
+ return this.assert(base);
1086
757
  }
1087
758
  extractCustomerIdFromScopes(scopes) {
1088
759
  const scopeList = scopes.split(" ");
@@ -1094,55 +765,22 @@ var CommercetoolsIdentityProvider = class extends IdentityProvider {
1094
765
 
1095
766
  // providers/commercetools/src/providers/cart.provider.ts
1096
767
  var CommercetoolsCartProvider = class extends CartProvider {
1097
- constructor(config, schema, querySchema, mutationSchema) {
1098
- super(schema, querySchema, mutationSchema);
768
+ constructor(config, schema, cache) {
769
+ super(schema, cache);
1099
770
  this.config = config;
1100
771
  }
1101
- async fetch(queries, session) {
1102
- const results = [];
1103
- for (const query of queries) {
1104
- if (query.cart.key) {
1105
- const client = this.getClient(session);
1106
- const remote = await client.withId({ ID: query.cart.key }).get().execute();
1107
- const result = this.composeCart(remote.body);
1108
- results.push(result);
1109
- }
1110
- }
1111
- return results;
1112
- }
1113
- async process(mutations, session) {
1114
- let cart = this.newModel();
1115
- for (const mutation of mutations) {
1116
- switch (mutation.mutation) {
1117
- case "add":
1118
- cart = await this.add(mutation, session);
1119
- break;
1120
- case "adjustQuantity":
1121
- cart = await this.adjust(mutation, session);
1122
- break;
1123
- case "remove":
1124
- cart = await this.remove(mutation, session);
1125
- }
772
+ async getById(payload, session) {
773
+ if (!payload.cart.key) {
774
+ const result = this.newModel();
775
+ result.meta = {
776
+ cache: { hit: false, key: "empty" },
777
+ placeholder: true
778
+ };
779
+ return this.assert(result);
1126
780
  }
1127
- return cart;
1128
- }
1129
- async adjust(payload, session) {
1130
781
  const client = this.getClient(session);
1131
- const existing = await client.withId({ ID: payload.cart.key }).get().execute();
1132
- const remote = await client.withId({ ID: payload.cart.key }).post({
1133
- body: {
1134
- version: existing.body.version,
1135
- actions: [
1136
- {
1137
- action: "changeLineItemQuantity",
1138
- lineItemId: payload.item.key,
1139
- quantity: payload.quantity
1140
- }
1141
- ]
1142
- }
1143
- }).execute();
1144
- const result = this.composeCart(remote.body);
1145
- return result;
782
+ const remote = await client.withId({ ID: payload.cart.key }).get().execute();
783
+ return this.composeCart(remote.body);
1146
784
  }
1147
785
  async add(payload, session) {
1148
786
  const client = this.getClient(session);
@@ -1173,8 +811,7 @@ var CommercetoolsCartProvider = class extends CartProvider {
1173
811
  ]
1174
812
  }
1175
813
  }).execute();
1176
- const result = this.composeCart(remoteAdd.body);
1177
- return result;
814
+ return this.composeCart(remoteAdd.body);
1178
815
  }
1179
816
  async remove(payload, session) {
1180
817
  const client = this.getClient(session);
@@ -1190,8 +827,24 @@ var CommercetoolsCartProvider = class extends CartProvider {
1190
827
  ]
1191
828
  }
1192
829
  }).execute();
1193
- const result = this.composeCart(remote.body);
1194
- return result;
830
+ return this.composeCart(remote.body);
831
+ }
832
+ async changeQuantity(payload, session) {
833
+ const client = this.getClient(session);
834
+ const existing = await client.withId({ ID: payload.cart.key }).get().execute();
835
+ const remote = await client.withId({ ID: payload.cart.key }).post({
836
+ body: {
837
+ version: existing.body.version,
838
+ actions: [
839
+ {
840
+ action: "changeLineItemQuantity",
841
+ lineItemId: payload.item.key,
842
+ quantity: payload.quantity
843
+ }
844
+ ]
845
+ }
846
+ }).execute();
847
+ return this.composeCart(remote.body);
1195
848
  }
1196
849
  getClient(session) {
1197
850
  const client = new CommercetoolsClient(this.config).getClient(
@@ -1210,41 +863,28 @@ var CommercetoolsCartProvider = class extends CartProvider {
1210
863
  item.quantity = remoteItem.quantity;
1211
864
  result.items.push(item);
1212
865
  }
1213
- return result;
866
+ result.meta = {
867
+ cache: { hit: false, key: remote.id },
868
+ placeholder: false
869
+ };
870
+ return this.assert(result);
1214
871
  }
1215
872
  };
1216
873
 
1217
874
  // providers/commercetools/src/providers/inventory.provider.ts
1218
875
  var CommercetoolsInventoryProvider = class extends InventoryProvider {
1219
- constructor(config, schema, querySchema, mutationSchema) {
1220
- super(schema, querySchema, mutationSchema);
1221
- this.cache = new RedisCache(new BaseCachingStrategy());
876
+ constructor(config, schema, cache) {
877
+ super(schema, cache);
1222
878
  this.config = config;
1223
879
  }
1224
- async fetch(queries, session) {
1225
- const results = [];
1226
- for (const query of queries) {
1227
- let result = await this.cache.get(query, session, this.schema);
1228
- console.log("from cache: ", result);
1229
- if (!result) {
1230
- result = await this.get(query, session);
1231
- this.cache.put(query, session, result);
1232
- }
1233
- results.push(result);
1234
- }
1235
- return results;
1236
- }
1237
- process(mutations, session) {
1238
- throw new Error("Method not implemented.");
1239
- }
1240
- async get(query, session) {
880
+ async getBySKU(payload, session) {
1241
881
  const client = new CommercetoolsClient(this.config).getClient(
1242
882
  session.identity?.token
1243
883
  );
1244
884
  const remote = await client.withProjectKey({ projectKey: this.config.projectKey }).inventory().get({
1245
885
  queryArgs: {
1246
886
  where: "sku=:sku",
1247
- "var.sku": query.sku
887
+ "var.sku": payload.sku
1248
888
  }
1249
889
  }).execute();
1250
890
  const base = this.newModel();
@@ -1252,73 +892,76 @@ var CommercetoolsInventoryProvider = class extends InventoryProvider {
1252
892
  const inv = remote.body.results[0];
1253
893
  base.quantity = inv.availableQuantity;
1254
894
  }
1255
- return base;
895
+ base.meta = {
896
+ cache: { hit: false, key: payload.sku },
897
+ placeholder: false
898
+ };
899
+ return this.assert(base);
1256
900
  }
1257
901
  };
1258
902
 
1259
903
  // providers/commercetools/src/providers/price.provider.ts
1260
904
  var CommercetoolsPriceProvider = class extends PriceProvider {
1261
- constructor(config, schema, querySchema, mutationSchema) {
1262
- super(schema, querySchema, mutationSchema);
905
+ constructor(config, schema, cache) {
906
+ super(schema, cache);
1263
907
  this.config = config;
1264
908
  }
1265
- async fetch(queries, session) {
909
+ async getBySKU(payload, session) {
1266
910
  const client = new CommercetoolsClient(this.config).getClient(
1267
911
  session.identity?.token
1268
912
  );
1269
913
  const queryArgs = {
1270
- where: "sku in :skus",
1271
- "var.skus": queries.map((x) => x.sku.key)
914
+ where: "sku=:sku",
915
+ "var.sku": payload.sku.key
1272
916
  };
1273
917
  const remote = await client.withProjectKey({ projectKey: this.config.projectKey }).standalonePrices().get({
1274
918
  queryArgs
1275
919
  }).execute();
1276
- const results = new Array();
1277
- for (const query of queries) {
1278
- const base = this.newModel();
1279
- const matched = remote.body.results.find((x) => x.sku === query.sku.key);
1280
- if (matched) {
1281
- base.value = {
1282
- cents: matched.value.centAmount,
1283
- currency: "USD"
1284
- };
1285
- }
1286
- base.identifier = {
1287
- sku: {
1288
- key: query.sku.key
1289
- }
920
+ const base = this.newModel();
921
+ if (remote.body.results.length > 0) {
922
+ const matched = remote.body.results[0];
923
+ base.value = {
924
+ cents: matched.value.centAmount,
925
+ currency: "USD"
1290
926
  };
1291
- results.push(base);
1292
927
  }
1293
- return results;
1294
- }
1295
- process(mutation, session) {
1296
- throw new Error("Method not implemented.");
928
+ base.identifier = {
929
+ sku: {
930
+ key: payload.sku.key
931
+ }
932
+ };
933
+ base.meta = {
934
+ cache: { hit: false, key: payload.sku.key },
935
+ placeholder: false
936
+ };
937
+ return this.assert(base);
1297
938
  }
1298
939
  };
1299
940
 
1300
941
  // providers/commercetools/src/core/initialize.ts
1301
942
  function withCommercetoolsCapabilities(configuration, capabilities) {
1302
- const client = {};
1303
- if (capabilities.product) {
1304
- client.product = new CommercetoolsProductProvider(configuration, ProductSchema, ProductQuerySchema, ProductMutationSchema);
1305
- }
1306
- if (capabilities.search) {
1307
- client.search = new CommercetoolsSearchProvider(configuration, SearchResultSchema, SearchQuerySchema, SearchMutationSchema);
1308
- }
1309
- if (capabilities.identity) {
1310
- client.identity = new CommercetoolsIdentityProvider(configuration, IdentitySchema, IdentityQuerySchema, IdentityMutationSchema);
1311
- }
1312
- if (capabilities.cart) {
1313
- client.cart = new CommercetoolsCartProvider(configuration, CartSchema, CartQuerySchema, CartMutationSchema);
1314
- }
1315
- if (capabilities.inventory) {
1316
- client.inventory = new CommercetoolsInventoryProvider(configuration, InventorySchema, InventoryQuerySchema, InventoryMutationSchema);
1317
- }
1318
- if (capabilities.price) {
1319
- client.price = new CommercetoolsPriceProvider(configuration, PriceSchema, PriceQuerySchema, PriceMutationSchema);
1320
- }
1321
- return client;
943
+ return (cache) => {
944
+ const client = {};
945
+ if (capabilities.product) {
946
+ client.product = new CommercetoolsProductProvider(configuration, ProductSchema, cache);
947
+ }
948
+ if (capabilities.search) {
949
+ client.search = new CommercetoolsSearchProvider(configuration, SearchResultSchema, cache);
950
+ }
951
+ if (capabilities.identity) {
952
+ client.identity = new CommercetoolsIdentityProvider(configuration, IdentitySchema, cache);
953
+ }
954
+ if (capabilities.cart) {
955
+ client.cart = new CommercetoolsCartProvider(configuration, CartSchema, cache);
956
+ }
957
+ if (capabilities.inventory) {
958
+ client.inventory = new CommercetoolsInventoryProvider(configuration, InventorySchema, cache);
959
+ }
960
+ if (capabilities.price) {
961
+ client.price = new CommercetoolsPriceProvider(configuration, PriceSchema, cache);
962
+ }
963
+ return client;
964
+ };
1322
965
  }
1323
966
 
1324
967
  // providers/commercetools/src/schema/capabilities.schema.ts
@@ -1332,13 +975,13 @@ var CommercetoolsCapabilitiesSchema = CapabilitiesSchema.pick({
1332
975
  }).partial();
1333
976
 
1334
977
  // providers/commercetools/src/schema/configuration.schema.ts
1335
- import { z as z26 } from "zod";
1336
- var CommercetoolsConfigurationSchema = z26.looseInterface({
1337
- projectKey: z26.string(),
1338
- authUrl: z26.string(),
1339
- apiUrl: z26.string(),
1340
- clientId: z26.string(),
1341
- clientSecret: z26.string()
978
+ import { z as z23 } from "zod";
979
+ var CommercetoolsConfigurationSchema = z23.looseInterface({
980
+ projectKey: z23.string(),
981
+ authUrl: z23.string(),
982
+ apiUrl: z23.string(),
983
+ clientId: z23.string(),
984
+ clientSecret: z23.string()
1342
985
  });
1343
986
  export {
1344
987
  CommercetoolsCapabilitiesSchema,
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@reactionary/provider-commercetools",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "dependencies": {
5
- "@reactionary/core": "0.0.30",
5
+ "@reactionary/core": "0.0.32",
6
6
  "zod": "4.0.0-beta.20250430T185432",
7
7
  "@commercetools/ts-client": "^3.2.2",
8
8
  "@commercetools/platform-sdk": "^8.8.0"
@@ -1,4 +1,4 @@
1
- import { Client } from "@reactionary/core";
1
+ import { Client, Cache } from "@reactionary/core";
2
2
  import { CommercetoolsCapabilities } from "../schema/capabilities.schema";
3
3
  import { CommercetoolsConfiguration } from "../schema/configuration.schema";
4
- export declare function withCommercetoolsCapabilities(configuration: CommercetoolsConfiguration, capabilities: CommercetoolsCapabilities): Partial<Client>;
4
+ export declare function withCommercetoolsCapabilities(configuration: CommercetoolsConfiguration, capabilities: CommercetoolsCapabilities): (cache: Cache) => Partial<Client>;
@@ -1,15 +1,14 @@
1
- import { Cart, CartMutation, CartMutationItemAdd, CartMutationItemQuantityChange, CartMutationItemRemove, CartProvider, CartQuery, Session } from '@reactionary/core';
1
+ import { Cart, CartMutationItemAdd, CartMutationItemQuantityChange, CartMutationItemRemove, CartProvider, CartQueryById, Session, Cache } from '@reactionary/core';
2
2
  import { CommercetoolsConfiguration } from '../schema/configuration.schema';
3
3
  import { z } from 'zod';
4
4
  import { Cart as CTCart } from '@commercetools/platform-sdk';
5
- export declare class CommercetoolsCartProvider<T extends Cart = Cart, Q extends CartQuery = CartQuery, M extends CartMutation = CartMutation> extends CartProvider<T, Q, M> {
5
+ export declare class CommercetoolsCartProvider<T extends Cart = Cart> extends CartProvider<T> {
6
6
  protected config: CommercetoolsConfiguration;
7
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>);
8
- protected fetch(queries: Q[], session: Session): Promise<T[]>;
9
- protected process(mutations: M[], session: Session): Promise<T>;
10
- protected adjust(payload: CartMutationItemQuantityChange, session: Session): Promise<T>;
11
- protected add(payload: CartMutationItemAdd, session: Session): Promise<T>;
12
- protected remove(payload: CartMutationItemRemove, session: Session): Promise<T>;
7
+ constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache);
8
+ getById(payload: CartQueryById, session: Session): Promise<T>;
9
+ add(payload: CartMutationItemAdd, session: Session): Promise<T>;
10
+ remove(payload: CartMutationItemRemove, session: Session): Promise<T>;
11
+ changeQuantity(payload: CartMutationItemQuantityChange, session: Session): Promise<T>;
13
12
  protected getClient(session: Session): import("@commercetools/platform-sdk").ByProjectKeyCartsRequestBuilder;
14
13
  protected composeCart(remote: CTCart): T;
15
14
  }
@@ -1,13 +1,11 @@
1
- import { Identity, IdentityMutation, IdentityMutationLogin, IdentityProvider, IdentityQuery, Session } from '@reactionary/core';
1
+ import { Identity, IdentityMutationLogin, IdentityProvider, IdentityQuerySelf, Session, Cache } from '@reactionary/core';
2
2
  import { CommercetoolsConfiguration } from '../schema/configuration.schema';
3
3
  import z from 'zod';
4
- export declare class CommercetoolsIdentityProvider<T extends Identity = Identity, Q extends IdentityQuery = IdentityQuery, M extends IdentityMutation = IdentityMutation> extends IdentityProvider<T, Q, M> {
4
+ export declare class CommercetoolsIdentityProvider<T extends Identity = Identity> extends IdentityProvider<T> {
5
5
  protected config: CommercetoolsConfiguration;
6
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>);
7
- protected fetch(queries: Q[], session: Session): Promise<T[]>;
8
- protected process(mutations: M[], session: Session): Promise<T>;
9
- protected get(session: Session): Promise<T>;
10
- protected login(payload: IdentityMutationLogin, session: Session): Promise<T>;
11
- protected logout(session: Session): Promise<T>;
6
+ constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache);
7
+ getSelf(payload: IdentityQuerySelf, session: Session): Promise<T>;
8
+ login(payload: IdentityMutationLogin, session: Session): Promise<T>;
9
+ logout(payload: Record<string, never>, session: Session): Promise<T>;
12
10
  protected extractCustomerIdFromScopes(scopes: string): string;
13
11
  }
@@ -1,12 +1,8 @@
1
- import { Inventory, InventoryProvider, InventoryQuery, RedisCache, Session } from '@reactionary/core';
1
+ import { Inventory, InventoryProvider, InventoryQuery, Session, Cache } from '@reactionary/core';
2
2
  import z from 'zod';
3
3
  import { CommercetoolsConfiguration } from '../schema/configuration.schema';
4
- import { InventoryMutation } from 'core/src/schemas/mutations/inventory.mutation';
5
- export declare class CommercetoolsInventoryProvider<T extends Inventory = Inventory, Q extends InventoryQuery = InventoryQuery, M extends InventoryMutation = InventoryMutation> extends InventoryProvider<T, Q, M> {
4
+ export declare class CommercetoolsInventoryProvider<T extends Inventory = Inventory> extends InventoryProvider<T> {
6
5
  protected config: CommercetoolsConfiguration;
7
- protected cache: RedisCache;
8
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>);
9
- protected fetch(queries: Q[], session: Session): Promise<T[]>;
10
- protected process(mutations: M[], session: Session): Promise<T>;
11
- protected get(query: Q, session: Session): Promise<T>;
6
+ constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache);
7
+ getBySKU(payload: InventoryQuery, session: Session): Promise<T>;
12
8
  }
@@ -1,10 +1,8 @@
1
- import { BaseMutation, Price, PriceProvider, PriceQuery, Session } from '@reactionary/core';
1
+ import { Price, PriceProvider, PriceQueryBySku, Session, Cache } from '@reactionary/core';
2
2
  import z from 'zod';
3
3
  import { CommercetoolsConfiguration } from '../schema/configuration.schema';
4
- import { PriceMutation } from 'core/src/schemas/mutations/price.mutation';
5
- export declare class CommercetoolsPriceProvider<T extends Price = Price, Q extends PriceQuery = PriceQuery, M extends PriceMutation = PriceMutation> extends PriceProvider<T, Q, M> {
4
+ export declare class CommercetoolsPriceProvider<T extends Price = Price> extends PriceProvider<T> {
6
5
  protected config: CommercetoolsConfiguration;
7
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>);
8
- protected fetch(queries: Q[], session: Session): Promise<T[]>;
9
- protected process(mutation: BaseMutation[], session: Session): Promise<T>;
6
+ constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache);
7
+ getBySKU(payload: PriceQueryBySku, session: Session): Promise<T>;
10
8
  }
@@ -1,11 +1,11 @@
1
- import { ProductProvider, ProductQuery, Product, Session, BaseMutation, ProductMutation } from '@reactionary/core';
1
+ import { ProductProvider, Product, ProductQueryById, ProductQueryBySlug, Session, Cache } from '@reactionary/core';
2
2
  import { z } from 'zod';
3
3
  import { CommercetoolsConfiguration } from '../schema/configuration.schema';
4
4
  import { ProductProjection } from '@commercetools/platform-sdk';
5
- export declare class CommercetoolsProductProvider<T extends Product = Product, Q extends ProductQuery = ProductQuery, M extends ProductMutation = ProductMutation> extends ProductProvider<T, Q, M> {
5
+ export declare class CommercetoolsProductProvider<T extends Product = Product> extends ProductProvider<T> {
6
6
  protected config: CommercetoolsConfiguration;
7
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>);
8
- protected fetch(queries: ProductQuery[], session: Session): Promise<T[]>;
9
- protected process(mutation: BaseMutation[], session: Session): Promise<T>;
7
+ constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache);
8
+ getById(payload: ProductQueryById, _session: Session): Promise<T>;
9
+ getBySlug(payload: ProductQueryBySlug, _session: Session): Promise<T>;
10
10
  protected parse(data: ProductProjection): T;
11
11
  }
@@ -1,11 +1,9 @@
1
- import { SearchIdentifier, SearchMutation, SearchProvider, SearchQuery, SearchResult, Session } from '@reactionary/core';
1
+ import { SearchProvider, SearchQueryByTerm, SearchResult, Session, Cache } from '@reactionary/core';
2
2
  import z from 'zod';
3
3
  import { CommercetoolsConfiguration } from '../schema/configuration.schema';
4
- export declare class CommercetoolsSearchProvider<T extends SearchResult = SearchResult, Q extends SearchQuery = SearchQuery, M extends SearchMutation = SearchMutation> extends SearchProvider<T, Q, M> {
4
+ export declare class CommercetoolsSearchProvider<T extends SearchResult = SearchResult> extends SearchProvider<T> {
5
5
  protected config: CommercetoolsConfiguration;
6
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>);
7
- protected fetch(queries: Q[], session: Session): Promise<T[]>;
8
- protected process(mutations: M[], session: Session): Promise<T>;
9
- get(identifier: SearchIdentifier): Promise<T>;
10
- parse(remote: any, query: SearchIdentifier): T;
6
+ constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache);
7
+ queryByTerm(payload: SearchQueryByTerm, _session: Session): Promise<T>;
8
+ protected parseSearchResult(remote: unknown, payload: SearchQueryByTerm): T;
11
9
  }