@reactionary/provider-algolia 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
|
@@ -1,244 +1,16 @@
|
|
|
1
1
|
// core/src/cache/redis-cache.ts
|
|
2
2
|
import { Redis } from "@upstash/redis";
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
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
10
|
var BaseProvider = class {
|
|
237
|
-
constructor(schema,
|
|
11
|
+
constructor(schema, cache) {
|
|
238
12
|
this.schema = schema;
|
|
239
|
-
this.
|
|
240
|
-
this.mutationSchema = mutationSchema;
|
|
241
|
-
this.instrumentation = createProviderInstrumentation(this.constructor.name);
|
|
13
|
+
this.cache = cache;
|
|
242
14
|
}
|
|
243
15
|
/**
|
|
244
16
|
* Validates that the final domain model constructed by the provider
|
|
@@ -254,41 +26,12 @@ var BaseProvider = class {
|
|
|
254
26
|
return this.schema.parse({});
|
|
255
27
|
}
|
|
256
28
|
/**
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* result list will never contain nulls or undefined. The order
|
|
260
|
-
* 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.
|
|
261
31
|
*/
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
async (span) => {
|
|
266
|
-
span.setAttribute("provider.query.count", queries.length);
|
|
267
|
-
const results = await this.fetch(queries, session);
|
|
268
|
-
for (const result of results) {
|
|
269
|
-
this.assert(result);
|
|
270
|
-
}
|
|
271
|
-
span.setAttribute("provider.result.count", results.length);
|
|
272
|
-
return results;
|
|
273
|
-
},
|
|
274
|
-
{ queryCount: queries.length }
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Executes the listed mutations in order and returns the final state
|
|
279
|
-
* resulting from that set of operations.
|
|
280
|
-
*/
|
|
281
|
-
async mutate(mutations, session) {
|
|
282
|
-
return this.instrumentation.traceMutation(
|
|
283
|
-
"mutate",
|
|
284
|
-
async (span) => {
|
|
285
|
-
span.setAttribute("provider.mutation.count", mutations.length);
|
|
286
|
-
const result = await this.process(mutations, session);
|
|
287
|
-
this.assert(result);
|
|
288
|
-
return result;
|
|
289
|
-
},
|
|
290
|
-
{ mutationCount: mutations.length }
|
|
291
|
-
);
|
|
32
|
+
parseSingle(_body) {
|
|
33
|
+
const model = this.newModel();
|
|
34
|
+
return this.assert(model);
|
|
292
35
|
}
|
|
293
36
|
};
|
|
294
37
|
|
|
@@ -645,42 +388,32 @@ var SearchResultSchema = BaseModelSchema.extend({
|
|
|
645
388
|
|
|
646
389
|
// core/src/schemas/mutations/base.mutation.ts
|
|
647
390
|
import { z as z12 } from "zod";
|
|
648
|
-
var BaseMutationSchema = z12.looseInterface({
|
|
649
|
-
mutation: z12.ZodLiteral
|
|
650
|
-
});
|
|
391
|
+
var BaseMutationSchema = z12.looseInterface({});
|
|
651
392
|
|
|
652
393
|
// core/src/schemas/mutations/cart.mutation.ts
|
|
653
394
|
import { z as z13 } from "zod";
|
|
654
395
|
var CartMutationItemAddSchema = BaseMutationSchema.extend({
|
|
655
|
-
mutation: z13.literal("add"),
|
|
656
396
|
cart: CartIdentifierSchema.required(),
|
|
657
397
|
product: ProductIdentifierSchema.required(),
|
|
658
398
|
quantity: z13.number()
|
|
659
399
|
});
|
|
660
400
|
var CartMutationItemRemoveSchema = BaseMutationSchema.extend({
|
|
661
|
-
mutation: z13.literal("remove"),
|
|
662
401
|
cart: CartIdentifierSchema.required(),
|
|
663
402
|
item: CartItemIdentifierSchema.required()
|
|
664
403
|
});
|
|
665
404
|
var CartMutationItemQuantityChangeSchema = BaseMutationSchema.extend({
|
|
666
|
-
mutation: z13.literal("adjustQuantity"),
|
|
667
405
|
cart: CartIdentifierSchema.required(),
|
|
668
406
|
item: CartItemIdentifierSchema.required(),
|
|
669
407
|
quantity: z13.number()
|
|
670
408
|
});
|
|
671
|
-
var CartMutationSchema = z13.union([CartMutationItemAddSchema, CartMutationItemRemoveSchema, CartMutationItemQuantityChangeSchema]);
|
|
672
409
|
|
|
673
410
|
// core/src/schemas/mutations/identity.mutation.ts
|
|
674
411
|
import { z as z14 } from "zod";
|
|
675
412
|
var IdentityMutationLoginSchema = BaseMutationSchema.extend({
|
|
676
|
-
mutation: z14.literal("login"),
|
|
677
413
|
username: z14.string(),
|
|
678
414
|
password: z14.string()
|
|
679
415
|
});
|
|
680
|
-
var IdentityMutationLogoutSchema = BaseMutationSchema.extend({
|
|
681
|
-
mutation: z14.literal("logout")
|
|
682
|
-
});
|
|
683
|
-
var IdentityMutationSchema = z14.union([IdentityMutationLoginSchema, IdentityMutationLogoutSchema]);
|
|
416
|
+
var IdentityMutationLogoutSchema = BaseMutationSchema.extend({});
|
|
684
417
|
|
|
685
418
|
// core/src/schemas/mutations/inventory.mutation.ts
|
|
686
419
|
import { z as z15 } from "zod";
|
|
@@ -700,162 +433,154 @@ var SearchMutationSchema = z18.union([]);
|
|
|
700
433
|
|
|
701
434
|
// core/src/schemas/queries/base.query.ts
|
|
702
435
|
import { z as z19 } from "zod";
|
|
703
|
-
var BaseQuerySchema = z19.looseInterface({
|
|
704
|
-
query: z19.ZodLiteral
|
|
705
|
-
});
|
|
436
|
+
var BaseQuerySchema = z19.looseInterface({});
|
|
706
437
|
|
|
707
438
|
// core/src/schemas/queries/cart.query.ts
|
|
708
439
|
import { z as z20 } from "zod";
|
|
709
440
|
var CartQueryByIdSchema = BaseQuerySchema.extend({
|
|
710
|
-
query: z20.literal("id"),
|
|
711
441
|
cart: CartIdentifierSchema.required()
|
|
712
442
|
});
|
|
713
443
|
var CartQuerySchema = z20.union([CartQueryByIdSchema]);
|
|
714
444
|
|
|
715
445
|
// core/src/schemas/queries/identity.query.ts
|
|
716
|
-
|
|
717
|
-
var IdentityQuerySelfSchema = BaseQuerySchema.extend({
|
|
718
|
-
query: z21.literal("self")
|
|
719
|
-
});
|
|
720
|
-
var IdentityQuerySchema = z21.union([IdentityQuerySelfSchema]);
|
|
446
|
+
var IdentityQuerySelfSchema = BaseQuerySchema.extend({});
|
|
721
447
|
|
|
722
448
|
// core/src/schemas/queries/inventory.query.ts
|
|
723
|
-
import { z as
|
|
449
|
+
import { z as z21 } from "zod";
|
|
724
450
|
var InventoryQuerySchema = BaseQuerySchema.extend({
|
|
725
|
-
|
|
726
|
-
sku: z22.string()
|
|
451
|
+
sku: z21.string()
|
|
727
452
|
});
|
|
728
453
|
|
|
729
454
|
// core/src/schemas/queries/price.query.ts
|
|
730
|
-
import { z as z23 } from "zod";
|
|
731
455
|
var PriceQueryBySkuSchema = BaseQuerySchema.extend({
|
|
732
|
-
query: z23.literal("sku"),
|
|
733
456
|
sku: SKUIdentifierSchema.required()
|
|
734
457
|
});
|
|
735
|
-
var PriceQuerySchema = z23.union([PriceQueryBySkuSchema]);
|
|
736
458
|
|
|
737
459
|
// core/src/schemas/queries/product.query.ts
|
|
738
|
-
import { z as
|
|
460
|
+
import { z as z22 } from "zod";
|
|
739
461
|
var ProductQueryBySlugSchema = BaseQuerySchema.extend({
|
|
740
|
-
|
|
741
|
-
slug: z24.string()
|
|
462
|
+
slug: z22.string()
|
|
742
463
|
});
|
|
743
464
|
var ProductQueryByIdSchema = BaseQuerySchema.extend({
|
|
744
|
-
|
|
745
|
-
id: z24.string()
|
|
465
|
+
id: z22.string()
|
|
746
466
|
});
|
|
747
|
-
var ProductQuerySchema = z24.union([ProductQueryBySlugSchema, ProductQueryByIdSchema]);
|
|
748
467
|
|
|
749
468
|
// core/src/schemas/queries/search.query.ts
|
|
750
|
-
import { z as z25 } from "zod";
|
|
751
469
|
var SearchQueryByTermSchema = BaseQuerySchema.extend({
|
|
752
|
-
query: z25.literal("term"),
|
|
753
470
|
search: SearchIdentifierSchema.required()
|
|
754
471
|
});
|
|
755
|
-
var SearchQuerySchema = z25.union([SearchQueryByTermSchema]);
|
|
756
472
|
|
|
757
473
|
// providers/algolia/src/providers/product.provider.ts
|
|
758
474
|
var AlgoliaProductProvider = class extends ProductProvider {
|
|
759
|
-
constructor(config, schema,
|
|
760
|
-
super(schema,
|
|
475
|
+
constructor(config, schema, cache) {
|
|
476
|
+
super(schema, cache);
|
|
761
477
|
this.config = config;
|
|
762
478
|
}
|
|
763
|
-
async
|
|
764
|
-
|
|
479
|
+
async getById(payload, _session) {
|
|
480
|
+
const result = this.newModel();
|
|
481
|
+
result.identifier = { key: payload.id };
|
|
482
|
+
result.name = `Algolia Product ${payload.id}`;
|
|
483
|
+
result.slug = payload.id;
|
|
484
|
+
result.description = "Product from Algolia";
|
|
485
|
+
result.meta = {
|
|
486
|
+
cache: { hit: false, key: payload.id },
|
|
487
|
+
placeholder: true
|
|
488
|
+
};
|
|
489
|
+
return this.assert(result);
|
|
765
490
|
}
|
|
766
|
-
|
|
767
|
-
|
|
491
|
+
async getBySlug(payload, _session) {
|
|
492
|
+
const result = this.newModel();
|
|
493
|
+
result.identifier = { key: payload.slug };
|
|
494
|
+
result.name = `Algolia Product ${payload.slug}`;
|
|
495
|
+
result.slug = payload.slug;
|
|
496
|
+
result.description = "Product from Algolia";
|
|
497
|
+
result.meta = {
|
|
498
|
+
cache: { hit: false, key: payload.slug },
|
|
499
|
+
placeholder: true
|
|
500
|
+
};
|
|
501
|
+
return this.assert(result);
|
|
768
502
|
}
|
|
769
503
|
};
|
|
770
504
|
|
|
771
505
|
// providers/algolia/src/providers/search.provider.ts
|
|
772
506
|
import { algoliasearch } from "algoliasearch";
|
|
773
507
|
var AlgoliaSearchProvider = class extends SearchProvider {
|
|
774
|
-
constructor(config, schema,
|
|
775
|
-
super(schema,
|
|
508
|
+
constructor(config, schema, cache) {
|
|
509
|
+
super(schema, cache);
|
|
776
510
|
this.config = config;
|
|
777
511
|
}
|
|
778
|
-
async
|
|
779
|
-
const results = [];
|
|
780
|
-
for (const query of queries) {
|
|
781
|
-
const result = await this.get(query.search);
|
|
782
|
-
results.push(result);
|
|
783
|
-
}
|
|
784
|
-
return results;
|
|
785
|
-
}
|
|
786
|
-
process(mutations, session) {
|
|
787
|
-
throw new Error("Method not implemented.");
|
|
788
|
-
}
|
|
789
|
-
async get(identifier) {
|
|
512
|
+
async queryByTerm(payload, _session) {
|
|
790
513
|
const client = algoliasearch(this.config.appId, this.config.apiKey);
|
|
791
514
|
const remote = await client.search({
|
|
792
515
|
requests: [
|
|
793
516
|
{
|
|
794
517
|
indexName: this.config.indexName,
|
|
795
|
-
query:
|
|
796
|
-
page:
|
|
797
|
-
hitsPerPage:
|
|
518
|
+
query: payload.search.term,
|
|
519
|
+
page: payload.search.page,
|
|
520
|
+
hitsPerPage: payload.search.pageSize,
|
|
798
521
|
facets: ["*"],
|
|
799
522
|
analytics: true,
|
|
800
523
|
clickAnalytics: true,
|
|
801
|
-
facetFilters:
|
|
524
|
+
facetFilters: payload.search.facets.map(
|
|
802
525
|
(x) => `${encodeURIComponent(x.facet.key)}:${x.key}`
|
|
803
526
|
)
|
|
804
527
|
}
|
|
805
528
|
]
|
|
806
529
|
});
|
|
807
|
-
|
|
808
|
-
return parsed;
|
|
530
|
+
return this.parseSearchResult(remote, payload);
|
|
809
531
|
}
|
|
810
|
-
|
|
532
|
+
parseSearchResult(remote, payload) {
|
|
811
533
|
const result = this.newModel();
|
|
812
|
-
const
|
|
534
|
+
const remoteData = remote;
|
|
535
|
+
const remoteProducts = remoteData.results[0];
|
|
813
536
|
for (const id in remoteProducts.facets) {
|
|
814
537
|
const f = remoteProducts.facets[id];
|
|
815
|
-
const facet =
|
|
816
|
-
|
|
817
|
-
|
|
538
|
+
const facet = {
|
|
539
|
+
identifier: { key: id },
|
|
540
|
+
name: id,
|
|
541
|
+
values: []
|
|
542
|
+
};
|
|
818
543
|
for (const vid in f) {
|
|
819
544
|
const fv = f[vid];
|
|
820
|
-
const
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
}
|
|
830
|
-
facet.values.push(facetValue);
|
|
545
|
+
const isActive = payload.search.facets.find(
|
|
546
|
+
(x) => x.facet.key === id && x.key === vid
|
|
547
|
+
);
|
|
548
|
+
facet.values.push({
|
|
549
|
+
identifier: { key: vid, facet: { key: id } },
|
|
550
|
+
count: fv,
|
|
551
|
+
name: vid,
|
|
552
|
+
active: !!isActive
|
|
553
|
+
});
|
|
831
554
|
}
|
|
832
555
|
result.facets.push(facet);
|
|
833
556
|
}
|
|
834
557
|
for (const p of remoteProducts.hits) {
|
|
835
558
|
result.products.push({
|
|
836
|
-
identifier: {
|
|
837
|
-
key: p.objectID
|
|
838
|
-
},
|
|
559
|
+
identifier: { key: p.objectID },
|
|
839
560
|
slug: p.slug,
|
|
840
561
|
name: p.name,
|
|
841
562
|
image: p.image
|
|
842
563
|
});
|
|
843
564
|
}
|
|
844
565
|
result.identifier = {
|
|
845
|
-
...
|
|
566
|
+
...payload.search,
|
|
846
567
|
index: remoteProducts.index,
|
|
847
568
|
key: remoteProducts.queryID
|
|
848
569
|
};
|
|
849
570
|
result.pages = remoteProducts.nbPages;
|
|
850
|
-
|
|
571
|
+
result.meta = {
|
|
572
|
+
cache: { hit: false, key: payload.search.term },
|
|
573
|
+
placeholder: false
|
|
574
|
+
};
|
|
575
|
+
return this.assert(result);
|
|
851
576
|
}
|
|
852
577
|
};
|
|
853
578
|
|
|
854
579
|
// providers/algolia/src/schema/search.schema.ts
|
|
855
|
-
import { z as
|
|
580
|
+
import { z as z23 } from "zod";
|
|
856
581
|
var AlgoliaSearchIdentifierSchema = SearchIdentifierSchema.extend({
|
|
857
|
-
key:
|
|
858
|
-
index:
|
|
582
|
+
key: z23.string().default(""),
|
|
583
|
+
index: z23.string().default("")
|
|
859
584
|
});
|
|
860
585
|
var AlgoliaSearchResultSchema = SearchResultSchema.extend({
|
|
861
586
|
identifier: AlgoliaSearchIdentifierSchema.default(() => AlgoliaSearchIdentifierSchema.parse({}))
|
|
@@ -863,22 +588,24 @@ var AlgoliaSearchResultSchema = SearchResultSchema.extend({
|
|
|
863
588
|
|
|
864
589
|
// providers/algolia/src/core/initialize.ts
|
|
865
590
|
function withAlgoliaCapabilities(configuration, capabilities) {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
591
|
+
return (cache) => {
|
|
592
|
+
const client = {};
|
|
593
|
+
if (capabilities.product) {
|
|
594
|
+
client.product = new AlgoliaProductProvider(configuration, ProductSchema, cache);
|
|
595
|
+
}
|
|
596
|
+
if (capabilities.search) {
|
|
597
|
+
client.search = new AlgoliaSearchProvider(configuration, AlgoliaSearchResultSchema, cache);
|
|
598
|
+
}
|
|
599
|
+
return client;
|
|
600
|
+
};
|
|
874
601
|
}
|
|
875
602
|
|
|
876
603
|
// providers/algolia/src/schema/configuration.schema.ts
|
|
877
|
-
import { z as
|
|
878
|
-
var AlgoliaConfigurationSchema =
|
|
879
|
-
appId:
|
|
880
|
-
apiKey:
|
|
881
|
-
indexName:
|
|
604
|
+
import { z as z24 } from "zod";
|
|
605
|
+
var AlgoliaConfigurationSchema = z24.looseInterface({
|
|
606
|
+
appId: z24.string(),
|
|
607
|
+
apiKey: z24.string(),
|
|
608
|
+
indexName: z24.string()
|
|
882
609
|
});
|
|
883
610
|
|
|
884
611
|
// providers/algolia/src/schema/capabilities.schema.ts
|
package/package.json
CHANGED
package/src/core/initialize.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Client } from "@reactionary/core";
|
|
1
|
+
import { Client, Cache } from "@reactionary/core";
|
|
2
2
|
import { AlgoliaCapabilities } from "../schema/capabilities.schema";
|
|
3
3
|
import { AlgoliaConfiguration } from "../schema/configuration.schema";
|
|
4
|
-
export declare function withAlgoliaCapabilities(configuration: AlgoliaConfiguration, capabilities: AlgoliaCapabilities): Partial<Client>;
|
|
4
|
+
export declare function withAlgoliaCapabilities(configuration: AlgoliaConfiguration, capabilities: AlgoliaCapabilities): (cache: Cache) => Partial<Client>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Product, ProductProvider, ProductQueryById, ProductQueryBySlug, Session, Cache } from '@reactionary/core';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { AlgoliaConfiguration } from '../schema/configuration.schema';
|
|
4
|
-
export declare class AlgoliaProductProvider<T extends Product = Product
|
|
4
|
+
export declare class AlgoliaProductProvider<T extends Product = Product> extends ProductProvider<T> {
|
|
5
5
|
protected config: AlgoliaConfiguration;
|
|
6
|
-
constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>,
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>, cache: Cache);
|
|
7
|
+
getById(payload: ProductQueryById, _session: Session): Promise<T>;
|
|
8
|
+
getBySlug(payload: ProductQueryBySlug, _session: Session): Promise<T>;
|
|
9
9
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SearchProvider, SearchQueryByTerm, SearchResult, Session, Cache } from '@reactionary/core';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { AlgoliaConfiguration } from '../schema/configuration.schema';
|
|
4
|
-
export declare class AlgoliaSearchProvider<T extends SearchResult = SearchResult
|
|
4
|
+
export declare class AlgoliaSearchProvider<T extends SearchResult = SearchResult> extends SearchProvider<T> {
|
|
5
5
|
protected config: AlgoliaConfiguration;
|
|
6
|
-
constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>,
|
|
7
|
-
|
|
8
|
-
protected
|
|
9
|
-
protected get(identifier: SearchIdentifier): Promise<T>;
|
|
10
|
-
protected parse(remote: any, query: SearchIdentifier): T;
|
|
6
|
+
constructor(config: AlgoliaConfiguration, schema: z.ZodType<T>, cache: Cache);
|
|
7
|
+
queryByTerm(payload: SearchQueryByTerm, _session: Session): Promise<SearchResult>;
|
|
8
|
+
protected parseSearchResult(remote: unknown, payload: SearchQueryByTerm): T;
|
|
11
9
|
}
|