From aea93f66a7328302983c6cbe82bdf1f14b1cf488 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Sun, 24 Oct 2021 11:47:15 +0300 Subject: [PATCH 01/11] fix(dependencies): Add missing dependencies --- packages/adapter-tests/package.json | 1 + packages/express/package.json | 5 ++++- packages/rest-client/package.json | 1 + packages/schema/package.json | 1 + packages/socketio/package.json | 2 +- packages/transport-commons/package.json | 4 +++- 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/adapter-tests/package.json b/packages/adapter-tests/package.json index 93a87ada64..9047888393 100644 --- a/packages/adapter-tests/package.json +++ b/packages/adapter-tests/package.json @@ -48,6 +48,7 @@ "access": "public" }, "devDependencies": { + "@types/mocha": "^9.0.0", "@types/node": "^16.10.4", "mocha": "^9.1.2", "shx": "^0.3.3", diff --git a/packages/express/package.json b/packages/express/package.json index ca45c32ac9..50712e3342 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -51,16 +51,19 @@ "dependencies": { "@feathersjs/commons": "^5.0.0-pre.14", "@feathersjs/errors": "^5.0.0-pre.14", + "@feathersjs/feathers": "^5.0.0-pre.14", + "@feathersjs/hooks": "^0.6.5", "@feathersjs/transport-commons": "^5.0.0-pre.14", "@types/express": "^4.17.13", + "@types/express-serve-static-core": "^4.17.24", "express": "^4.17.1", "lodash": "^4.17.21" }, "devDependencies": { "@feathersjs/authentication": "^5.0.0-pre.14", "@feathersjs/authentication-local": "^5.0.0-pre.14", - "@feathersjs/feathers": "^5.0.0-pre.14", "@feathersjs/tests": "^5.0.0-pre.14", + "@types/lodash": "^4.14.175", "@types/mocha": "^9.0.0", "@types/node": "^16.10.4", "axios": "^0.23.0", diff --git a/packages/rest-client/package.json b/packages/rest-client/package.json index 22664c0708..4f845e703d 100644 --- a/packages/rest-client/package.json +++ b/packages/rest-client/package.json @@ -63,6 +63,7 @@ "@feathersjs/tests": "^5.0.0-pre.14", "@types/mocha": "^9.0.0", "@types/node": "^16.10.4", + "@types/qs": "^6.9.7", "axios": "^0.23.0", "mocha": "^9.1.2", "node-fetch": "^2.6.1", diff --git a/packages/schema/package.json b/packages/schema/package.json index 336b4390eb..9b3a9362f5 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -52,6 +52,7 @@ "dependencies": { "@feathersjs/errors": "^5.0.0-pre.14", "@feathersjs/feathers": "^5.0.0-pre.14", + "@types/json-schema": "^7.0.9", "ajv": "^8.6.3", "json-schema": "^0.3.0", "json-schema-to-ts": "^1.6.4" diff --git a/packages/socketio/package.json b/packages/socketio/package.json index 5e9e7b8232..38c80eb905 100644 --- a/packages/socketio/package.json +++ b/packages/socketio/package.json @@ -51,13 +51,13 @@ }, "dependencies": { "@feathersjs/commons": "^5.0.0-pre.14", + "@feathersjs/feathers": "^5.0.0-pre.14", "@feathersjs/transport-commons": "^5.0.0-pre.14", "socket.io": "^4.2.0" }, "devDependencies": { "@feathersjs/commons": "^5.0.0-pre.2", "@feathersjs/express": "^5.0.0-pre.14", - "@feathersjs/feathers": "^5.0.0-pre.14", "@feathersjs/memory": "^5.0.0-pre.14", "@feathersjs/tests": "^5.0.0-pre.14", "@types/mocha": "^9.0.0", diff --git a/packages/transport-commons/package.json b/packages/transport-commons/package.json index 639886bf8f..66ebf18d20 100644 --- a/packages/transport-commons/package.json +++ b/packages/transport-commons/package.json @@ -54,10 +54,12 @@ "dependencies": { "@feathersjs/commons": "^5.0.0-pre.14", "@feathersjs/errors": "^5.0.0-pre.14", + "@feathersjs/feathers": "^5.0.0-pre.14", + "@feathersjs/hooks": "^0.6.5", "lodash": "^4.17.21" }, "devDependencies": { - "@feathersjs/feathers": "^5.0.0-pre.14", + "@types/lodash": "^4.14.175", "@types/mocha": "^9.0.0", "@types/node": "^16.10.4", "mocha": "^9.1.2", From 5d9ae6e2dd16a83517c44d6620205318bee2966e Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:35:40 +0300 Subject: [PATCH 02/11] fix(typescript): Rename type params ServiceTypes, AppSettings --- packages/authentication-client/src/index.ts | 2 +- packages/authentication/src/service.ts | 2 +- packages/express/src/declarations.ts | 16 ++++++------- packages/feathers/src/application.ts | 24 +++++++++---------- packages/feathers/src/declarations.ts | 24 +++++++++---------- packages/koa/src/index.ts | 4 ++-- packages/socketio/src/index.ts | 2 +- .../transport-commons/src/channels/index.ts | 2 +- .../transport-commons/src/routing/index.ts | 2 +- 9 files changed, 39 insertions(+), 39 deletions(-) diff --git a/packages/authentication-client/src/index.ts b/packages/authentication-client/src/index.ts index 294eb155fd..9ae2e4423b 100644 --- a/packages/authentication-client/src/index.ts +++ b/packages/authentication-client/src/index.ts @@ -4,7 +4,7 @@ import { Application } from '@feathersjs/feathers'; import { Storage, MemoryStorage, StorageWrapper } from './storage'; declare module '@feathersjs/feathers/lib/declarations' { - interface Application { // eslint-disable-line + interface Application { // eslint-disable-line io?: any; rest?: any; authentication: AuthenticationClient; diff --git a/packages/authentication/src/service.ts b/packages/authentication/src/service.ts index ef87cef7c6..6d3e575866 100644 --- a/packages/authentication/src/service.ts +++ b/packages/authentication/src/service.ts @@ -10,7 +10,7 @@ import jsonwebtoken from 'jsonwebtoken'; const debug = createDebug('@feathersjs/authentication/service'); declare module '@feathersjs/feathers/lib/declarations' { - interface FeathersApplication { // eslint-disable-line + interface FeathersApplication { // eslint-disable-line /** * Returns the default authentication service or the * authentication service for a given path. diff --git a/packages/express/src/declarations.ts b/packages/express/src/declarations.ts index 43ea2b8e69..4720707231 100644 --- a/packages/express/src/declarations.ts +++ b/packages/express/src/declarations.ts @@ -5,12 +5,12 @@ import { HookContext, ServiceMethods, ServiceInterface } from '@feathersjs/feathers'; -interface ExpressUseHandler { - ( +interface ExpressUseHandler { + ( path: L, ...middlewareOrService: ( Express|express.RequestHandler| - (keyof any extends keyof ServiceTypes ? ServiceInterface : ServiceTypes[L]) + (keyof any extends keyof Services ? ServiceInterface : Services[L]) )[] ): T; (path: string|RegExp, ...expressHandlers: express.RequestHandler[]): T; @@ -18,18 +18,18 @@ interface ExpressUseHandler { (handler: Express|express.ErrorRequestHandler): T; } -export interface ExpressOverrides { +export interface ExpressOverrides { listen(port: number, hostname: string, backlog: number, callback?: () => void): Promise; listen(port: number, hostname: string, callback?: () => void): Promise; listen(port: number|string|any, callback?: () => void): Promise; listen(callback?: () => void): Promise; - use: ExpressUseHandler; + use: ExpressUseHandler; } -export type Application = +export type Application = Omit & - FeathersApplication & - ExpressOverrides; + FeathersApplication & + ExpressOverrides; declare module '@feathersjs/feathers/lib/declarations' { export interface ServiceOptions { diff --git a/packages/feathers/src/application.ts b/packages/feathers/src/application.ts index 3daeaa4aef..7d9b535e0a 100644 --- a/packages/feathers/src/application.ts +++ b/packages/feathers/src/application.ts @@ -21,13 +21,13 @@ import { enableLegacyHooks } from './hooks/legacy'; const debug = createDebug('@feathersjs/feathers'); -export class Feathers extends EventEmitter implements FeathersApplication { - services: ServiceTypes = ({} as ServiceTypes); - settings: AppSettings = ({} as AppSettings); - mixins: ServiceMixin>[] = [ hookMixin, eventMixin ]; +export class Feathers extends EventEmitter implements FeathersApplication { + services: Services = ({} as Services); + settings: Settings = ({} as Settings); + mixins: ServiceMixin>[] = [ hookMixin, eventMixin ]; version: string = version; _isSetup = false; - appHooks: HookMap, any> = { + appHooks: HookMap, any> = { [HOOKS]: [ (eventHook as any) ] }; @@ -38,11 +38,11 @@ export class Feathers extends EventEmitter implements this.legacyHooks = enableLegacyHooks(this); } - get (name: L): AppSettings[L] { + get (name: L): Settings[L] { return this.settings[name]; } - set (name: L, value: AppSettings[L]) { + set (name: L, value: Settings[L]) { this.settings[name] = value; return this; } @@ -57,9 +57,9 @@ export class Feathers extends EventEmitter implements throw new Error(`Can not find service '${location}'`); } - service ( + service ( location: L - ): FeathersService : ServiceTypes[L]> { + ): FeathersService : Services[L]> { const path = (stripSlashes(location) || '/') as L; const current = this.services[path]; @@ -71,9 +71,9 @@ export class Feathers extends EventEmitter implements return current as any; } - use ( + use ( path: L, - service: keyof any extends keyof ServiceTypes ? ServiceInterface | Application : ServiceTypes[L], + service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L], options?: ServiceOptions ): this { if (typeof path !== 'string') { @@ -127,7 +127,7 @@ export class Feathers extends EventEmitter implements if (Array.isArray(hookMap)) { this.appHooks[HOOKS].push(...hookMap as any); } else { - const methodHookMap = hookMap as HookMap, any>; + const methodHookMap = hookMap as HookMap, any>; Object.keys(methodHookMap).forEach(key => { const methodHooks = this.appHooks[key] || []; diff --git a/packages/feathers/src/declarations.ts b/packages/feathers/src/declarations.ts index 8865f5f5e7..beacac6785 100644 --- a/packages/feathers/src/declarations.ts +++ b/packages/feathers/src/declarations.ts @@ -115,7 +115,7 @@ export type ServiceMixin = (service: FeathersService, path: string, option export type ServiceGenericType = S extends ServiceInterface ? T : any; export type ServiceGenericData = S extends ServiceInterface ? D : any; -export interface FeathersApplication { +export interface FeathersApplication { /** * The Feathers application version */ @@ -124,7 +124,7 @@ export interface FeathersApplication { /** * A list of callbacks that run when a new service is registered */ - mixins: ServiceMixin>[]; + mixins: ServiceMixin>[]; /** * The index of all services keyed by their path. @@ -132,13 +132,13 @@ export interface FeathersApplication { * __Important:__ Services should always be retrieved via `app.service('name')` * not via `app.services`. */ - services: ServiceTypes; + services: Services; /** * The application settings that can be used via * `app.get` and `app.set` */ - settings: AppSettings; + settings: Settings; /** * A private-ish indicator if `app.setup()` has been called already @@ -148,14 +148,14 @@ export interface FeathersApplication { /** * Contains all registered application level hooks. */ - appHooks: HookMap, any>; + appHooks: HookMap, any>; /** * Retrieve an application setting by name * * @param name The setting name */ - get (name: L): AppSettings[L]; + get (name: L): Settings[L]; /** * Set an application setting @@ -163,7 +163,7 @@ export interface FeathersApplication { * @param name The setting name * @param value The setting value */ - set (name: L, value: AppSettings[L]): this; + set (name: L, value: Settings[L]): this; /** * Runs a callback configure function with the current application instance. @@ -191,9 +191,9 @@ export interface FeathersApplication { * Feathers application to use a sub-app under the `path` prefix. * @param options The options for this service */ - use ( + use ( path: L, - service: keyof any extends keyof ServiceTypes ? ServiceInterface | Application : ServiceTypes[L], + service: keyof any extends keyof Services ? ServiceInterface | Application : Services[L], options?: ServiceOptions ): this; @@ -204,9 +204,9 @@ export interface FeathersApplication { * * @param path The name of the service. */ - service ( + service ( path: L - ): FeathersService : ServiceTypes[L]>; + ): FeathersService : Services[L]>; setup (server?: any): Promise; @@ -220,7 +220,7 @@ export interface FeathersApplication { // This needs to be an interface instead of a type // so that the declaration can be extended by other modules -export interface Application extends FeathersApplication, EventEmitter { +export interface Application extends FeathersApplication, EventEmitter { } diff --git a/packages/koa/src/index.ts b/packages/koa/src/index.ts index 6b6f073a61..6d8f884a73 100644 --- a/packages/koa/src/index.ts +++ b/packages/koa/src/index.ts @@ -15,11 +15,11 @@ export * from './authenticate'; export { rest } from './rest'; export { Koa, bodyParser, errorHandler }; -export function koa (_app?: FeathersApplication): Application { +export function koa (_app?: FeathersApplication): Application { const koaApp = new Koa(); if (!_app) { - return koaApp as unknown as Application; + return koaApp as unknown as Application; } if (typeof _app.setup !== 'function') { diff --git a/packages/socketio/src/index.ts b/packages/socketio/src/index.ts index 65462033c2..7a438e2e5c 100644 --- a/packages/socketio/src/index.ts +++ b/packages/socketio/src/index.ts @@ -9,7 +9,7 @@ import { disconnect, params, authentication, FeathersSocket } from './middleware const debug = createDebug('@feathersjs/socketio'); declare module '@feathersjs/feathers/lib/declarations' { - interface Application { // eslint-disable-line + interface Application { // eslint-disable-line io: Server; listen (options: any): Promise; } diff --git a/packages/transport-commons/src/channels/index.ts b/packages/transport-commons/src/channels/index.ts index a2b4c278cb..b0973e28d5 100644 --- a/packages/transport-commons/src/channels/index.ts +++ b/packages/transport-commons/src/channels/index.ts @@ -18,7 +18,7 @@ declare module '@feathersjs/feathers/lib/declarations' { registerPublisher (event: Event, publisher: Publisher>): this; } - interface Application { // eslint-disable-line + interface Application { // eslint-disable-line channels: string[]; channel (name: string[]): Channel; diff --git a/packages/transport-commons/src/routing/index.ts b/packages/transport-commons/src/routing/index.ts index 6bcd141f6e..0c79b4a855 100644 --- a/packages/transport-commons/src/routing/index.ts +++ b/packages/transport-commons/src/routing/index.ts @@ -7,7 +7,7 @@ declare module '@feathersjs/feathers/lib/declarations' { params: { [key: string]: string } } - interface Application { // eslint-disable-line + interface Application { // eslint-disable-line routes: Router; lookup (path: string): RouteLookup; } From cb14684edab1a73d047ba7976f16e55a2bd06e48 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:44:39 +0300 Subject: [PATCH 03/11] fix(typescript): Default T to any in Service and related types --- packages/adapter-commons/test/service.test.ts | 2 +- .../src/hooks/hash-password.ts | 2 +- .../authentication-local/src/hooks/protect.ts | 2 +- .../authentication/src/hooks/authenticate.ts | 2 +- packages/authentication/src/strategy.ts | 2 +- .../test/hooks/authenticate.test.ts | 2 +- packages/authentication/test/jwt.test.ts | 4 ++-- packages/express/src/declarations.ts | 6 ++--- packages/feathers/src/application.ts | 4 ++-- packages/feathers/src/declarations.ts | 22 +++++++++---------- packages/feathers/src/hooks/index.ts | 2 +- packages/feathers/test/hooks/error.test.ts | 2 +- .../transport-commons/src/channels/index.ts | 2 +- .../transport-commons/src/routing/index.ts | 6 ++--- .../transport-commons/src/routing/router.ts | 2 +- 15 files changed, 31 insertions(+), 31 deletions(-) diff --git a/packages/adapter-commons/test/service.test.ts b/packages/adapter-commons/test/service.test.ts index 91ce4942e9..5329df86ef 100644 --- a/packages/adapter-commons/test/service.test.ts +++ b/packages/adapter-commons/test/service.test.ts @@ -27,7 +27,7 @@ describe('@feathersjs/adapter-commons/service', () => { }); describe('works when methods exist', () => { - class MethodService extends AdapterService implements InternalServiceMethods { + class MethodService extends AdapterService implements InternalServiceMethods { _find (_params?: Params) { return Promise.resolve([]); } diff --git a/packages/authentication-local/src/hooks/hash-password.ts b/packages/authentication-local/src/hooks/hash-password.ts index eeca165586..7fa13237d6 100644 --- a/packages/authentication-local/src/hooks/hash-password.ts +++ b/packages/authentication-local/src/hooks/hash-password.ts @@ -18,7 +18,7 @@ export default function hashPassword (field: string, options: HashPasswordOption throw new Error('The hashPassword hook requires a field name option'); } - return async (context: HookContext, next?: NextFunction) => { + return async (context: HookContext, next?: NextFunction) => { const { app, data, params } = context; if (data !== undefined) { diff --git a/packages/authentication-local/src/hooks/protect.ts b/packages/authentication-local/src/hooks/protect.ts index 5e2cccbc56..5313f3f058 100644 --- a/packages/authentication-local/src/hooks/protect.ts +++ b/packages/authentication-local/src/hooks/protect.ts @@ -1,7 +1,7 @@ import omit from 'lodash/omit'; import { HookContext, NextFunction } from '@feathersjs/feathers'; -export default (...fields: string[]) => async (context: HookContext, next?: NextFunction) => { +export default (...fields: string[]) => async (context: HookContext, next?: NextFunction) => { const o = (current: any) => { if (typeof current === 'object' && !Array.isArray(current)) { const data = typeof current.toJSON === 'function' diff --git a/packages/authentication/src/hooks/authenticate.ts b/packages/authentication/src/hooks/authenticate.ts index 67ff3f6101..b9e47d8f8b 100644 --- a/packages/authentication/src/hooks/authenticate.ts +++ b/packages/authentication/src/hooks/authenticate.ts @@ -20,7 +20,7 @@ export default (originalSettings: string | AuthenticateHookSettings, ...original throw new Error('The authenticate hook needs at least one allowed strategy'); } - return async (context: HookContext, _next?: NextFunction) => { + return async (context: HookContext, _next?: NextFunction) => { const next = typeof _next === 'function' ? _next : async () => context; const { app, params, type, path, service } = context; const { strategies } = settings; diff --git a/packages/authentication/src/strategy.ts b/packages/authentication/src/strategy.ts index 00de0695e4..51fc84ac69 100644 --- a/packages/authentication/src/strategy.ts +++ b/packages/authentication/src/strategy.ts @@ -22,7 +22,7 @@ export class AuthenticationBaseStrategy implements AuthenticationStrategy { return this.authentication.configuration[this.name]; } - get entityService (): Service { + get entityService (): Service { const { service } = this.configuration; if (!service) { diff --git a/packages/authentication/test/hooks/authenticate.test.ts b/packages/authentication/test/hooks/authenticate.test.ts index 6f8a07a780..e13debb63c 100644 --- a/packages/authentication/test/hooks/authenticate.test.ts +++ b/packages/authentication/test/hooks/authenticate.test.ts @@ -10,7 +10,7 @@ describe('authentication/hooks/authenticate', () => { let app: Application<{ authentication: AuthenticationService, 'auth-v2': AuthenticationService, - users: Partial> & { id: string } + users: Partial & { id: string } }>; beforeEach(() => { diff --git a/packages/authentication/test/jwt.test.ts b/packages/authentication/test/jwt.test.ts index 728f3a5d57..e1d23bb7ee 100644 --- a/packages/authentication/test/jwt.test.ts +++ b/packages/authentication/test/jwt.test.ts @@ -12,8 +12,8 @@ const { authenticate } = hooks; describe('authentication/jwt', () => { let app: Application<{ authentication: AuthenticationService, - users: Partial>, - protected: Partial> + users: Partial, + protected: Partial }>; let user: any; let accessToken: string; diff --git a/packages/express/src/declarations.ts b/packages/express/src/declarations.ts index 4720707231..2b1056170b 100644 --- a/packages/express/src/declarations.ts +++ b/packages/express/src/declarations.ts @@ -10,7 +10,7 @@ interface ExpressUseHandler { path: L, ...middlewareOrService: ( Express|express.RequestHandler| - (keyof any extends keyof Services ? ServiceInterface : Services[L]) + (keyof any extends keyof Services ? ServiceInterface : Services[L]) )[] ): T; (path: string|RegExp, ...expressHandlers: express.RequestHandler[]): T; @@ -32,7 +32,7 @@ export type Application = ExpressOverrides; declare module '@feathersjs/feathers/lib/declarations' { - export interface ServiceOptions { + interface ServiceOptions { middleware?: { before: express.RequestHandler[], after: express.RequestHandler[] @@ -54,7 +54,7 @@ declare module 'express-serve-static-core' { // eslint-disable-next-line

( path: PathParams, - ...handlers: (RequestHandler | Partial> | Application)[] + ...handlers: (RequestHandler | Partial | Application)[] ): T; } } diff --git a/packages/feathers/src/application.ts b/packages/feathers/src/application.ts index 7d9b535e0a..4b3c618e18 100644 --- a/packages/feathers/src/application.ts +++ b/packages/feathers/src/application.ts @@ -53,13 +53,13 @@ export class Feathers extends EventEmitter implements Feathe return this; } - defaultService (location: string): ServiceInterface { + defaultService (location: string): ServiceInterface { throw new Error(`Can not find service '${location}'`); } service ( location: L - ): FeathersService : Services[L]> { + ): FeathersService { const path = (stripSlashes(location) || '/') as L; const current = this.services[path]; diff --git a/packages/feathers/src/declarations.ts b/packages/feathers/src/declarations.ts index beacac6785..f4222a7bba 100644 --- a/packages/feathers/src/declarations.ts +++ b/packages/feathers/src/declarations.ts @@ -20,7 +20,7 @@ export interface ServiceOptions { serviceEvents?: string[]; } -export interface ServiceMethods> { +export interface ServiceMethods> { find (params?: Params): Promise; get (id: Id, params?: Params): Promise; @@ -36,7 +36,7 @@ export interface ServiceMethods> { setup (app: Application, path: string): Promise; } -export interface ServiceOverloads { +export interface ServiceOverloads> { create? (data: D[], params?: Params): Promise; update? (id: Id, data: D, params?: Params): Promise; @@ -52,14 +52,14 @@ export interface ServiceOverloads { remove? (id: null, params?: Params): Promise; } -export type Service> = +export type Service> = ServiceMethods & ServiceOverloads; -export type ServiceInterface> = +export type ServiceInterface> = Partial>; -export interface ServiceAddons> extends EventEmitter { +export interface ServiceAddons extends EventEmitter { id?: string; hooks (options: HookOptions): this; } @@ -103,7 +103,7 @@ export interface ServiceHookOverloads { ): Promise; } -export type FeathersService> = +export type FeathersService = S & ServiceAddons & OptionalPick, keyof S>; export type CustomMethod = { @@ -179,7 +179,7 @@ export interface FeathersApplication { * * @param location The path of the service */ - defaultService (location: string): ServiceInterface; + defaultService (location: string): ServiceInterface; /** * Register a new service or a sub-app. When passed another @@ -206,7 +206,7 @@ export interface FeathersApplication { */ service ( path: L - ): FeathersService : Services[L]>; + ): FeathersService; setup (server?: any): Promise; @@ -318,10 +318,10 @@ export interface HookContext extends BaseHookContext> = +export type LegacyHookFunction = (this: S, context: HookContext) => (Promise | void> | HookContext | void); -export type Hook> = LegacyHookFunction; +export type Hook = LegacyHookFunction; type LegacyHookMethodMap = { [L in keyof S]?: SelfOrArray>; } & @@ -337,7 +337,7 @@ export type LegacyHookMap = { } // New @feathersjs/hook typings -export type HookFunction> = +export type HookFunction = (context: HookContext, next: NextFunction) => Promise; export type HookMap = { diff --git a/packages/feathers/src/hooks/index.ts b/packages/feathers/src/hooks/index.ts index 5c9879664a..8a9aba0e8b 100644 --- a/packages/feathers/src/hooks/index.ts +++ b/packages/feathers/src/hooks/index.ts @@ -15,7 +15,7 @@ import { export { fromAfterHook, fromBeforeHook, fromErrorHooks }; -export function createContext (service: Service, method: string, data: HookContextData = {}) { +export function createContext (service: Service, method: string, data: HookContextData = {}) { const createContext = (service as any)[method].createContext; if (typeof createContext !== 'function') { diff --git a/packages/feathers/test/hooks/error.test.ts b/packages/feathers/test/hooks/error.test.ts index 3398c3136d..332738f678 100644 --- a/packages/feathers/test/hooks/error.test.ts +++ b/packages/feathers/test/hooks/error.test.ts @@ -170,7 +170,7 @@ describe('`error` hooks', () => { const errorMessage = 'before hook broke'; let app: Application; - let service: FeathersService; + let service: FeathersService; beforeEach(() => { app = feathers().use('/dummy', { diff --git a/packages/transport-commons/src/channels/index.ts b/packages/transport-commons/src/channels/index.ts index b0973e28d5..5e74e42e18 100644 --- a/packages/transport-commons/src/channels/index.ts +++ b/packages/transport-commons/src/channels/index.ts @@ -51,7 +51,7 @@ export function channels () { } }); - app.mixins.push((service: FeathersService, path: string) => { + app.mixins.push((service: FeathersService, path: string) => { const { serviceEvents } = getServiceOptions(service); if (typeof service.publish === 'function') { diff --git a/packages/transport-commons/src/routing/index.ts b/packages/transport-commons/src/routing/index.ts index 0c79b4a855..01a3b5e2b4 100644 --- a/packages/transport-commons/src/routing/index.ts +++ b/packages/transport-commons/src/routing/index.ts @@ -3,12 +3,12 @@ import { Router } from './router'; declare module '@feathersjs/feathers/lib/declarations' { interface RouteLookup { - service: Service, + service: Service, params: { [key: string]: string } } interface Application { // eslint-disable-line - routes: Router; + routes: Router; lookup (path: string): RouteLookup; } } @@ -38,7 +38,7 @@ export const routing = () => (app: Application) => { }); // Add a mixin that registers a service on the router - app.mixins.push((service: Service, path: string) => { + app.mixins.push((service: Service, path: string) => { app.routes.insert(path, service); app.routes.insert(`${path}/:__id`, service); }); diff --git a/packages/transport-commons/src/routing/router.ts b/packages/transport-commons/src/routing/router.ts index 29ecf29e21..bf883f853a 100644 --- a/packages/transport-commons/src/routing/router.ts +++ b/packages/transport-commons/src/routing/router.ts @@ -77,7 +77,7 @@ export class RouteNode { } } -export class Router { +export class Router { constructor (public root: RouteNode = new RouteNode('', 0)) {} getPath (path: string) { From 345a757fddc6842534c6e65401443912aac85061 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:45:53 +0300 Subject: [PATCH 04/11] fix(typescript): Fix authentication types export --- packages/authentication/src/index.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/authentication/src/index.ts b/packages/authentication/src/index.ts index 06dcc6e7f8..c634a3f7a5 100644 --- a/packages/authentication/src/index.ts +++ b/packages/authentication/src/index.ts @@ -1,9 +1,5 @@ -import * as hooks from './hooks'; - -const { authenticate } = hooks; - -export { hooks }; -export { authenticate }; +export * as hooks from './hooks'; +export { authenticate } from './hooks'; export { AuthenticationBase, AuthenticationRequest, From 2180d4c261141cfe1cbed34dd6797b760e6d58a1 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:48:49 +0300 Subject: [PATCH 05/11] fix(typescript): Fix Publisher and App.channel in transport-commons --- .../transport-commons/src/channels/index.ts | 18 +++++++++--------- .../transport-commons/src/channels/mixins.ts | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/transport-commons/src/channels/index.ts b/packages/transport-commons/src/channels/index.ts index 5e74e42e18..c8c5ca3a3b 100644 --- a/packages/transport-commons/src/channels/index.ts +++ b/packages/transport-commons/src/channels/index.ts @@ -11,24 +11,24 @@ const { CHANNELS } = keys; declare module '@feathersjs/feathers/lib/declarations' { interface ServiceAddons extends EventEmitter { // eslint-disable-line - publish (publisher: Publisher>): this; - publish (event: Event, publisher: Publisher>): this; + publish (publisher: Publisher, A, this>): this; + publish (event: Event, publisher: Publisher, A, this>): this; - registerPublisher (publisher: Publisher>): this; - registerPublisher (event: Event, publisher: Publisher>): this; + registerPublisher (publisher: Publisher, A, this>): this; + registerPublisher (event: Event, publisher: Publisher, A, this>): this; } interface Application { // eslint-disable-line channels: string[]; - channel (name: string[]): Channel; + channel (name: string | string[]): Channel; channel (...names: string[]): Channel; - publish (publisher: Publisher): this; - publish (event: Event, publisher: Publisher): this; + publish (publisher: Publisher): this; + publish (event: Event, publisher: Publisher): this; - registerPublisher (publisher: Publisher): this; - registerPublisher (event: Event, publisher: Publisher): this; + registerPublisher (publisher: Publisher): this; + registerPublisher (event: Event, publisher: Publisher): this; } interface Params { diff --git a/packages/transport-commons/src/channels/mixins.ts b/packages/transport-commons/src/channels/mixins.ts index 079f051af0..5f0fdfbd1b 100644 --- a/packages/transport-commons/src/channels/mixins.ts +++ b/packages/transport-commons/src/channels/mixins.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */ -import { HookContext, getServiceOptions } from '@feathersjs/feathers'; +import { Application, HookContext, getServiceOptions } from '@feathersjs/feathers'; import { createDebug } from '@feathersjs/commons'; import { Channel } from './channel/base'; import { CombinedChannel } from './channel/combined'; @@ -63,7 +63,7 @@ export function channelMixin () { export type Event = string|(typeof ALL_EVENTS); -export type Publisher = (data: T, context: HookContext) => Channel | Channel[] | void | Promise; +export type Publisher = (data: T, context: HookContext) => Channel | Channel[] | void | Promise; export interface PublishMixin { [PUBLISHERS]: { [ALL_EVENTS]?: Publisher, [key: string]: Publisher }; From c17f85d965425e27e903afd86d6071d7ef611159 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:51:03 +0300 Subject: [PATCH 06/11] fix(typescript): Change CustomMethod type --- packages/feathers/src/declarations.ts | 4 ++-- packages/rest-client/test/declarations.ts | 4 ++-- packages/socketio-client/test/index.test.ts | 4 ++-- packages/transport-commons/test/client.test.ts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/feathers/src/declarations.ts b/packages/feathers/src/declarations.ts index f4222a7bba..8c9cfff5ba 100644 --- a/packages/feathers/src/declarations.ts +++ b/packages/feathers/src/declarations.ts @@ -106,8 +106,8 @@ export interface ServiceHookOverloads { export type FeathersService = S & ServiceAddons & OptionalPick, keyof S>; -export type CustomMethod = { - [k in Methods]: (data: any, params?: Params) => Promise; +export type CustomMethods = { + [K in keyof T]: (data: T[K][0], params?: Params) => Promise; } export type ServiceMixin = (service: FeathersService, path: string, options?: ServiceOptions) => void; diff --git a/packages/rest-client/test/declarations.ts b/packages/rest-client/test/declarations.ts index eab07a15e7..06f94766c2 100644 --- a/packages/rest-client/test/declarations.ts +++ b/packages/rest-client/test/declarations.ts @@ -1,6 +1,6 @@ -import { CustomMethod } from '@feathersjs/feathers'; +import { CustomMethods } from '@feathersjs/feathers'; import { RestService } from '../src'; export type ServiceTypes = { - todos: RestService & CustomMethod<'customMethod'> + todos: RestService & CustomMethods<{customMethod: any}> } diff --git a/packages/socketio-client/test/index.test.ts b/packages/socketio-client/test/index.test.ts index 2df312ace2..9bd3350c17 100644 --- a/packages/socketio-client/test/index.test.ts +++ b/packages/socketio-client/test/index.test.ts @@ -1,6 +1,6 @@ import { strict as assert } from 'assert'; import { Server } from 'http'; -import { CustomMethod, feathers } from '@feathersjs/feathers'; +import { CustomMethods, feathers } from '@feathersjs/feathers'; import { io, Socket } from 'socket.io-client'; import { clientTests } from '@feathersjs/tests'; @@ -9,7 +9,7 @@ import socketio, { SocketService } from '../src'; type ServiceTypes = { '/': SocketService, - 'todos': SocketService & CustomMethod<'customMethod'>, + 'todos': SocketService & CustomMethods<{customMethod: any}>, [key: string]: any; } diff --git a/packages/transport-commons/test/client.test.ts b/packages/transport-commons/test/client.test.ts index 1901fd4661..f141e7f8eb 100644 --- a/packages/transport-commons/test/client.test.ts +++ b/packages/transport-commons/test/client.test.ts @@ -1,6 +1,6 @@ import assert from 'assert'; import { EventEmitter } from 'events'; -import { CustomMethod } from '@feathersjs/feathers'; +import { CustomMethods } from '@feathersjs/feathers'; import { NotAuthenticated } from '@feathersjs/errors'; import { Service, SocketService } from '../src/client'; @@ -9,7 +9,7 @@ declare type DummyCallback = (err: any, data?: any) => void; describe('client', () => { let connection: any; let testData: any; - let service: SocketService & CustomMethod<'customMethod'> & EventEmitter; + let service: SocketService & CustomMethods<{customMethod: any}> & EventEmitter; beforeEach(() => { connection = new EventEmitter(); From 3d6bd774faaca014be6de42bca0677f00d9b1843 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:53:38 +0300 Subject: [PATCH 07/11] fix(core): Enable legacy hooks for service custom methods --- packages/feathers/src/hooks/index.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/feathers/src/hooks/index.ts b/packages/feathers/src/hooks/index.ts index 8a9aba0e8b..faac89bcb4 100644 --- a/packages/feathers/src/hooks/index.ts +++ b/packages/feathers/src/hooks/index.ts @@ -63,7 +63,9 @@ export function hookMixin ( } const app = this; - const serviceMethodHooks = getHookMethods(service, options).reduce((res, method) => { + const hookMethods = getHookMethods(service, options); + + const serviceMethodHooks = hookMethods.reduce((res, method) => { const params = (defaultServiceArguments as any)[method] || [ 'data', 'params' ]; res[method] = new FeathersHookManager(app, method) @@ -79,7 +81,8 @@ export function hookMixin ( return res; }, {} as HookMap); - const handleLegacyHooks = enableLegacyHooks(service); + + const handleLegacyHooks = enableLegacyHooks(service, hookMethods); hooks(service, serviceMethodHooks); From f9f5d76b3279ce097dd0a47de7ed35e5a8104ea6 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:54:32 +0300 Subject: [PATCH 08/11] fix(koa): Add headers to params --- packages/koa/src/rest.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/koa/src/rest.ts b/packages/koa/src/rest.ts index 017110ac9b..ab5e5df833 100644 --- a/packages/koa/src/rest.ts +++ b/packages/koa/src/rest.ts @@ -10,7 +10,7 @@ const debug = createDebug('@feathersjs/koa:rest'); export function rest () { return async (ctx: FeathersKoaContext, next: Next) => { const { app, request } = ctx; - const { query: koaQuery, path, body: data, method: httpMethod } = request; + const { query: koaQuery, headers, path, body: data, method: httpMethod } = request; const query = { ...koaQuery }; const methodOverride = request.headers[http.METHOD_HEADER] ? request.headers[http.METHOD_HEADER] as string : null; @@ -33,6 +33,7 @@ export function rest () { const params = { ...ctx.feathers, query, + headers, route }; const args = createArguments({ id, data, params }); From 42d1b1ba34e1385e9a8de444e616713b9fff6fde Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:55:43 +0300 Subject: [PATCH 09/11] fix(koa): Type feathers props on koa context --- packages/koa/src/declarations.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/koa/src/declarations.ts b/packages/koa/src/declarations.ts index e62150d254..13292463e1 100644 --- a/packages/koa/src/declarations.ts +++ b/packages/koa/src/declarations.ts @@ -1,6 +1,6 @@ import Koa from 'koa'; import { Server } from 'http'; -import { Application as FeathersApplication } from '@feathersjs/feathers'; +import { Application as FeathersApplication, HookContext, Params } from '@feathersjs/feathers'; import '@feathersjs/authentication'; export type ApplicationAddons = { @@ -13,3 +13,10 @@ export type Application = export type FeathersKoaContext = Koa.Context & { app: A; }; + +declare module 'koa' { + interface ExtendableContext { + feathers?: Partial; + hook?: HookContext; + } +} From 60615744eb561a2967701b0be4ea802279daf531 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 02:58:06 +0300 Subject: [PATCH 10/11] fix(transport-commons): Do not use generic non-feathers hook context --- packages/transport-commons/package.json | 1 - packages/transport-commons/src/http.ts | 21 ++++++------------ packages/transport-commons/test/http.test.ts | 23 +++++++++----------- 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/packages/transport-commons/package.json b/packages/transport-commons/package.json index 66ebf18d20..1d47674298 100644 --- a/packages/transport-commons/package.json +++ b/packages/transport-commons/package.json @@ -55,7 +55,6 @@ "@feathersjs/commons": "^5.0.0-pre.14", "@feathersjs/errors": "^5.0.0-pre.14", "@feathersjs/feathers": "^5.0.0-pre.14", - "@feathersjs/hooks": "^0.6.5", "lodash": "^4.17.21" }, "devDependencies": { diff --git a/packages/transport-commons/src/http.ts b/packages/transport-commons/src/http.ts index aa7d92b18e..23ed293ec9 100644 --- a/packages/transport-commons/src/http.ts +++ b/packages/transport-commons/src/http.ts @@ -1,6 +1,5 @@ import { MethodNotAllowed } from '@feathersjs/errors/lib'; import { HookContext, NullableId, Params } from '@feathersjs/feathers'; -import { BaseHookContext } from '@feathersjs/hooks'; export const METHOD_HEADER = 'x-service-method'; @@ -17,7 +16,7 @@ export const statusCodes = { success: 200 }; -export const knownMethods: { [key: string]: any } = { +export const knownMethods: { [key: string]: string } = { post: 'create', patch: 'patch', put: 'update', @@ -54,25 +53,19 @@ export const argumentsFor = { default: ({ data, params }: ServiceParams) => [ data, params ] } -export function getData (context: HookContext|{ [key: string]: any }) { - if (!(context instanceof BaseHookContext)) { - return context; - } - +export function getData (context: HookContext) { return context.dispatch !== undefined ? context.dispatch : context.result; } export function getStatusCode (context: HookContext, data?: any) { - if (context instanceof BaseHookContext) { - if (context.statusCode) { - return context.statusCode; - } + if (context.statusCode) { + return context.statusCode; + } - if (context.method === 'create') { - return statusCodes.created; - } + if (context.method === 'create') { + return statusCodes.created; } if (!data) { diff --git a/packages/transport-commons/test/http.test.ts b/packages/transport-commons/test/http.test.ts index ea100044a1..c23da805e4 100644 --- a/packages/transport-commons/test/http.test.ts +++ b/packages/transport-commons/test/http.test.ts @@ -1,32 +1,29 @@ import assert from 'assert'; import { HookContext } from '@feathersjs/feathers'; -import { BaseHookContext } from '@feathersjs/hooks'; - import { http } from '../src'; describe('@feathersjs/transport-commons HTTP helpers', () => { it('getData', () => { const plainData = { message: 'hi' }; const dispatch = { message: 'from dispatch' }; - const resultContext = new BaseHookContext({ + const resultContext = { result: plainData - }); - const dispatchContext = new BaseHookContext({ + }; + const dispatchContext = { dispatch - }); + }; - assert.deepStrictEqual(http.getData(plainData), plainData); - assert.deepStrictEqual(http.getData(resultContext), plainData); - assert.deepStrictEqual(http.getData(dispatchContext), dispatch); + assert.deepStrictEqual(http.getData(resultContext as HookContext), plainData); + assert.deepStrictEqual(http.getData(dispatchContext as HookContext), dispatch); }); it('getStatusCode', async () => { - const statusContext = new BaseHookContext({ + const statusContext = { statusCode: 202 - }); - const createContext = new BaseHookContext({ + }; + const createContext = { method: 'create' - }); + }; assert.strictEqual(http.getStatusCode(statusContext as HookContext, {}), 202); assert.strictEqual(http.getStatusCode(createContext as HookContext, {}), http.statusCodes.created); From 797dc40992bbc92f160c79bcfd448da6348dbf05 Mon Sep 17 00:00:00 2001 From: Dmitrii Maganov Date: Wed, 27 Oct 2021 03:01:07 +0300 Subject: [PATCH 11/11] fix(express): Use correct type for feathers hook context --- packages/express/package.json | 1 - packages/express/src/rest.ts | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/express/package.json b/packages/express/package.json index 50712e3342..6da414750b 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -52,7 +52,6 @@ "@feathersjs/commons": "^5.0.0-pre.14", "@feathersjs/errors": "^5.0.0-pre.14", "@feathersjs/feathers": "^5.0.0-pre.14", - "@feathersjs/hooks": "^0.6.5", "@feathersjs/transport-commons": "^5.0.0-pre.14", "@types/express": "^4.17.13", "@types/express-serve-static-core": "^4.17.24", diff --git a/packages/express/src/rest.ts b/packages/express/src/rest.ts index 25c458558a..2976d7fe16 100644 --- a/packages/express/src/rest.ts +++ b/packages/express/src/rest.ts @@ -1,15 +1,14 @@ import { MethodNotAllowed } from '@feathersjs/errors'; -import { HookContext } from '@feathersjs/hooks'; import { createDebug } from '@feathersjs/commons'; import { http } from '@feathersjs/transport-commons'; -import { createContext, defaultServiceMethods, getServiceOptions } from '@feathersjs/feathers'; +import { HookContext, createContext, defaultServiceMethods, getServiceOptions } from '@feathersjs/feathers'; import { Request, Response, NextFunction, RequestHandler, Router } from 'express'; import { parseAuthentication } from './authentication'; const debug = createDebug('@feathersjs/express/rest'); -export type ServiceCallback = (req: Request, res: Response, options: http.ServiceParams) => Promise; +export type ServiceCallback = (req: Request, res: Response, options: http.ServiceParams) => Promise; export const feathersParams = (req: Request, _res: Response, next: NextFunction) => { req.feathers = { @@ -69,7 +68,7 @@ export const serviceMethodHandler = ( const args = getArgs(options); const context = createContext(service, method); - res.hook = context as any; + res.hook = context; return service[method](...args, context); });