@reactionary/source 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.
Files changed (119) hide show
  1. package/CLAUDE.md +11 -0
  2. package/core/package.json +1 -1
  3. package/core/src/cache/cache-evaluation.interface.ts +19 -0
  4. package/core/src/cache/cache.interface.ts +38 -0
  5. package/core/src/cache/noop-cache.ts +42 -0
  6. package/core/src/cache/redis-cache.ts +55 -22
  7. package/core/src/client/client-builder.ts +63 -0
  8. package/core/src/client/client.ts +27 -3
  9. package/core/src/decorators/trpc.decorators.ts +144 -0
  10. package/core/src/index.ts +6 -1
  11. package/core/src/providers/analytics.provider.ts +3 -6
  12. package/core/src/providers/base.provider.ts +13 -63
  13. package/core/src/providers/cart.provider.ts +10 -6
  14. package/core/src/providers/identity.provider.ts +8 -5
  15. package/core/src/providers/inventory.provider.ts +5 -6
  16. package/core/src/providers/price.provider.ts +6 -6
  17. package/core/src/providers/product.provider.ts +6 -6
  18. package/core/src/providers/search.provider.ts +6 -6
  19. package/core/src/schemas/mutations/base.mutation.ts +0 -1
  20. package/core/src/schemas/mutations/cart.mutation.ts +0 -6
  21. package/core/src/schemas/mutations/identity.mutation.ts +0 -5
  22. package/core/src/schemas/mutations/product.mutation.ts +0 -1
  23. package/core/src/schemas/queries/base.query.ts +0 -1
  24. package/core/src/schemas/queries/cart.query.ts +1 -3
  25. package/core/src/schemas/queries/identity.query.ts +1 -3
  26. package/core/src/schemas/queries/inventory.query.ts +0 -1
  27. package/core/src/schemas/queries/price.query.ts +0 -3
  28. package/core/src/schemas/queries/product.query.ts +2 -7
  29. package/core/src/schemas/queries/search.query.ts +0 -3
  30. package/examples/node/package.json +1 -5
  31. package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +97 -0
  32. package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +84 -0
  33. package/examples/node/src/basic/basic-node-setup.spec.ts +40 -0
  34. package/otel/src/index.ts +3 -0
  35. package/otel/src/trace-decorator.ts +246 -0
  36. package/package.json +2 -1
  37. package/providers/algolia/src/core/initialize.ts +11 -9
  38. package/providers/algolia/src/providers/product.provider.ts +44 -11
  39. package/providers/algolia/src/providers/search.provider.ts +47 -66
  40. package/providers/commercetools/src/core/client.ts +0 -1
  41. package/providers/commercetools/src/core/initialize.ts +28 -24
  42. package/providers/commercetools/src/providers/cart.provider.ts +58 -89
  43. package/providers/commercetools/src/providers/identity.provider.ts +34 -50
  44. package/providers/commercetools/src/providers/inventory.provider.ts +16 -38
  45. package/providers/commercetools/src/providers/price.provider.ts +30 -35
  46. package/providers/commercetools/src/providers/product.provider.ts +48 -38
  47. package/providers/commercetools/src/providers/search.provider.ts +32 -47
  48. package/providers/commercetools/src/schema/capabilities.schema.ts +1 -1
  49. package/providers/fake/package.json +1 -0
  50. package/providers/fake/src/core/initialize.ts +17 -14
  51. package/providers/fake/src/index.ts +4 -0
  52. package/providers/fake/src/providers/analytics.provider.ts +19 -0
  53. package/providers/fake/src/providers/cart.provider.ts +107 -0
  54. package/providers/fake/src/providers/identity.provider.ts +78 -67
  55. package/providers/fake/src/providers/inventory.provider.ts +54 -0
  56. package/providers/fake/src/providers/price.provider.ts +60 -0
  57. package/providers/fake/src/providers/product.provider.ts +53 -49
  58. package/providers/fake/src/providers/search.provider.ts +15 -33
  59. package/providers/posthog/src/core/initialize.ts +6 -4
  60. package/trpc/__mocks__/superjson.js +25 -0
  61. package/trpc/jest.config.ts +14 -0
  62. package/trpc/package.json +2 -1
  63. package/trpc/src/client.ts +176 -0
  64. package/trpc/src/index.ts +35 -62
  65. package/trpc/src/integration.spec.ts +216 -0
  66. package/trpc/src/server.ts +123 -0
  67. package/trpc/src/transparent-client.spec.ts +160 -0
  68. package/trpc/src/types.ts +142 -0
  69. package/trpc/tsconfig.json +3 -0
  70. package/trpc/tsconfig.lib.json +2 -1
  71. package/trpc/tsconfig.spec.json +15 -0
  72. package/tsconfig.base.json +0 -2
  73. package/core/src/cache/caching-strategy.ts +0 -25
  74. package/examples/angular/e2e/example.spec.ts +0 -9
  75. package/examples/angular/eslint.config.mjs +0 -41
  76. package/examples/angular/playwright.config.ts +0 -38
  77. package/examples/angular/project.json +0 -86
  78. package/examples/angular/public/favicon.ico +0 -0
  79. package/examples/angular/src/app/app.component.html +0 -6
  80. package/examples/angular/src/app/app.component.scss +0 -22
  81. package/examples/angular/src/app/app.component.ts +0 -14
  82. package/examples/angular/src/app/app.config.ts +0 -16
  83. package/examples/angular/src/app/app.routes.ts +0 -25
  84. package/examples/angular/src/app/cart/cart.component.html +0 -4
  85. package/examples/angular/src/app/cart/cart.component.scss +0 -14
  86. package/examples/angular/src/app/cart/cart.component.ts +0 -73
  87. package/examples/angular/src/app/identity/identity.component.html +0 -6
  88. package/examples/angular/src/app/identity/identity.component.scss +0 -18
  89. package/examples/angular/src/app/identity/identity.component.ts +0 -49
  90. package/examples/angular/src/app/product/product.component.html +0 -14
  91. package/examples/angular/src/app/product/product.component.scss +0 -11
  92. package/examples/angular/src/app/product/product.component.ts +0 -42
  93. package/examples/angular/src/app/search/search.component.html +0 -35
  94. package/examples/angular/src/app/search/search.component.scss +0 -129
  95. package/examples/angular/src/app/search/search.component.ts +0 -50
  96. package/examples/angular/src/app/services/product.service.ts +0 -35
  97. package/examples/angular/src/app/services/search.service.ts +0 -48
  98. package/examples/angular/src/app/services/trpc.client.ts +0 -27
  99. package/examples/angular/src/index.html +0 -13
  100. package/examples/angular/src/main.ts +0 -7
  101. package/examples/angular/src/styles.scss +0 -17
  102. package/examples/angular/src/test-setup.ts +0 -6
  103. package/examples/angular/tsconfig.app.json +0 -10
  104. package/examples/angular/tsconfig.editor.json +0 -6
  105. package/examples/angular/tsconfig.json +0 -32
  106. package/examples/node/src/initialize-algolia.spec.ts +0 -29
  107. package/examples/node/src/initialize-commercetools.spec.ts +0 -31
  108. package/examples/node/src/initialize-extended-providers.spec.ts +0 -38
  109. package/examples/node/src/initialize-mixed-providers.spec.ts +0 -36
  110. package/examples/node/src/providers/custom-algolia-product.provider.ts +0 -18
  111. package/examples/node/src/schemas/custom-product.schema.ts +0 -8
  112. package/examples/trpc-node/.env.example +0 -52
  113. package/examples/trpc-node/eslint.config.mjs +0 -3
  114. package/examples/trpc-node/project.json +0 -61
  115. package/examples/trpc-node/src/assets/.gitkeep +0 -0
  116. package/examples/trpc-node/src/main.ts +0 -59
  117. package/examples/trpc-node/src/router-instance.ts +0 -52
  118. package/examples/trpc-node/tsconfig.app.json +0 -9
  119. package/examples/trpc-node/tsconfig.json +0 -13
