mirror of
https://github.com/strapi/strapi.git
synced 2025-11-10 15:19:00 +00:00
chore: reintegrate policy logic into core
This commit is contained in:
parent
29d9bfaedc
commit
78d30d2e60
44
packages/core/core/src/registries/__tests__/policies.test.ts
Normal file
44
packages/core/core/src/registries/__tests__/policies.test.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import createPoliciesRegistry from '../policies';
|
||||||
|
|
||||||
|
describe('Policy util', () => {
|
||||||
|
const registry = createPoliciesRegistry();
|
||||||
|
|
||||||
|
describe('Get policy', () => {
|
||||||
|
test('Throws on policy not found', () => {
|
||||||
|
expect(registry.get('undefined')).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Retrieves policy by fullName', () => {
|
||||||
|
const policyFn = () => {};
|
||||||
|
|
||||||
|
registry.set('global::test-policy', policyFn as any);
|
||||||
|
|
||||||
|
expect(registry.get('global::test-policy')).toBe(policyFn);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Retrieves a global plugin policy', () => {
|
||||||
|
const policyFn = () => {};
|
||||||
|
|
||||||
|
registry.set('plugin::test-plugin.test-policy', policyFn as any);
|
||||||
|
|
||||||
|
expect(registry.get('test-plugin.test-policy')).toBeUndefined();
|
||||||
|
expect(registry.get('plugin::test-plugin.test-policy')).toBe(policyFn);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Retrieves a plugin policy locally', () => {
|
||||||
|
const policyFn = () => {};
|
||||||
|
|
||||||
|
registry.set('plugin::test-plugin.test-policy', policyFn as any);
|
||||||
|
|
||||||
|
expect(registry.get('test-policy', { pluginName: 'test-plugin' })).toBe(policyFn);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Retrieves an api policy locally', () => {
|
||||||
|
const policyFn = () => {};
|
||||||
|
|
||||||
|
registry.set('api::test-api.test-policy', policyFn as any);
|
||||||
|
|
||||||
|
expect(registry.get('test-policy', { apiName: 'test-api' })).toBe(policyFn);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,48 +1,128 @@
|
|||||||
import { pickBy, has } from 'lodash/fp';
|
import { pickBy, has, castArray } from 'lodash/fp';
|
||||||
import type { Core, UID } from '@strapi/types';
|
import type { Core } from '@strapi/types';
|
||||||
import { addNamespace, hasNamespace } from './namespace';
|
import { addNamespace, hasNamespace } from './namespace';
|
||||||
|
|
||||||
type PolicyExtendFn = (policy: Core.Policy) => Core.Policy;
|
const PLUGIN_PREFIX = 'plugin::';
|
||||||
type PolicyMap = Record<string, Core.Policy>;
|
const API_PREFIX = 'api::';
|
||||||
|
|
||||||
|
interface PolicyInfo {
|
||||||
|
name: string;
|
||||||
|
config: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PolicyConfig = string | PolicyInfo;
|
||||||
|
|
||||||
|
interface NamespaceInfo {
|
||||||
|
pluginName?: string;
|
||||||
|
apiName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsePolicy = (policy: string | PolicyInfo) => {
|
||||||
|
if (typeof policy === 'string') {
|
||||||
|
return { policyName: policy, config: {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { name, config } = policy;
|
||||||
|
return { policyName: name, config };
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: move instantiation part here instead of in the policy utils
|
|
||||||
const policiesRegistry = () => {
|
const policiesRegistry = () => {
|
||||||
const policies: PolicyMap = {};
|
const policies = new Map<string, Core.Policy>();
|
||||||
|
|
||||||
|
const find = (name: string, namespaceInfo?: NamespaceInfo) => {
|
||||||
|
const { pluginName, apiName } = namespaceInfo ?? {};
|
||||||
|
|
||||||
|
// try to resolve a full name to avoid extra prefixing
|
||||||
|
const policy = policies.get(name);
|
||||||
|
|
||||||
|
if (policy) {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pluginName) {
|
||||||
|
return policies.get(`${PLUGIN_PREFIX}${pluginName}.${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiName) {
|
||||||
|
return policies.get(`${API_PREFIX}${apiName}.${name}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function resolveHandler(policyConfig: PolicyConfig, namespaceInfo?: NamespaceInfo): Core.Policy;
|
||||||
|
function resolveHandler(
|
||||||
|
policyConfig: PolicyConfig[],
|
||||||
|
namespaceInfo?: NamespaceInfo
|
||||||
|
): Core.Policy[];
|
||||||
|
function resolveHandler(
|
||||||
|
policyConfig: PolicyConfig | PolicyConfig[],
|
||||||
|
namespaceInfo?: NamespaceInfo
|
||||||
|
): Core.Policy | Core.Policy[] {
|
||||||
|
if (Array.isArray(policyConfig)) {
|
||||||
|
return policyConfig.map((config) => {
|
||||||
|
return resolveHandler(config, namespaceInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { policyName, config } = parsePolicy(policyConfig);
|
||||||
|
|
||||||
|
const policy = find(policyName, namespaceInfo);
|
||||||
|
|
||||||
|
if (!policy) {
|
||||||
|
throw new Error(`Policy ${policyName} not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof policy === 'function') {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policy.validator) {
|
||||||
|
policy.validator(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
return policy.handler;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* Returns this list of registered policies uids
|
* Returns this list of registered policies uids
|
||||||
*/
|
*/
|
||||||
keys() {
|
keys() {
|
||||||
return Object.keys(policies);
|
return policies.keys();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the instance of a policy. Instantiate the policy if not already done
|
* Returns the instance of a policy. Instantiate the policy if not already done
|
||||||
*/
|
*/
|
||||||
get(uid: UID.Policy) {
|
get(name: string, namespaceInfo?: NamespaceInfo) {
|
||||||
return policies[uid];
|
return find(name, namespaceInfo);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Checks if a policy is registered
|
||||||
|
*/
|
||||||
|
has(name: string, namespaceInfo?: NamespaceInfo) {
|
||||||
|
const res = find(name, namespaceInfo);
|
||||||
|
return !!res;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a map with all the policies in a namespace
|
* Returns a map with all the policies in a namespace
|
||||||
*/
|
*/
|
||||||
getAll(namespace: string) {
|
getAll(namespace: string) {
|
||||||
return pickBy((_, uid) => hasNamespace(uid, namespace))(policies);
|
return pickBy((_, uid) => hasNamespace(uid, namespace))(Object.fromEntries(policies));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a policy
|
* Registers a policy
|
||||||
*/
|
*/
|
||||||
set(uid: string, policy: Core.Policy) {
|
set(uid: string, policy: Core.Policy) {
|
||||||
policies[uid] = policy;
|
policies.set(uid, policy);
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a map of policies for a specific namespace
|
* Registers a map of policies for a specific namespace
|
||||||
*/
|
*/
|
||||||
add(namespace: string, newPolicies: PolicyMap) {
|
add(namespace: string, newPolicies: Record<string, Core.Policy>) {
|
||||||
for (const policyName of Object.keys(newPolicies)) {
|
for (const policyName of Object.keys(newPolicies)) {
|
||||||
const policy = newPolicies[policyName];
|
const policy = newPolicies[policyName];
|
||||||
const uid = addNamespace(policyName, namespace);
|
const uid = addNamespace(policyName, namespace);
|
||||||
@ -50,26 +130,23 @@ const policiesRegistry = () => {
|
|||||||
if (has(uid, policies)) {
|
if (has(uid, policies)) {
|
||||||
throw new Error(`Policy ${uid} has already been registered.`);
|
throw new Error(`Policy ${uid} has already been registered.`);
|
||||||
}
|
}
|
||||||
policies[uid] = policy;
|
|
||||||
|
policies.set(uid, policy);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps a policy to extend it
|
* Resolves a list of policies
|
||||||
* @param {string} uid
|
|
||||||
* @param {(policy: Policy) => Policy} extendFn
|
|
||||||
*/
|
*/
|
||||||
extend(uid: UID.Policy, extendFn: PolicyExtendFn) {
|
resolve(config: PolicyConfig | PolicyConfig[], namespaceInfo?: NamespaceInfo) {
|
||||||
const currentPolicy = this.get(uid);
|
const { pluginName, apiName } = namespaceInfo ?? {};
|
||||||
|
|
||||||
if (!currentPolicy) {
|
return castArray(config).map((policyConfig) => {
|
||||||
throw new Error(`Policy ${uid} doesn't exist`);
|
return {
|
||||||
}
|
handler: resolveHandler(policyConfig, { pluginName, apiName }),
|
||||||
|
config: (typeof policyConfig === 'object' && policyConfig.config) || {},
|
||||||
const newPolicy = extendFn(currentPolicy);
|
};
|
||||||
policies[uid] = newPolicy;
|
});
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Router from '@koa/router';
|
|||||||
|
|
||||||
import compose from 'koa-compose';
|
import compose from 'koa-compose';
|
||||||
import { resolveRouteMiddlewares } from './middleware';
|
import { resolveRouteMiddlewares } from './middleware';
|
||||||
import { resolvePolicies } from './policy';
|
import { createPolicicesMiddleware } from './policy';
|
||||||
|
|
||||||
const getMethod = (route: Core.Route) => {
|
const getMethod = (route: Core.Route) => {
|
||||||
return trim(toLower(route.method)) as Lowercase<Core.Route['method']>;
|
return trim(toLower(route.method)) as Lowercase<Core.Route['method']>;
|
||||||
@ -79,7 +79,6 @@ export default (strapi: Core.Strapi) => {
|
|||||||
const path = getPath(route);
|
const path = getPath(route);
|
||||||
|
|
||||||
const middlewares = resolveRouteMiddlewares(route, strapi);
|
const middlewares = resolveRouteMiddlewares(route, strapi);
|
||||||
const policies = resolvePolicies(route);
|
|
||||||
|
|
||||||
const action = getAction(route, strapi);
|
const action = getAction(route, strapi);
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ export default (strapi: Core.Strapi) => {
|
|||||||
createRouteInfoMiddleware(route),
|
createRouteInfoMiddleware(route),
|
||||||
authenticate,
|
authenticate,
|
||||||
authorize,
|
authorize,
|
||||||
...policies,
|
createPolicicesMiddleware(route, strapi),
|
||||||
...middlewares,
|
...middlewares,
|
||||||
returnBodyMiddleware,
|
returnBodyMiddleware,
|
||||||
...castArray(action),
|
...castArray(action),
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { policy as policyUtils, errors } from '@strapi/utils';
|
import { policy as policyUtils, errors } from '@strapi/utils';
|
||||||
import type { Core } from '@strapi/types';
|
import type { Core } from '@strapi/types';
|
||||||
|
|
||||||
const resolvePolicies = (route: Core.Route) => {
|
const createPolicicesMiddleware = (route: Core.Route, strapi: Core.Strapi) => {
|
||||||
const policiesConfig = route?.config?.policies ?? [];
|
const policiesConfig = route?.config?.policies ?? [];
|
||||||
const resolvedPolicies = policyUtils.resolve(policiesConfig, route.info);
|
const resolvedPolicies = strapi.get('policies').resolve(policiesConfig, route.info);
|
||||||
|
|
||||||
const policiesMiddleware: Core.MiddlewareHandler = async (ctx, next) => {
|
const policiesMiddleware: Core.MiddlewareHandler = async (ctx, next) => {
|
||||||
const context = policyUtils.createPolicyContext('koa', ctx);
|
const context = policyUtils.createPolicyContext('koa', ctx);
|
||||||
@ -19,7 +19,7 @@ const resolvePolicies = (route: Core.Route) => {
|
|||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
|
|
||||||
return [policiesMiddleware];
|
return policiesMiddleware;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { resolvePolicies };
|
export { createPolicicesMiddleware };
|
||||||
|
|||||||
@ -7,8 +7,16 @@ export type PolicyContext = Omit<ExtendableContext, 'is'> & {
|
|||||||
is(name: string): boolean;
|
is(name: string): boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Policy<T = unknown> = (
|
export type PolicyHandler<TConfig = unknown> = (
|
||||||
ctx: PolicyContext,
|
ctx: PolicyContext,
|
||||||
cfg: T,
|
cfg: TConfig,
|
||||||
{ strapi }: { strapi: Strapi }
|
opts: { strapi: Strapi }
|
||||||
) => boolean | undefined;
|
) => boolean | undefined;
|
||||||
|
|
||||||
|
export type Policy<TConfig = unknown> =
|
||||||
|
| {
|
||||||
|
name: string;
|
||||||
|
validator?: (config: unknown) => boolean;
|
||||||
|
handler: PolicyHandler<TConfig>;
|
||||||
|
}
|
||||||
|
| PolicyHandler<TConfig>;
|
||||||
|
|||||||
@ -1,71 +0,0 @@
|
|||||||
import * as policyUtils from '../policy';
|
|
||||||
|
|
||||||
describe('Policy util', () => {
|
|
||||||
describe('Get policy', () => {
|
|
||||||
test('Throws on policy not found', () => {
|
|
||||||
expect(() => policyUtils.get('undefined')).toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Retrieves global policy', () => {
|
|
||||||
const policyFn = () => {};
|
|
||||||
|
|
||||||
// init global strapi
|
|
||||||
global.strapi = {
|
|
||||||
policy(name) {
|
|
||||||
return this.policies[name];
|
|
||||||
},
|
|
||||||
policies: {
|
|
||||||
'global::test-policy': policyFn,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(policyUtils.get('global::test-policy')).toBe(policyFn);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Retrieves a global plugin policy', () => {
|
|
||||||
const policyFn = () => {};
|
|
||||||
|
|
||||||
global.strapi = {
|
|
||||||
policy(name) {
|
|
||||||
return this.policies[name];
|
|
||||||
},
|
|
||||||
policies: {
|
|
||||||
'plugin::test-plugin.test-policy': policyFn,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(() => policyUtils.get('test-plugin.test-policy')).toThrow();
|
|
||||||
expect(policyUtils.get('plugin::test-plugin.test-policy')).toBe(policyFn);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Retrieves a plugin policy locally', () => {
|
|
||||||
const policyFn = () => {};
|
|
||||||
|
|
||||||
global.strapi = {
|
|
||||||
policy(name) {
|
|
||||||
return this.policies[name];
|
|
||||||
},
|
|
||||||
policies: {
|
|
||||||
'plugin::test-plugin.test-policy': policyFn,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(policyUtils.get('test-policy', { pluginName: 'test-plugin' })).toBe(policyFn);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Retrieves an api policy locally', () => {
|
|
||||||
const policyFn = () => {};
|
|
||||||
|
|
||||||
global.strapi = {
|
|
||||||
policy(name) {
|
|
||||||
return this.policies[name];
|
|
||||||
},
|
|
||||||
policies: {
|
|
||||||
'api::test-api.test-policy': policyFn,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(policyUtils.get('test-policy', { apiName: 'test-api' })).toBe(policyFn);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,118 +1,4 @@
|
|||||||
/**
|
|
||||||
* Policies util
|
|
||||||
*/
|
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { eq } from 'lodash/fp';
|
import { eq } from 'lodash/fp';
|
||||||
import type Koa from 'koa';
|
|
||||||
|
|
||||||
const PLUGIN_PREFIX = 'plugin::';
|
|
||||||
const API_PREFIX = 'api::';
|
|
||||||
|
|
||||||
interface PolicyInfo {
|
|
||||||
name: string;
|
|
||||||
config: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
type PolicyConfig = string | PolicyInfo | (() => PolicyInfo);
|
|
||||||
|
|
||||||
interface PolicyContext {
|
|
||||||
pluginName?: string;
|
|
||||||
apiName?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RouteInfo {
|
|
||||||
method: string;
|
|
||||||
endpoint: string;
|
|
||||||
controller: string;
|
|
||||||
action: string;
|
|
||||||
plugin: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parsePolicy = (policy: string | PolicyInfo) => {
|
|
||||||
if (typeof policy === 'string') {
|
|
||||||
return { policyName: policy, config: {} };
|
|
||||||
}
|
|
||||||
|
|
||||||
const { name, config } = policy;
|
|
||||||
return { policyName: name, config };
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchLocalPolicy = (policyName: string, policyContext: PolicyContext) => {
|
|
||||||
const { pluginName, apiName } = policyContext ?? {};
|
|
||||||
|
|
||||||
if (pluginName) {
|
|
||||||
return strapi.policy(`${PLUGIN_PREFIX}${pluginName}.${policyName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apiName) {
|
|
||||||
return strapi.policy(`${API_PREFIX}${apiName}.${policyName}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const globalPolicy = ({ method, endpoint, controller, action, plugin }: RouteInfo) => {
|
|
||||||
return async (ctx: Koa.Context, next: () => void) => {
|
|
||||||
ctx.request.route = {
|
|
||||||
endpoint: `${method} ${endpoint}`,
|
|
||||||
controller: _.toLower(controller),
|
|
||||||
action: _.toLower(action),
|
|
||||||
verb: _.toLower(method),
|
|
||||||
plugin,
|
|
||||||
};
|
|
||||||
|
|
||||||
await next();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const resolvePolicies = (config: PolicyConfig[], policyContext: PolicyContext) => {
|
|
||||||
const { pluginName, apiName } = policyContext ?? {};
|
|
||||||
|
|
||||||
return config.map((policyConfig) => {
|
|
||||||
return {
|
|
||||||
handler: getPolicy(policyConfig, { pluginName, apiName }),
|
|
||||||
config: (typeof policyConfig === 'object' && policyConfig.config) || {},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const findPolicy = (name: string, policyContext: PolicyContext) => {
|
|
||||||
const { pluginName, apiName } = policyContext ?? {};
|
|
||||||
const resolvedPolicy = strapi.policy(name);
|
|
||||||
|
|
||||||
if (resolvedPolicy !== undefined) {
|
|
||||||
return resolvedPolicy;
|
|
||||||
}
|
|
||||||
|
|
||||||
const localPolicy = searchLocalPolicy(name, { pluginName, apiName });
|
|
||||||
|
|
||||||
if (localPolicy !== undefined) {
|
|
||||||
return localPolicy;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`Could not find policy "${name}"`);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getPolicy = (policyConfig: PolicyConfig, policyContext?: PolicyContext) => {
|
|
||||||
const { pluginName, apiName } = policyContext ?? {};
|
|
||||||
|
|
||||||
if (typeof policyConfig === 'function') {
|
|
||||||
return policyConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { policyName, config } = parsePolicy(policyConfig);
|
|
||||||
|
|
||||||
const policy = findPolicy(policyName, { pluginName, apiName });
|
|
||||||
|
|
||||||
if (typeof policy === 'function') {
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (policy.validator) {
|
|
||||||
policy.validator(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
return policy.handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
name: string;
|
name: string;
|
||||||
@ -152,10 +38,4 @@ const createPolicyContext = (type: string, ctx: object) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export { createPolicy, createPolicyContext };
|
||||||
getPolicy as get,
|
|
||||||
resolvePolicies as resolve,
|
|
||||||
globalPolicy,
|
|
||||||
createPolicy,
|
|
||||||
createPolicyContext,
|
|
||||||
};
|
|
||||||
|
|||||||
@ -3,6 +3,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "dist"
|
"outDir": "dist"
|
||||||
},
|
},
|
||||||
"include": ["src", "../core/src/configuration/urls.ts"],
|
"include": ["src"],
|
||||||
"exclude": ["node_modules", "**/__tests__/**"]
|
"exclude": ["node_modules", "**/__tests__/**"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ const getPoliciesConfig = propOr([], 'policies');
|
|||||||
|
|
||||||
const createPoliciesMiddleware = (resolverConfig: any, { strapi }: { strapi: Core.Strapi }) => {
|
const createPoliciesMiddleware = (resolverConfig: any, { strapi }: { strapi: Core.Strapi }) => {
|
||||||
const resolverPolicies = getPoliciesConfig(resolverConfig);
|
const resolverPolicies = getPoliciesConfig(resolverConfig);
|
||||||
const policies = policyUtils.resolve(resolverPolicies, {});
|
const policies = strapi.get('policies').resolve(resolverPolicies, {});
|
||||||
|
|
||||||
return async (
|
return async (
|
||||||
resolve: GraphQLFieldResolver<any, any>,
|
resolve: GraphQLFieldResolver<any, any>,
|
||||||
|
|||||||
29
yarn.lock
29
yarn.lock
@ -12112,31 +12112,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"caniuse-lite@npm:^1.0.30001400, caniuse-lite@npm:^1.0.30001517":
|
"caniuse-lite@npm:^1.0.30001400, caniuse-lite@npm:^1.0.30001517, caniuse-lite@npm:^1.0.30001541, caniuse-lite@npm:^1.0.30001565, caniuse-lite@npm:^1.0.30001587":
|
||||||
version: 1.0.30001522
|
version: 1.0.30001600
|
||||||
resolution: "caniuse-lite@npm:1.0.30001522"
|
resolution: "caniuse-lite@npm:1.0.30001600"
|
||||||
checksum: fbb72297c5be7de37fbd51b321b930a5525aeb060dbce706b7c3017de02bc059cd40817274821463fb8230d73009668f8393c941b68b8e36370369580c82b8c8
|
checksum: 4c52f83ed71bc5f6e443bd17923460f1c77915adc2c2aa79ddaedceccc690b5917054b0c41b79e9138cbbd9abcdc0db9e224e79e3e734e581dfec06505f3a2b4
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"caniuse-lite@npm:^1.0.30001541":
|
|
||||||
version: 1.0.30001542
|
|
||||||
resolution: "caniuse-lite@npm:1.0.30001542"
|
|
||||||
checksum: 07b14b8341d7bf0ea386a5fa5b5edbee41d81dfc072d3d11db22dd1d7a929358f522b16fdf3cbd154c8a5cae84662578cf5c9e490e7d7606ee7d156ccf07c9fa
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"caniuse-lite@npm:^1.0.30001565":
|
|
||||||
version: 1.0.30001574
|
|
||||||
resolution: "caniuse-lite@npm:1.0.30001574"
|
|
||||||
checksum: 159ebd04d9bbef11bd08499f058f70bf795a55641929be5efadf0f6b17216d4b923506778e59bbb939246834304b753b2e88ff1e2430f6a5aef0a86971f98bd3
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"caniuse-lite@npm:^1.0.30001587":
|
|
||||||
version: 1.0.30001599
|
|
||||||
resolution: "caniuse-lite@npm:1.0.30001599"
|
|
||||||
checksum: c9a5ad806fc0d446e4f995d551b840d8fdcbe97958b7f83ff7a255a8ef5e40ca12ca1a508c66b3ab147e19eef932d28772d205c046500dd0740ea9dfb602e2e1
|
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user