@feathersjs/schema
Advanced tools
Comparing version 5.0.0-pre.35 to 5.0.0-pre.36
@@ -6,2 +6,12 @@ # Change Log | ||
# [5.0.0-pre.36](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.35...v5.0.0-pre.36) (2023-01-29) | ||
### Bug Fixes | ||
- **configuration:** Add pool and connection object to SQL database default configuration ([#3023](https://github.com/feathersjs/feathers/issues/3023)) ([092c749](https://github.com/feathersjs/feathers/commit/092c749d43f7da4d019576d1210fe7d3719a44a2)) | ||
- **databases:** Ensure that query sanitization is not necessary when using query schemas ([#3022](https://github.com/feathersjs/feathers/issues/3022)) ([dbf514e](https://github.com/feathersjs/feathers/commit/dbf514e85d1508b95c007462a39b3cadd4ff391d)) | ||
- **schema:** Allow any type in resolver hooks ([#3006](https://github.com/feathersjs/feathers/issues/3006)) ([f01281f](https://github.com/feathersjs/feathers/commit/f01281f7d83262738459585fc3f53f56c0a0deb8)) | ||
- **schema:** Ensure all types of nested data are securely dispatched ([#3005](https://github.com/feathersjs/feathers/issues/3005)) ([e4a9da5](https://github.com/feathersjs/feathers/commit/e4a9da5f3288e8e9f02087754473c7a9dfda6cb1)) | ||
- Update all dependencies ([#3024](https://github.com/feathersjs/feathers/issues/3024)) ([283dc47](https://github.com/feathersjs/feathers/commit/283dc4798d85584bc031e6e54b83b4ea77d1edd0)) | ||
# [5.0.0-pre.35](https://github.com/feathersjs/feathers/compare/v5.0.0-pre.34...v5.0.0-pre.35) (2023-01-12) | ||
@@ -8,0 +18,0 @@ |
@@ -125,4 +125,36 @@ import { FromSchema } from 'json-schema-to-ts'; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -279,4 +311,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -291,4 +355,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -303,4 +399,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -315,4 +443,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -470,4 +630,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -482,4 +674,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -494,4 +718,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -506,4 +762,36 @@ }; | ||
}; | ||
readonly pool: { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly min: { | ||
readonly type: "number"; | ||
}; | ||
readonly max: { | ||
readonly type: "number"; | ||
}; | ||
}; | ||
}; | ||
readonly connection: { | ||
readonly type: "string"; | ||
readonly oneOf: readonly [{ | ||
readonly type: "string"; | ||
}, { | ||
readonly type: "object"; | ||
readonly properties: { | ||
readonly host: { | ||
readonly type: "string"; | ||
}; | ||
readonly port: { | ||
readonly type: "number"; | ||
}; | ||
readonly user: { | ||
readonly type: "string"; | ||
}; | ||
readonly password: { | ||
readonly type: "string"; | ||
}; | ||
readonly database: { | ||
readonly type: "string"; | ||
}; | ||
}; | ||
}]; | ||
}; | ||
@@ -510,0 +798,0 @@ }; |
@@ -115,3 +115,24 @@ "use strict"; | ||
client: { type: 'string' }, | ||
connection: { type: 'string' } | ||
pool: { | ||
type: 'object', | ||
properties: { | ||
min: { type: 'number' }, | ||
max: { type: 'number' } | ||
} | ||
}, | ||
connection: { | ||
oneOf: [ | ||
{ type: 'string' }, | ||
{ | ||
type: 'object', | ||
properties: { | ||
host: { type: 'string' }, | ||
port: { type: 'number' }, | ||
user: { type: 'string' }, | ||
password: { type: 'string' }, | ||
database: { type: 'string' } | ||
} | ||
} | ||
] | ||
} | ||
} | ||
@@ -118,0 +139,0 @@ }; |
import { HookContext, NextFunction } from '@feathersjs/feathers'; | ||
import { Resolver } from '../resolver'; | ||
export type ResolverSetting<H extends HookContext> = Resolver<any, H> | Resolver<any, H>[]; | ||
export declare const resolveQuery: <T, H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<T, H>[]) => (context: H, next?: NextFunction) => Promise<any>; | ||
export declare const resolveData: <T, H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<T, H>[]) => (context: H, next?: NextFunction) => Promise<any>; | ||
export declare const resolveResult: <T, H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<T, H>[]) => (context: H, next?: NextFunction) => Promise<void>; | ||
export declare const resolveQuery: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<any, H>[]) => (context: H, next?: NextFunction) => Promise<any>; | ||
export declare const resolveData: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<any, H>[]) => (context: H, next?: NextFunction) => Promise<any>; | ||
export declare const resolveResult: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<any, H>[]) => (context: H, next?: NextFunction) => Promise<void>; | ||
export declare const DISPATCH: unique symbol; | ||
export declare const getDispatch: (value: any, fallback?: any) => any; | ||
export declare const resolveDispatch: <T, H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<T, H>[]) => (context: H, next?: NextFunction) => Promise<void>; | ||
export declare const resolveExternal: <T, H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<T, H>[]) => (context: H, next?: NextFunction) => Promise<void>; | ||
export type ResolveAllSettings<H extends HookContext> = { | ||
export declare const getDispatchValue: (value: any) => any; | ||
export declare const getDispatch: (value: any) => any; | ||
export declare const setDispatch: (current: any, dispatch: any) => any; | ||
export declare const resolveDispatch: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<any, H>[]) => (context: H, next?: NextFunction) => Promise<void>; | ||
export declare const resolveExternal: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(...resolvers: Resolver<any, H>[]) => (context: H, next?: NextFunction) => Promise<void>; | ||
type ResolveAllSettings<H extends HookContext> = { | ||
data?: { | ||
@@ -21,2 +23,11 @@ create: Resolver<any, H>; | ||
}; | ||
/** | ||
* Resolve all resolvers at once. | ||
* | ||
* @param map The individual resolvers | ||
* @returns A combined resolver middleware | ||
* @deprecated Use individual data, query and external resolvers and hooks instead. | ||
* @see https://dove.feathersjs.com/guides/cli/service.schemas.html | ||
*/ | ||
export declare const resolveAll: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(map: ResolveAllSettings<H>) => (this: any, context: H, next?: import("@feathersjs/hooks").AsyncMiddleware<H>) => Promise<any>; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.resolveAll = exports.resolveExternal = exports.resolveDispatch = exports.getDispatch = exports.DISPATCH = exports.resolveResult = exports.resolveData = exports.resolveQuery = void 0; | ||
exports.resolveAll = exports.resolveExternal = exports.resolveDispatch = exports.setDispatch = exports.getDispatch = exports.getDispatchValue = exports.DISPATCH = exports.resolveResult = exports.resolveData = exports.resolveQuery = void 0; | ||
const hooks_1 = require("@feathersjs/hooks"); | ||
@@ -14,3 +14,3 @@ const getContext = (context) => { | ||
}; | ||
const getData = (context) => { | ||
const getResult = (context) => { | ||
const isPaginated = context.method === 'find' && context.result.data; | ||
@@ -79,3 +79,3 @@ const data = isPaginated ? context.result.data : context.result; | ||
...query, | ||
$select | ||
...($select ? { $select } : {}) | ||
} | ||
@@ -87,3 +87,3 @@ }; | ||
const status = context.params.resolve; | ||
const { isPaginated, data } = getData(context); | ||
const { isPaginated, data } = getResult(context); | ||
const result = Array.isArray(data) | ||
@@ -102,4 +102,25 @@ ? await Promise.all(data.map(async (current) => runResolvers(resolvers, current, ctx, status))) | ||
exports.DISPATCH = Symbol('@feathersjs/schema/dispatch'); | ||
const getDispatch = (value, fallback = value) => typeof value === 'object' && value !== null && value[exports.DISPATCH] !== undefined ? value[exports.DISPATCH] : fallback; | ||
const getDispatchValue = (value) => { | ||
if (typeof value === 'object' && value !== null) { | ||
if (value[exports.DISPATCH] !== undefined) { | ||
return value[exports.DISPATCH]; | ||
} | ||
if (Array.isArray(value)) { | ||
return value.map((item) => (0, exports.getDispatchValue)(item)); | ||
} | ||
} | ||
return value; | ||
}; | ||
exports.getDispatchValue = getDispatchValue; | ||
const getDispatch = (value) => typeof value === 'object' && value !== null && value[exports.DISPATCH] ? value[exports.DISPATCH] : null; | ||
exports.getDispatch = getDispatch; | ||
const setDispatch = (current, dispatch) => { | ||
Object.defineProperty(current, exports.DISPATCH, { | ||
value: dispatch, | ||
enumerable: false, | ||
configurable: false | ||
}); | ||
return dispatch; | ||
}; | ||
exports.setDispatch = setDispatch; | ||
const resolveDispatch = (...resolvers) => async (context, next) => { | ||
@@ -110,3 +131,3 @@ if (typeof next === 'function') { | ||
const ctx = getContext(context); | ||
const existingDispatch = (0, exports.getDispatch)(context.result, null); | ||
const existingDispatch = (0, exports.getDispatch)(context.result); | ||
if (existingDispatch !== null) { | ||
@@ -117,9 +138,10 @@ context.dispatch = existingDispatch; | ||
const status = context.params.resolve; | ||
const { isPaginated, data } = getData(context); | ||
const { isPaginated, data } = getResult(context); | ||
const resolveAndGetDispatch = async (current) => { | ||
const resolved = await runResolvers(resolvers, current, ctx, status); | ||
return Object.keys(resolved).reduce((res, key) => { | ||
res[key] = (0, exports.getDispatch)(resolved[key]); | ||
const currentDispatch = Object.keys(resolved).reduce((res, key) => { | ||
res[key] = (0, exports.getDispatchValue)(resolved[key]); | ||
return res; | ||
}, {}); | ||
return (0, exports.setDispatch)(current, currentDispatch); | ||
}; | ||
@@ -135,8 +157,3 @@ const result = await (Array.isArray(data) | ||
: result; | ||
context.dispatch = dispatch; | ||
Object.defineProperty(context.result, exports.DISPATCH, { | ||
value: dispatch, | ||
enumerable: false, | ||
configurable: false | ||
}); | ||
context.dispatch = (0, exports.setDispatch)(context.result, dispatch); | ||
} | ||
@@ -147,2 +164,10 @@ }; | ||
const dataMethods = ['create', 'update', 'patch']; | ||
/** | ||
* Resolve all resolvers at once. | ||
* | ||
* @param map The individual resolvers | ||
* @returns A combined resolver middleware | ||
* @deprecated Use individual data, query and external resolvers and hooks instead. | ||
* @see https://dove.feathersjs.com/guides/cli/service.schemas.html | ||
*/ | ||
const resolveAll = (map) => { | ||
@@ -149,0 +174,0 @@ const middleware = []; |
@@ -142,2 +142,19 @@ import { JSONSchema } from 'json-schema-to-ts'; | ||
}; | ||
readonly $and: { | ||
readonly type: "array"; | ||
readonly items: { | ||
readonly type: "object"; | ||
readonly additionalProperties: false; | ||
readonly properties: { [K_2 in keyof T]: PropertyQuery<T[K_2], X[K_2]>; } & { | ||
readonly $or: { | ||
readonly type: "array"; | ||
readonly items: { | ||
readonly type: "object"; | ||
readonly additionalProperties: false; | ||
readonly properties: { [K_2 in keyof T]: PropertyQuery<T[K_2], X[K_2]>; }; | ||
}; | ||
}; | ||
}; | ||
}; | ||
}; | ||
} & { [K_2 in keyof T]: PropertyQuery<T[K_2], X[K_2]>; }; |
@@ -108,2 +108,21 @@ "use strict"; | ||
const props = (0, exports.queryProperties)(definition, extensions); | ||
const $or = { | ||
type: 'array', | ||
items: { | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: props | ||
} | ||
}; | ||
const $and = { | ||
type: 'array', | ||
items: { | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: { | ||
...props, | ||
$or | ||
} | ||
} | ||
}; | ||
return { | ||
@@ -137,10 +156,4 @@ $limit: { | ||
}, | ||
$or: { | ||
type: 'array', | ||
items: { | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: props | ||
} | ||
}, | ||
$or, | ||
$and, | ||
...props | ||
@@ -147,0 +160,0 @@ }; |
{ | ||
"name": "@feathersjs/schema", | ||
"description": "A common data schema definition format", | ||
"version": "5.0.0-pre.35", | ||
"version": "5.0.0-pre.36", | ||
"homepage": "https://feathersjs.com", | ||
@@ -57,9 +57,9 @@ "main": "lib/", | ||
"dependencies": { | ||
"@feathersjs/adapter-commons": "^5.0.0-pre.35", | ||
"@feathersjs/commons": "^5.0.0-pre.35", | ||
"@feathersjs/errors": "^5.0.0-pre.35", | ||
"@feathersjs/feathers": "^5.0.0-pre.35", | ||
"@feathersjs/adapter-commons": "^5.0.0-pre.36", | ||
"@feathersjs/commons": "^5.0.0-pre.36", | ||
"@feathersjs/errors": "^5.0.0-pre.36", | ||
"@feathersjs/feathers": "^5.0.0-pre.36", | ||
"@feathersjs/hooks": "^0.7.6", | ||
"@types/json-schema": "^7.0.11", | ||
"ajv": "^8.11.2", | ||
"ajv": "^8.12.0", | ||
"ajv-formats": "^2.1.1", | ||
@@ -69,3 +69,3 @@ "json-schema-to-ts": "^2.6.2" | ||
"devDependencies": { | ||
"@feathersjs/memory": "^5.0.0-pre.35", | ||
"@feathersjs/memory": "^5.0.0-pre.36", | ||
"@types/mocha": "^10.0.1", | ||
@@ -78,3 +78,3 @@ "@types/node": "^18.11.18", | ||
}, | ||
"gitHead": "c641598d9a4de3ceda10f56cf2af288a4236b15e" | ||
"gitHead": "9a107b463cc80d7f3c28553c908987e05b0b634a" | ||
} |
@@ -21,4 +21,4 @@ # @feathersjs/schema | ||
Copyright (c) 2022 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) | ||
Copyright (c) 2023 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) | ||
Licensed under the [MIT license](LICENSE). |
@@ -120,3 +120,24 @@ import { FromSchema } from 'json-schema-to-ts' | ||
client: { type: 'string' }, | ||
connection: { type: 'string' } | ||
pool: { | ||
type: 'object', | ||
properties: { | ||
min: { type: 'number' }, | ||
max: { type: 'number' } | ||
} | ||
}, | ||
connection: { | ||
oneOf: [ | ||
{ type: 'string' }, | ||
{ | ||
type: 'object', | ||
properties: { | ||
host: { type: 'string' }, | ||
port: { type: 'number' }, | ||
user: { type: 'string' }, | ||
password: { type: 'string' }, | ||
database: { type: 'string' } | ||
} | ||
} | ||
] | ||
} | ||
} | ||
@@ -123,0 +144,0 @@ } as const |
@@ -15,3 +15,3 @@ import { HookContext, NextFunction } from '@feathersjs/feathers' | ||
const getData = <H extends HookContext>(context: H) => { | ||
const getResult = <H extends HookContext>(context: H) => { | ||
const isPaginated = context.method === 'find' && context.result.data | ||
@@ -43,3 +43,3 @@ const data = isPaginated ? context.result.data : context.result | ||
export const resolveQuery = | ||
<T, H extends HookContext>(...resolvers: Resolver<T, H>[]) => | ||
<H extends HookContext>(...resolvers: Resolver<any, H>[]) => | ||
async (context: H, next?: NextFunction) => { | ||
@@ -61,3 +61,3 @@ const ctx = getContext(context) | ||
export const resolveData = | ||
<T, H extends HookContext>(...resolvers: Resolver<T, H>[]) => | ||
<H extends HookContext>(...resolvers: Resolver<any, H>[]) => | ||
async (context: H, next?: NextFunction) => { | ||
@@ -84,6 +84,4 @@ if (context.data !== undefined) { | ||
export const resolveResult = <T, H extends HookContext>(...resolvers: Resolver<T, H>[]) => { | ||
const virtualProperties = new Set( | ||
resolvers.reduce((acc, current) => acc.concat(current.virtualNames), [] as (keyof T)[]) | ||
) | ||
export const resolveResult = <H extends HookContext>(...resolvers: Resolver<any, H>[]) => { | ||
const virtualProperties = new Set(resolvers.reduce((acc, current) => acc.concat(current.virtualNames), [])) | ||
@@ -105,3 +103,3 @@ return async (context: H, next?: NextFunction) => { | ||
...query, | ||
$select | ||
...($select ? { $select } : {}) | ||
} | ||
@@ -115,3 +113,3 @@ } | ||
const status = context.params.resolve | ||
const { isPaginated, data } = getData(context) | ||
const { isPaginated, data } = getResult(context) | ||
@@ -132,7 +130,31 @@ const result = Array.isArray(data) | ||
export const getDispatch = (value: any, fallback = value) => | ||
typeof value === 'object' && value !== null && value[DISPATCH] !== undefined ? value[DISPATCH] : fallback | ||
export const getDispatchValue = (value: any): any => { | ||
if (typeof value === 'object' && value !== null) { | ||
if (value[DISPATCH] !== undefined) { | ||
return value[DISPATCH] | ||
} | ||
if (Array.isArray(value)) { | ||
return value.map((item) => getDispatchValue(item)) | ||
} | ||
} | ||
return value | ||
} | ||
export const getDispatch = (value: any): any => | ||
typeof value === 'object' && value !== null && value[DISPATCH] ? value[DISPATCH] : null | ||
export const setDispatch = (current: any, dispatch: any) => { | ||
Object.defineProperty(current, DISPATCH, { | ||
value: dispatch, | ||
enumerable: false, | ||
configurable: false | ||
}) | ||
return dispatch | ||
} | ||
export const resolveDispatch = | ||
<T, H extends HookContext>(...resolvers: Resolver<T, H>[]) => | ||
<H extends HookContext>(...resolvers: Resolver<any, H>[]) => | ||
async (context: H, next?: NextFunction) => { | ||
@@ -144,3 +166,3 @@ if (typeof next === 'function') { | ||
const ctx = getContext(context) | ||
const existingDispatch = getDispatch(context.result, null) | ||
const existingDispatch = getDispatch(context.result) | ||
@@ -151,11 +173,12 @@ if (existingDispatch !== null) { | ||
const status = context.params.resolve | ||
const { isPaginated, data } = getData(context) | ||
const { isPaginated, data } = getResult(context) | ||
const resolveAndGetDispatch = async (current: any) => { | ||
const resolved: any = await runResolvers(resolvers, current, ctx, status) | ||
const resolved = await runResolvers(resolvers, current, ctx, status) | ||
const currentDispatch = Object.keys(resolved).reduce((res, key) => { | ||
res[key] = getDispatchValue(resolved[key]) | ||
return Object.keys(resolved).reduce((res, key) => { | ||
res[key] = getDispatch(resolved[key]) | ||
return res | ||
}, {} as Record<string, any>) | ||
return res | ||
}, {} as any) | ||
return setDispatch(current, currentDispatch) | ||
} | ||
@@ -173,8 +196,3 @@ | ||
context.dispatch = dispatch | ||
Object.defineProperty(context.result, DISPATCH, { | ||
value: dispatch, | ||
enumerable: false, | ||
configurable: false | ||
}) | ||
context.dispatch = setDispatch(context.result, dispatch) | ||
} | ||
@@ -185,3 +203,3 @@ } | ||
export type ResolveAllSettings<H extends HookContext> = { | ||
type ResolveAllSettings<H extends HookContext> = { | ||
data?: { | ||
@@ -199,2 +217,10 @@ create: Resolver<any, H> | ||
/** | ||
* Resolve all resolvers at once. | ||
* | ||
* @param map The individual resolvers | ||
* @returns A combined resolver middleware | ||
* @deprecated Use individual data, query and external resolvers and hooks instead. | ||
* @see https://dove.feathersjs.com/guides/cli/service.schemas.html | ||
*/ | ||
export const resolveAll = <H extends HookContext>(map: ResolveAllSettings<H>) => { | ||
@@ -201,0 +227,0 @@ const middleware = [] |
@@ -175,2 +175,21 @@ import { _ } from '@feathersjs/commons' | ||
const props = queryProperties(definition, extensions) | ||
const $or = { | ||
type: 'array', | ||
items: { | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: props | ||
} | ||
} as const | ||
const $and = { | ||
type: 'array', | ||
items: { | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: { | ||
...props, | ||
$or | ||
} | ||
} | ||
} as const | ||
@@ -207,12 +226,6 @@ return { | ||
}, | ||
$or: { | ||
type: 'array', | ||
items: { | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: props | ||
} | ||
}, | ||
$or, | ||
$and, | ||
...props | ||
} as const | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
140647
2763