mercurius-cache
Advanced tools
Comparing version 1.1.1 to 1.2.0
14
index.js
@@ -64,3 +64,3 @@ 'use strict' | ||
for (const [fieldName, field] of Object.entries(schemaType.getFields())) { | ||
const policy = fieldPolicy[fieldName] | ||
const policy = getPolicyOptions(fieldPolicy, fieldName) | ||
if (all || policy) { | ||
@@ -81,2 +81,14 @@ // validate schema vs query values | ||
function getPolicyOptions (fieldPolicy, fieldName) { | ||
if (!fieldPolicy[fieldName]) { | ||
return | ||
} | ||
if (fieldPolicy[fieldName].__options) { | ||
return fieldPolicy[fieldName].__options | ||
} | ||
return fieldPolicy[fieldName] | ||
} | ||
function makeCachedResolver (prefix, fieldName, cache, originalFieldResolver, policy, skip, onDedupe, onHit, onMiss, onSkip, onError, report) { | ||
@@ -83,0 +95,0 @@ const name = prefix + '.' + fieldName |
@@ -83,4 +83,3 @@ 'use strict' | ||
for (const name of Object.keys(policyType)) { | ||
const policyField = policy[type][name] | ||
// TODO need to validate also nested | ||
const policyField = validateNestedPolicy(policyType, name) | ||
if (policyField.ttl && (typeof policyField.ttl !== 'number' || policyField.ttl < 0)) { | ||
@@ -129,2 +128,11 @@ throw new Error(`policy '${type}.${name}' ttl must be a number greater than 0`) | ||
// TODO need to validate also nested | ||
function validateNestedPolicy (policyType, fieldName) { | ||
if (policyType[fieldName].__options) { | ||
return policyType[fieldName].__options | ||
} | ||
return policyType[fieldName] | ||
} | ||
function validateStorage (app, storage, maxTTL) { | ||
@@ -131,0 +139,0 @@ if (typeof storage !== 'object') { |
{ | ||
"name": "mercurius-cache", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "Cache the results of your GraphQL resolvers, for Mercurius", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -262,2 +262,28 @@ # mercurius-cache | ||
- **policy~__options** | ||
should be used in case of conflicts with nested fields with the same name as policy fields (ttl, skip, storage....). | ||
Example | ||
```js | ||
policy: { | ||
Query: { | ||
welcome: { | ||
// no __options key present, so policy options are considered as it is | ||
ttl: 6 | ||
}, | ||
hello: { | ||
// since "hello" query has a ttl property | ||
__options: { | ||
ttl: 6 | ||
}, | ||
ttl: { | ||
// here we can use both __options or list policy options | ||
skip: () { /* .. */ } | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
- **skip** | ||
@@ -264,0 +290,0 @@ |
@@ -1555,1 +1555,115 @@ 'use strict' | ||
}) | ||
test('cache nested resolvers with __options', async ({ same, pass, plan, teardown }) => { | ||
pass(4) | ||
const app = fastify() | ||
teardown(app.close.bind(app)) | ||
const dogs = [{ | ||
name: 'Max' | ||
}, { | ||
name: 'Charlie' | ||
}, { | ||
name: 'Buddy' | ||
}, { | ||
name: 'Max' | ||
}] | ||
const owners = { | ||
Max: { | ||
name: 'Jennifer' | ||
}, | ||
Charlie: { | ||
name: 'Sarah' | ||
}, | ||
Buddy: { | ||
name: 'Tracy' | ||
} | ||
} | ||
const schema = ` | ||
type Human { | ||
name: String! | ||
} | ||
type Dog { | ||
name: String! | ||
owner: Human | ||
} | ||
type Query { | ||
dogs: [Dog] | ||
} | ||
` | ||
const resolvers = { | ||
Query: { | ||
dogs (_, params, { reply }) { | ||
pass('call Query.dogs') | ||
return dogs | ||
} | ||
} | ||
} | ||
const loaders = { | ||
Dog: { | ||
async owner (queries) { | ||
pass('call Dog.owner') | ||
return queries.map(({ obj }) => owners[obj.name]) | ||
} | ||
} | ||
} | ||
app.register(mercurius, { | ||
schema, | ||
resolvers, | ||
loaders | ||
}) | ||
app.register(cache, { | ||
policy: { | ||
Query: { | ||
dogs: { | ||
__options: { | ||
ttl: 1 | ||
} | ||
} | ||
} | ||
} | ||
}) | ||
const res = await app.inject({ | ||
method: 'POST', | ||
url: '/graphql', | ||
body: { | ||
query: `{ | ||
dogs { | ||
owner { | ||
name | ||
} | ||
} | ||
}` | ||
} | ||
}) | ||
same(res.json(), | ||
{ data: { dogs: [{ owner: { name: 'Jennifer' } }, { owner: { name: 'Sarah' } }, { owner: { name: 'Tracy' } }, { owner: { name: 'Jennifer' } }] } } | ||
) | ||
const res2 = await app.inject({ | ||
method: 'POST', | ||
url: '/graphql', | ||
body: { | ||
query: `{ | ||
dogs { | ||
name | ||
owner { | ||
name | ||
} | ||
} | ||
}` | ||
} | ||
}) | ||
same(res2.json(), | ||
{ data: { dogs: [{ name: 'Max', owner: { name: 'Jennifer' } }, { name: 'Charlie', owner: { name: 'Sarah' } }, { name: 'Buddy', owner: { name: 'Tracy' } }, { name: 'Max', owner: { name: 'Jennifer' } }] } } | ||
) | ||
}) |
@@ -125,2 +125,24 @@ 'use strict' | ||
test('should not throw error when "__options" is used with valid parameters', async (t) => { | ||
const options = { | ||
policy: { | ||
Query: { | ||
a: { | ||
__options: { | ||
ttl: 2, | ||
storage: { type: 'redis', options: { client: {} } }, | ||
extendKey: () => {}, | ||
skip: () => {}, | ||
invalidate: () => {}, | ||
references: () => {} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
const app = { log: 'the-logger' } | ||
t.doesNotThrow(() => validateOpts(app, options)) | ||
}) | ||
const cases = [ | ||
@@ -127,0 +149,0 @@ { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
135077
4203
603