@faststore/api 1.11.8 → 1.12.6

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.
@@ -0,0 +1,9 @@
1
+ import type { Directive } from "./index";
2
+ export interface CacheControl {
3
+ sMaxAge?: number;
4
+ staleWhileRevalidate?: number;
5
+ scope?: string;
6
+ }
7
+ export declare const stringify: ({ scope, sMaxAge, staleWhileRevalidate }: CacheControl) => string;
8
+ declare const directive: Directive;
9
+ export default directive;
@@ -0,0 +1,5 @@
1
+ import { GraphQLSchema } from "graphql";
2
+ export declare type Directive = {
3
+ typeDefs: string;
4
+ transformer: (schema: GraphQLSchema) => GraphQLSchema;
5
+ };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import type { Options as OptionsVTEX } from './platforms/vtex';
2
2
  export * from './__generated__/schema';
3
3
  export * from './platforms/errors';
4
+ export { stringify as stringifyCacheControl } from './directives/cacheControl';
5
+ export type { CacheControl } from './directives/cacheControl';
4
6
  export declare type Options = OptionsVTEX;
5
- export declare const getTypeDefs: () => string;
7
+ export declare const getTypeDefs: () => string[];
6
8
  export declare const getResolvers: (options: Options) => {
7
9
  StoreCollection: Record<string, import("./platforms/vtex").Resolver<import("./platforms/vtex/clients/commerce/types/Brand").Brand | (import("./platforms/vtex/clients/commerce/types/CategoryTree").CategoryTree & {
8
10
  level: number;
@@ -1,7 +1,7 @@
1
- import type { SearchArgs } from './clients/search';
2
1
  import type { Loaders } from './loaders';
3
2
  import type { Clients } from './clients';
4
3
  import type { Channel } from './utils/channel';
4
+ import type { SearchArgs } from './clients/search';
5
5
  export interface Options {
6
6
  platform: 'vtex';
7
7
  account: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/api",
3
- "version": "1.11.8",
3
+ "version": "1.12.6",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -46,5 +46,5 @@
46
46
  "peerDependencies": {
47
47
  "graphql": "^15.6.0"
48
48
  },
49
- "gitHead": "3775ec32d866149eb6519e68b7b2b977ffc0dace"
49
+ "gitHead": "74bbbc8c3573be89754ccb50b0d1bc135b332ca9"
50
50
  }
@@ -0,0 +1,76 @@
1
+ import { getDirective, MapperKind, mapSchema } from "@graphql-tools/utils";
2
+ import { GraphQLSchema } from "graphql";
3
+
4
+ import type { Directive } from "./index";
5
+
6
+ const NAME = "cacheControl";
7
+
8
+ export interface CacheControl {
9
+ sMaxAge?: number;
10
+ staleWhileRevalidate?: number;
11
+ scope?: string;
12
+ }
13
+
14
+ export const stringify = (
15
+ { scope = "private", sMaxAge = 0, staleWhileRevalidate = 0 }: CacheControl,
16
+ ) =>
17
+ `${scope}, s-maxage=${sMaxAge}, stale-while-revalidate=${staleWhileRevalidate}`;
18
+
19
+ const min = (a: number | undefined, b: number | undefined) => {
20
+ if (typeof a === "number" && typeof b === "number") {
21
+ return a > b ? b : a;
22
+ }
23
+
24
+ if (typeof a === "number") {
25
+ return a;
26
+ }
27
+
28
+ return b;
29
+ };
30
+
31
+ const minScope = (
32
+ a: string | undefined,
33
+ b: string | undefined,
34
+ ) => {
35
+ if (typeof a === "string" && typeof b === "string") {
36
+ return a === "public" && b === "public" ? "public" : "private";
37
+ }
38
+
39
+ return a || b;
40
+ };
41
+
42
+ const directive: Directive = {
43
+ typeDefs:
44
+ `directive @cacheControl(sMaxAge: Int, staleWhileRevalidate: Int, scope: String) on FIELD_DEFINITION`,
45
+ transformer: (schema: GraphQLSchema) =>
46
+ mapSchema(schema, {
47
+ [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
48
+ const cacheControl = getDirective(schema, fieldConfig, NAME)?.[0] as
49
+ | CacheControl
50
+ | undefined;
51
+
52
+ if (cacheControl) {
53
+ const { sMaxAge, staleWhileRevalidate, scope } = cacheControl;
54
+
55
+ const resolver = fieldConfig.resolve
56
+
57
+ fieldConfig.resolve = (obj, args, ctx, info) => {
58
+ ctx.cacheControl = {
59
+ sMaxAge: min(ctx.cacheControl?.sMaxAge, sMaxAge),
60
+ staleWhileRevalidate: min(
61
+ ctx.cacheControl?.staleWhileRevalidate,
62
+ staleWhileRevalidate,
63
+ ),
64
+ scope: minScope(ctx.cacheControl?.scope, scope),
65
+ };
66
+
67
+ return resolver?.(obj, args, ctx, info);
68
+ };
69
+ }
70
+
71
+ return fieldConfig;
72
+ },
73
+ }),
74
+ };
75
+
76
+ export default directive;
@@ -0,0 +1,6 @@
1
+ import { GraphQLSchema } from "graphql"
2
+
3
+ export type Directive = {
4
+ typeDefs: string
5
+ transformer: (schema: GraphQLSchema) => GraphQLSchema
6
+ }
package/src/index.ts CHANGED
@@ -5,10 +5,14 @@ import {
5
5
  getResolvers as getResolversVTEX,
6
6
  } from './platforms/vtex'
7
7
  import { typeDefs } from './typeDefs'
8
+ import cacheControlDirective from './directives/cacheControl'
9
+ import type { Directive } from './directives'
8
10
  import type { Options as OptionsVTEX } from './platforms/vtex'
9
11
 
10
12
  export * from './__generated__/schema'
11
13
  export * from './platforms/errors'
14
+ export { stringify as stringifyCacheControl } from './directives/cacheControl'
15
+ export type { CacheControl } from './directives/cacheControl'
12
16
 
13
17
  export type Options = OptionsVTEX
14
18
 
@@ -19,7 +23,11 @@ const platforms = {
19
23
  },
20
24
  }
21
25
 
22
- export const getTypeDefs = () => typeDefs
26
+ const directives: Directive[] = [
27
+ cacheControlDirective
28
+ ]
29
+
30
+ export const getTypeDefs = () => [typeDefs, ...directives.map(d => d.typeDefs)]
23
31
 
24
32
  export const getResolvers = (options: Options) =>
25
33
  platforms[options.platform].getResolvers(options)
@@ -27,8 +35,11 @@ export const getResolvers = (options: Options) =>
27
35
  export const getContextFactory = (options: Options) =>
28
36
  platforms[options.platform].getContextFactory(options)
29
37
 
30
- export const getSchema = async (options: Options) =>
31
- makeExecutableSchema({
38
+ export const getSchema = async (options: Options) => {
39
+ const schema = makeExecutableSchema({
32
40
  resolvers: getResolvers(options),
33
- typeDefs,
41
+ typeDefs: getTypeDefs(),
34
42
  })
43
+
44
+ return directives.reduce((s, d) => d.transformer(s), schema)
45
+ }
@@ -1,5 +1,4 @@
1
1
  import { getClients } from './clients'
2
- import type { SearchArgs } from './clients/search'
3
2
  import { getLoaders } from './loaders'
4
3
  import { StoreAggregateOffer } from './resolvers/aggregateOffer'
5
4
  import { StoreAggregateRating } from './resolvers/aggregateRating'
@@ -25,6 +24,7 @@ import ChannelMarshal from './utils/channel'
25
24
  import type { Loaders } from './loaders'
26
25
  import type { Clients } from './clients'
27
26
  import type { Channel } from './utils/channel'
27
+ import type { SearchArgs } from './clients/search'
28
28
 
29
29
  export interface Options {
30
30
  platform: 'vtex'
@@ -176,6 +176,7 @@ type Query {
176
176
  """
177
177
  locator: [IStoreSelectedFacet!]!
178
178
  ): StoreProduct!
179
+ @cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600)
179
180
 
180
181
  """
181
182
  Returns the details of a collection based on the collection slug.
@@ -186,6 +187,7 @@ type Query {
186
187
  """
187
188
  slug: String!
188
189
  ): StoreCollection!
190
+ @cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600)
189
191
 
190
192
  """
191
193
  Returns the result of a product, facet, or suggestion search.
@@ -212,6 +214,7 @@ type Query {
212
214
  """
213
215
  selectedFacets: [IStoreSelectedFacet!]
214
216
  ): StoreSearchResult!
217
+ @cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600)
215
218
 
216
219
  """
217
220
  Returns information about all products.
@@ -220,12 +223,13 @@ type Query {
220
223
  """
221
224
  Product pagination argument, indicating how many items should be returned from the complete result list.
222
225
  """
223
- first: Int!,
226
+ first: Int!
224
227
  """
225
228
  Product pagination argument, indicating the cursor corresponding with the item after which the items should be fetched.
226
229
  """
227
230
  after: String
228
231
  ): StoreProductConnection!
232
+ @cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600)
229
233
 
230
234
  """
231
235
  Returns information about all collections.
@@ -234,10 +238,11 @@ type Query {
234
238
  """
235
239
  Collection pagination argument, indicating how many items should be returned from the complete result list.
236
240
  """
237
- first: Int!,
241
+ first: Int!
238
242
  """
239
243
  Collection pagination argument, indicating the cursor corresponding with the item after which the items should be fetched.
240
244
  """
241
245
  after: String
242
246
  ): StoreCollectionConnection!
247
+ @cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600)
243
248
  }