refactor: Migrate externalHooks mixin to composables (no-changelog) (#7930)
## Summary Provide details about your pull request and what it adds, fixes, or changes. Photos and videos are recommended. As part of NodeView refactor, this PR migrates all externalHooks calls to `useExternalHooks` composable. #### How to test the change: 1. Run using env `export N8N_DEPLOYMENT_TYPE=cloud` 2. Hooks should still run as expected ## Issues fixed Include links to Github issue or Community forum post or **Linear ticket**: > Important in order to close automatically and provide context to reviewers https://linear.app/n8n/issue/N8N-6349/externalhooks ## Review / Merge checklist - [x] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [x] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [x] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. A feature is not complete without tests. > > *(internal)* You can use Slack commands to trigger [e2e tests](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#a39f9e5ba64a48b58a71d81c837e8227) or [deploy test instance](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#f6a177d32bde4b57ae2da0b8e454bfce) or [deploy early access version on Cloud](https://www.notion.so/n8n/Cloudbot-3dbe779836004972b7057bc989526998?pvs=4#fef2d36ab02247e1a0f65a74f6fb534e).
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
import type { IExternalHooks } from '@/Interface';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
import type { ExternalHooks, ExternalHooksGenericContext } from '@/types';
|
||||
import { defineComponent } from 'vue';
|
||||
import { runExternalHook } from '@/utils/externalHooks';
|
||||
|
||||
export function extendExternalHooks(hooksExtension: PartialDeep<ExternalHooks>) {
|
||||
if (typeof window.n8nExternalHooks === 'undefined') {
|
||||
window.n8nExternalHooks = {};
|
||||
}
|
||||
|
||||
for (const resource of Object.keys(hooksExtension) as Array<keyof ExternalHooks>) {
|
||||
if (typeof window.n8nExternalHooks[resource] === 'undefined') {
|
||||
window.n8nExternalHooks[resource] = {};
|
||||
}
|
||||
|
||||
const extensionContext = hooksExtension[resource] as ExternalHooksGenericContext;
|
||||
const context = window.n8nExternalHooks[resource] as ExternalHooksGenericContext;
|
||||
for (const operator of Object.keys(extensionContext)) {
|
||||
if (typeof context[operator] === 'undefined') {
|
||||
context[operator] = [];
|
||||
}
|
||||
|
||||
context[operator].push(...extensionContext[operator]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const externalHooks = defineComponent({
|
||||
methods: {
|
||||
$externalHooks(): IExternalHooks {
|
||||
return {
|
||||
run: runExternalHook,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -13,6 +13,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { NodeConnectionType, NodeHelpers, jsonParse, jsonStringify } from 'n8n-workflow';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
|
||||
export type PinDataSource =
|
||||
| 'pin-icon-click'
|
||||
@@ -168,7 +169,7 @@ export const pinData = defineComponent({
|
||||
view: this.displayMode,
|
||||
run_index: this.runIndex,
|
||||
};
|
||||
void this.$externalHooks().run('runData.onDataPinningSuccess', telemetryPayload);
|
||||
void useExternalHooks().run('runData.onDataPinningSuccess', telemetryPayload);
|
||||
this.$telemetry.track('Ndv data pinning success', telemetryPayload);
|
||||
},
|
||||
onDataPinningError({
|
||||
|
||||
@@ -5,7 +5,6 @@ import type {
|
||||
IPushDataExecutionFinished,
|
||||
} from '@/Interface';
|
||||
|
||||
import { externalHooks } from '@/mixins/externalHooks';
|
||||
import { nodeHelpers } from '@/mixins/nodeHelpers';
|
||||
import { useTitleChange } from '@/composables/useTitleChange';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
@@ -39,6 +38,7 @@ import { defineComponent } from 'vue';
|
||||
import { useOrchestrationStore } from '@/stores/orchestration.store';
|
||||
import { usePushConnectionStore } from '@/stores/pushConnection.store';
|
||||
import { useCollaborationStore } from '@/stores/collaboration.store';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
|
||||
export const pushConnection = defineComponent({
|
||||
setup() {
|
||||
@@ -52,7 +52,7 @@ export const pushConnection = defineComponent({
|
||||
void this.pushMessageReceived(message);
|
||||
});
|
||||
},
|
||||
mixins: [externalHooks, nodeHelpers, workflowHelpers],
|
||||
mixins: [nodeHelpers, workflowHelpers],
|
||||
data() {
|
||||
return {
|
||||
retryTimeout: null as NodeJS.Timeout | null,
|
||||
@@ -518,7 +518,7 @@ export const pushConnection = defineComponent({
|
||||
runDataExecuted.data.resultData.runData[lastNodeExecuted][0].data!.main[0]!.length;
|
||||
}
|
||||
|
||||
void this.$externalHooks().run('pushConnection.executionFinished', {
|
||||
void useExternalHooks().run('pushConnection.executionFinished', {
|
||||
itemsCount,
|
||||
nodeName: runDataExecuted.data.resultData.lastNodeExecuted,
|
||||
errorMessage: runDataExecutedErrorMessage,
|
||||
|
||||
@@ -2,7 +2,6 @@ import { defineComponent } from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useStorage } from '@/composables/useStorage';
|
||||
|
||||
import { externalHooks } from '@/mixins/externalHooks';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
|
||||
@@ -14,9 +13,10 @@ import {
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
|
||||
export const workflowActivate = defineComponent({
|
||||
mixins: [externalHooks, workflowHelpers],
|
||||
mixins: [workflowHelpers],
|
||||
setup() {
|
||||
return {
|
||||
...useToast(),
|
||||
@@ -64,7 +64,7 @@ export const workflowActivate = defineComponent({
|
||||
ndv_input: telemetrySource === 'ndv',
|
||||
};
|
||||
this.$telemetry.track('User set workflow active status', telemetryPayload);
|
||||
void this.$externalHooks().run('workflowActivate.updateWorkflowActivation', telemetryPayload);
|
||||
void useExternalHooks().run('workflowActivate.updateWorkflowActivation', telemetryPayload);
|
||||
|
||||
try {
|
||||
if (isWorkflowActive && newActiveState) {
|
||||
@@ -111,7 +111,7 @@ export const workflowActivate = defineComponent({
|
||||
const activationEventName = isCurrentWorkflow
|
||||
? 'workflow.activeChangeCurrent'
|
||||
: 'workflow.activeChange';
|
||||
void this.$externalHooks().run(activationEventName, {
|
||||
void useExternalHooks().run(activationEventName, {
|
||||
workflowId: currWorkflowId,
|
||||
active: newActiveState,
|
||||
});
|
||||
|
||||
@@ -47,7 +47,6 @@ import type {
|
||||
|
||||
import { useMessage } from '@/composables/useMessage';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { externalHooks } from '@/mixins/externalHooks';
|
||||
import { genericHelpers } from '@/mixins/genericHelpers';
|
||||
import { nodeHelpers } from '@/mixins/nodeHelpers';
|
||||
|
||||
@@ -68,6 +67,7 @@ import { getSourceItems } from '@/utils/pairedItemUtils';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { getCredentialTypeName, isCredentialOnlyNodeType } from '@/utils/credentialOnlyNodes';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
|
||||
export function getParentMainInputNode(workflow: Workflow, node: INode): INode {
|
||||
const nodeType = useNodeTypesStore().getNodeType(node.type);
|
||||
@@ -474,7 +474,7 @@ export function executeData(
|
||||
}
|
||||
|
||||
export const workflowHelpers = defineComponent({
|
||||
mixins: [externalHooks, nodeHelpers, genericHelpers],
|
||||
mixins: [nodeHelpers, genericHelpers],
|
||||
setup() {
|
||||
return {
|
||||
...useToast(),
|
||||
@@ -912,7 +912,7 @@ export const workflowHelpers = defineComponent({
|
||||
|
||||
this.uiStore.stateIsDirty = false;
|
||||
this.uiStore.removeActiveAction('workflowSaving');
|
||||
void this.$externalHooks().run('workflow.afterUpdate', { workflowData });
|
||||
void useExternalHooks().run('workflow.afterUpdate', { workflowData });
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
@@ -1077,7 +1077,7 @@ export const workflowHelpers = defineComponent({
|
||||
|
||||
this.uiStore.removeActiveAction('workflowSaving');
|
||||
this.uiStore.stateIsDirty = false;
|
||||
void this.$externalHooks().run('workflow.afterUpdate', { workflowData });
|
||||
void useExternalHooks().run('workflow.afterUpdate', { workflowData });
|
||||
|
||||
getCurrentWorkflow(true); // refresh cache
|
||||
return true;
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { externalHooks } from '@/mixins/externalHooks';
|
||||
import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||
|
||||
import { useTitleChange } from '@/composables/useTitleChange';
|
||||
@@ -20,9 +19,10 @@ import { useUIStore } from '@/stores/ui.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { FORM_TRIGGER_NODE_TYPE } from '@/constants';
|
||||
import { openPopUpWindow } from '@/utils/executionUtils';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
|
||||
export const workflowRun = defineComponent({
|
||||
mixins: [externalHooks, workflowHelpers],
|
||||
mixins: [workflowHelpers],
|
||||
setup() {
|
||||
return {
|
||||
...useTitleChange(),
|
||||
@@ -125,7 +125,7 @@ export const workflowRun = defineComponent({
|
||||
duration: 0,
|
||||
});
|
||||
this.titleSet(workflow.name as string, 'ERROR');
|
||||
void this.$externalHooks().run('workflowRun.runError', {
|
||||
void useExternalHooks().run('workflowRun.runError', {
|
||||
errorMessages,
|
||||
nodeName: options.destinationNode,
|
||||
});
|
||||
@@ -287,7 +287,7 @@ export const workflowRun = defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
await this.$externalHooks().run('workflowRun.runWorkflow', {
|
||||
await useExternalHooks().run('workflowRun.runWorkflow', {
|
||||
nodeName: options.destinationNode,
|
||||
source: options.source,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user