Skip to content

Commit

Permalink
feat: migrate hooks to TypeScript (#15131)
Browse files Browse the repository at this point in the history
* feat: migrate hooks to TS

* feat: migrate hooks to TS

Co-authored-by: Rik Smale <13023439+WikiRik@users.noreply.github.com>
  • Loading branch information
ephys and WikiRik committed Oct 31, 2022
1 parent dc3af40 commit 9cd8d89
Show file tree
Hide file tree
Showing 23 changed files with 985 additions and 1,981 deletions.
6 changes: 3 additions & 3 deletions src/associations/helpers.ts
Expand Up @@ -27,7 +27,7 @@ export function checkNamingCollision(source: ModelStatic<any>, associationName:

export function addForeignKeyConstraints(
newAttribute: ModelAttributeColumnOptions,
source: ModelStatic<Model>,
source: ModelStatic,
options: AssociationOptions<string>,
key: string,
): void {
Expand Down Expand Up @@ -239,7 +239,7 @@ export function defineAssociation<
});

if (normalizedOptions.hooks) {
source.runHooks('beforeAssociate', { source, target, type, sequelize }, normalizedOptions);
source.hooks.runSync('beforeAssociate', { source, target, type, sequelize }, normalizedOptions);
}

let association;
Expand All @@ -255,7 +255,7 @@ export function defineAssociation<
}

if (normalizedOptions.hooks) {
source.runHooks('afterAssociate', { source, target, type, association, sequelize }, normalizedOptions);
source.hooks.runSync('afterAssociate', { source, target, type, association, sequelize }, normalizedOptions);
}

checkNamingCollision(source, normalizedOptions.as);
Expand Down
18 changes: 9 additions & 9 deletions src/associations/index.ts
Expand Up @@ -9,13 +9,13 @@ export * from './has-one';
export * from './has-many';
export * from './belongs-to-many';

export type BeforeAssociateEventData = {
source: ModelStatic<Model>,
target: ModelStatic<Model>,
sequelize: Sequelize,
type: Class<Association>,
};
export interface BeforeAssociateEventData {
source: ModelStatic<Model>;
target: ModelStatic<Model>;
sequelize: Sequelize;
type: Class<Association>;
}

export type AfterAssociateEventData = BeforeAssociateEventData & {
association: Association,
};
export interface AfterAssociateEventData extends BeforeAssociateEventData {
association: Association;
}
8 changes: 4 additions & 4 deletions src/dialects/abstract/connection-manager.ts
Expand Up @@ -279,9 +279,9 @@ export class AbstractConnectionManager<TConnection extends Connection = Connecti
* @internal
*/
async _connect(config: ConnectionOptions): Promise<TConnection> {
await this.sequelize.runHooks('beforeConnect', config);
await this.sequelize.hooks.runAsync('beforeConnect', config);
const connection = await this.connect(config);
await this.sequelize.runHooks('afterConnect', connection, config);
await this.sequelize.hooks.runAsync('afterConnect', connection, config);

return connection;
}
Expand All @@ -293,8 +293,8 @@ export class AbstractConnectionManager<TConnection extends Connection = Connecti
* @private
*/
async _disconnect(connection: TConnection) {
await this.sequelize.runHooks('beforeDisconnect', connection);
await this.sequelize.hooks.runAsync('beforeDisconnect', connection);
await this.disconnect(connection);
await this.sequelize.runHooks('afterDisconnect', connection);
await this.sequelize.hooks.runAsync('afterDisconnect', connection);
}
}
130 changes: 130 additions & 0 deletions src/hooks-legacy.ts
@@ -0,0 +1,130 @@
import type { HookHandlerBuilder } from './hooks.js';
import { hooksReworked } from './utils/deprecations.js';

// TODO: delete this in Sequelize v8

