@atom8n/n8n 2.4.7 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build.tsbuildinfo +1 -1
- package/dist/chat/chat-service.types.d.ts +6 -6
- package/dist/commands/execute-batch.d.ts +2 -2
- package/dist/commands/execute.js +0 -0
- package/dist/commands/import/credentials.d.ts +2 -2
- package/dist/commands/import/credentials.js +0 -0
- package/dist/commands/import/workflow.d.ts +2 -2
- package/dist/commands/ldap/reset.d.ts +2 -2
- package/dist/commands/mcp.d.ts +23 -0
- package/dist/commands/mcp.js +315 -0
- package/dist/commands/run.d.ts +23 -0
- package/dist/commands/run.js +162 -0
- package/dist/controllers/annotation-tags.controller.ee.d.ts +1 -1
- package/dist/controllers/cli.controller.d.ts +26 -0
- package/dist/controllers/cli.controller.js +334 -0
- package/dist/controllers/orchestration.controller.js +0 -0
- package/dist/controllers/users.controller.d.ts +1 -1
- package/dist/environments.ee/source-control/source-control-status.service.ee.d.ts +2 -2
- package/dist/environments.ee/source-control/source-control.controller.ee.d.ts +4 -4
- package/dist/environments.ee/source-control/source-control.service.ee.d.ts +2 -2
- package/dist/environments.ee/source-control/types/source-control-set-branch.js +0 -0
- package/dist/eventbus/event-message-classes/index.js +0 -0
- package/dist/events/relays/workflow-failure-notification.event-relay.d.ts +13 -0
- package/dist/events/relays/workflow-failure-notification.event-relay.js +77 -0
- package/dist/executions/execution-data/types.d.ts +17 -0
- package/dist/executions/execution-data/types.js +2 -0
- package/dist/executions/failed-run-factory.d.ts +4 -0
- package/dist/executions/failed-run-factory.js +71 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +8 -0
- package/dist/interfaces.d.ts +1 -1
- package/dist/license.js +1 -1
- package/dist/middlewares/webview-frame-options.d.ts +2 -0
- package/dist/middlewares/webview-frame-options.js +22 -0
- package/dist/modules/chat-hub/chat-hub-extractor.d.ts +22 -0
- package/dist/modules/chat-hub/chat-hub-extractor.js +63 -0
- package/dist/modules/dynamic-credentials.ee/credential-resolvers/storage/dynamic-credential-user-entry-storage.d.ts +11 -0
- package/dist/modules/dynamic-credentials.ee/credential-resolvers/storage/dynamic-credential-user-entry-storage.js +58 -0
- package/dist/modules/dynamic-credentials.ee/database/entities/dynamic-credential-user-entry.d.ts +12 -0
- package/dist/modules/dynamic-credentials.ee/database/entities/dynamic-credential-user-entry.js +64 -0
- package/dist/modules/dynamic-credentials.ee/database/repositories/dynamic-credential-user-entry.repository.d.ts +5 -0
- package/dist/modules/dynamic-credentials.ee/database/repositories/dynamic-credential-user-entry.repository.js +25 -0
- package/dist/modules/dynamic-credentials.ee/dynamic-credentials.config.d.ts +5 -0
- package/dist/modules/dynamic-credentials.ee/dynamic-credentials.config.js +36 -0
- package/dist/modules/dynamic-credentials.ee/services/dynamic-credential-cors.service.d.ts +12 -0
- package/dist/modules/dynamic-credentials.ee/services/dynamic-credential-cors.service.js +69 -0
- package/dist/modules/dynamic-credentials.ee/services/resolver-config-expression.service.d.ts +7 -0
- package/dist/modules/dynamic-credentials.ee/services/resolver-config-expression.service.js +46 -0
- package/dist/modules/insights/database/entities/insights-metadata.js +1 -1
- package/dist/modules/insights/database/repositories/insights-by-period-query.helper.js +4 -1
- package/dist/modules/insights/database/repositories/insights-by-period.repository.d.ts +1 -1
- package/dist/modules/insights/insights.module.d.ts +1 -1
- package/dist/modules/insights/insights.service.d.ts +1 -1
- package/dist/modules/log-streaming.ee/database/entities/event-destination.entity.d.ts +6 -0
- package/dist/modules/log-streaming.ee/database/entities/event-destination.entity.js +28 -0
- package/dist/modules/log-streaming.ee/database/entities/index.d.ts +1 -0
- package/dist/modules/log-streaming.ee/database/entities/index.js +5 -0
- package/dist/modules/log-streaming.ee/database/repositories/event-destination.repository.d.ts +5 -0
- package/dist/modules/log-streaming.ee/database/repositories/event-destination.repository.js +25 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-from-db.d.ts +4 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-from-db.js +24 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-sentry.ee.d.ts +17 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-sentry.ee.js +131 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-syslog.ee.d.ts +22 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-syslog.ee.js +116 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-webhook.ee.d.ts +35 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination-webhook.ee.js +328 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination.ee.d.ts +28 -0
- package/dist/modules/log-streaming.ee/destinations/message-event-bus-destination.ee.js +74 -0
- package/dist/modules/log-streaming.ee/log-streaming-destination.service.d.ts +32 -0
- package/dist/modules/log-streaming.ee/log-streaming-destination.service.js +175 -0
- package/dist/modules/log-streaming.ee/log-streaming.controller.d.ts +15 -0
- package/dist/modules/log-streaming.ee/log-streaming.controller.js +149 -0
- package/dist/modules/log-streaming.ee/log-streaming.module.d.ts +5 -0
- package/dist/modules/log-streaming.ee/log-streaming.module.js +66 -0
- package/dist/modules/mcp/mcp-oauth.helpers.js +0 -0
- package/dist/modules/mcp/mcp.oauth-clients.controller.js +0 -0
- package/dist/modules/mcp/tools/execute-workflow.tool.d.ts +10 -10
- package/dist/modules/mcp/tools/schemas.d.ts +10 -10
- package/dist/modules/source-control.ee/constants.d.ts +17 -0
- package/dist/modules/source-control.ee/constants.js +22 -0
- package/dist/modules/source-control.ee/middleware/source-control-enabled-middleware.ee.d.ts +2 -0
- package/dist/modules/source-control.ee/middleware/source-control-enabled-middleware.ee.js +18 -0
- package/dist/modules/source-control.ee/source-control-export.service.ee.d.ts +37 -0
- package/dist/modules/source-control.ee/source-control-export.service.ee.js +426 -0
- package/dist/modules/source-control.ee/source-control-git.service.ee.d.ts +59 -0
- package/dist/modules/source-control.ee/source-control-git.service.ee.js +427 -0
- package/dist/modules/source-control.ee/source-control-helper.ee.d.ts +49 -0
- package/dist/modules/source-control.ee/source-control-helper.ee.js +241 -0
- package/dist/modules/source-control.ee/source-control-import.service.ee.d.ts +110 -0
- package/dist/modules/source-control.ee/source-control-import.service.ee.js +957 -0
- package/dist/modules/source-control.ee/source-control-preferences.service.ee.d.ts +46 -0
- package/dist/modules/source-control.ee/source-control-preferences.service.ee.js +309 -0
- package/dist/modules/source-control.ee/source-control-resource-helper.d.ts +4 -0
- package/dist/modules/source-control.ee/source-control-resource-helper.js +20 -0
- package/dist/modules/source-control.ee/source-control-scoped.service.d.ts +17 -0
- package/dist/modules/source-control.ee/source-control-scoped.service.js +134 -0
- package/dist/modules/source-control.ee/source-control-status.service.ee.d.ts +90 -0
- package/dist/modules/source-control.ee/source-control-status.service.ee.js +596 -0
- package/dist/modules/source-control.ee/source-control.config.d.ts +3 -0
- package/dist/modules/source-control.ee/source-control.config.js +26 -0
- package/dist/modules/source-control.ee/source-control.controller.ee.d.ts +157 -0
- package/dist/modules/source-control.ee/source-control.controller.ee.js +347 -0
- package/dist/modules/source-control.ee/source-control.module.d.ts +4 -0
- package/dist/modules/source-control.ee/source-control.module.js +59 -0
- package/dist/modules/source-control.ee/source-control.service.ee.d.ts +125 -0
- package/dist/modules/source-control.ee/source-control.service.ee.js +466 -0
- package/dist/modules/source-control.ee/types/export-result.d.ts +10 -0
- package/dist/modules/source-control.ee/types/export-result.js +2 -0
- package/dist/modules/source-control.ee/types/exportable-credential.d.ts +14 -0
- package/dist/modules/source-control.ee/types/exportable-credential.js +2 -0
- package/dist/modules/source-control.ee/types/exportable-folders.d.ts +11 -0
- package/dist/modules/source-control.ee/types/exportable-folders.js +2 -0
- package/dist/modules/source-control.ee/types/exportable-project.d.ts +17 -0
- package/dist/modules/source-control.ee/types/exportable-project.js +2 -0
- package/dist/modules/source-control.ee/types/exportable-tags.d.ts +5 -0
- package/dist/modules/source-control.ee/types/exportable-tags.js +2 -0
- package/dist/modules/source-control.ee/types/exportable-variable.d.ts +7 -0
- package/dist/modules/source-control.ee/types/exportable-variable.js +2 -0
- package/dist/modules/source-control.ee/types/exportable-workflow.d.ts +14 -0
- package/dist/modules/source-control.ee/types/exportable-workflow.js +2 -0
- package/dist/modules/source-control.ee/types/import-result.d.ts +20 -0
- package/dist/modules/source-control.ee/types/import-result.js +2 -0
- package/dist/modules/source-control.ee/types/key-pair-type.d.ts +1 -0
- package/dist/modules/source-control.ee/types/key-pair-type.js +2 -0
- package/dist/modules/source-control.ee/types/key-pair.d.ts +4 -0
- package/dist/modules/source-control.ee/types/key-pair.js +2 -0
- package/dist/modules/source-control.ee/types/requests.d.ts +21 -0
- package/dist/modules/source-control.ee/types/requests.js +2 -0
- package/dist/modules/source-control.ee/types/resource-owner.d.ts +17 -0
- package/dist/modules/source-control.ee/types/resource-owner.js +2 -0
- package/dist/modules/source-control.ee/types/source-control-commit.d.ts +3 -0
- package/dist/modules/source-control.ee/types/source-control-commit.js +20 -0
- package/dist/modules/source-control.ee/types/source-control-context.d.ts +7 -0
- package/dist/modules/source-control.ee/types/source-control-context.js +16 -0
- package/dist/modules/source-control.ee/types/source-control-disconnect.d.ts +3 -0
- package/dist/modules/source-control.ee/types/source-control-disconnect.js +21 -0
- package/dist/modules/source-control.ee/types/source-control-generate-key-pair.d.ts +4 -0
- package/dist/modules/source-control.ee/types/source-control-generate-key-pair.js +21 -0
- package/dist/modules/source-control.ee/types/source-control-get-status.d.ts +10 -0
- package/dist/modules/source-control.ee/types/source-control-get-status.js +42 -0
- package/dist/modules/source-control.ee/types/source-control-preferences.d.ts +17 -0
- package/dist/modules/source-control.ee/types/source-control-preferences.js +88 -0
- package/dist/modules/source-control.ee/types/source-control-push.d.ts +3 -0
- package/dist/modules/source-control.ee/types/source-control-push.js +21 -0
- package/dist/modules/source-control.ee/types/source-control-set-branch.d.ts +3 -0
- package/dist/modules/source-control.ee/types/source-control-set-branch.js +20 -0
- package/dist/modules/source-control.ee/types/source-control-set-read-only.d.ts +3 -0
- package/dist/modules/source-control.ee/types/source-control-set-read-only.js +20 -0
- package/dist/modules/source-control.ee/types/source-control-stage.d.ts +5 -0
- package/dist/modules/source-control.ee/types/source-control-stage.js +31 -0
- package/dist/modules/source-control.ee/types/source-control-workflow-version-id.d.ts +12 -0
- package/dist/modules/source-control.ee/types/source-control-workflow-version-id.js +2 -0
- package/dist/modules/sso-oidc/constants.d.ts +3 -0
- package/dist/modules/sso-oidc/constants.js +6 -0
- package/dist/modules/sso-oidc/oidc.controller.ee.d.ts +23 -0
- package/dist/modules/sso-oidc/oidc.controller.ee.js +123 -0
- package/dist/modules/sso-oidc/oidc.service.ee.d.ts +56 -0
- package/dist/modules/sso-oidc/oidc.service.ee.js +468 -0
- package/dist/modules/sso-oidc/sso-oidc.module.d.ts +4 -0
- package/dist/modules/sso-oidc/sso-oidc.module.js +55 -0
- package/dist/modules/sso-saml/constants.d.ts +3 -0
- package/dist/modules/sso-saml/constants.js +6 -0
- package/dist/modules/sso-saml/errors/invalid-saml-metadata-url.error.d.ts +4 -0
- package/dist/modules/sso-saml/errors/invalid-saml-metadata-url.error.js +10 -0
- package/dist/modules/sso-saml/errors/invalid-saml-metadata.error.d.ts +4 -0
- package/dist/modules/sso-saml/errors/invalid-saml-metadata.error.js +10 -0
- package/dist/modules/sso-saml/middleware/saml-enabled-middleware.d.ts +3 -0
- package/dist/modules/sso-saml/middleware/saml-enabled-middleware.js +22 -0
- package/dist/modules/sso-saml/saml-helpers.d.ts +19 -0
- package/dist/modules/sso-saml/saml-helpers.js +129 -0
- package/dist/modules/sso-saml/saml-validator.d.ts +16 -0
- package/dist/modules/sso-saml/saml-validator.js +129 -0
- package/dist/modules/sso-saml/saml.controller.ee.d.ts +50 -0
- package/dist/modules/sso-saml/saml.controller.ee.js +227 -0
- package/dist/modules/sso-saml/saml.service.ee.d.ts +52 -0
- package/dist/modules/sso-saml/saml.service.ee.js +462 -0
- package/dist/modules/sso-saml/schema/metadata-exchange.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/metadata-exchange.xsd.js +118 -0
- package/dist/modules/sso-saml/schema/oasis-200401-wss-wssecurity-secext-1.0.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/oasis-200401-wss-wssecurity-secext-1.0.xsd.js +201 -0
- package/dist/modules/sso-saml/schema/oasis-200401-wss-wssecurity-utility-1.0.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/oasis-200401-wss-wssecurity-utility-1.0.xsd.js +114 -0
- package/dist/modules/sso-saml/schema/saml-schema-assertion-2.0.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/saml-schema-assertion-2.0.xsd.js +289 -0
- package/dist/modules/sso-saml/schema/saml-schema-metadata-2.0.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/saml-schema-metadata-2.0.xsd.js +344 -0
- package/dist/modules/sso-saml/schema/saml-schema-protocol-2.0.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/saml-schema-protocol-2.0.xsd.js +308 -0
- package/dist/modules/sso-saml/schema/ws-addr.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/ws-addr.xsd.js +143 -0
- package/dist/modules/sso-saml/schema/ws-authorization.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/ws-authorization.xsd.js +151 -0
- package/dist/modules/sso-saml/schema/ws-federation.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/ws-federation.xsd.js +476 -0
- package/dist/modules/sso-saml/schema/ws-securitypolicy-1.2.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/ws-securitypolicy-1.2.xsd.js +1211 -0
- package/dist/modules/sso-saml/schema/xenc-schema.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/xenc-schema.xsd.js +151 -0
- package/dist/modules/sso-saml/schema/xml.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/xml.xsd.js +123 -0
- package/dist/modules/sso-saml/schema/xmldsig-core-schema.xsd.d.ts +2 -0
- package/dist/modules/sso-saml/schema/xmldsig-core-schema.xsd.js +324 -0
- package/dist/modules/sso-saml/service-provider.ee.d.ts +6 -0
- package/dist/modules/sso-saml/service-provider.ee.js +44 -0
- package/dist/modules/sso-saml/sso-saml.module.d.ts +4 -0
- package/dist/modules/sso-saml/sso-saml.module.js +55 -0
- package/dist/modules/sso-saml/types.d.ts +4 -0
- package/dist/modules/sso-saml/types.js +2 -0
- package/dist/modules/sso-saml/views/init-sso-post.d.ts +2 -0
- package/dist/modules/sso-saml/views/init-sso-post.js +16 -0
- package/dist/node-lib.d.ts +10 -0
- package/dist/node-lib.js +137 -0
- package/dist/push/index.d.ts +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/dist/services/cors-service.d.ts +7 -0
- package/dist/services/cors-service.js +50 -0
- package/dist/services/static-auth-service.d.ts +4 -0
- package/dist/services/static-auth-service.js +29 -0
- package/dist/sso.ee/saml/schema/metadata-exchange.xsd.js +0 -0
- package/dist/task-runners/task-broker/errors/task-runner-accept-timeout.error.js +0 -0
- package/dist/typecheck.tsbuildinfo +1 -0
- package/dist/user-management/email/templates/workflow-failure.handlebars +211 -0
- package/dist/utils/cors.util.d.ts +2 -0
- package/dist/utils/cors.util.js +17 -0
- package/dist/webhooks/waiting-forms.js +3 -3
- package/dist/webhooks/waiting-webhooks.js +2 -0
- package/dist/workflows/workflow.service.d.ts +2 -2
- package/dist/workflows/workflows.controller.d.ts +6 -6
- package/package.json +22 -21
|
@@ -129,20 +129,20 @@ export declare const workflowDetailsOutputSchema: z.ZodObject<{
|
|
|
129
129
|
triggerInfo: z.ZodString;
|
|
130
130
|
}, "strip", z.ZodTypeAny, {
|
|
131
131
|
workflow: {
|
|
132
|
+
name: string | null;
|
|
133
|
+
nodes: z.objectOutputType<{
|
|
134
|
+
name: z.ZodString;
|
|
135
|
+
type: z.ZodString;
|
|
136
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
132
137
|
tags: z.objectOutputType<{
|
|
133
138
|
id: z.ZodString;
|
|
134
139
|
name: z.ZodString;
|
|
135
140
|
}, z.ZodTypeAny, "passthrough">[];
|
|
136
141
|
id: string;
|
|
137
|
-
name: string | null;
|
|
138
142
|
active: boolean;
|
|
139
143
|
versionId: string;
|
|
140
144
|
createdAt: string | null;
|
|
141
145
|
updatedAt: string | null;
|
|
142
|
-
nodes: z.objectOutputType<{
|
|
143
|
-
name: z.ZodString;
|
|
144
|
-
type: z.ZodString;
|
|
145
|
-
}, z.ZodTypeAny, "passthrough">[];
|
|
146
146
|
connections: Record<string, unknown>;
|
|
147
147
|
isArchived: boolean;
|
|
148
148
|
parentFolderId: string | null;
|
|
@@ -156,20 +156,20 @@ export declare const workflowDetailsOutputSchema: z.ZodObject<{
|
|
|
156
156
|
triggerInfo: string;
|
|
157
157
|
}, {
|
|
158
158
|
workflow: {
|
|
159
|
+
name: string | null;
|
|
160
|
+
nodes: z.objectInputType<{
|
|
161
|
+
name: z.ZodString;
|
|
162
|
+
type: z.ZodString;
|
|
163
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
159
164
|
tags: z.objectInputType<{
|
|
160
165
|
id: z.ZodString;
|
|
161
166
|
name: z.ZodString;
|
|
162
167
|
}, z.ZodTypeAny, "passthrough">[];
|
|
163
168
|
id: string;
|
|
164
|
-
name: string | null;
|
|
165
169
|
active: boolean;
|
|
166
170
|
versionId: string;
|
|
167
171
|
createdAt: string | null;
|
|
168
172
|
updatedAt: string | null;
|
|
169
|
-
nodes: z.objectInputType<{
|
|
170
|
-
name: z.ZodString;
|
|
171
|
-
type: z.ZodString;
|
|
172
|
-
}, z.ZodTypeAny, "passthrough">[];
|
|
173
173
|
connections: Record<string, unknown>;
|
|
174
174
|
isArchived: boolean;
|
|
175
175
|
parentFolderId: string | null;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const SOURCE_CONTROL_PREFERENCES_DB_KEY = "features.sourceControl";
|
|
2
|
+
export declare const SOURCE_CONTROL_GIT_FOLDER = "git";
|
|
3
|
+
export declare const SOURCE_CONTROL_GIT_KEY_COMMENT = "n8n deploy key";
|
|
4
|
+
export declare const SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER = "workflows";
|
|
5
|
+
export declare const SOURCE_CONTROL_PROJECT_EXPORT_FOLDER = "projects";
|
|
6
|
+
export declare const SOURCE_CONTROL_CREDENTIAL_EXPORT_FOLDER = "credential_stubs";
|
|
7
|
+
export declare const SOURCE_CONTROL_VARIABLES_EXPORT_FILE = "variable_stubs.json";
|
|
8
|
+
export declare const SOURCE_CONTROL_TAGS_EXPORT_FILE = "tags.json";
|
|
9
|
+
export declare const SOURCE_CONTROL_FOLDERS_EXPORT_FILE = "folders.json";
|
|
10
|
+
export declare const SOURCE_CONTROL_OWNERS_EXPORT_FILE = "workflow_owners.json";
|
|
11
|
+
export declare const SOURCE_CONTROL_SSH_FOLDER = "ssh";
|
|
12
|
+
export declare const SOURCE_CONTROL_SSH_KEY_NAME = "key";
|
|
13
|
+
export declare const SOURCE_CONTROL_DEFAULT_BRANCH = "main";
|
|
14
|
+
export declare const SOURCE_CONTROL_ORIGIN = "origin";
|
|
15
|
+
export declare const SOURCE_CONTROL_README = "\n# n8n Source Control\n";
|
|
16
|
+
export declare const SOURCE_CONTROL_DEFAULT_NAME = "n8n user";
|
|
17
|
+
export declare const SOURCE_CONTROL_DEFAULT_EMAIL = "n8n@example.com";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SOURCE_CONTROL_DEFAULT_EMAIL = exports.SOURCE_CONTROL_DEFAULT_NAME = exports.SOURCE_CONTROL_README = exports.SOURCE_CONTROL_ORIGIN = exports.SOURCE_CONTROL_DEFAULT_BRANCH = exports.SOURCE_CONTROL_SSH_KEY_NAME = exports.SOURCE_CONTROL_SSH_FOLDER = exports.SOURCE_CONTROL_OWNERS_EXPORT_FILE = exports.SOURCE_CONTROL_FOLDERS_EXPORT_FILE = exports.SOURCE_CONTROL_TAGS_EXPORT_FILE = exports.SOURCE_CONTROL_VARIABLES_EXPORT_FILE = exports.SOURCE_CONTROL_CREDENTIAL_EXPORT_FOLDER = exports.SOURCE_CONTROL_PROJECT_EXPORT_FOLDER = exports.SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER = exports.SOURCE_CONTROL_GIT_KEY_COMMENT = exports.SOURCE_CONTROL_GIT_FOLDER = exports.SOURCE_CONTROL_PREFERENCES_DB_KEY = void 0;
|
|
4
|
+
exports.SOURCE_CONTROL_PREFERENCES_DB_KEY = 'features.sourceControl';
|
|
5
|
+
exports.SOURCE_CONTROL_GIT_FOLDER = 'git';
|
|
6
|
+
exports.SOURCE_CONTROL_GIT_KEY_COMMENT = 'n8n deploy key';
|
|
7
|
+
exports.SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER = 'workflows';
|
|
8
|
+
exports.SOURCE_CONTROL_PROJECT_EXPORT_FOLDER = 'projects';
|
|
9
|
+
exports.SOURCE_CONTROL_CREDENTIAL_EXPORT_FOLDER = 'credential_stubs';
|
|
10
|
+
exports.SOURCE_CONTROL_VARIABLES_EXPORT_FILE = 'variable_stubs.json';
|
|
11
|
+
exports.SOURCE_CONTROL_TAGS_EXPORT_FILE = 'tags.json';
|
|
12
|
+
exports.SOURCE_CONTROL_FOLDERS_EXPORT_FILE = 'folders.json';
|
|
13
|
+
exports.SOURCE_CONTROL_OWNERS_EXPORT_FILE = 'workflow_owners.json';
|
|
14
|
+
exports.SOURCE_CONTROL_SSH_FOLDER = 'ssh';
|
|
15
|
+
exports.SOURCE_CONTROL_SSH_KEY_NAME = 'key';
|
|
16
|
+
exports.SOURCE_CONTROL_DEFAULT_BRANCH = 'main';
|
|
17
|
+
exports.SOURCE_CONTROL_ORIGIN = 'origin';
|
|
18
|
+
exports.SOURCE_CONTROL_README = `
|
|
19
|
+
# n8n Source Control
|
|
20
|
+
`;
|
|
21
|
+
exports.SOURCE_CONTROL_DEFAULT_NAME = 'n8n user';
|
|
22
|
+
exports.SOURCE_CONTROL_DEFAULT_EMAIL = 'n8n@example.com';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sourceControlEnabledMiddleware = void 0;
|
|
4
|
+
const di_1 = require("@n8n/di");
|
|
5
|
+
const source_control_preferences_service_ee_1 = require("../source-control-preferences.service.ee");
|
|
6
|
+
const sourceControlEnabledMiddleware = (_req, res, next) => {
|
|
7
|
+
const sourceControlPreferencesService = di_1.Container.get(source_control_preferences_service_ee_1.SourceControlPreferencesService);
|
|
8
|
+
if (sourceControlPreferencesService.isSourceControlConnected()) {
|
|
9
|
+
next();
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
res.status(412).json({
|
|
13
|
+
status: 'error',
|
|
14
|
+
message: 'source_control_not_connected',
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
exports.sourceControlEnabledMiddleware = sourceControlEnabledMiddleware;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { SourceControlledFile } from '@n8n/api-types';
|
|
2
|
+
import { Logger } from '@n8n/backend-common';
|
|
3
|
+
import { FolderRepository, ProjectRepository, SharedCredentialsRepository, SharedWorkflowRepository, TagRepository, WorkflowRepository, WorkflowTagMappingRepository } from '@n8n/db';
|
|
4
|
+
import { InstanceSettings } from 'n8n-core';
|
|
5
|
+
import { SourceControlScopedService } from './source-control-scoped.service';
|
|
6
|
+
import { VariablesService } from '../../environments.ee/variables/variables.service.ee';
|
|
7
|
+
import type { ExportResult } from './types/export-result';
|
|
8
|
+
import type { SourceControlContext } from './types/source-control-context';
|
|
9
|
+
export declare class SourceControlExportService {
|
|
10
|
+
private readonly logger;
|
|
11
|
+
private readonly variablesService;
|
|
12
|
+
private readonly tagRepository;
|
|
13
|
+
private readonly projectRepository;
|
|
14
|
+
private readonly sharedCredentialsRepository;
|
|
15
|
+
private readonly sharedWorkflowRepository;
|
|
16
|
+
private readonly workflowRepository;
|
|
17
|
+
private readonly workflowTagMappingRepository;
|
|
18
|
+
private readonly folderRepository;
|
|
19
|
+
private readonly sourceControlScopedService;
|
|
20
|
+
private gitFolder;
|
|
21
|
+
private workflowExportFolder;
|
|
22
|
+
private projectExportFolder;
|
|
23
|
+
private credentialExportFolder;
|
|
24
|
+
constructor(logger: Logger, variablesService: VariablesService, tagRepository: TagRepository, projectRepository: ProjectRepository, sharedCredentialsRepository: SharedCredentialsRepository, sharedWorkflowRepository: SharedWorkflowRepository, workflowRepository: WorkflowRepository, workflowTagMappingRepository: WorkflowTagMappingRepository, folderRepository: FolderRepository, sourceControlScopedService: SourceControlScopedService, instanceSettings: InstanceSettings);
|
|
25
|
+
getWorkflowPath(workflowId: string): string;
|
|
26
|
+
getCredentialsPath(credentialsId: string): string;
|
|
27
|
+
deleteRepositoryFolder(): Promise<void>;
|
|
28
|
+
rmFilesFromExportFolder(filesToBeDeleted: Set<string>): Set<string>;
|
|
29
|
+
private writeExportableWorkflowsToExportFolder;
|
|
30
|
+
exportWorkflowsToWorkFolder(candidates: SourceControlledFile[]): Promise<ExportResult>;
|
|
31
|
+
exportGlobalVariablesToWorkFolder(): Promise<ExportResult>;
|
|
32
|
+
exportFoldersToWorkFolder(context: SourceControlContext): Promise<ExportResult>;
|
|
33
|
+
exportTagsToWorkFolder(context: SourceControlContext): Promise<ExportResult>;
|
|
34
|
+
private replaceCredentialData;
|
|
35
|
+
exportCredentialsToWorkFolder(candidates: SourceControlledFile[]): Promise<ExportResult>;
|
|
36
|
+
exportTeamProjectsToWorkFolder(candidates: SourceControlledFile[]): Promise<ExportResult>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SourceControlExportService = void 0;
|
|
16
|
+
const backend_common_1 = require("@n8n/backend-common");
|
|
17
|
+
const db_1 = require("@n8n/db");
|
|
18
|
+
const di_1 = require("@n8n/di");
|
|
19
|
+
const permissions_1 = require("@n8n/permissions");
|
|
20
|
+
const typeorm_1 = require("@n8n/typeorm");
|
|
21
|
+
const fs_1 = require("fs");
|
|
22
|
+
const n8n_core_1 = require("n8n-core");
|
|
23
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
24
|
+
const promises_1 = require("node:fs/promises");
|
|
25
|
+
const path_1 = __importDefault(require("path"));
|
|
26
|
+
const workflow_formatter_1 = require("../../workflows/workflow.formatter");
|
|
27
|
+
const constants_1 = require("./constants");
|
|
28
|
+
const source_control_helper_ee_1 = require("./source-control-helper.ee");
|
|
29
|
+
const source_control_scoped_service_1 = require("./source-control-scoped.service");
|
|
30
|
+
const variables_service_ee_1 = require("../../environments.ee/variables/variables.service.ee");
|
|
31
|
+
let SourceControlExportService = class SourceControlExportService {
|
|
32
|
+
constructor(logger, variablesService, tagRepository, projectRepository, sharedCredentialsRepository, sharedWorkflowRepository, workflowRepository, workflowTagMappingRepository, folderRepository, sourceControlScopedService, instanceSettings) {
|
|
33
|
+
this.logger = logger;
|
|
34
|
+
this.variablesService = variablesService;
|
|
35
|
+
this.tagRepository = tagRepository;
|
|
36
|
+
this.projectRepository = projectRepository;
|
|
37
|
+
this.sharedCredentialsRepository = sharedCredentialsRepository;
|
|
38
|
+
this.sharedWorkflowRepository = sharedWorkflowRepository;
|
|
39
|
+
this.workflowRepository = workflowRepository;
|
|
40
|
+
this.workflowTagMappingRepository = workflowTagMappingRepository;
|
|
41
|
+
this.folderRepository = folderRepository;
|
|
42
|
+
this.sourceControlScopedService = sourceControlScopedService;
|
|
43
|
+
this.replaceCredentialData = (data) => {
|
|
44
|
+
for (const [key] of Object.entries(data)) {
|
|
45
|
+
const value = data[key];
|
|
46
|
+
try {
|
|
47
|
+
if (value === null) {
|
|
48
|
+
delete data[key];
|
|
49
|
+
}
|
|
50
|
+
else if (typeof value === 'object') {
|
|
51
|
+
data[key] = this.replaceCredentialData(value);
|
|
52
|
+
}
|
|
53
|
+
else if (typeof value === 'string') {
|
|
54
|
+
data[key] = (0, source_control_helper_ee_1.stringContainsExpression)(value) ? data[key] : '';
|
|
55
|
+
}
|
|
56
|
+
else if (typeof data[key] === 'number') {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this.logger.error(`Failed to sanitize credential data: ${error.message}`);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return data;
|
|
66
|
+
};
|
|
67
|
+
this.gitFolder = path_1.default.join(instanceSettings.n8nFolder, constants_1.SOURCE_CONTROL_GIT_FOLDER);
|
|
68
|
+
this.workflowExportFolder = path_1.default.join(this.gitFolder, constants_1.SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER);
|
|
69
|
+
this.projectExportFolder = path_1.default.join(this.gitFolder, constants_1.SOURCE_CONTROL_PROJECT_EXPORT_FOLDER);
|
|
70
|
+
this.credentialExportFolder = path_1.default.join(this.gitFolder, constants_1.SOURCE_CONTROL_CREDENTIAL_EXPORT_FOLDER);
|
|
71
|
+
}
|
|
72
|
+
getWorkflowPath(workflowId) {
|
|
73
|
+
return (0, source_control_helper_ee_1.getWorkflowExportPath)(workflowId, this.workflowExportFolder);
|
|
74
|
+
}
|
|
75
|
+
getCredentialsPath(credentialsId) {
|
|
76
|
+
return (0, source_control_helper_ee_1.getCredentialExportPath)(credentialsId, this.credentialExportFolder);
|
|
77
|
+
}
|
|
78
|
+
async deleteRepositoryFolder() {
|
|
79
|
+
try {
|
|
80
|
+
await (0, promises_1.rm)(this.gitFolder, { recursive: true });
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
this.logger.error(`Failed to delete work folder: ${error.message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
rmFilesFromExportFolder(filesToBeDeleted) {
|
|
87
|
+
try {
|
|
88
|
+
filesToBeDeleted.forEach((e) => (0, fs_1.rmSync)(e));
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
this.logger.error(`Failed to delete workflows from work folder: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
return filesToBeDeleted;
|
|
94
|
+
}
|
|
95
|
+
async writeExportableWorkflowsToExportFolder(workflowsToBeExported, owners) {
|
|
96
|
+
await Promise.all(workflowsToBeExported.map(async (e) => {
|
|
97
|
+
const fileName = this.getWorkflowPath(e.id);
|
|
98
|
+
const sanitizedWorkflow = {
|
|
99
|
+
id: e.id,
|
|
100
|
+
name: e.name,
|
|
101
|
+
nodes: e.nodes,
|
|
102
|
+
connections: e.connections,
|
|
103
|
+
settings: e.settings,
|
|
104
|
+
triggerCount: e.triggerCount,
|
|
105
|
+
versionId: e.versionId,
|
|
106
|
+
owner: owners[e.id],
|
|
107
|
+
parentFolderId: e.parentFolder?.id ?? null,
|
|
108
|
+
isArchived: e.isArchived,
|
|
109
|
+
};
|
|
110
|
+
this.logger.debug(`Writing workflow ${e.id} to ${fileName}`);
|
|
111
|
+
return await (0, promises_1.writeFile)(fileName, JSON.stringify(sanitizedWorkflow, null, 2));
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
async exportWorkflowsToWorkFolder(candidates) {
|
|
115
|
+
try {
|
|
116
|
+
(0, source_control_helper_ee_1.sourceControlFoldersExistCheck)([this.workflowExportFolder]);
|
|
117
|
+
const workflowIds = candidates.map((e) => e.id);
|
|
118
|
+
const sharedWorkflows = await this.sharedWorkflowRepository.findByWorkflowIds(workflowIds);
|
|
119
|
+
const workflows = await this.workflowRepository.find({
|
|
120
|
+
where: { id: (0, typeorm_1.In)(workflowIds) },
|
|
121
|
+
relations: ['parentFolder'],
|
|
122
|
+
});
|
|
123
|
+
const owners = {};
|
|
124
|
+
sharedWorkflows.forEach((sharedWorkflow) => {
|
|
125
|
+
const project = sharedWorkflow.project;
|
|
126
|
+
if (!project) {
|
|
127
|
+
throw new n8n_workflow_1.UnexpectedError(`Workflow ${(0, workflow_formatter_1.formatWorkflow)(sharedWorkflow.workflow)} has no owner`);
|
|
128
|
+
}
|
|
129
|
+
if (project.type === 'personal') {
|
|
130
|
+
const ownerRelation = project.projectRelations.find((pr) => pr.role.slug === permissions_1.PROJECT_OWNER_ROLE_SLUG);
|
|
131
|
+
if (!ownerRelation) {
|
|
132
|
+
throw new n8n_workflow_1.UnexpectedError(`Workflow ${(0, workflow_formatter_1.formatWorkflow)(sharedWorkflow.workflow)} has no owner`);
|
|
133
|
+
}
|
|
134
|
+
owners[sharedWorkflow.workflowId] = {
|
|
135
|
+
type: 'personal',
|
|
136
|
+
projectId: project.id,
|
|
137
|
+
projectName: project.name,
|
|
138
|
+
personalEmail: ownerRelation.user.email,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
else if (project.type === 'team') {
|
|
142
|
+
owners[sharedWorkflow.workflowId] = {
|
|
143
|
+
type: 'team',
|
|
144
|
+
teamId: project.id,
|
|
145
|
+
teamName: project.name,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
throw new n8n_workflow_1.UnexpectedError(`Workflow belongs to unknown project type: ${project.type}`);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
await this.writeExportableWorkflowsToExportFolder(workflows, owners);
|
|
153
|
+
return {
|
|
154
|
+
count: sharedWorkflows.length,
|
|
155
|
+
folder: this.workflowExportFolder,
|
|
156
|
+
files: workflows.map((e) => ({
|
|
157
|
+
id: e?.id,
|
|
158
|
+
name: this.getWorkflowPath(e?.name),
|
|
159
|
+
})),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (error instanceof n8n_workflow_1.UnexpectedError)
|
|
164
|
+
throw error;
|
|
165
|
+
throw new n8n_workflow_1.UnexpectedError('Failed to export workflows to work folder', { cause: error });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async exportGlobalVariablesToWorkFolder() {
|
|
169
|
+
try {
|
|
170
|
+
(0, source_control_helper_ee_1.sourceControlFoldersExistCheck)([this.gitFolder]);
|
|
171
|
+
const variables = await this.variablesService.getAllCached({ globalOnly: true });
|
|
172
|
+
if (variables.length === 0) {
|
|
173
|
+
return {
|
|
174
|
+
count: 0,
|
|
175
|
+
folder: this.gitFolder,
|
|
176
|
+
files: [],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const fileName = (0, source_control_helper_ee_1.getVariablesPath)(this.gitFolder);
|
|
180
|
+
const sanitizedVariables = variables.map((e) => ({
|
|
181
|
+
id: e.id,
|
|
182
|
+
key: e.key,
|
|
183
|
+
type: e.type,
|
|
184
|
+
value: '',
|
|
185
|
+
}));
|
|
186
|
+
await (0, promises_1.writeFile)(fileName, JSON.stringify(sanitizedVariables, null, 2));
|
|
187
|
+
return {
|
|
188
|
+
count: sanitizedVariables.length,
|
|
189
|
+
folder: this.gitFolder,
|
|
190
|
+
files: [
|
|
191
|
+
{
|
|
192
|
+
id: '',
|
|
193
|
+
name: fileName,
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
this.logger.error('Failed to export variables to work folder', { error });
|
|
200
|
+
throw new n8n_workflow_1.UnexpectedError('Failed to export variables to work folder', {
|
|
201
|
+
cause: error,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async exportFoldersToWorkFolder(context) {
|
|
206
|
+
try {
|
|
207
|
+
(0, source_control_helper_ee_1.sourceControlFoldersExistCheck)([this.gitFolder]);
|
|
208
|
+
const folders = await this.folderRepository.find({
|
|
209
|
+
relations: ['parentFolder', 'homeProject'],
|
|
210
|
+
select: {
|
|
211
|
+
id: true,
|
|
212
|
+
name: true,
|
|
213
|
+
createdAt: true,
|
|
214
|
+
updatedAt: true,
|
|
215
|
+
parentFolder: {
|
|
216
|
+
id: true,
|
|
217
|
+
},
|
|
218
|
+
homeProject: {
|
|
219
|
+
id: true,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
where: this.sourceControlScopedService.getFoldersInAdminProjectsFromContextFilter(context),
|
|
223
|
+
});
|
|
224
|
+
if (folders.length === 0) {
|
|
225
|
+
return {
|
|
226
|
+
count: 0,
|
|
227
|
+
folder: this.gitFolder,
|
|
228
|
+
files: [],
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
const allowedProjects = await this.sourceControlScopedService.getAuthorizedProjectsFromContext(context);
|
|
232
|
+
const fileName = (0, source_control_helper_ee_1.getFoldersPath)(this.gitFolder);
|
|
233
|
+
const existingFolders = await (0, source_control_helper_ee_1.readFoldersFromSourceControlFile)(fileName);
|
|
234
|
+
const foldersToKeepUnchanged = context.hasAccessToAllProjects()
|
|
235
|
+
? []
|
|
236
|
+
: existingFolders.folders.filter((folder) => {
|
|
237
|
+
return !allowedProjects.some((project) => project.id === folder.homeProjectId);
|
|
238
|
+
});
|
|
239
|
+
const newFolders = foldersToKeepUnchanged.concat(...folders.map((f) => ({
|
|
240
|
+
id: f.id,
|
|
241
|
+
name: f.name,
|
|
242
|
+
parentFolderId: f.parentFolder?.id ?? null,
|
|
243
|
+
homeProjectId: f.homeProject.id,
|
|
244
|
+
createdAt: f.createdAt.toISOString(),
|
|
245
|
+
updatedAt: f.updatedAt.toISOString(),
|
|
246
|
+
})));
|
|
247
|
+
await (0, promises_1.writeFile)(fileName, JSON.stringify({
|
|
248
|
+
folders: newFolders,
|
|
249
|
+
}, null, 2));
|
|
250
|
+
return {
|
|
251
|
+
count: folders.length,
|
|
252
|
+
folder: this.gitFolder,
|
|
253
|
+
files: [
|
|
254
|
+
{
|
|
255
|
+
id: '',
|
|
256
|
+
name: fileName,
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
this.logger.error('Failed to export folders to work folder', { error });
|
|
263
|
+
throw new n8n_workflow_1.UnexpectedError('Failed to export folders to work folder', { cause: error });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async exportTagsToWorkFolder(context) {
|
|
267
|
+
try {
|
|
268
|
+
const fileName = path_1.default.join(this.gitFolder, constants_1.SOURCE_CONTROL_TAGS_EXPORT_FILE);
|
|
269
|
+
(0, source_control_helper_ee_1.sourceControlFoldersExistCheck)([this.gitFolder]);
|
|
270
|
+
const tags = await this.tagRepository.find();
|
|
271
|
+
if (tags.length === 0) {
|
|
272
|
+
await (0, promises_1.writeFile)(fileName, JSON.stringify({ tags: [], mappings: [] }, null, 2));
|
|
273
|
+
return {
|
|
274
|
+
count: 0,
|
|
275
|
+
folder: this.gitFolder,
|
|
276
|
+
files: [{ id: '', name: fileName }],
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const mappingsOfAllowedWorkflows = await this.workflowTagMappingRepository.find({
|
|
280
|
+
where: this.sourceControlScopedService.getWorkflowTagMappingInAdminProjectsFromContextFilter(context),
|
|
281
|
+
});
|
|
282
|
+
const allowedWorkflows = await this.workflowRepository.find({
|
|
283
|
+
where: this.sourceControlScopedService.getWorkflowsInAdminProjectsFromContextFilter(context),
|
|
284
|
+
});
|
|
285
|
+
const existingTagsAndMapping = await (0, source_control_helper_ee_1.readTagAndMappingsFromSourceControlFile)(fileName);
|
|
286
|
+
const mappingsToKeep = existingTagsAndMapping.mappings.filter((mapping) => {
|
|
287
|
+
return !allowedWorkflows.some((allowedWorkflow) => allowedWorkflow.id === mapping.workflowId);
|
|
288
|
+
});
|
|
289
|
+
await (0, promises_1.writeFile)(fileName, JSON.stringify({
|
|
290
|
+
tags: tags.map((tag) => ({ id: tag.id, name: tag.name })),
|
|
291
|
+
mappings: mappingsToKeep.concat(mappingsOfAllowedWorkflows),
|
|
292
|
+
}, null, 2));
|
|
293
|
+
return {
|
|
294
|
+
count: tags.length,
|
|
295
|
+
folder: this.gitFolder,
|
|
296
|
+
files: [{ id: '', name: fileName }],
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
this.logger.error('Failed to export tags to work folder', { error });
|
|
301
|
+
throw new n8n_workflow_1.UnexpectedError('Failed to export tags to work folder', { cause: error });
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
async exportCredentialsToWorkFolder(candidates) {
|
|
305
|
+
try {
|
|
306
|
+
(0, source_control_helper_ee_1.sourceControlFoldersExistCheck)([this.credentialExportFolder]);
|
|
307
|
+
const credentialIds = candidates.map((e) => e.id);
|
|
308
|
+
const credentialsToBeExported = await this.sharedCredentialsRepository.findByCredentialIds(credentialIds, 'credential:owner');
|
|
309
|
+
let missingIds = [];
|
|
310
|
+
if (credentialsToBeExported.length !== credentialIds.length) {
|
|
311
|
+
const foundCredentialIds = credentialsToBeExported.map((e) => e.credentialsId);
|
|
312
|
+
missingIds = credentialIds.filter((remote) => foundCredentialIds.findIndex((local) => local === remote) === -1);
|
|
313
|
+
}
|
|
314
|
+
await Promise.all(credentialsToBeExported.map(async (sharing) => {
|
|
315
|
+
const { name, type, data, id, isGlobal = false } = sharing.credentials;
|
|
316
|
+
const credentials = new n8n_core_1.Credentials({ id, name }, type, data);
|
|
317
|
+
let owner = null;
|
|
318
|
+
if (sharing.project.type === 'personal') {
|
|
319
|
+
const ownerRelation = sharing.project.projectRelations.find((pr) => pr.role.slug === permissions_1.PROJECT_OWNER_ROLE_SLUG);
|
|
320
|
+
if (ownerRelation) {
|
|
321
|
+
owner = {
|
|
322
|
+
type: 'personal',
|
|
323
|
+
projectId: sharing.project.id,
|
|
324
|
+
projectName: sharing.project.name,
|
|
325
|
+
personalEmail: ownerRelation.user.email,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else if (sharing.project.type === 'team') {
|
|
330
|
+
owner = {
|
|
331
|
+
type: 'team',
|
|
332
|
+
teamId: sharing.project.id,
|
|
333
|
+
teamName: sharing.project.name,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
const credentialData = credentials.getData();
|
|
337
|
+
const { oauthTokenData, ...rest } = credentialData;
|
|
338
|
+
const stub = {
|
|
339
|
+
id,
|
|
340
|
+
name,
|
|
341
|
+
type,
|
|
342
|
+
data: this.replaceCredentialData(rest),
|
|
343
|
+
ownedBy: owner,
|
|
344
|
+
isGlobal,
|
|
345
|
+
};
|
|
346
|
+
const filePath = this.getCredentialsPath(id);
|
|
347
|
+
this.logger.debug(`Writing credentials stub "${name}" (ID ${id}) to: ${filePath}`);
|
|
348
|
+
return await (0, promises_1.writeFile)(filePath, JSON.stringify(stub, null, 2));
|
|
349
|
+
}));
|
|
350
|
+
return {
|
|
351
|
+
count: credentialsToBeExported.length,
|
|
352
|
+
folder: this.credentialExportFolder,
|
|
353
|
+
files: credentialsToBeExported.map((e) => ({
|
|
354
|
+
id: e.credentials.id,
|
|
355
|
+
name: path_1.default.join(this.credentialExportFolder, `${e.credentials.name}.json`),
|
|
356
|
+
})),
|
|
357
|
+
missingIds,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
this.logger.error('Failed to export credentials to work folder', { error });
|
|
362
|
+
throw new n8n_workflow_1.UnexpectedError('Failed to export credentials to work folder', { cause: error });
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
async exportTeamProjectsToWorkFolder(candidates) {
|
|
366
|
+
try {
|
|
367
|
+
(0, source_control_helper_ee_1.sourceControlFoldersExistCheck)([this.projectExportFolder], true);
|
|
368
|
+
const projectIds = candidates.map((e) => e.id);
|
|
369
|
+
const projects = await this.projectRepository.find({
|
|
370
|
+
where: { id: (0, typeorm_1.In)(projectIds), type: 'team' },
|
|
371
|
+
relations: ['variables'],
|
|
372
|
+
});
|
|
373
|
+
await Promise.all(projects.map(async (project) => {
|
|
374
|
+
const fileName = (0, source_control_helper_ee_1.getProjectExportPath)(project.id, this.projectExportFolder);
|
|
375
|
+
const sanitizedProject = {
|
|
376
|
+
id: project.id,
|
|
377
|
+
name: project.name,
|
|
378
|
+
icon: project.icon,
|
|
379
|
+
description: project.description,
|
|
380
|
+
type: 'team',
|
|
381
|
+
owner: {
|
|
382
|
+
type: 'team',
|
|
383
|
+
teamId: project.id,
|
|
384
|
+
teamName: project.name,
|
|
385
|
+
},
|
|
386
|
+
variableStubs: project.variables.map((variable) => ({
|
|
387
|
+
id: variable.id,
|
|
388
|
+
key: variable.key,
|
|
389
|
+
type: variable.type,
|
|
390
|
+
value: '',
|
|
391
|
+
})),
|
|
392
|
+
};
|
|
393
|
+
this.logger.debug(`Writing project ${project.id} to ${fileName}`);
|
|
394
|
+
return await (0, promises_1.writeFile)(fileName, JSON.stringify(sanitizedProject, null, 2));
|
|
395
|
+
}));
|
|
396
|
+
return {
|
|
397
|
+
count: projects.length,
|
|
398
|
+
folder: this.projectExportFolder,
|
|
399
|
+
files: projects.map((project) => ({
|
|
400
|
+
id: project.id,
|
|
401
|
+
name: (0, source_control_helper_ee_1.getProjectExportPath)(project.id, this.projectExportFolder),
|
|
402
|
+
})),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
if (error instanceof n8n_workflow_1.UnexpectedError)
|
|
407
|
+
throw error;
|
|
408
|
+
throw new n8n_workflow_1.UnexpectedError('Failed to export projects to work folder', { cause: error });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
exports.SourceControlExportService = SourceControlExportService;
|
|
413
|
+
exports.SourceControlExportService = SourceControlExportService = __decorate([
|
|
414
|
+
(0, di_1.Service)(),
|
|
415
|
+
__metadata("design:paramtypes", [backend_common_1.Logger,
|
|
416
|
+
variables_service_ee_1.VariablesService,
|
|
417
|
+
db_1.TagRepository,
|
|
418
|
+
db_1.ProjectRepository,
|
|
419
|
+
db_1.SharedCredentialsRepository,
|
|
420
|
+
db_1.SharedWorkflowRepository,
|
|
421
|
+
db_1.WorkflowRepository,
|
|
422
|
+
db_1.WorkflowTagMappingRepository,
|
|
423
|
+
db_1.FolderRepository,
|
|
424
|
+
source_control_scoped_service_1.SourceControlScopedService,
|
|
425
|
+
n8n_core_1.InstanceSettings])
|
|
426
|
+
], SourceControlExportService);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Logger } from '@n8n/backend-common';
|
|
2
|
+
import type { User } from '@n8n/db';
|
|
3
|
+
import type { CommitResult, DiffResult, FetchResult, PullResult, PushResult, SimpleGit, StatusResult } from 'simple-git';
|
|
4
|
+
import { OwnershipService } from '../../services/ownership.service';
|
|
5
|
+
import { SourceControlPreferencesService } from './source-control-preferences.service.ee';
|
|
6
|
+
import type { SourceControlPreferences } from './types/source-control-preferences';
|
|
7
|
+
export declare class SourceControlGitService {
|
|
8
|
+
private readonly logger;
|
|
9
|
+
private readonly ownershipService;
|
|
10
|
+
private readonly sourceControlPreferencesService;
|
|
11
|
+
git: SimpleGit | null;
|
|
12
|
+
private gitOptions;
|
|
13
|
+
constructor(logger: Logger, ownershipService: OwnershipService, sourceControlPreferencesService: SourceControlPreferencesService);
|
|
14
|
+
private preInitCheck;
|
|
15
|
+
initService(options: {
|
|
16
|
+
sourceControlPreferences: SourceControlPreferences;
|
|
17
|
+
gitFolder: string;
|
|
18
|
+
sshFolder: string;
|
|
19
|
+
sshKeyName: string;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
setGitCommand(gitFolder?: string, sshFolder?: string): Promise<void>;
|
|
22
|
+
resetService(): void;
|
|
23
|
+
private checkRepositorySetup;
|
|
24
|
+
private hasRemote;
|
|
25
|
+
initRepository(sourceControlPreferences: Pick<SourceControlPreferences, 'repositoryUrl' | 'branchName' | 'initRepo' | 'connectionType'>, user: User): Promise<void>;
|
|
26
|
+
private trackRemoteIfReady;
|
|
27
|
+
private ensureBranchSetup;
|
|
28
|
+
setGitUserDetails(name: string, email: string): Promise<void>;
|
|
29
|
+
getBranches(): Promise<{
|
|
30
|
+
branches: string[];
|
|
31
|
+
currentBranch: string;
|
|
32
|
+
}>;
|
|
33
|
+
setBranch(branch: string): Promise<{
|
|
34
|
+
branches: string[];
|
|
35
|
+
currentBranch: string;
|
|
36
|
+
}>;
|
|
37
|
+
getCurrentBranch(): Promise<{
|
|
38
|
+
current: string;
|
|
39
|
+
remote: string;
|
|
40
|
+
}>;
|
|
41
|
+
diffRemote(): Promise<DiffResult | undefined>;
|
|
42
|
+
diffLocal(): Promise<DiffResult | undefined>;
|
|
43
|
+
fetch(): Promise<FetchResult>;
|
|
44
|
+
pull(options?: {
|
|
45
|
+
ffOnly: boolean;
|
|
46
|
+
}): Promise<PullResult>;
|
|
47
|
+
push(options?: {
|
|
48
|
+
force: boolean;
|
|
49
|
+
branch: string;
|
|
50
|
+
}): Promise<PushResult>;
|
|
51
|
+
stage(files: Set<string>, deletedFiles?: Set<string>): Promise<string>;
|
|
52
|
+
resetBranch(options?: {
|
|
53
|
+
hard: boolean;
|
|
54
|
+
target: string;
|
|
55
|
+
}): Promise<string>;
|
|
56
|
+
commit(message: string): Promise<CommitResult>;
|
|
57
|
+
status(): Promise<StatusResult>;
|
|
58
|
+
getFileContent(filePath: string, commit?: string): Promise<string>;
|
|
59
|
+
}
|