From 7088af64a539dc7f1a016d832b77b98aaaf92603 Mon Sep 17 00:00:00 2001 From: David Luecke Date: Wed, 14 Dec 2022 11:18:46 -0800 Subject: [PATCH] feat(cli): Use separate patch schema and types (#2916) --- docs/guides/basics/schemas.md | 151 ++++--- package-lock.json | 379 ++++++++++-------- .../templates/schema.json.tpl.ts | 34 +- .../templates/schema.typebox.tpl.ts | 18 +- .../src/service/templates/schema.json.tpl.ts | 18 +- .../service/templates/schema.typebox.tpl.ts | 16 +- .../cli/src/service/templates/service.tpl.ts | 54 ++- packages/cli/src/service/type/custom.tpl.ts | 8 +- packages/cli/src/service/type/knex.tpl.ts | 4 +- packages/cli/src/service/type/mongodb.tpl.ts | 4 +- packages/knex/src/index.ts | 41 +- packages/schema/src/hooks/validate.ts | 4 +- packages/schema/test/fixture.ts | 6 +- 13 files changed, 456 insertions(+), 281 deletions(-) diff --git a/docs/guides/basics/schemas.md b/docs/guides/basics/schemas.md index 78c668caa7..88ca258417 100644 --- a/docs/guides/basics/schemas.md +++ b/docs/guides/basics/schemas.md @@ -50,7 +50,8 @@ First we need to update the `src/services/users/users.schema.js` file with the s -```ts{1,16-17,32,42-52,56,63-67} +```ts{2,17-18,33,43-53,81-85} +// For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html import crypto from 'crypto' import { resolve } from '@feathersjs/schema' import { Type, getDataValidator, getValidator, querySyntax } from '@feathersjs/typebox' @@ -79,7 +80,7 @@ export const userExternalResolver = resolve({ password: async () => undefined }) -// Schema for the basic data model (e.g. creating new entries) +// Schema for creating new users export const userDataSchema = Type.Pick( userSchema, ['email', 'password', 'githubId', 'avatar'], @@ -105,9 +106,26 @@ export const userDataResolver = resolve({ } }) +// Schema for updating existing users +export const userPatchSchema = Type.Partial(userSchema, { + $id: 'UserPatch' +}) +export type UserPatch = Static +export const userPatchValidator = getDataValidator(userPatchSchema, dataValidator) +export const userPatchResolver = resolve({ + password: passwordHash({ strategy: 'local' }) +}) + // Schema for allowed query properties export const userQueryProperties = Type.Pick(userSchema, ['id', 'email', 'githubId']) -export const userQuerySchema = querySyntax(userQueryProperties) +export const userQuerySchema = Type.Intersect( + [ + querySyntax(userQueryProperties), + // Add additional query properties here + Type.Object({}, { additionalProperties: false }) + ], + { additionalProperties: false } +) export type UserQuery = Static export const userQueryValidator = getValidator(userQuerySchema, queryValidator) export const userQueryResolver = resolve({ @@ -128,7 +146,8 @@ export const userQueryResolver = resolve({ -```ts{1,16-17,32,42-52,56,63-67} +```ts{2,17-18,33,43-53,81-85} +// For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html import crypto from 'crypto' import { resolve } from '@feathersjs/schema' import { Type, getDataValidator, getValidator, querySyntax } from '@feathersjs/typebox' @@ -157,11 +176,15 @@ export const userExternalResolver = resolve({ password: async () => undefined }) -// Schema for the basic data model (e.g. creating new entries) -export const userDataSchema = Type.Pick(userSchema, ['email', 'password', 'githubId', 'avatar'], { - $id: 'UserData', - additionalProperties: false -}) +// Schema for creating new users +export const userDataSchema = Type.Pick( + userSchema, + ['email', 'password', 'githubId', 'avatar'], + { + $id: 'UserData', + additionalProperties: false + } +) export type UserData = Static export const userDataValidator = getDataValidator(userDataSchema, dataValidator) export const userDataResolver = resolve({ @@ -179,9 +202,26 @@ export const userDataResolver = resolve({ } }) +// Schema for updating existing users +export const userPatchSchema = Type.Partial(userSchema, { + $id: 'UserPatch' +}) +export type UserPatch = Static +export const userPatchValidator = getDataValidator(userPatchSchema, dataValidator) +export const userPatchResolver = resolve({ + password: passwordHash({ strategy: 'local' }) +}) + // Schema for allowed query properties -export const userQueryProperties = Type.Pick(userSchema, ['_id', 'email', 'githubId']) -export const userQuerySchema = querySyntax(userQueryProperties) +export const userQueryProperties = Type.Pick(userSchema, ['id', 'email', 'githubId']) +export const userQuerySchema = Type.Intersect( + [ + querySyntax(userQueryProperties), + // Add additional query properties here + Type.Object({}, { additionalProperties: false }) + ], + { additionalProperties: false } +) export type UserQuery = Static export const userQueryValidator = getValidator(userQuerySchema, queryValidator) export const userQueryResolver = resolve({ @@ -217,7 +257,8 @@ Update the `src/services/messages/messages.schema.js` file like this: -```ts{1, 7,14-16,22-25,38-44,50,60-64} +```ts{2,8,15-17,23-26,38-44,57-60} +// For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html import { resolve, virtual } from '@feathersjs/schema' import { Type, getDataValidator, getValidator, querySyntax } from '@feathersjs/typebox' import type { Static } from '@feathersjs/typebox' @@ -232,7 +273,7 @@ export const messageSchema = Type.Object( id: Type.Number(), text: Type.String(), createdAt: Type.Number(), - userId: Type.Number(), + userId: Type.String(), user: Type.Ref(userSchema) }, { $id: 'Message', additionalProperties: false } @@ -249,8 +290,7 @@ export const messageExternalResolver = resolve({}) // Schema for creating new entries export const messageDataSchema = Type.Pick(messageSchema, ['text'], { - $id: 'MessageData', - additionalProperties: false + $id: 'MessageData' }) export type MessageData = Static export const messageDataValidator = getDataValidator(messageDataSchema, dataValidator) @@ -264,35 +304,40 @@ export const messageDataResolver = resolve({ } }) +// Schema for updating existing entries +export const messagePatchSchema = Type.Partial(messageSchema, { + $id: 'MessagePatch' +}) +export type MessagePatch = Static +export const messagePatchValidator = getDataValidator(messagePatchSchema, dataValidator) +export const messagePatchResolver = resolve({}) + // Schema for allowed query properties -export const messageQueryProperties = Type.Pick( - messageSchema, - ['id', 'text', 'createdAt', 'userId'], - { - additionalProperties: false - } +export const messageQueryProperties = Type.Pick(messageSchema,[ + 'id', + 'text', + 'createdAt', + 'userId' +]) +export const messageQuerySchema = Type.Intersect( + [ + querySyntax(messageQueryProperties), + // Add additional query properties here + Type.Object({}, { additionalProperties: false }) + ], + { additionalProperties: false } ) -export const messageQuerySchema = querySyntax(messageQueryProperties) export type MessageQuery = Static export const messageQueryValidator = getValidator(messageQuerySchema, queryValidator) -export const messageQueryResolver = resolve({ - userId: async (value, user, context) => { - // We want to be able to get a list of all messages but - // only let a user access their own messages otherwise - if (context.params.user && context.method !== 'find') { - return context.params.user.id - } - - return value - } -}) +export const messageQueryResolver = resolve({}) ``` -```ts{1,7,14-16,22-25,38-44,50,60-64} +```ts{2,8,15-17,23-26,38-44,57-60} +// For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html import { resolve, virtual } from '@feathersjs/schema' import { Type, getDataValidator, getValidator, querySyntax } from '@feathersjs/typebox' import type { Static } from '@feathersjs/typebox' @@ -324,8 +369,7 @@ export const messageExternalResolver = resolve({}) // Schema for creating new entries export const messageDataSchema = Type.Pick(messageSchema, ['text'], { - $id: 'MessageData', - additionalProperties: false + $id: 'MessageData' }) export type MessageData = Static export const messageDataValidator = getDataValidator(messageDataSchema, dataValidator) @@ -339,24 +383,29 @@ export const messageDataResolver = resolve({ } }) -// Schema for allowed query properties -export const messageQueryProperties = Type.Pick(messageSchema, ['_id', 'text', 'createdAt', 'userId'], { - additionalProperties: false +// Schema for updating existing entries +export const messagePatchSchema = Type.Partial(messageSchema, { + $id: 'MessagePatch' }) -export const messageQuerySchema = querySyntax(messageQueryProperties) +export type MessagePatch = Static +export const messagePatchValidator = getDataValidator(messagePatchSchema, dataValidator) +export const messagePatchResolver = resolve({}) + +// Schema for allowed query properties +export const messageQueryProperties = Type.Pick(messageSchema, +['_id', 'text', 'createdAt', 'userId'] +) +export const messageQuerySchema = Type.Intersect( + [ + querySyntax(messageQueryProperties), + // Add additional query properties here + Type.Object({}, { additionalProperties: false }) + ], + { additionalProperties: false } +) export type MessageQuery = Static export const messageQueryValidator = getValidator(messageQuerySchema, queryValidator) -export const messageQueryResolver = resolve({ - userId: async (value, user, context) => { - // We want to be able to get a list of all messages but - // only let a user access their own messages otherwise - if (context.params.user && context.method !== 'find') { - return context.params.user._id - } - - return value - } -}) +export const messageQueryResolver = resolve({}) ``` diff --git a/package-lock.json b/package-lock.json index 598c9c7ba1..80eb553f58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -220,16 +220,16 @@ } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.226.0.tgz", - "integrity": "sha512-f97yYtFN2YyVLCkDM51yLakb5NKy9gTSSXWe9mA9rgynLPfgsJbIHXv3zr1Qg0Ay0p4j1eLYukLaVw1MKlHDgw==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.229.0.tgz", + "integrity": "sha512-t2WIJ/6SdLQOoahhY+mze8BFY3Cny+1qmo8AVRsdU9Y0aDU4+3pW07j+hkoeFpnEtBEseJCxKuCCNFCD6qJD5Q==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.226.0", + "@aws-sdk/client-sts": "3.229.0", "@aws-sdk/config-resolver": "3.226.0", - "@aws-sdk/credential-provider-node": "3.226.0", + "@aws-sdk/credential-provider-node": "3.229.0", "@aws-sdk/fetch-http-handler": "3.226.0", "@aws-sdk/hash-node": "3.226.0", "@aws-sdk/invalid-dependency": "3.226.0", @@ -238,7 +238,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-signing": "3.226.0", "@aws-sdk/middleware-stack": "3.226.0", @@ -255,6 +255,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -266,9 +267,9 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.226.0.tgz", - "integrity": "sha512-+Hl1YSLKrxPnQLijhWryI6uV8eKZIsUhvWlzFKx75kjxzjsC/jyk5zV59jnCu0SCCepXB8DKyLVa2WpH7iAHew==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.229.0.tgz", + "integrity": "sha512-gcPitIBAxwwhkCPKtod02ZjaFD5UCdwFYq31XsCY0OQDV+CFalSd+3gjKyDQOMtfgegLYyOvMQvlIU+geUFRZg==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "2.0.0", @@ -282,7 +283,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-stack": "3.226.0", "@aws-sdk/middleware-user-agent": "3.226.0", @@ -298,6 +299,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -309,9 +311,9 @@ } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.226.0.tgz", - "integrity": "sha512-IKzAhL6RoPs7IZ/rJvekjedQ4oesazCO+Aqh9l2Xct+XY0MFBdh4amgg4t/8fjksfIzmJH48BZoNv5gVak6yRw==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.229.0.tgz", + "integrity": "sha512-sb9eRqnqMWVvdg4k9UTuC08IvRQOwpX2bT3XXoYioHYoy/ChUFPrNazrmuZwj6GFrIWkl0pIPCeqVfScZM3EYw==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "2.0.0", @@ -325,7 +327,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-stack": "3.226.0", "@aws-sdk/middleware-user-agent": "3.226.0", @@ -341,6 +343,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -352,15 +355,15 @@ } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.226.0.tgz", - "integrity": "sha512-ZBlqRVbnHvvbkN5g56+mXltNybHNzgV69+2ARubQ8ge9U2qF/LweCmGqZnZLWqdGXwaB9IOvz5ZW2npyJh1X/A==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.229.0.tgz", + "integrity": "sha512-UjGVIzYouEu14YkDy4o+IkVUsx8kLEYNYX5vrymNAT67lNnN/gSyV3h0XgMNzNQHZvtso9c96C6ZGeGW/AVUqQ==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", "@aws-sdk/config-resolver": "3.226.0", - "@aws-sdk/credential-provider-node": "3.226.0", + "@aws-sdk/credential-provider-node": "3.229.0", "@aws-sdk/fetch-http-handler": "3.226.0", "@aws-sdk/hash-node": "3.226.0", "@aws-sdk/invalid-dependency": "3.226.0", @@ -369,7 +372,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-sdk-sts": "3.226.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-signing": "3.226.0", @@ -387,6 +390,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -415,12 +419,12 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.226.0.tgz", - "integrity": "sha512-ukueK6kgTxvUX89oQBoArj7Oh0dYfkToHypnin08SHRZry9VNnK5IfSMO+Q1tXmxCnDtai1ejaAOny900OjMyg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.229.0.tgz", + "integrity": "sha512-RvIrJ/jHCUhGtAjp1hIrbbZ/FyAgx5GZ1Tu708FK58LoCqfA5mKUEmv4cUpRTo/VP7w1Wf3qloK4rmqfkNjAkg==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.226.0", + "@aws-sdk/client-cognito-identity": "3.229.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" @@ -460,14 +464,14 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.226.0.tgz", - "integrity": "sha512-Sj7SGl53qmKkD7wvgU0MSTyj8ho6A3tKVbadTHljVz60jiauTEM97Z1DIai6U3oPFVteaKqx7npc8ozeK6mKNg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.229.0.tgz", + "integrity": "sha512-DbzsaUXoBYvImlWaJ+gRL0HPelDFcQylIc+JnciYuSPLE+wwL3IZRdzkyIOBYz68JwMHd8jGJf+PycbkATOqOw==", "optional": true, "dependencies": { "@aws-sdk/credential-provider-env": "3.226.0", "@aws-sdk/credential-provider-imds": "3.226.0", - "@aws-sdk/credential-provider-sso": "3.226.0", + "@aws-sdk/credential-provider-sso": "3.229.0", "@aws-sdk/credential-provider-web-identity": "3.226.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", @@ -479,16 +483,16 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.226.0.tgz", - "integrity": "sha512-kuOeiVmlhSyMC1Eix0pqHmb4EmpbMHrTw+9ObZbQ2bRXy05Q9fLA6SVBcI01bI1KVh7Qqz9i8ojOY3A2zscjyA==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.229.0.tgz", + "integrity": "sha512-VIQ+eamKDqJ9ps4McSJGI0Bx57/NQ8WaU5dz1EOeluwM8LTK1i6aQeSzOcy+A66/b+pni1oIjAF7PfSsdEqdpA==", "optional": true, "dependencies": { "@aws-sdk/credential-provider-env": "3.226.0", "@aws-sdk/credential-provider-imds": "3.226.0", - "@aws-sdk/credential-provider-ini": "3.226.0", + "@aws-sdk/credential-provider-ini": "3.229.0", "@aws-sdk/credential-provider-process": "3.226.0", - "@aws-sdk/credential-provider-sso": "3.226.0", + "@aws-sdk/credential-provider-sso": "3.229.0", "@aws-sdk/credential-provider-web-identity": "3.226.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", @@ -515,15 +519,15 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.226.0.tgz", - "integrity": "sha512-QSBeyOIAus4/8u/DeAstE8w/zw+F7PQohdB8JFP/BPaCfc8uKue4UkqqvQWRfm4VSEnHeXt037MDopmCpd98Iw==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.229.0.tgz", + "integrity": "sha512-RI9xjwp2NBJjm2bPOcTK7NwAxqzJxIZPjukVjidC2N3B1Ca5Gn+yUji2iYf7c9KavTROY80j/rieHMb14n7iSw==", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.226.0", + "@aws-sdk/client-sso": "3.229.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", - "@aws-sdk/token-providers": "3.226.0", + "@aws-sdk/token-providers": "3.229.0", "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, @@ -546,21 +550,21 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.226.0.tgz", - "integrity": "sha512-oNkUBxlX0kmwt8jEyQAH7p5Tk1g9iWEKGGCTPPZ7A5RoZpmv83zT8ReZ/+QsSmJIWGb0zzraHMzKbmfMSeztZg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.229.0.tgz", + "integrity": "sha512-AGpLZFScqqkP6qiHlmxBX5yq7AR1uYLxrty0hT91IgzZxeI1lo951q0ynsfLUl+NFXsPkVAImvzyXdLCVN6W5A==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.226.0", - "@aws-sdk/client-sso": "3.226.0", - "@aws-sdk/client-sts": "3.226.0", - "@aws-sdk/credential-provider-cognito-identity": "3.226.0", + "@aws-sdk/client-cognito-identity": "3.229.0", + "@aws-sdk/client-sso": "3.229.0", + "@aws-sdk/client-sts": "3.229.0", + "@aws-sdk/credential-provider-cognito-identity": "3.229.0", "@aws-sdk/credential-provider-env": "3.226.0", "@aws-sdk/credential-provider-imds": "3.226.0", - "@aws-sdk/credential-provider-ini": "3.226.0", - "@aws-sdk/credential-provider-node": "3.226.0", + "@aws-sdk/credential-provider-ini": "3.229.0", + "@aws-sdk/credential-provider-node": "3.229.0", "@aws-sdk/credential-provider-process": "3.226.0", - "@aws-sdk/credential-provider-sso": "3.226.0", + "@aws-sdk/credential-provider-sso": "3.229.0", "@aws-sdk/credential-provider-web-identity": "3.226.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", @@ -695,13 +699,13 @@ } }, "node_modules/@aws-sdk/middleware-retry": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.226.0.tgz", - "integrity": "sha512-uMn4dSkv9Na2uvt6K3HgTnVrCRAlGv1MBAtUDLXONqUv1L/Z1fp3CkFkLKQHKylfBwBhe6dXfYEo87i8LZFoqg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.229.0.tgz", + "integrity": "sha512-/y0BWio9b2RRH2QvRTohbuqE0vhH4IZKlc6k+JRbGV9aSwyOzACU/L/qkGftC/W0puvgNvZYjGxmB6cGHAEZaw==", "optional": true, "dependencies": { "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/service-error-classification": "3.226.0", + "@aws-sdk/service-error-classification": "3.229.0", "@aws-sdk/types": "3.226.0", "@aws-sdk/util-middleware": "3.226.0", "tslib": "^2.3.1", @@ -878,9 +882,9 @@ } }, "node_modules/@aws-sdk/service-error-classification": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.226.0.tgz", - "integrity": "sha512-9R01dBpE8JILe2CTft7YN2tMufT2mMWMTqxmHwPSmOpsxHTj8hEII7GTfvpb95ThHwW7XMNhg7pbHLbrTJZCVA==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.229.0.tgz", + "integrity": "sha512-dnzWWQ0/NoWMUZ5C0DW3dPm0wC1O76Y/SpKbuJzWPkx1EYy6r8p32Ly4D9vUzrKDbRGf48YHIF2kOkBmu21CLg==", "optional": true, "engines": { "node": ">=14.0.0" @@ -931,12 +935,12 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.226.0.tgz", - "integrity": "sha512-3ouRt2i3ve8ivg54PxPhtOTcipzf6BoQsMw0EiO23yYKujhyeFH2IkxV4EYC687xFrUjheqJf8FWU/DD8EQ/ow==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.229.0.tgz", + "integrity": "sha512-LmB40GDKch3LUfTOC6r2fWQoMYrvXoO9eN3TE0eVTWi/p8xCaROcnwb5pWe3mCCrKVygA4XZXSXkUO3DZhJL3w==", "optional": true, "dependencies": { - "@aws-sdk/client-sso-oidc": "3.226.0", + "@aws-sdk/client-sso-oidc": "3.229.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", "@aws-sdk/types": "3.226.0", @@ -1109,6 +1113,19 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/util-retry": { + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.229.0.tgz", + "integrity": "sha512-0zKTqi0P1inD0LzIMuXRIYYQ/8c1lWMg/cfiqUcIAF1TpatlpZuN7umU0ierpBFud7S+zDgg0oemh+Nj8xliJw==", + "optional": true, + "dependencies": { + "@aws-sdk/service-error-classification": "3.229.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@aws-sdk/util-uri-escape": { "version": "3.201.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.201.0.tgz", @@ -4698,9 +4715,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.12.tgz", - "integrity": "sha512-xm46HDwYz69z8xcNh9esHYKpvhXmA02sD+K9cur6XZvwjZTSBJ8PNbK5xeSO0IYZqRzpxkXYsbpsF/hF0WdPew==" + "version": "0.25.13", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.13.tgz", + "integrity": "sha512-XiEwzYpUwE5y/k333Cy0Ujmxvw/mA4zIyEmwUyA0EDDik7ba8S/HClvz3ylOsABfYSj+/skQq4QJl0k/Z1eDLg==" }, "node_modules/@sindresorhus/is": { "version": "5.3.0", @@ -4875,12 +4892,12 @@ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" }, "node_modules/@types/express": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", - "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz", + "integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.31", "@types/qs": "*", "@types/serve-static": "*" } @@ -5059,9 +5076,9 @@ } }, "node_modules/@types/node": { - "version": "18.11.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.12.tgz", - "integrity": "sha512-FgD3NtTAKvyMmD44T07zz2fEf+OKwutgBCEVM8GcvMGVGaDktiLNTDvPwC/LUe3PinMW+X6CuLOF2Ui1mAlSXg==" + "version": "18.11.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", + "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==" }, "node_modules/@types/node-fetch": { "version": "2.6.2", @@ -14048,9 +14065,9 @@ } }, "node_modules/mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dependencies": { "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", @@ -14516,12 +14533,12 @@ } }, "node_modules/mongodb-memory-server": { - "version": "8.10.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.10.1.tgz", - "integrity": "sha512-xBo45TuU4SFjDWixOXJyTBDukYqGeCuh7RBcDm4Nqngd/2Pjja/XYYFFJk/I44mTrZ77W1HDmCA4d69XgNJUJQ==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.10.2.tgz", + "integrity": "sha512-f8v9rRiA7sL5UganOjTL8/hzmdU0Vd7pC5Nsgh6vLFySz23UzpGYwV+knPWreFlqToTdw1mHdPlofZ4Ss/gi7w==", "hasInstallScript": true, "dependencies": { - "mongodb-memory-server-core": "8.10.1", + "mongodb-memory-server-core": "8.10.2", "tslib": "^2.4.1" }, "engines": { @@ -14529,9 +14546,9 @@ } }, "node_modules/mongodb-memory-server-core": { - "version": "8.10.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.10.1.tgz", - "integrity": "sha512-Xva73v08VDojH1+423fJA6PWsoSWnkexk8/zSCdQTfKXACAgEaQ5fay89gzYn/bn/4So89hPVdLwEOt2VYMK7Q==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.10.2.tgz", + "integrity": "sha512-ro4k1eGcjk6p8214wFpv31dsB4eaBUMRr9WYLBcQDbmzCkM7ARn6vsJhlrKWH8eoayLZf0X6557j013t/Ld8aA==", "dependencies": { "@types/tmp": "^0.2.3", "async-mutex": "^0.3.2", @@ -14783,9 +14800,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.7.tgz", + "integrity": "sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ==" }, "node_modules/nopt": { "version": "5.0.0", @@ -18568,9 +18585,9 @@ "dev": true }, "node_modules/sqlite3": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.2.tgz", - "integrity": "sha512-D0Reg6pRWAFXFUnZKsszCI67tthFD8fGPewRddDCX6w4cYwz3MbvuwRICbL+YQjBAh9zbw+lJ/V9oC8nG5j6eg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.4.tgz", + "integrity": "sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==", "hasInstallScript": true, "dependencies": { "@mapbox/node-pre-gyp": "^1.0.0", @@ -19533,9 +19550,9 @@ } }, "node_modules/type-fest": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.3.0.tgz", - "integrity": "sha512-gezeeOIZyQLGW5uuCeEnXF1aXmtt2afKspXz3YqoOcZ3l/YMJq1pujvgT+cz/Nw1O/7q/kSav5fihJHsC/AOUg==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.4.0.tgz", + "integrity": "sha512-PEPg6RHlB9cFwoTMNENNrQFL0cXX04voWr2UPwQBJ3pVs7Mt8Y1oLWdUeMdGEwZE8HFFlujq8gS9enmyiQ8pLg==", "engines": { "node": ">=14.16" }, @@ -20728,16 +20745,16 @@ } }, "@aws-sdk/client-cognito-identity": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.226.0.tgz", - "integrity": "sha512-f97yYtFN2YyVLCkDM51yLakb5NKy9gTSSXWe9mA9rgynLPfgsJbIHXv3zr1Qg0Ay0p4j1eLYukLaVw1MKlHDgw==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.229.0.tgz", + "integrity": "sha512-t2WIJ/6SdLQOoahhY+mze8BFY3Cny+1qmo8AVRsdU9Y0aDU4+3pW07j+hkoeFpnEtBEseJCxKuCCNFCD6qJD5Q==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.226.0", + "@aws-sdk/client-sts": "3.229.0", "@aws-sdk/config-resolver": "3.226.0", - "@aws-sdk/credential-provider-node": "3.226.0", + "@aws-sdk/credential-provider-node": "3.229.0", "@aws-sdk/fetch-http-handler": "3.226.0", "@aws-sdk/hash-node": "3.226.0", "@aws-sdk/invalid-dependency": "3.226.0", @@ -20746,7 +20763,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-signing": "3.226.0", "@aws-sdk/middleware-stack": "3.226.0", @@ -20763,6 +20780,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -20771,9 +20789,9 @@ } }, "@aws-sdk/client-sso": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.226.0.tgz", - "integrity": "sha512-+Hl1YSLKrxPnQLijhWryI6uV8eKZIsUhvWlzFKx75kjxzjsC/jyk5zV59jnCu0SCCepXB8DKyLVa2WpH7iAHew==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.229.0.tgz", + "integrity": "sha512-gcPitIBAxwwhkCPKtod02ZjaFD5UCdwFYq31XsCY0OQDV+CFalSd+3gjKyDQOMtfgegLYyOvMQvlIU+geUFRZg==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "2.0.0", @@ -20787,7 +20805,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-stack": "3.226.0", "@aws-sdk/middleware-user-agent": "3.226.0", @@ -20803,6 +20821,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -20811,9 +20830,9 @@ } }, "@aws-sdk/client-sso-oidc": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.226.0.tgz", - "integrity": "sha512-IKzAhL6RoPs7IZ/rJvekjedQ4oesazCO+Aqh9l2Xct+XY0MFBdh4amgg4t/8fjksfIzmJH48BZoNv5gVak6yRw==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.229.0.tgz", + "integrity": "sha512-sb9eRqnqMWVvdg4k9UTuC08IvRQOwpX2bT3XXoYioHYoy/ChUFPrNazrmuZwj6GFrIWkl0pIPCeqVfScZM3EYw==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "2.0.0", @@ -20827,7 +20846,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-stack": "3.226.0", "@aws-sdk/middleware-user-agent": "3.226.0", @@ -20843,6 +20862,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -20851,15 +20871,15 @@ } }, "@aws-sdk/client-sts": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.226.0.tgz", - "integrity": "sha512-ZBlqRVbnHvvbkN5g56+mXltNybHNzgV69+2ARubQ8ge9U2qF/LweCmGqZnZLWqdGXwaB9IOvz5ZW2npyJh1X/A==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.229.0.tgz", + "integrity": "sha512-UjGVIzYouEu14YkDy4o+IkVUsx8kLEYNYX5vrymNAT67lNnN/gSyV3h0XgMNzNQHZvtso9c96C6ZGeGW/AVUqQ==", "optional": true, "requires": { "@aws-crypto/sha256-browser": "2.0.0", "@aws-crypto/sha256-js": "2.0.0", "@aws-sdk/config-resolver": "3.226.0", - "@aws-sdk/credential-provider-node": "3.226.0", + "@aws-sdk/credential-provider-node": "3.229.0", "@aws-sdk/fetch-http-handler": "3.226.0", "@aws-sdk/hash-node": "3.226.0", "@aws-sdk/invalid-dependency": "3.226.0", @@ -20868,7 +20888,7 @@ "@aws-sdk/middleware-host-header": "3.226.0", "@aws-sdk/middleware-logger": "3.226.0", "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.226.0", + "@aws-sdk/middleware-retry": "3.229.0", "@aws-sdk/middleware-sdk-sts": "3.226.0", "@aws-sdk/middleware-serde": "3.226.0", "@aws-sdk/middleware-signing": "3.226.0", @@ -20886,6 +20906,7 @@ "@aws-sdk/util-defaults-mode-browser": "3.226.0", "@aws-sdk/util-defaults-mode-node": "3.226.0", "@aws-sdk/util-endpoints": "3.226.0", + "@aws-sdk/util-retry": "3.229.0", "@aws-sdk/util-user-agent-browser": "3.226.0", "@aws-sdk/util-user-agent-node": "3.226.0", "@aws-sdk/util-utf8-browser": "3.188.0", @@ -20908,12 +20929,12 @@ } }, "@aws-sdk/credential-provider-cognito-identity": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.226.0.tgz", - "integrity": "sha512-ukueK6kgTxvUX89oQBoArj7Oh0dYfkToHypnin08SHRZry9VNnK5IfSMO+Q1tXmxCnDtai1ejaAOny900OjMyg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.229.0.tgz", + "integrity": "sha512-RvIrJ/jHCUhGtAjp1hIrbbZ/FyAgx5GZ1Tu708FK58LoCqfA5mKUEmv4cUpRTo/VP7w1Wf3qloK4rmqfkNjAkg==", "optional": true, "requires": { - "@aws-sdk/client-cognito-identity": "3.226.0", + "@aws-sdk/client-cognito-identity": "3.229.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" @@ -20944,14 +20965,14 @@ } }, "@aws-sdk/credential-provider-ini": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.226.0.tgz", - "integrity": "sha512-Sj7SGl53qmKkD7wvgU0MSTyj8ho6A3tKVbadTHljVz60jiauTEM97Z1DIai6U3oPFVteaKqx7npc8ozeK6mKNg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.229.0.tgz", + "integrity": "sha512-DbzsaUXoBYvImlWaJ+gRL0HPelDFcQylIc+JnciYuSPLE+wwL3IZRdzkyIOBYz68JwMHd8jGJf+PycbkATOqOw==", "optional": true, "requires": { "@aws-sdk/credential-provider-env": "3.226.0", "@aws-sdk/credential-provider-imds": "3.226.0", - "@aws-sdk/credential-provider-sso": "3.226.0", + "@aws-sdk/credential-provider-sso": "3.229.0", "@aws-sdk/credential-provider-web-identity": "3.226.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", @@ -20960,16 +20981,16 @@ } }, "@aws-sdk/credential-provider-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.226.0.tgz", - "integrity": "sha512-kuOeiVmlhSyMC1Eix0pqHmb4EmpbMHrTw+9ObZbQ2bRXy05Q9fLA6SVBcI01bI1KVh7Qqz9i8ojOY3A2zscjyA==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.229.0.tgz", + "integrity": "sha512-VIQ+eamKDqJ9ps4McSJGI0Bx57/NQ8WaU5dz1EOeluwM8LTK1i6aQeSzOcy+A66/b+pni1oIjAF7PfSsdEqdpA==", "optional": true, "requires": { "@aws-sdk/credential-provider-env": "3.226.0", "@aws-sdk/credential-provider-imds": "3.226.0", - "@aws-sdk/credential-provider-ini": "3.226.0", + "@aws-sdk/credential-provider-ini": "3.229.0", "@aws-sdk/credential-provider-process": "3.226.0", - "@aws-sdk/credential-provider-sso": "3.226.0", + "@aws-sdk/credential-provider-sso": "3.229.0", "@aws-sdk/credential-provider-web-identity": "3.226.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", @@ -20990,15 +21011,15 @@ } }, "@aws-sdk/credential-provider-sso": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.226.0.tgz", - "integrity": "sha512-QSBeyOIAus4/8u/DeAstE8w/zw+F7PQohdB8JFP/BPaCfc8uKue4UkqqvQWRfm4VSEnHeXt037MDopmCpd98Iw==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.229.0.tgz", + "integrity": "sha512-RI9xjwp2NBJjm2bPOcTK7NwAxqzJxIZPjukVjidC2N3B1Ca5Gn+yUji2iYf7c9KavTROY80j/rieHMb14n7iSw==", "optional": true, "requires": { - "@aws-sdk/client-sso": "3.226.0", + "@aws-sdk/client-sso": "3.229.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", - "@aws-sdk/token-providers": "3.226.0", + "@aws-sdk/token-providers": "3.229.0", "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" } @@ -21015,21 +21036,21 @@ } }, "@aws-sdk/credential-providers": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.226.0.tgz", - "integrity": "sha512-oNkUBxlX0kmwt8jEyQAH7p5Tk1g9iWEKGGCTPPZ7A5RoZpmv83zT8ReZ/+QsSmJIWGb0zzraHMzKbmfMSeztZg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.229.0.tgz", + "integrity": "sha512-AGpLZFScqqkP6qiHlmxBX5yq7AR1uYLxrty0hT91IgzZxeI1lo951q0ynsfLUl+NFXsPkVAImvzyXdLCVN6W5A==", "optional": true, "requires": { - "@aws-sdk/client-cognito-identity": "3.226.0", - "@aws-sdk/client-sso": "3.226.0", - "@aws-sdk/client-sts": "3.226.0", - "@aws-sdk/credential-provider-cognito-identity": "3.226.0", + "@aws-sdk/client-cognito-identity": "3.229.0", + "@aws-sdk/client-sso": "3.229.0", + "@aws-sdk/client-sts": "3.229.0", + "@aws-sdk/credential-provider-cognito-identity": "3.229.0", "@aws-sdk/credential-provider-env": "3.226.0", "@aws-sdk/credential-provider-imds": "3.226.0", - "@aws-sdk/credential-provider-ini": "3.226.0", - "@aws-sdk/credential-provider-node": "3.226.0", + "@aws-sdk/credential-provider-ini": "3.229.0", + "@aws-sdk/credential-provider-node": "3.229.0", "@aws-sdk/credential-provider-process": "3.226.0", - "@aws-sdk/credential-provider-sso": "3.226.0", + "@aws-sdk/credential-provider-sso": "3.229.0", "@aws-sdk/credential-provider-web-identity": "3.226.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", @@ -21140,13 +21161,13 @@ } }, "@aws-sdk/middleware-retry": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.226.0.tgz", - "integrity": "sha512-uMn4dSkv9Na2uvt6K3HgTnVrCRAlGv1MBAtUDLXONqUv1L/Z1fp3CkFkLKQHKylfBwBhe6dXfYEo87i8LZFoqg==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.229.0.tgz", + "integrity": "sha512-/y0BWio9b2RRH2QvRTohbuqE0vhH4IZKlc6k+JRbGV9aSwyOzACU/L/qkGftC/W0puvgNvZYjGxmB6cGHAEZaw==", "optional": true, "requires": { "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/service-error-classification": "3.226.0", + "@aws-sdk/service-error-classification": "3.229.0", "@aws-sdk/types": "3.226.0", "@aws-sdk/util-middleware": "3.226.0", "tslib": "^2.3.1", @@ -21286,9 +21307,9 @@ } }, "@aws-sdk/service-error-classification": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.226.0.tgz", - "integrity": "sha512-9R01dBpE8JILe2CTft7YN2tMufT2mMWMTqxmHwPSmOpsxHTj8hEII7GTfvpb95ThHwW7XMNhg7pbHLbrTJZCVA==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.229.0.tgz", + "integrity": "sha512-dnzWWQ0/NoWMUZ5C0DW3dPm0wC1O76Y/SpKbuJzWPkx1EYy6r8p32Ly4D9vUzrKDbRGf48YHIF2kOkBmu21CLg==", "optional": true }, "@aws-sdk/shared-ini-file-loader": { @@ -21327,12 +21348,12 @@ } }, "@aws-sdk/token-providers": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.226.0.tgz", - "integrity": "sha512-3ouRt2i3ve8ivg54PxPhtOTcipzf6BoQsMw0EiO23yYKujhyeFH2IkxV4EYC687xFrUjheqJf8FWU/DD8EQ/ow==", + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.229.0.tgz", + "integrity": "sha512-LmB40GDKch3LUfTOC6r2fWQoMYrvXoO9eN3TE0eVTWi/p8xCaROcnwb5pWe3mCCrKVygA4XZXSXkUO3DZhJL3w==", "optional": true, "requires": { - "@aws-sdk/client-sso-oidc": "3.226.0", + "@aws-sdk/client-sso-oidc": "3.229.0", "@aws-sdk/property-provider": "3.226.0", "@aws-sdk/shared-ini-file-loader": "3.226.0", "@aws-sdk/types": "3.226.0", @@ -21469,6 +21490,16 @@ "tslib": "^2.3.1" } }, + "@aws-sdk/util-retry": { + "version": "3.229.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.229.0.tgz", + "integrity": "sha512-0zKTqi0P1inD0LzIMuXRIYYQ/8c1lWMg/cfiqUcIAF1TpatlpZuN7umU0ierpBFud7S+zDgg0oemh+Nj8xliJw==", + "optional": true, + "requires": { + "@aws-sdk/service-error-classification": "3.229.0", + "tslib": "^2.3.1" + } + }, "@aws-sdk/util-uri-escape": { "version": "3.201.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.201.0.tgz", @@ -24167,9 +24198,9 @@ } }, "@sinclair/typebox": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.12.tgz", - "integrity": "sha512-xm46HDwYz69z8xcNh9esHYKpvhXmA02sD+K9cur6XZvwjZTSBJ8PNbK5xeSO0IYZqRzpxkXYsbpsF/hF0WdPew==" + "version": "0.25.13", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.13.tgz", + "integrity": "sha512-XiEwzYpUwE5y/k333Cy0Ujmxvw/mA4zIyEmwUyA0EDDik7ba8S/HClvz3ylOsABfYSj+/skQq4QJl0k/Z1eDLg==" }, "@sindresorhus/is": { "version": "5.3.0", @@ -24332,12 +24363,12 @@ "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" }, "@types/express": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", - "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz", + "integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==", "requires": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.31", "@types/qs": "*", "@types/serve-static": "*" } @@ -24515,9 +24546,9 @@ } }, "@types/node": { - "version": "18.11.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.12.tgz", - "integrity": "sha512-FgD3NtTAKvyMmD44T07zz2fEf+OKwutgBCEVM8GcvMGVGaDktiLNTDvPwC/LUe3PinMW+X6CuLOF2Ui1mAlSXg==" + "version": "18.11.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", + "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==" }, "@types/node-fetch": { "version": "2.6.2", @@ -31606,9 +31637,9 @@ } }, "mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.1.0.tgz", - "integrity": "sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "requires": { "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", @@ -31976,18 +32007,18 @@ } }, "mongodb-memory-server": { - "version": "8.10.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.10.1.tgz", - "integrity": "sha512-xBo45TuU4SFjDWixOXJyTBDukYqGeCuh7RBcDm4Nqngd/2Pjja/XYYFFJk/I44mTrZ77W1HDmCA4d69XgNJUJQ==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.10.2.tgz", + "integrity": "sha512-f8v9rRiA7sL5UganOjTL8/hzmdU0Vd7pC5Nsgh6vLFySz23UzpGYwV+knPWreFlqToTdw1mHdPlofZ4Ss/gi7w==", "requires": { - "mongodb-memory-server-core": "8.10.1", + "mongodb-memory-server-core": "8.10.2", "tslib": "^2.4.1" } }, "mongodb-memory-server-core": { - "version": "8.10.1", - "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.10.1.tgz", - "integrity": "sha512-Xva73v08VDojH1+423fJA6PWsoSWnkexk8/zSCdQTfKXACAgEaQ5fay89gzYn/bn/4So89hPVdLwEOt2VYMK7Q==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.10.2.tgz", + "integrity": "sha512-ro4k1eGcjk6p8214wFpv31dsB4eaBUMRr9WYLBcQDbmzCkM7ARn6vsJhlrKWH8eoayLZf0X6557j013t/Ld8aA==", "requires": { "@types/tmp": "^0.2.3", "async-mutex": "^0.3.2", @@ -32170,9 +32201,9 @@ "dev": true }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.7.tgz", + "integrity": "sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ==" }, "nopt": { "version": "5.0.0", @@ -35070,9 +35101,9 @@ "dev": true }, "sqlite3": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.2.tgz", - "integrity": "sha512-D0Reg6pRWAFXFUnZKsszCI67tthFD8fGPewRddDCX6w4cYwz3MbvuwRICbL+YQjBAh9zbw+lJ/V9oC8nG5j6eg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.4.tgz", + "integrity": "sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==", "requires": { "@mapbox/node-pre-gyp": "^1.0.0", "node-addon-api": "^4.2.0", @@ -35794,9 +35825,9 @@ "integrity": "sha512-f9Uv6ezcpvCQjJU0Zqbg+65qdcszv3qUQsZfjdRbWiZ7AMenrX1u0lNk9EoWWX6e1F+NULyg27mtdeZ5WhpljA==" }, "type-fest": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.3.0.tgz", - "integrity": "sha512-gezeeOIZyQLGW5uuCeEnXF1aXmtt2afKspXz3YqoOcZ3l/YMJq1pujvgT+cz/Nw1O/7q/kSav5fihJHsC/AOUg==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.4.0.tgz", + "integrity": "sha512-PEPg6RHlB9cFwoTMNENNrQFL0cXX04voWr2UPwQBJ3pVs7Mt8Y1oLWdUeMdGEwZE8HFFlujq8gS9enmyiQ8pLg==" }, "type-is": { "version": "1.6.18", diff --git a/packages/cli/src/authentication/templates/schema.json.tpl.ts b/packages/cli/src/authentication/templates/schema.json.tpl.ts index 3d7c4734a7..db8257c41a 100644 --- a/packages/cli/src/authentication/templates/schema.json.tpl.ts +++ b/packages/cli/src/authentication/templates/schema.json.tpl.ts @@ -11,7 +11,7 @@ const template = ({ type, relative }: AuthenticationGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html -import { resolve, querySyntax, getValidator, getDataValidator } from '@feathersjs/schema' +import { resolve, querySyntax, getValidator } from '@feathersjs/schema' import type { FromSchema } from '@feathersjs/schema' ${localTemplate(authStrategies, `import { passwordHash } from '@feathersjs/authentication-local'`)} @@ -43,7 +43,15 @@ export const ${camelName}Schema = { export type ${upperName} = FromSchema export const ${camelName}Resolver = resolve<${upperName}, HookContext>({}) -// Schema for the basic data model (e.g. creating new entries) +export const ${camelName}ExternalResolver = resolve<${upperName}, HookContext>({ + ${localTemplate( + authStrategies, + `// The password should never be visible externally + password: async () => undefined` + )} +}) + +// Schema for creating new users export const ${camelName}DataSchema = { $id: '${upperName}Data', type: 'object', @@ -54,17 +62,25 @@ export const ${camelName}DataSchema = { } } as const export type ${upperName}Data = FromSchema -export const ${camelName}DataValidator = getDataValidator(${camelName}DataSchema, dataValidator) +export const ${camelName}DataValidator = getValidator(${camelName}DataSchema, dataValidator) export const ${camelName}DataResolver = resolve<${upperName}Data, HookContext>({ ${localTemplate(authStrategies, `password: passwordHash({ strategy: 'local' })`)} }) -export const ${camelName}ExternalResolver = resolve<${upperName}, HookContext>({ - ${localTemplate( - authStrategies, - `// The password should never be visible externally - password: async () => undefined` - )} +// Schema for updating existing users +export const ${camelName}DataSchema = { + $id: '${upperName}Patch', + type: 'object', + additionalProperties: false, + required: [], + properties: { + ...${camelName}Schema.properties + } +} as const +export type ${upperName}Patch = FromSchema +export const ${camelName}PatchValidator = getValidator(${camelName}PatchSchema, dataValidator) +export const ${camelName}PatchResolver = resolve<${upperName}Patch, HookContext>({ + ${localTemplate(authStrategies, `password: passwordHash({ strategy: 'local' })`)} }) // Schema for allowed query properties diff --git a/packages/cli/src/authentication/templates/schema.typebox.tpl.ts b/packages/cli/src/authentication/templates/schema.typebox.tpl.ts index cbe1e57c9b..cb2e0f4f1a 100644 --- a/packages/cli/src/authentication/templates/schema.typebox.tpl.ts +++ b/packages/cli/src/authentication/templates/schema.typebox.tpl.ts @@ -44,7 +44,7 @@ export const ${camelName}ExternalResolver = resolve<${upperName}, HookContext>({ )} }) -// Schema for the basic data model (e.g. creating new entries) +// Schema for creating new users export const ${camelName}DataSchema = Type.Pick(${camelName}Schema, [ ${authStrategies.map((name) => (name === 'local' ? `'email', 'password'` : `'${name}Id'`)).join(', ')} ], @@ -56,12 +56,26 @@ export const ${camelName}DataResolver = resolve<${upperName}, HookContext>({ ${localTemplate(authStrategies, `password: passwordHash({ strategy: 'local' })`)} }) +// Schema for updating existing users +export const ${camelName}PatchSchema = Type.Partial(${camelName}Schema, { + $id: '${upperName}Patch' +}) +export type ${upperName}Patch = Static +export const ${camelName}PatchValidator = getDataValidator(${camelName}PatchSchema, dataValidator) +export const ${camelName}PatchResolver = resolve<${upperName}, HookContext>({ + ${localTemplate(authStrategies, `password: passwordHash({ strategy: 'local' })`)} +}) + // Schema for allowed query properties export const ${camelName}QueryProperties = Type.Pick(${camelName}Schema, ['${ type === 'mongodb' ? '_id' : 'id' }', ${authStrategies.map((name) => (name === 'local' ? `'email'` : `'${name}Id'`)).join(', ')} ]) -export const ${camelName}QuerySchema = querySyntax(${camelName}QueryProperties) +export const ${camelName}QuerySchema = Type.Intersect([ + querySyntax(${camelName}QueryProperties), + // Add additional query properties here + Type.Object({}, { additionalProperties: false }) +], { additionalProperties: false }) export type ${upperName}Query = Static export const ${camelName}QueryValidator = getValidator(${camelName}QuerySchema, queryValidator) export const ${camelName}QueryResolver = resolve<${upperName}Query, HookContext>({ diff --git a/packages/cli/src/service/templates/schema.json.tpl.ts b/packages/cli/src/service/templates/schema.json.tpl.ts index 1cacefeeb2..47576a8f8f 100644 --- a/packages/cli/src/service/templates/schema.json.tpl.ts +++ b/packages/cli/src/service/templates/schema.json.tpl.ts @@ -10,7 +10,7 @@ const template = ({ cwd, lib }: ServiceGeneratorContext) => /* ts */ `// For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html -import { resolve, getDataValidator, getValidator, querySyntax } from '@feathersjs/schema' +import { resolve, getValidator, querySyntax } from '@feathersjs/schema' import type { FromSchema } from '@feathersjs/schema' import type { HookContext } from '${relative}/declarations' @@ -50,9 +50,23 @@ export const ${camelName}DataSchema = { } } as const export type ${upperName}Data = FromSchema -export const ${camelName}DataValidator = getDataValidator(${camelName}DataSchema, dataValidator) +export const ${camelName}DataValidator = getValidator(${camelName}DataSchema, dataValidator) export const ${camelName}DataResolver = resolve<${upperName}Data, HookContext>({}) +// Schema for updating existing data +export const ${camelName}PatchSchema = { + $id: '${upperName}Patch', + type: 'object', + additionalProperties: false, + required: [], + properties: { + ...${camelName}Schema.properties + } +} as const +export type ${upperName}Patch = FromSchema +export const ${camelName}PatchValidator = getValidator(${camelName}PatchSchema, dataValidator) +export const ${camelName}PatchResolver = resolve<${upperName}Patch, HookContext>({}) + // Schema for allowed query properties export const ${camelName}QuerySchema = { $id: '${upperName}Query', diff --git a/packages/cli/src/service/templates/schema.typebox.tpl.ts b/packages/cli/src/service/templates/schema.typebox.tpl.ts index 60811b6a89..46225a40f3 100644 --- a/packages/cli/src/service/templates/schema.typebox.tpl.ts +++ b/packages/cli/src/service/templates/schema.typebox.tpl.ts @@ -31,17 +31,29 @@ export const ${camelName}ExternalResolver = resolve<${upperName}, HookContext>({ // Schema for creating new entries export const ${camelName}DataSchema = Type.Pick(${camelName}Schema, ['text'], { - $id: '${upperName}Data', additionalProperties: false + $id: '${upperName}Data' }) export type ${upperName}Data = Static export const ${camelName}DataValidator = getDataValidator(${camelName}DataSchema, dataValidator) export const ${camelName}DataResolver = resolve<${upperName}, HookContext>({}) +// Schema for updating existing entries +export const ${camelName}PatchSchema = Type.Partial(${camelName}Schema, { + $id: '${upperName}Patch' +}) +export type ${upperName}Patch = Static +export const ${camelName}PatchValidator = getDataValidator(${camelName}PatchSchema, dataValidator) +export const ${camelName}PatchResolver = resolve<${upperName}, HookContext>({}) + // Schema for allowed query properties export const ${camelName}QueryProperties = Type.Pick(${camelName}Schema, [ '${type === 'mongodb' ? '_id' : 'id'}', 'text' +]) +export const ${camelName}QuerySchema = Type.Intersect([ + querySyntax(${camelName}QueryProperties), + // Add additional query properties here + Type.Object({}, { additionalProperties: false }) ], { additionalProperties: false }) -export const ${camelName}QuerySchema = querySyntax(${camelName}QueryProperties) export type ${upperName}Query = Static export const ${camelName}QueryValidator = getValidator(${camelName}QuerySchema, queryValidator) export const ${camelName}QueryResolver = resolve<${upperName}Query, HookContext>({}) diff --git a/packages/cli/src/service/templates/service.tpl.ts b/packages/cli/src/service/templates/service.tpl.ts index 97963894d0..33c216d4a1 100644 --- a/packages/cli/src/service/templates/service.tpl.ts +++ b/packages/cli/src/service/templates/service.tpl.ts @@ -20,11 +20,13 @@ import { hooks as schemaHooks } from '@feathersjs/schema' import { ${camelName}DataValidator, + ${camelName}PatchValidator, ${camelName}QueryValidator, ${camelName}Resolver, + ${camelName}ExternalResolver, ${camelName}DataResolver, - ${camelName}QueryResolver, - ${camelName}ExternalResolver + ${camelName}PatchResolver, + ${camelName}QueryResolver } from './${fileName}.schema' ` : '' @@ -41,7 +43,7 @@ export const ${camelName} = (app: Application) => { // Register our service on the Feathers application app.use('${path}', new ${className}(getOptions(app)), { // A list of all methods this service exposes externally - methods: ['find', 'get', 'create', 'update', 'patch', 'remove'], + methods: ['find', 'get', 'create', 'patch', 'remove'], // You can add additional custom events to be sent to clients here events: [] }) @@ -53,33 +55,53 @@ export const ${camelName} = (app: Application) => { ? ` authenticate('jwt'),` : '' - } - ${ - schema - ? ` + } ${ + schema + ? ` schemaHooks.resolveExternal(${camelName}ExternalResolver), schemaHooks.resolveResult(${camelName}Resolver),` + : '' +} + ],${ + isEntityService + ? ` + find: [authenticate('jwt')], + get: [authenticate('jwt')], + create: [], + update: [authenticate('jwt')], + patch: [authenticate('jwt')], + remove: [authenticate('jwt')]` : '' } - ], - find: [${isEntityService ? `authenticate('jwt')` : ''}], - get: [${isEntityService ? `authenticate('jwt')` : ''}], - create: [], - update: [${isEntityService ? `authenticate('jwt')` : ''}], - patch: [${isEntityService ? `authenticate('jwt')` : ''}], - remove: [${isEntityService ? `authenticate('jwt')` : ''}] }, before: { all: [${ schema ? ` schemaHooks.validateQuery(${camelName}QueryValidator), + schemaHooks.resolveQuery(${camelName}QueryResolver) + ` + : '' + }], + find: [], + get: [], + create: [${ + schema + ? ` schemaHooks.validateData(${camelName}DataValidator), - schemaHooks.resolveQuery(${camelName}QueryResolver), schemaHooks.resolveData(${camelName}DataResolver) ` : '' - }] + }], + patch: [${ + schema + ? ` + schemaHooks.validateData(${camelName}PatchValidator), + schemaHooks.resolveData(${camelName}PatchResolver) + ` + : '' + }], + remove: [] }, after: { all: [] diff --git a/packages/cli/src/service/type/custom.tpl.ts b/packages/cli/src/service/type/custom.tpl.ts index e81aca1df6..a227c12190 100644 --- a/packages/cli/src/service/type/custom.tpl.ts +++ b/packages/cli/src/service/type/custom.tpl.ts @@ -17,12 +17,14 @@ ${ ? `import type { ${upperName}, ${upperName}Data, + ${upperName}Patch, ${upperName}Query } from './${fileName}.schema' ` : ` export type ${upperName} = any export type ${upperName}Data = any +export type ${upperName}Patch = any export type ${upperName}Query = any ` } @@ -36,7 +38,7 @@ export interface ${upperName}Params extends Params<${upperName}Query> { } // This is a skeleton for a custom service class. Remove or add the methods you need here -export class ${className} implements ServiceInterface<${upperName}, ${upperName}Data, ${upperName}Params> { +export class ${className} implements ServiceInterface<${upperName}, ${upperName}Data, ${upperName}Params, ${upperName}Patch> { constructor (public options: ${className}Options) { } @@ -64,6 +66,7 @@ export class ${className} implements ServiceInterface<${upperName}, ${upperName} } } + // This method has to be added to the 'methods' option to make it available to clients async update (id: NullableId, data: ${upperName}Data, _params?: ${upperName}Params): Promise<${upperName}> { return { id: 0, @@ -71,9 +74,10 @@ export class ${className} implements ServiceInterface<${upperName}, ${upperName} } } - async patch (id: NullableId, data: ${upperName}Data, _params?: ${upperName}Params): Promise<${upperName}> { + async patch (id: NullableId, data: ${upperName}Patch, _params?: ${upperName}Params): Promise<${upperName}> { return { id: 0, + text: \`Fallback for \${id}\`, ...data } } diff --git a/packages/cli/src/service/type/knex.tpl.ts b/packages/cli/src/service/type/knex.tpl.ts index b4e536986e..01241c5c8c 100644 --- a/packages/cli/src/service/type/knex.tpl.ts +++ b/packages/cli/src/service/type/knex.tpl.ts @@ -37,12 +37,14 @@ ${ ? `import type { ${upperName}, ${upperName}Data, + ${upperName}Patch, ${upperName}Query } from './${fileName}.schema' ` : ` export type ${upperName} = any export type ${upperName}Data = any +export type ${upperName}Patch = any export type ${upperName}Query = any ` } @@ -52,7 +54,7 @@ export interface ${upperName}Params extends KnexAdapterParams<${upperName}Query> // By default calls the standard Knex adapter service methods but can be customized with your own functionality. export class ${className} - extends KnexService<${upperName}, ${upperName}Data, ServiceParams> { + extends KnexService<${upperName}, ${upperName}Data, ServiceParams, ${upperName}Patch> { } export const getOptions = (app: Application): KnexAdapterOptions => { diff --git a/packages/cli/src/service/type/mongodb.tpl.ts b/packages/cli/src/service/type/mongodb.tpl.ts index b6a36e3471..7e8a947cc2 100644 --- a/packages/cli/src/service/type/mongodb.tpl.ts +++ b/packages/cli/src/service/type/mongodb.tpl.ts @@ -20,12 +20,14 @@ ${ ? `import type { ${upperName}, ${upperName}Data, + ${upperName}Patch, ${upperName}Query } from './${fileName}.schema' ` : ` export type ${upperName} = any export type ${upperName}Data = any +export type ${upperName}Patch = any export type ${upperName}Query = any ` } @@ -35,7 +37,7 @@ export interface ${upperName}Params extends MongoDBAdapterParams<${upperName}Que // By default calls the standard MongoDB adapter service methods but can be customized with your own functionality. export class ${className} - extends MongoDBService<${upperName}, ${upperName}Data, ServiceParams> { + extends MongoDBService<${upperName}, ${upperName}Data, ServiceParams, ${upperName}Patch> { } export const getOptions = (app: Application): MongoDBAdapterOptions => { diff --git a/packages/knex/src/index.ts b/packages/knex/src/index.ts index 7b9008f608..59a59e1841 100644 --- a/packages/knex/src/index.ts +++ b/packages/knex/src/index.ts @@ -9,30 +9,35 @@ export * from './adapter' export * from './error-handler' export * as transaction from './hooks' -export class KnexService, P extends Params = KnexAdapterParams> - extends KnexAdapter - implements ServiceMethods, D, P> +export class KnexService< + Result = any, + Data = Partial, + ServiceParams extends Params = KnexAdapterParams, + PatchData = Partial + > + extends KnexAdapter + implements ServiceMethods, Data, ServiceParams, PatchData> { - async find(params?: P & { paginate?: PaginationOptions }): Promise> - async find(params?: P & { paginate: false }): Promise - async find(params?: P): Promise | T[]> - async find(params?: P): Promise | T[]> { + async find(params?: ServiceParams & { paginate?: PaginationOptions }): Promise> + async find(params?: ServiceParams & { paginate: false }): Promise + async find(params?: ServiceParams): Promise | Result[]> + async find(params?: ServiceParams): Promise | Result[]> { return this._find({ ...params, query: await this.sanitizeQuery(params) }) } - async get(id: Id, params?: P): Promise { + async get(id: Id, params?: ServiceParams): Promise { return this._get(id, { ...params, query: await this.sanitizeQuery(params) }) } - async create(data: D, params?: P): Promise - async create(data: D[], params?: P): Promise - async create(data: D | D[], params?: P): Promise { + async create(data: Data, params?: ServiceParams): Promise + async create(data: Data[], params?: ServiceParams): Promise + async create(data: Data | Data[], params?: ServiceParams): Promise { if (Array.isArray(data) && !this.allowsMulti('create', params)) { throw new MethodNotAllowed('Can not create multiple entries') } @@ -40,16 +45,16 @@ export class KnexService, P extends Params = KnexAd return this._create(data, params) } - async update(id: Id, data: D, params?: P): Promise { + async update(id: Id, data: Data, params?: ServiceParams): Promise { return this._update(id, data, { ...params, query: await this.sanitizeQuery(params) }) } - async patch(id: Id, data: Partial, params?: P): Promise - async patch(id: null, data: Partial, params?: P): Promise - async patch(id: NullableId, data: Partial, params?: P): Promise { + async patch(id: Id, data: PatchData, params?: ServiceParams): Promise + async patch(id: null, data: PatchData, params?: ServiceParams): Promise + async patch(id: NullableId, data: PatchData, params?: ServiceParams): Promise { const { $limit, ...query } = await this.sanitizeQuery(params) return this._patch(id, data, { @@ -58,9 +63,9 @@ export class KnexService, P extends Params = KnexAd }) } - async remove(id: Id, params?: P): Promise - async remove(id: null, params?: P): Promise - async remove(id: NullableId, params?: P): Promise { + async remove(id: Id, params?: ServiceParams): Promise + async remove(id: null, params?: ServiceParams): Promise + async remove(id: NullableId, params?: ServiceParams): Promise { const { $limit, ...query } = await this.sanitizeQuery(params) return this._remove(id, { diff --git a/packages/schema/src/hooks/validate.ts b/packages/schema/src/hooks/validate.ts index 5fd0ed3b51..dc31de5fbe 100644 --- a/packages/schema/src/hooks/validate.ts +++ b/packages/schema/src/hooks/validate.ts @@ -29,12 +29,14 @@ export const validateQuery = (schema: Schema | Valid } } -export const validateData = (schema: Schema | DataValidatorMap) => { +export const validateData = (schema: Schema | DataValidatorMap | Validator) => { return async (context: H, next?: NextFunction) => { const data = context.data const validator = typeof (schema as Schema).validate === 'function' ? (schema as Schema).validate.bind(schema) + : typeof schema === 'function' + ? schema : (schema as any)[context.method] if (validator) { diff --git a/packages/schema/test/fixture.ts b/packages/schema/test/fixture.ts index b2b4839605..f203b5a106 100644 --- a/packages/schema/test/fixture.ts +++ b/packages/schema/test/fixture.ts @@ -36,7 +36,9 @@ export const userDataSchema = { } } as const -export const userDataValidator = getDataValidator(userDataSchema, fixtureAjv) +export const userDataValidator = getValidator(userDataSchema, fixtureAjv) + +export const userDataValidatorMap = getDataValidator(userDataSchema, fixtureAjv) export type UserData = FromSchema @@ -232,7 +234,7 @@ app .hooks([resolveDispatch(userExternalResolver), resolveResult(userResolver, secondUserResolver)]) app.service('users').hooks({ - create: [validateData(userDataValidator), resolveData(userDataResolver)] + create: [validateData(userDataValidator), validateData(userDataValidatorMap), resolveData(userDataResolver)] }) export { app }