export interface LegacyRunHookFunction<HookConfig extends {}, Return> {
<HookName extends keyof HookConfig>(
hookName: HookName,
...args: HookConfig[HookName] extends (...args2: any) => any
? Parameters<HookConfig[HookName]>
: never
): Return;
}

export function legacyBuildRunHook<HookConfig extends {}>(
hookHandlerBuilder: HookHandlerBuilder<HookConfig>,
): LegacyRunHookFunction<HookConfig, void> {

return async function runHooks<HookName extends keyof HookConfig>(
this: object,
hookName: HookName,
...args: HookConfig[HookName] extends (...args2: any) => any
? Parameters<HookConfig[HookName]>
: never
): Promise<void> {
hooksReworked();

return hookHandlerBuilder.getFor(this).runAsync(hookName, ...args);
};
}

export interface LegacyAddAnyHookFunction<HookConfig extends {}> {
/**
* Adds a hook listener
*/
<This, HookName extends keyof HookConfig>(this: This, hookName: HookName, hook: HookConfig[HookName]): This;

/**
* Adds a hook listener
*
* @param listenerName Provide a name for the hook function. It can be used to remove the hook later.
*/
<This, HookName extends keyof HookConfig>(
this: This,
hookName: HookName,
listenerName: string,
hook: HookConfig[HookName]
): This;
}

export function legacyBuildAddAnyHook<HookConfig extends {}>(
hookHandlerBuilder: HookHandlerBuilder<HookConfig>,
): LegacyAddAnyHookFunction<HookConfig> {

return function addHook<This extends object, HookName extends keyof HookConfig>(
this: This,
hookName: HookName,
listenerNameOrHook: HookConfig[HookName] | string,
hook?: HookConfig[HookName],
): This {
hooksReworked();

if (hook) {
// @ts-expect-error
hookHandlerBuilder.getFor(this).addListener(hookName, hook, listenerNameOrHook);
} else {
// @ts-expect-error
hookHandlerBuilder.getFor(this).addListener(hookName, listenerNameOrHook);
}

return this;
};
}

export interface LegacyAddHookFunction<Fn> {
/**
* Adds a hook listener
*/
<This extends object>(this: This, hook: Fn): This;

/**
* Adds a hook listener
*
* @param listenerName Provide a name for the hook function. It can be used to remove the hook later.
*/
<This extends object>(this: This, listenerName: string, hook: Fn): This;
}

export function legacyBuildAddHook<HookConfig extends {}, HookName extends keyof HookConfig>(
hookHandlerBuilder: HookHandlerBuilder<HookConfig>,
hookName: HookName,
): LegacyAddHookFunction<HookConfig[HookName]> {
return function addHook<This extends object>(
this: This,
listenerNameOrHook: HookConfig[HookName] | string,
hook?: HookConfig[HookName],
): This {
hooksReworked();

if (hook) {
// @ts-expect-error
hookHandlerBuilder.getFor(this).addListener(hookName, hook, listenerNameOrHook);
} else {
// @ts-expect-error
return hookHandlerBuilder.getFor(this).addListener(hookName, listenerNameOrHook);
}

return this;
};
}

export function legacyBuildHasHook<HookConfig extends {}>(hookHandlerBuilder: HookHandlerBuilder<HookConfig>) {
return function hasHook<HookName extends keyof HookConfig>(this: object, hookName: HookName): boolean {
hooksReworked();

return hookHandlerBuilder.getFor(this).hasListeners(hookName);
};
}

export function legacyBuildRemoveHook<HookConfig extends {}>(hookHandlerBuilder: HookHandlerBuilder<HookConfig>) {
return function removeHook<HookName extends keyof HookConfig>(
this: object,
hookName: HookName,
listenerNameOrListener: HookConfig[HookName] | string,
): void {
hooksReworked();

return hookHandlerBuilder.getFor(this).removeListener(hookName, listenerNameOrListener);
};
}

0 comments on commit 9cd8d89

Please sign in to comment.