@@ -1,46 +1,30 @@
1
1
  import {
2
- SearchIdentifier,
3
- SearchMutation,
4
2
  SearchProvider,
5
- SearchQuery,
3
+ SearchQueryByTerm,
6
4
  SearchResult,
7
- SearchResultProductSchema,
5
+ SearchResultProduct,
8
6
  Session,
7
+ Cache,
9
8
  } from '@reactionary/core';
10
9
  import { CommercetoolsClient } from '../core/client';
11
10
  import z from 'zod';
12
11
  import { CommercetoolsConfiguration } from '../schema/configuration.schema';
13
12
 
14
13
  export class CommercetoolsSearchProvider<
15
- T extends SearchResult = SearchResult,
16
- Q extends SearchQuery = SearchQuery,
17
- M extends SearchMutation = SearchMutation
18
- > extends SearchProvider<T, Q, M> {
14
+ T extends SearchResult = SearchResult
15
+ > extends SearchProvider<T> {
19
16
  protected config: CommercetoolsConfiguration;
20
17
 
21
- constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, querySchema: z.ZodType<Q, Q>, mutationSchema: z.ZodType<M, M>) {
22
- super(schema, querySchema, mutationSchema);
18
+ constructor(config: CommercetoolsConfiguration, schema: z.ZodType<T>, cache: Cache) {
19
+ super(schema, cache);
23
20
 
24
21
  this.config = config;
25
22
  }
26
23
 
27
- protected override async fetch(queries: Q[], session: Session): Promise<T[]> {
28
- const results = [];
29
-
30
- for (const query of queries) {
31
- const result = await this.get(query.search);
32
-
33
- results.push(result);
34
- }
35
-
36
- return results;
37
- }
38
-
39
- protected override process(mutations: M[], session: Session): Promise<T> {
40
- throw new Error('Method not implemented.');
41
- }
42
-
43
- public async get(identifier: SearchIdentifier): Promise<T> {
24
+ public override async queryByTerm(
25
+ payload: SearchQueryByTerm,
26
+ _session: Session
27
+ ): Promise<T> {
44
28
  const client = new CommercetoolsClient(this.config).createAnonymousClient();
45
29
 
46
30
  const remote = await client
@@ -49,38 +33,39 @@ export class CommercetoolsSearchProvider<
49
33
  .search()
50
34
  .get({
51
35
  queryArgs: {
52
- limit: identifier.pageSize,
53
- offset: identifier.pageSize * identifier.page,
54
- ['text.en-US']: identifier.term,
36
+ limit: payload.search.pageSize,
37
+ offset: payload.search.pageSize * payload.search.page,
38
+ ['text.en-US']: payload.search.term,
55
39
  },
56
40
  })
57
41
  .execute();
58
42
 
59
- const parsed = this.parse(remote, identifier);
60
-
61
- return parsed;
43
+ return this.parseSearchResult(remote, payload);
62
44
  }
63
45
 
64
- public parse(remote: any, query: SearchIdentifier): T {
65
- const result = super.newModel();
66
-
67
- result.identifier = query;
68
-
69
- for (const p of remote.body.results) {
70
- const product = SearchResultProductSchema.parse({});
46
+ protected parseSearchResult(remote: unknown, payload: SearchQueryByTerm): T {
47
+ const result = this.newModel();
48
+ const remoteData = remote as { body: { results: Array<{ id: string; name: Record<string, string>; slug?: Record<string, string>; masterVariant: { images?: Array<{ url?: string }> } }>; total?: number } };
71
49
 
72
- product.identifier.key = p.id;
73
- product.name = p.name['en-US'];
50
+ result.identifier = payload.search;
74
51
 
75
- if (p.masterVariant.images) {
76
- product.image = p.masterVariant.images[0].url;
77
- }
52
+ for (const p of remoteData.body.results) {
53
+ const product: SearchResultProduct = {
54
+ identifier: { key: p.id },
55
+ name: p.name['en-US'],
56
+ slug: p.slug?.['en-US'] || p.id,
57
+ image: p.masterVariant.images?.[0]?.url || 'https://placehold.co/400'
58
+ };
78
59
 
79
60
  result.products.push(product);
80
61
  }
81
62
 
82
- result.pages = Math.ceil((remote.body.total || 0) / query.pageSize);
63
+ result.pages = Math.ceil((remoteData.body.total || 0) / payload.search.pageSize);
64
+ result.meta = {
65
+ cache: { hit: false, key: payload.search.term },
66
+ placeholder: false
67
+ };
83
68
 
84
- return result;
69
+ return this.assert(result);
85
70
  }
86
71
  }
@@ -1,4 +1,4 @@
1
- import { CapabilitiesSchema, Price, PriceQuery } from "@reactionary/core";
1
+ import { CapabilitiesSchema } from "@reactionary/core";
2
2
  import { z } from 'zod';
3
3
 
4
4
  export const CommercetoolsCapabilitiesSchema = CapabilitiesSchema.pick({
@@ -3,6 +3,7 @@
3
3
  "version": "0.0.1",
4
4
  "dependencies": {
5
5
  "@reactionary/core": "0.0.1",
6
+ "@reactionary/otel": "0.0.1",
6
7
  "zod": "4.0.0-beta.20250430T185432",
7
8
  "@faker-js/faker": "^9.8.0"
8
9
  }
@@ -1,24 +1,27 @@
1
- import { Client, IdentityMutationSchema, IdentityQuerySchema, IdentitySchema, ProductMutationSchema, ProductQuerySchema, ProductSchema, SearchMutationSchema, SearchQuerySchema, SearchResultSchema } from "@reactionary/core";
1
+ import { ProductSchema, SearchResultSchema, Cache as ReactinaryCache, ProductProvider, SearchProvider, IdentityProvider } from "@reactionary/core";
2
2
  import { FakeProductProvider } from "../providers/product.provider";
3
3
  import { FakeSearchProvider } from "../providers/search.provider";
4
4
  import { FakeConfiguration } from "../schema/configuration.schema";
5
5
  import { FakeCapabilities } from "../schema/capabilities.schema";
6
- import { FakeIdentityProvider } from "../providers/identity.provider";
7
6
 
8
- export function withFakeCapabilities(configuration: FakeConfiguration, capabilities: FakeCapabilities) {
9
- const client = {} as Partial<Client>;
7
+ type FakeClient<T extends FakeCapabilities> = Partial<{
8
+ product: T['product'] extends true ? ProductProvider : never;
9
+ search: T['search'] extends true ? SearchProvider : never;
10
+ identity: T['identity'] extends true ? IdentityProvider : never;
11
+ }>;
10
12
 
11
- if (capabilities.product) {
12
- client.product = new FakeProductProvider(configuration, ProductSchema, ProductQuerySchema, ProductMutationSchema);
13
- }
13
+ export function withFakeCapabilities<T extends FakeCapabilities>(configuration: FakeConfiguration, capabilities: T) {
14
+ return (cache: ReactinaryCache): FakeClient<T> => {
15
+ const client: any = {};
14
16
 
15
- if (capabilities.search) {
16
- client.search = new FakeSearchProvider(configuration, SearchResultSchema, SearchQuerySchema, SearchMutationSchema);
17
- }
17
+ if (capabilities.product) {
18
+ client.product = new FakeProductProvider(configuration, ProductSchema, cache);
19
+ }
18
20
 
19
- if (capabilities.identity) {
20
- client.identity = new FakeIdentityProvider(configuration, IdentitySchema, IdentityQuerySchema, IdentityMutationSchema);
21
- }
21
+ if (capabilities.search) {
22
+ client.search = new FakeSearchProvider(configuration, SearchResultSchema, cache);
23
+ }
22
24
 
23
- return client;
25
+ return client;
26
+ };
24
27
  }
@@ -1,6 +1,10 @@
1
1
  export * from './core/initialize';
2
2
 
3
+ export * from './providers/analytics.provider';
4
+ export * from './providers/cart.provider';
3
5
  export * from './providers/identity.provider';
6
+ export * from './providers/inventory.provider';
7
+ export * from './providers/price.provider';
4
8
  export * from './providers/product.provider';
5
9
  export * from './providers/search.provider';
6
10
 
@@ -0,0 +1,19 @@
1
+ import {
2
+ AnalyticsProvider,
3
+ BaseModel,
4
+ Cache,
5
+ } from '@reactionary/core';
6
+ import z from 'zod';
7
+ import { FakeConfiguration } from '../schema/configuration.schema';
8
+
9
+ export class FakeAnalyticsProvider<
10
+ T extends BaseModel = BaseModel
11
+ > extends AnalyticsProvider<T> {
12
+ protected config: FakeConfiguration;
13
+
14
+ constructor(config: FakeConfiguration, schema: z.ZodType<T>, cache: Cache) {
15
+ super(schema, cache);
16
+
17
+ this.config = config;
18
+ }
19
+ }
@@ -0,0 +1,107 @@
1
+ import {
2
+ Cart,
3
+ CartProvider,
4
+ CartQueryById,
5
+ CartMutationItemAdd,
6
+ CartMutationItemRemove,
7
+ CartMutationItemQuantityChange,
8
+ Session,
9
+ Cache,
10
+ } from '@reactionary/core';
11
+ import z from 'zod';
12
+ import { FakeConfiguration } from '../schema/configuration.schema';
13
+
14
+ export class FakeCartProvider<
15
+ T extends Cart = Cart
16
+ > extends CartProvider<T> {
17
+ protected config: FakeConfiguration;
18
+ private carts: Map<string, T> = new Map();
19
+
20
+ constructor(config: FakeConfiguration, schema: z.ZodType<T>, cache: Cache) {
21
+ super(schema, cache);
22
+
23
+ this.config = config;
24
+ }
25
+
26
+ public override async getById(
27
+ payload: CartQueryById,
28
+ _session: Session
29
+ ): Promise<T> {
30
+ const cartId = payload.cart.key;
31
+
32
+ if (!this.carts.has(cartId)) {
33
+ const model = this.newModel();
34
+ Object.assign(model, {
35
+ identifier: { key: cartId },
36
+ items: [],
37
+ meta: {
38
+ cache: {
39
+ hit: false,
40
+ key: cartId,
41
+ },
42
+ placeholder: false,
43
+ },
44
+ });
45
+ this.carts.set(cartId, this.assert(model));
46
+ }
47
+
48
+ const cart = this.carts.get(cartId);
49
+ if (!cart) {
50
+ throw new Error(`Cart with id ${cartId} not found`);
51
+ }
52
+ return cart;
53
+ }
54
+
55
+ public override async add(
56
+ payload: CartMutationItemAdd,
57
+ session: Session
58
+ ): Promise<T> {
59
+ const cart = await this.getById({ cart: payload.cart }, session);
60
+
61
+ const existingItemIndex = cart.items.findIndex(
62
+ item => item.product.key === payload.product.key
63
+ );
64
+
65
+ if (existingItemIndex >= 0) {
66
+ cart.items[existingItemIndex].quantity += payload.quantity;
67
+ } else {
68
+ cart.items.push({
69
+ identifier: { key: `item-${Date.now()}` },
70
+ product: payload.product,
71
+ quantity: payload.quantity,
72
+ });
73
+ }
74
+
75
+ return this.assert(cart);
76
+ }
77
+
78
+ public override async remove(
79
+ payload: CartMutationItemRemove,
80
+ session: Session
81
+ ): Promise<T> {
82
+ const cart = await this.getById({ cart: payload.cart }, session);
83
+
84
+ cart.items = cart.items.filter(
85
+ item => item.identifier.key !== payload.item.key
86
+ );
87
+
88
+ return this.assert(cart);
89
+ }
90
+
91
+ public override async changeQuantity(
92
+ payload: CartMutationItemQuantityChange,
93
+ session: Session
94
+ ): Promise<T> {
95
+ const cart = await this.getById({ cart: payload.cart }, session);
96
+
97
+ const item = cart.items.find(
98
+ item => item.identifier.key === payload.item.key
99
+ );
100
+
101
+ if (item) {
102
+ item.quantity = payload.quantity;
103
+ }
104
+
105
+ return this.assert(cart);
106
+ }
107
+ }
@@ -1,91 +1,102 @@
1
1
  import {
2
2
  Identity,
3
- IdentityMutation,
4
- IdentityMutationLogin,
5
3
  IdentityProvider,
6
- IdentityQuery,
4
+ IdentityQuerySelf,
5
+ IdentityMutationLogin,
6
+ IdentityMutationLogout,
7
7
  Session,
8
+ Cache,
8
9
  } from '@reactionary/core';
9
- import { FakeConfiguration } from '../schema/configuration.schema';
10
10
  import z from 'zod';
11
- import { faker } from '@faker-js/faker';
11
+ import { FakeConfiguration } from '../schema/configuration.schema';
12
+ import { base, en, Faker } from '@faker-js/faker';
12
13
 
13
14
  export class FakeIdentityProvider<
14
- T extends Identity = Identity,
15
- Q extends IdentityQuery = IdentityQuery,
16
- M extends IdentityMutation = IdentityMutation
17
- > extends IdentityProvider<T, Q, M> {
15
+ T extends Identity = Identity
16
+ > extends IdentityProvider<T> {
18
17
  protected config: FakeConfiguration;
18
+ private currentIdentity: T | null = null;
19
19
 
20
- constructor(
21
- config: FakeConfiguration,
22
- schema: z.ZodType<T>,
23
- querySchema: z.ZodType<Q, Q>,
24
- mutationSchema: z.ZodType<M, M>
25
- ) {
26
- super(schema, querySchema, mutationSchema);
20
+ constructor(config: FakeConfiguration, schema: z.ZodType<T>, cache: Cache) {
21
+ super(schema, cache);
27
22
 
28
23
  this.config = config;
29
24
  }
30
25
 
31
- protected override async fetch(queries: Q[], session: Session): Promise<T[]> {
32
- const results = [];
33
-
34
- for (const query of queries) {
35
- const result = await this.get(session);
36
-
37
- results.push(result);
38
- }
39
-
40
- return results;
41
- }
42
-
43
- protected override async process(
44
- mutations: M[],
45
- session: Session
26
+ public override async getSelf(
27
+ _payload: IdentityQuerySelf,
28
+ _session: Session
46
29
  ): Promise<T> {
47
- let result = this.newModel();
48
-
49
- for (const mutation of mutations) {
50
- switch (mutation.mutation) {
51
- case 'login':
52
- result = await this.login(mutation, session);
53
- break;
54
- case 'logout':
55
- result = await this.logout(session);
56
- break;
57
- }
30
+ if (!this.currentIdentity) {
31
+ const model = this.newModel();
32
+ Object.assign(model, {
33
+ id: 'anonymous',
34
+ type: 'Anonymous',
35
+ issued: new Date(),
36
+ expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours from now
37
+ meta: {
38
+ cache: {
39
+ hit: false,
40
+ key: 'anonymous',
41
+ },
42
+ placeholder: false,
43
+ },
44
+ });
45
+ this.currentIdentity = this.assert(model);
58
46
  }
59
47
 
60
- return result;
48
+ return this.currentIdentity;
61
49
  }
62
50
 
63
- protected async login(
51
+ public override async login(
64
52
  payload: IdentityMutationLogin,
65
- session: Session
53
+ _session: Session
66
54
  ): Promise<T> {
67
- const base = this.newModel();
68
-
69
- base.id = faker.string.uuid();
70
- base.token = faker.string.uuid();
71
- base.issued = faker.date.recent();
72
- base.issued = faker.date.soon();
73
- base.type = 'Registered';
74
-
75
- return base;
55
+ const generator = new Faker({
56
+ seed: 42,
57
+ locale: [en, base],
58
+ });
59
+
60
+ const model = this.newModel();
61
+ Object.assign(model, {
62
+ id: generator.string.uuid(),
63
+ type: 'Registered',
64
+ token: generator.string.alphanumeric(32),
65
+ issued: new Date(),
66
+ expiry: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days from now
67
+ meta: {
68
+ cache: {
69
+ hit: false,
70
+ key: payload.username,
71
+ },
72
+ placeholder: false,
73
+ },
74
+ });
75
+
76
+ this.currentIdentity = this.assert(model);
77
+ return this.currentIdentity;
76
78
  }
77
79
 
78
- protected async get(session: Session): Promise<T> {
79
- const base = this.schema.parse(session.identity);
80
-
81
- return base;
82
- }
83
-
84
- protected async logout(session: Session): Promise<T> {
85
- const base = this.newModel();
86
-
87
- session.identity = base;
88
-
89
- return base;
80
+ public override async logout(
81
+ _payload: IdentityMutationLogout,
82
+ _session: Session
83
+ ): Promise<T> {
84
+ const model = this.newModel();
85
+ Object.assign(model, {
86
+ id: 'anonymous',
87
+ type: 'Anonymous',
88
+ issued: new Date(),
89
+ expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours from now
90
+ meta: {
91
+ cache: {
92
+ hit: false,
93
+ key: 'anonymous',
94
+ },
95
+ placeholder: false,
96
+ },
97
+ });
98
+
99
+ this.currentIdentity = this.assert(model);
100
+ return this.currentIdentity;
90
101
  }
91
- }
102
+ }
@@ -0,0 +1,54 @@
1
+ import {
2
+ Inventory,
3
+ InventoryProvider,
4
+ InventoryQuery,
5
+ Session,
6
+ Cache,
7
+ } from '@reactionary/core';
8
+ import z from 'zod';
9
+ import { FakeConfiguration } from '../schema/configuration.schema';
10
+ import { base, en, Faker } from '@faker-js/faker';
11
+
12
+ export class FakeInventoryProvider<
13
+ T extends Inventory = Inventory
14
+ > extends InventoryProvider<T> {
15
+ protected config: FakeConfiguration;
16
+
17
+ constructor(config: FakeConfiguration, schema: z.ZodType<T>, cache: Cache) {
18
+ super(schema, cache);
19
+
20
+ this.config = config;
21
+ }
22
+
23
+ public override async getBySKU(
24
+ payload: InventoryQuery,
25
+ _session: Session
26
+ ): Promise<T> {
27
+ // Generate a simple hash from the SKU string for seeding
28
+ let hash = 0;
29
+ const skuString = payload.sku;
30
+ for (let i = 0; i < skuString.length; i++) {
31
+ hash = ((hash << 5) - hash) + skuString.charCodeAt(i);
32
+ hash = hash & hash; // Convert to 32bit integer
33
+ }
34
+
35
+ const generator = new Faker({
36
+ seed: hash || 42,
37
+ locale: [en, base],
38
+ });
39
+
40
+ const model = this.newModel();
41
+ Object.assign(model, {
42
+ quantity: generator.number.int({ min: 0, max: 100 }),
43
+ meta: {
44
+ cache: {
45
+ hit: false,
46
+ key: payload.sku,
47
+ },
48
+ placeholder: false,
49
+ },
50
+ });
51
+
52
+ return this.assert(model);
53
+ }
54
+ }
@@ -0,0 +1,60 @@
1
+ import {
2
+ Price,
3
+ PriceProvider,
4
+ PriceQueryBySku,
5
+ Session,
6
+ Cache,
7
+ } from '@reactionary/core';
8
+ import z from 'zod';
9
+ import { FakeConfiguration } from '../schema/configuration.schema';
10
+ import { base, en, Faker } from '@faker-js/faker';
11
+
12
+ export class FakePriceProvider<
13
+ T extends Price = Price
14
+ > extends PriceProvider<T> {
15
+ protected config: FakeConfiguration;
16
+
17
+ constructor(config: FakeConfiguration, schema: z.ZodType<T>, cache: Cache) {
18
+ super(schema, cache);
19
+
20
+ this.config = config;
21
+ }
22
+
23
+ public override async getBySKU(
24
+ payload: PriceQueryBySku,
25
+ _session: Session
26
+ ): Promise<T> {
27
+ // Generate a simple hash from the SKU key string for seeding
28
+ let hash = 0;
29
+ const skuString = payload.sku.key;
30
+ for (let i = 0; i < skuString.length; i++) {
31
+ hash = ((hash << 5) - hash) + skuString.charCodeAt(i);
32
+ hash = hash & hash; // Convert to 32bit integer
33
+ }
34
+
35
+ const generator = new Faker({
36
+ seed: hash || 42,
37
+ locale: [en, base],
38
+ });
39
+
40
+ const model = this.newModel();
41
+ Object.assign(model, {
42
+ identifier: {
43
+ sku: payload.sku,
44
+ },
45
+ value: {
46
+ cents: generator.number.int({ min: 100, max: 100000 }),
47
+ currency: 'USD',
48
+ },
49
+ meta: {
50
+ cache: {
51
+ hit: false,
52
+ key: payload.sku,
53
+ },
54
+ placeholder: false,
55
+ },
56
+ });
57
+
58
+ return this.assert(model);
59
+ }
60
+ }