@atom8n/n8n-benchmark 2.0.0
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/.turbo/turbo-build.log +4 -0
- package/Dockerfile +63 -0
- package/README.md +122 -0
- package/bin/n8n-benchmark +13 -0
- package/biome.jsonc +7 -0
- package/dist/build.tsbuildinfo +1 -0
- package/dist/commands/list.d.ts +8 -0
- package/dist/commands/list.js +23 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/run.d.ts +24 -0
- package/dist/commands/run.js +128 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/config/common-flags.d.ts +1 -0
- package/dist/config/common-flags.js +9 -0
- package/dist/config/common-flags.js.map +1 -0
- package/dist/n8n-api-client/authenticated-n8n-api-client.d.ts +15 -0
- package/dist/n8n-api-client/authenticated-n8n-api-client.js +67 -0
- package/dist/n8n-api-client/authenticated-n8n-api-client.js.map +1 -0
- package/dist/n8n-api-client/credentials-api-client.d.ts +9 -0
- package/dist/n8n-api-client/credentials-api-client.js +24 -0
- package/dist/n8n-api-client/credentials-api-client.js.map +1 -0
- package/dist/n8n-api-client/data-table-api-client.d.ts +9 -0
- package/dist/n8n-api-client/data-table-api-client.js +23 -0
- package/dist/n8n-api-client/data-table-api-client.js.map +1 -0
- package/dist/n8n-api-client/n8n-api-client.d.ts +13 -0
- package/dist/n8n-api-client/n8n-api-client.js +82 -0
- package/dist/n8n-api-client/n8n-api-client.js.map +1 -0
- package/dist/n8n-api-client/n8n-api-client.types.d.ts +21 -0
- package/dist/n8n-api-client/n8n-api-client.types.js +3 -0
- package/dist/n8n-api-client/n8n-api-client.types.js.map +1 -0
- package/dist/n8n-api-client/project-api-client.d.ts +6 -0
- package/dist/n8n-api-client/project-api-client.js +14 -0
- package/dist/n8n-api-client/project-api-client.js.map +1 -0
- package/dist/n8n-api-client/workflows-api-client.d.ts +11 -0
- package/dist/n8n-api-client/workflows-api-client.js +30 -0
- package/dist/n8n-api-client/workflows-api-client.js.map +1 -0
- package/dist/scenario/scenario-data-loader.d.ts +13 -0
- package/dist/scenario/scenario-data-loader.js +84 -0
- package/dist/scenario/scenario-data-loader.js.map +1 -0
- package/dist/scenario/scenario-loader.d.ts +7 -0
- package/dist/scenario/scenario-loader.js +101 -0
- package/dist/scenario/scenario-loader.js.map +1 -0
- package/dist/test-execution/app-metrics-poller.d.ts +13 -0
- package/dist/test-execution/app-metrics-poller.js +54 -0
- package/dist/test-execution/app-metrics-poller.js.map +1 -0
- package/dist/test-execution/k6-executor.d.ts +33 -0
- package/dist/test-execution/k6-executor.js +120 -0
- package/dist/test-execution/k6-executor.js.map +1 -0
- package/dist/test-execution/k6-summary.d.ts +82 -0
- package/dist/test-execution/k6-summary.js +2 -0
- package/dist/test-execution/k6-summary.js.map +1 -0
- package/dist/test-execution/prometheus-metrics-parser.d.ts +9 -0
- package/dist/test-execution/prometheus-metrics-parser.js +44 -0
- package/dist/test-execution/prometheus-metrics-parser.js.map +1 -0
- package/dist/test-execution/scenario-data-importer.d.ts +21 -0
- package/dist/test-execution/scenario-data-importer.js +108 -0
- package/dist/test-execution/scenario-data-importer.js.map +1 -0
- package/dist/test-execution/scenario-runner.d.ts +18 -0
- package/dist/test-execution/scenario-runner.js +46 -0
- package/dist/test-execution/scenario-runner.js.map +1 -0
- package/dist/test-execution/test-report.d.ts +56 -0
- package/dist/test-execution/test-report.js +65 -0
- package/dist/test-execution/test-report.js.map +1 -0
- package/dist/types/scenario.d.ts +16 -0
- package/dist/types/scenario.js +3 -0
- package/dist/types/scenario.js.map +1 -0
- package/eslint.config.mjs +22 -0
- package/infra/.terraform.lock.hcl +60 -0
- package/infra/benchmark-env.tf +54 -0
- package/infra/modules/benchmark-vm/output.tf +11 -0
- package/infra/modules/benchmark-vm/vars.tf +29 -0
- package/infra/modules/benchmark-vm/vm.tf +126 -0
- package/infra/output.tf +16 -0
- package/infra/providers.tf +23 -0
- package/infra/vars.tf +34 -0
- package/package.json +55 -0
- package/scenarios/binary-data/binary-data.json +67 -0
- package/scenarios/binary-data/binary-data.manifest.json +7 -0
- package/scenarios/binary-data/binary-data.script.js +29 -0
- package/scenarios/credential-http-node/credential-bearer.json +8 -0
- package/scenarios/credential-http-node/credential-http-node.json +241 -0
- package/scenarios/credential-http-node/credential-http-node.manifest.json +10 -0
- package/scenarios/credential-http-node/credential-http-node.script.js +30 -0
- package/scenarios/data-table-node/data-table-node.json +168 -0
- package/scenarios/data-table-node/data-table-node.manifest.json +10 -0
- package/scenarios/data-table-node/data-table-node.script.js +38 -0
- package/scenarios/data-table-node/data-table.json +25 -0
- package/scenarios/http-node/http-node.json +213 -0
- package/scenarios/http-node/http-node.manifest.json +7 -0
- package/scenarios/http-node/http-node.script.js +30 -0
- package/scenarios/js-code-node/js-code-node.json +96 -0
- package/scenarios/js-code-node/js-code-node.manifest.json +7 -0
- package/scenarios/js-code-node/js-code-node.script.js +29 -0
- package/scenarios/multiple-webhooks/multiple-webhooks.manifest.json +20 -0
- package/scenarios/multiple-webhooks/multiple-webhooks.script.js +19 -0
- package/scenarios/multiple-webhooks/multiple-webhooks1.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks10.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks2.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks3.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks4.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks5.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks6.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks7.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks8.json +25 -0
- package/scenarios/multiple-webhooks/multiple-webhooks9.json +25 -0
- package/scenarios/py-code-node/py-code-node.json +98 -0
- package/scenarios/py-code-node/py-code-node.manifest.json +7 -0
- package/scenarios/py-code-node/py-code-node.script.js +29 -0
- package/scenarios/scenario.schema.json +51 -0
- package/scenarios/set-node-expressions/set-node-expressions.json +91 -0
- package/scenarios/set-node-expressions/set-node-expressions.manifest.json +7 -0
- package/scenarios/set-node-expressions/set-node-expressions.script.js +18 -0
- package/scenarios/single-webhook/single-webhook.json +25 -0
- package/scenarios/single-webhook/single-webhook.manifest.json +7 -0
- package/scenarios/single-webhook/single-webhook.script.js +18 -0
- package/scripts/bootstrap.sh +63 -0
- package/scripts/clients/docker-compose-client.mjs +45 -0
- package/scripts/clients/ssh-client.mjs +37 -0
- package/scripts/clients/terraform-client.mjs +71 -0
- package/scripts/destroy-cloud-env.mjs +86 -0
- package/scripts/mock-api/mappings/mockApiData.json +92110 -0
- package/scripts/n8n-setups/postgres/docker-compose.yml +76 -0
- package/scripts/n8n-setups/postgres/setup.mjs +15 -0
- package/scripts/n8n-setups/scaling-multi-main/docker-compose.yml +230 -0
- package/scripts/n8n-setups/scaling-multi-main/nginx.conf +24 -0
- package/scripts/n8n-setups/scaling-multi-main/setup.mjs +15 -0
- package/scripts/n8n-setups/scaling-single-main/docker-compose.yml +174 -0
- package/scripts/n8n-setups/scaling-single-main/setup.mjs +15 -0
- package/scripts/n8n-setups/sqlite/docker-compose.yml +55 -0
- package/scripts/n8n-setups/sqlite/setup.mjs +15 -0
- package/scripts/provision-cloud-env.mjs +36 -0
- package/scripts/run-for-n8n-setup.mjs +175 -0
- package/scripts/run-in-cloud.mjs +167 -0
- package/scripts/run-locally.mjs +73 -0
- package/scripts/run.mjs +192 -0
- package/scripts/utils/flags.mjs +20 -0
- package/src/commands/list.ts +26 -0
- package/src/commands/run.ts +140 -0
- package/src/config/common-flags.ts +6 -0
- package/src/n8n-api-client/authenticated-n8n-api-client.ts +88 -0
- package/src/n8n-api-client/credentials-api-client.ts +28 -0
- package/src/n8n-api-client/data-table-api-client.ts +30 -0
- package/src/n8n-api-client/n8n-api-client.ts +85 -0
- package/src/n8n-api-client/n8n-api-client.types.ts +27 -0
- package/src/n8n-api-client/project-api-client.ts +11 -0
- package/src/n8n-api-client/workflows-api-client.ts +38 -0
- package/src/scenario/scenario-data-loader.ts +75 -0
- package/src/scenario/scenario-loader.ts +90 -0
- package/src/test-execution/app-metrics-poller.ts +81 -0
- package/src/test-execution/k6-executor.ts +192 -0
- package/src/test-execution/k6-summary.ts +255 -0
- package/src/test-execution/prometheus-metrics-parser.ts +63 -0
- package/src/test-execution/scenario-data-importer.ts +165 -0
- package/src/test-execution/scenario-runner.ts +76 -0
- package/src/test-execution/test-report.ts +152 -0
- package/src/types/scenario.ts +33 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthenticatedN8nApiClient = void 0;
|
|
4
|
+
const n8n_api_client_1 = require("./n8n-api-client");
|
|
5
|
+
class AuthenticatedN8nApiClient extends n8n_api_client_1.N8nApiClient {
|
|
6
|
+
constructor(apiBaseUrl, authCookie) {
|
|
7
|
+
super(apiBaseUrl);
|
|
8
|
+
this.authCookie = authCookie;
|
|
9
|
+
}
|
|
10
|
+
static async createUsingUsernameAndPassword(apiClient, loginDetails) {
|
|
11
|
+
const response = await apiClient.restApiRequest('/login', {
|
|
12
|
+
method: 'POST',
|
|
13
|
+
data: {
|
|
14
|
+
emailOrLdapLoginId: loginDetails.email,
|
|
15
|
+
password: loginDetails.password,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
if (response.data === 'n8n is starting up. Please wait') {
|
|
19
|
+
await apiClient.delay(1000);
|
|
20
|
+
return await this.createUsingUsernameAndPassword(apiClient, loginDetails);
|
|
21
|
+
}
|
|
22
|
+
const cookieHeader = response.headers['set-cookie'];
|
|
23
|
+
const authCookie = Array.isArray(cookieHeader) ? cookieHeader.join('; ') : cookieHeader;
|
|
24
|
+
if (!authCookie) {
|
|
25
|
+
throw new Error('Did not receive authentication cookie even tho login succeeded: ' +
|
|
26
|
+
JSON.stringify({
|
|
27
|
+
status: response.status,
|
|
28
|
+
headers: response.headers,
|
|
29
|
+
data: response.data,
|
|
30
|
+
}, null, 2));
|
|
31
|
+
}
|
|
32
|
+
return new AuthenticatedN8nApiClient(apiClient.apiBaseUrl, authCookie);
|
|
33
|
+
}
|
|
34
|
+
async get(endpoint) {
|
|
35
|
+
return await this.authenticatedRequest(endpoint, {
|
|
36
|
+
method: 'GET',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async post(endpoint, data) {
|
|
40
|
+
return await this.authenticatedRequest(endpoint, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
data,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async patch(endpoint, data) {
|
|
46
|
+
return await this.authenticatedRequest(endpoint, {
|
|
47
|
+
method: 'PATCH',
|
|
48
|
+
data,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async delete(endpoint) {
|
|
52
|
+
return await this.authenticatedRequest(endpoint, {
|
|
53
|
+
method: 'DELETE',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async authenticatedRequest(endpoint, init) {
|
|
57
|
+
return await this.restApiRequest(endpoint, {
|
|
58
|
+
...init,
|
|
59
|
+
headers: {
|
|
60
|
+
...init.headers,
|
|
61
|
+
cookie: this.authCookie,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.AuthenticatedN8nApiClient = AuthenticatedN8nApiClient;
|
|
67
|
+
//# sourceMappingURL=authenticated-n8n-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticated-n8n-api-client.js","sourceRoot":"","sources":["../../src/n8n-api-client/authenticated-n8n-api-client.ts"],"names":[],"mappings":";;;AAEA,qDAAgD;AAEhD,MAAa,yBAA0B,SAAQ,6BAAY;IAC1D,YACC,UAAkB,EACD,UAAkB;QAEnC,KAAK,CAAC,UAAU,CAAC,CAAC;QAFD,eAAU,GAAV,UAAU,CAAQ;IAGpC,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAC1C,SAAuB,EACvB,YAGC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE;YACzD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE;gBACL,kBAAkB,EAAE,YAAY,CAAC,KAAK;gBACtC,QAAQ,EAAE,YAAY,CAAC,QAAQ;aAC/B;SACD,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,IAAI,KAAK,iCAAiC,EAAE,CAAC;YACzD,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,MAAM,IAAI,CAAC,8BAA8B,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QACxF,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACd,kEAAkE;gBACjE,IAAI,CAAC,SAAS,CACb;oBACC,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;iBACnB,EACD,IAAI,EACJ,CAAC,CACD,CACF,CAAC;QACH,CAAC;QAED,OAAO,IAAI,yBAAyB,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,QAAgB;QAC5B,OAAO,MAAM,IAAI,CAAC,oBAAoB,CAAI,QAAQ,EAAE;YACnD,MAAM,EAAE,KAAK;SACb,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,QAAgB,EAAE,IAAa;QAC5C,OAAO,MAAM,IAAI,CAAC,oBAAoB,CAAI,QAAQ,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,IAAI;SACJ,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK,CAAI,QAAgB,EAAE,IAAa;QAC7C,OAAO,MAAM,IAAI,CAAC,oBAAoB,CAAI,QAAQ,EAAE;YACnD,MAAM,EAAE,OAAO;YACf,IAAI;SACJ,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAI,QAAgB;QAC/B,OAAO,MAAM,IAAI,CAAC,oBAAoB,CAAI,QAAQ,EAAE;YACnD,MAAM,EAAE,QAAQ;SAChB,CAAC,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,oBAAoB,CAAI,QAAgB,EAAE,IAAqC;QAC9F,OAAO,MAAM,IAAI,CAAC,cAAc,CAAI,QAAQ,EAAE;YAC7C,GAAG,IAAI;YACP,OAAO,EAAE;gBACR,GAAG,IAAI,CAAC,OAAO;gBACf,MAAM,EAAE,IAAI,CAAC,UAAU;aACvB;SACD,CAAC,CAAC;IACJ,CAAC;CACD;AAnFD,8DAmFC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Credential } from '../n8n-api-client/n8n-api-client.types';
|
|
2
|
+
import type { AuthenticatedN8nApiClient } from './authenticated-n8n-api-client';
|
|
3
|
+
export declare class CredentialApiClient {
|
|
4
|
+
private readonly apiClient;
|
|
5
|
+
constructor(apiClient: AuthenticatedN8nApiClient);
|
|
6
|
+
getAllCredentials(): Promise<Credential[]>;
|
|
7
|
+
createCredential(credential: Credential): Promise<Credential>;
|
|
8
|
+
deleteCredential(credentialId: Credential['id']): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CredentialApiClient = void 0;
|
|
4
|
+
class CredentialApiClient {
|
|
5
|
+
constructor(apiClient) {
|
|
6
|
+
this.apiClient = apiClient;
|
|
7
|
+
}
|
|
8
|
+
async getAllCredentials() {
|
|
9
|
+
const response = await this.apiClient.get('/credentials');
|
|
10
|
+
return response.data.data;
|
|
11
|
+
}
|
|
12
|
+
async createCredential(credential) {
|
|
13
|
+
const response = await this.apiClient.post('/credentials', {
|
|
14
|
+
...credential,
|
|
15
|
+
id: undefined,
|
|
16
|
+
});
|
|
17
|
+
return response.data.data;
|
|
18
|
+
}
|
|
19
|
+
async deleteCredential(credentialId) {
|
|
20
|
+
await this.apiClient.delete(`/credentials/${credentialId}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.CredentialApiClient = CredentialApiClient;
|
|
24
|
+
//# sourceMappingURL=credentials-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-api-client.js","sourceRoot":"","sources":["../../src/n8n-api-client/credentials-api-client.ts"],"names":[],"mappings":";;;AAIA,MAAa,mBAAmB;IAC/B,YAA6B,SAAoC;QAApC,cAAS,GAAT,SAAS,CAA2B;IAAG,CAAC;IAErE,KAAK,CAAC,iBAAiB;QACtB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CACxC,cAAc,CACd,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,UAAsB;QAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAuB,cAAc,EAAE;YAChF,GAAG,UAAU;YACb,EAAE,EAAE,SAAS;SACb,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,YAA8B;QACpD,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;IAC7D,CAAC;CACD;AAvBD,kDAuBC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DataTable } from '../n8n-api-client/n8n-api-client.types';
|
|
2
|
+
import type { AuthenticatedN8nApiClient } from './authenticated-n8n-api-client';
|
|
3
|
+
export declare class DataTableApiClient {
|
|
4
|
+
private readonly apiClient;
|
|
5
|
+
constructor(apiClient: AuthenticatedN8nApiClient);
|
|
6
|
+
getAllDataTables(): Promise<DataTable[]>;
|
|
7
|
+
deleteDataTable(projectId: string, dataTableId: DataTable['id']): Promise<void>;
|
|
8
|
+
createDataTable(projectId: string, dataTable: DataTable): Promise<DataTable>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataTableApiClient = void 0;
|
|
4
|
+
class DataTableApiClient {
|
|
5
|
+
constructor(apiClient) {
|
|
6
|
+
this.apiClient = apiClient;
|
|
7
|
+
}
|
|
8
|
+
async getAllDataTables() {
|
|
9
|
+
const response = await this.apiClient.get('/data-tables-global');
|
|
10
|
+
return response.data.data.data;
|
|
11
|
+
}
|
|
12
|
+
async deleteDataTable(projectId, dataTableId) {
|
|
13
|
+
await this.apiClient.delete(`/projects/${projectId}/data-tables/${dataTableId}`);
|
|
14
|
+
}
|
|
15
|
+
async createDataTable(projectId, dataTable) {
|
|
16
|
+
const response = await this.apiClient.post(`/projects/${projectId}/data-tables`, {
|
|
17
|
+
...dataTable,
|
|
18
|
+
});
|
|
19
|
+
return response.data.data;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.DataTableApiClient = DataTableApiClient;
|
|
23
|
+
//# sourceMappingURL=data-table-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table-api-client.js","sourceRoot":"","sources":["../../src/n8n-api-client/data-table-api-client.ts"],"names":[],"mappings":";;;AAIA,MAAa,kBAAkB;IAC9B,YAA6B,SAAoC;QAApC,cAAS,GAAT,SAAS,CAA2B;IAAG,CAAC;IAErE,KAAK,CAAC,gBAAgB;QACrB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CACxC,qBAAqB,CACrB,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,WAA4B;QACpE,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,SAAS,gBAAgB,WAAW,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,SAAoB;QAC5D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACzC,aAAa,SAAS,cAAc,EACpC;YACC,GAAG,SAAS;SACZ,CACD,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC;CACD;AAzBD,gDAyBC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AxiosRequestConfig } from 'axios';
|
|
2
|
+
export declare class N8nApiClient {
|
|
3
|
+
readonly apiBaseUrl: string;
|
|
4
|
+
constructor(apiBaseUrl: string);
|
|
5
|
+
waitForInstanceToBecomeOnline(): Promise<void>;
|
|
6
|
+
setupOwnerIfNeeded(loginDetails: {
|
|
7
|
+
email: string;
|
|
8
|
+
password: string;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
restApiRequest<T>(endpoint: string, init: Omit<AxiosRequestConfig, 'url'>): Promise<import("axios").AxiosResponse<T, any, {}>>;
|
|
11
|
+
delay(ms: number): Promise<void>;
|
|
12
|
+
protected getRestEndpointUrl(endpoint: string): string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.N8nApiClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
class N8nApiClient {
|
|
9
|
+
constructor(apiBaseUrl) {
|
|
10
|
+
this.apiBaseUrl = apiBaseUrl;
|
|
11
|
+
}
|
|
12
|
+
async waitForInstanceToBecomeOnline() {
|
|
13
|
+
const HEALTH_ENDPOINT = 'healthz';
|
|
14
|
+
const START_TIME = Date.now();
|
|
15
|
+
const INTERVAL_MS = 1000;
|
|
16
|
+
const TIMEOUT_MS = 60_000;
|
|
17
|
+
while (Date.now() - START_TIME < TIMEOUT_MS) {
|
|
18
|
+
try {
|
|
19
|
+
const response = await axios_1.default.request({
|
|
20
|
+
url: `${this.apiBaseUrl}/${HEALTH_ENDPOINT}`,
|
|
21
|
+
method: 'GET',
|
|
22
|
+
});
|
|
23
|
+
if (response.status === 200 && response.data.status === 'ok') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch { }
|
|
28
|
+
console.log(`n8n instance not online yet, retrying in ${INTERVAL_MS / 1000} seconds...`);
|
|
29
|
+
await this.delay(INTERVAL_MS);
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`n8n instance did not come online within ${TIMEOUT_MS / 1000} seconds`);
|
|
32
|
+
}
|
|
33
|
+
async setupOwnerIfNeeded(loginDetails) {
|
|
34
|
+
const response = await this.restApiRequest('/owner/setup', {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
data: {
|
|
37
|
+
email: loginDetails.email,
|
|
38
|
+
password: loginDetails.password,
|
|
39
|
+
firstName: 'Test',
|
|
40
|
+
lastName: 'User',
|
|
41
|
+
},
|
|
42
|
+
validateStatus: () => true,
|
|
43
|
+
});
|
|
44
|
+
const responsePayload = response.data;
|
|
45
|
+
if (response.status === 200) {
|
|
46
|
+
console.log('Owner setup successful');
|
|
47
|
+
}
|
|
48
|
+
else if (response.status === 400) {
|
|
49
|
+
if (responsePayload.message === 'Instance owner already setup')
|
|
50
|
+
console.log('Owner already set up');
|
|
51
|
+
}
|
|
52
|
+
else if (response.status === 404) {
|
|
53
|
+
console.log('Owner setup endpoint not available yet, retrying in 1s...');
|
|
54
|
+
await this.delay(1000);
|
|
55
|
+
await this.setupOwnerIfNeeded(loginDetails);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new Error(`Owner setup failed with status ${response.status}: ${responsePayload.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async restApiRequest(endpoint, init) {
|
|
62
|
+
try {
|
|
63
|
+
return await axios_1.default.request({
|
|
64
|
+
...init,
|
|
65
|
+
url: this.getRestEndpointUrl(endpoint),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
const error = e;
|
|
70
|
+
console.error(`[ERROR] Request failed ${init.method} ${endpoint}`, error?.response?.data);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async delay(ms) {
|
|
75
|
+
return await new Promise((resolve) => setTimeout(resolve, ms));
|
|
76
|
+
}
|
|
77
|
+
getRestEndpointUrl(endpoint) {
|
|
78
|
+
return `${this.apiBaseUrl}/rest${endpoint}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.N8nApiClient = N8nApiClient;
|
|
82
|
+
//# sourceMappingURL=n8n-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"n8n-api-client.js","sourceRoot":"","sources":["../../src/n8n-api-client/n8n-api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type Workflow = {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
versionId: string;
|
|
5
|
+
tags?: string[];
|
|
6
|
+
};
|
|
7
|
+
export type Credential = {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
type: string;
|
|
11
|
+
};
|
|
12
|
+
export type DataTableColumn = {
|
|
13
|
+
name: string;
|
|
14
|
+
type: 'string' | 'number' | 'boolean' | 'date';
|
|
15
|
+
};
|
|
16
|
+
export type DataTable = {
|
|
17
|
+
id?: string;
|
|
18
|
+
projectId?: number;
|
|
19
|
+
name: string;
|
|
20
|
+
columns: DataTableColumn[];
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"n8n-api-client.types.js","sourceRoot":"","sources":["../../src/n8n-api-client/n8n-api-client.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProjectApiClient = void 0;
|
|
4
|
+
class ProjectApiClient {
|
|
5
|
+
constructor(apiClient) {
|
|
6
|
+
this.apiClient = apiClient;
|
|
7
|
+
}
|
|
8
|
+
async getPersonalProject() {
|
|
9
|
+
const response = await this.apiClient.get('/projects/personal');
|
|
10
|
+
return response.data.data.id;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.ProjectApiClient = ProjectApiClient;
|
|
14
|
+
//# sourceMappingURL=project-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-api-client.js","sourceRoot":"","sources":["../../src/n8n-api-client/project-api-client.ts"],"names":[],"mappings":";;;AAEA,MAAa,gBAAgB;IAC5B,YAA6B,SAAoC;QAApC,cAAS,GAAT,SAAS,CAA2B;IAAG,CAAC;IAErE,KAAK,CAAC,kBAAkB;QACvB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAA2B,oBAAoB,CAAC,CAAC;QAE1F,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9B,CAAC;CACD;AARD,4CAQC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Workflow } from '../n8n-api-client/n8n-api-client.types';
|
|
2
|
+
import type { AuthenticatedN8nApiClient } from './authenticated-n8n-api-client';
|
|
3
|
+
export declare class WorkflowApiClient {
|
|
4
|
+
private readonly apiClient;
|
|
5
|
+
constructor(apiClient: AuthenticatedN8nApiClient);
|
|
6
|
+
getAllWorkflows(): Promise<Workflow[]>;
|
|
7
|
+
createWorkflow(workflow: unknown): Promise<Workflow>;
|
|
8
|
+
activateWorkflow(workflow: Workflow): Promise<Workflow>;
|
|
9
|
+
archiveWorkflow(workflowId: Workflow['id']): Promise<void>;
|
|
10
|
+
deleteWorkflow(workflowId: Workflow['id']): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WorkflowApiClient = void 0;
|
|
4
|
+
class WorkflowApiClient {
|
|
5
|
+
constructor(apiClient) {
|
|
6
|
+
this.apiClient = apiClient;
|
|
7
|
+
}
|
|
8
|
+
async getAllWorkflows() {
|
|
9
|
+
const response = await this.apiClient.get('/workflows');
|
|
10
|
+
return response.data.data;
|
|
11
|
+
}
|
|
12
|
+
async createWorkflow(workflow) {
|
|
13
|
+
const response = await this.apiClient.post('/workflows', workflow);
|
|
14
|
+
return response.data.data;
|
|
15
|
+
}
|
|
16
|
+
async activateWorkflow(workflow) {
|
|
17
|
+
const response = await this.apiClient.post(`/workflows/${workflow.id}/activate`, {
|
|
18
|
+
versionId: workflow.versionId,
|
|
19
|
+
});
|
|
20
|
+
return response.data.data;
|
|
21
|
+
}
|
|
22
|
+
async archiveWorkflow(workflowId) {
|
|
23
|
+
await this.apiClient.post(`/workflows/${workflowId}/archive`, {});
|
|
24
|
+
}
|
|
25
|
+
async deleteWorkflow(workflowId) {
|
|
26
|
+
await this.apiClient.delete(`/workflows/${workflowId}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.WorkflowApiClient = WorkflowApiClient;
|
|
30
|
+
//# sourceMappingURL=workflows-api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflows-api-client.js","sourceRoot":"","sources":["../../src/n8n-api-client/workflows-api-client.ts"],"names":[],"mappings":";;;AAIA,MAAa,iBAAiB;IAC7B,YAA6B,SAAoC;QAApC,cAAS,GAAT,SAAS,CAA2B;IAAG,CAAC;IAErE,KAAK,CAAC,eAAe;QACpB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAsC,YAAY,CAAC,CAAC;QAE7F,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAiB;QACrC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAqB,YAAY,EAAE,QAAQ,CAAC,CAAC;QAEvF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAkB;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACzC,cAAc,QAAQ,CAAC,EAAE,WAAW,EACpC;YACC,SAAS,EAAE,QAAQ,CAAC,SAAS;SAC7B,CACD,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,UAA0B;QAC/C,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,UAAU,UAAU,EAAE,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,UAA0B;QAC9C,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,UAAU,EAAE,CAAC,CAAC;IACzD,CAAC;CACD;AAjCD,8CAiCC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Workflow, Credential, DataTable } from '../n8n-api-client/n8n-api-client.types';
|
|
2
|
+
import type { Scenario } from '../types/scenario';
|
|
3
|
+
export type LoadableScenarioData = {
|
|
4
|
+
workflows: Workflow[];
|
|
5
|
+
credentials: Credential[];
|
|
6
|
+
dataTable: DataTable | null;
|
|
7
|
+
};
|
|
8
|
+
export declare class ScenarioDataFileLoader {
|
|
9
|
+
loadDataForScenario(scenario: Scenario): Promise<LoadableScenarioData>;
|
|
10
|
+
private loadSingleCredentialFromFile;
|
|
11
|
+
private loadSingleWorkflowFromFile;
|
|
12
|
+
private loadSingleDataTableFromFile;
|
|
13
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ScenarioDataFileLoader = void 0;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
class ScenarioDataFileLoader {
|
|
40
|
+
async loadDataForScenario(scenario) {
|
|
41
|
+
const workflows = await Promise.all(scenario.scenarioData.workflowFiles?.map((workflowFilePath) => this.loadSingleWorkflowFromFile(path.join(scenario.scenarioDirPath, workflowFilePath))) ?? []);
|
|
42
|
+
const credentials = await Promise.all(scenario.scenarioData.credentialFiles?.map((credentialFilePath) => this.loadSingleCredentialFromFile(path.join(scenario.scenarioDirPath, credentialFilePath))) ?? []);
|
|
43
|
+
const dataTable = scenario.scenarioData.dataTableFile
|
|
44
|
+
? this.loadSingleDataTableFromFile(path.join(scenario.scenarioDirPath, scenario.scenarioData.dataTableFile))
|
|
45
|
+
: null;
|
|
46
|
+
return {
|
|
47
|
+
workflows,
|
|
48
|
+
credentials,
|
|
49
|
+
dataTable,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
loadSingleCredentialFromFile(credentialFilePath) {
|
|
53
|
+
const fileContent = fs.readFileSync(credentialFilePath, 'utf8');
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(fileContent);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const e = error;
|
|
59
|
+
throw new Error(`Failed to parse credential file ${credentialFilePath}: ${e.message}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
loadSingleWorkflowFromFile(workflowFilePath) {
|
|
63
|
+
const fileContent = fs.readFileSync(workflowFilePath, 'utf8');
|
|
64
|
+
try {
|
|
65
|
+
return JSON.parse(fileContent);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const e = error;
|
|
69
|
+
throw new Error(`Failed to parse workflow file ${workflowFilePath}: ${e.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
loadSingleDataTableFromFile(dataTableFilePath) {
|
|
73
|
+
const fileContent = fs.readFileSync(dataTableFilePath, 'utf8');
|
|
74
|
+
try {
|
|
75
|
+
return JSON.parse(fileContent);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const e = error;
|
|
79
|
+
throw new Error(`Failed to parse data table file ${dataTableFilePath}: ${e.message}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.ScenarioDataFileLoader = ScenarioDataFileLoader;
|
|
84
|
+
//# sourceMappingURL=scenario-data-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenario-data-loader.js","sourceRoot":"","sources":["../../src/scenario/scenario-data-loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAclC,MAAa,sBAAsB;IAClC,KAAK,CAAC,mBAAmB,CAAC,QAAkB;QAC3C,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,QAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAC7D,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CACtF,IAAI,EAAE,CACP,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,QAAQ,CAAC,YAAY,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,kBAAkB,EAAE,EAAE,CACjE,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAC1F,IAAI,EAAE,CACP,CAAC;QAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,aAAa;YACpD,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,YAAY,CAAC,aAAa,CAAC,CACxE;YACF,CAAC,CAAC,IAAI,CAAC;QAER,OAAO;YACN,SAAS;YACT,WAAW;YACX,SAAS;SACT,CAAC;IACH,CAAC;IAEO,4BAA4B,CAAC,kBAA0B;QAC9D,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QAEhE,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAe,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,GAAG,KAAc,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,mCAAmC,kBAAkB,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACxF,CAAC;IACF,CAAC;IAEO,0BAA0B,CAAC,gBAAwB;QAC1D,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;QAE9D,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAa,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,GAAG,KAAc,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,gBAAgB,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACpF,CAAC;IACF,CAAC;IAEO,2BAA2B,CAAC,iBAAyB;QAC5D,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAE/D,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAc,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,GAAG,KAAc,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,mCAAmC,iBAAiB,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACvF,CAAC;IACF,CAAC;CACD;AA3DD,wDA2DC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ScenarioLoader = void 0;
|
|
37
|
+
const node_crypto_1 = require("node:crypto");
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
class ScenarioLoader {
|
|
41
|
+
loadAll(pathToScenarios, filter) {
|
|
42
|
+
pathToScenarios = path.resolve(pathToScenarios);
|
|
43
|
+
const scenarioFolders = fs
|
|
44
|
+
.readdirSync(pathToScenarios, { withFileTypes: true })
|
|
45
|
+
.filter((dirent) => dirent.isDirectory())
|
|
46
|
+
.map((dirent) => dirent.name);
|
|
47
|
+
const scenarios = [];
|
|
48
|
+
for (const folder of scenarioFolders) {
|
|
49
|
+
if (filter && folder.toLowerCase() !== filter.toLowerCase()) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const scenarioPath = path.join(pathToScenarios, folder);
|
|
53
|
+
const manifestFileName = `${folder}.manifest.json`;
|
|
54
|
+
const scenarioManifestPath = path.join(pathToScenarios, folder, manifestFileName);
|
|
55
|
+
if (!fs.existsSync(scenarioManifestPath)) {
|
|
56
|
+
console.warn(`Scenario at ${scenarioPath} is missing the ${manifestFileName} file`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const [scenario, validationErrors] = this.loadAndValidateScenarioManifest(scenarioManifestPath);
|
|
60
|
+
if (validationErrors) {
|
|
61
|
+
console.warn(`Scenario at ${scenarioPath} has the following validation errors: ${validationErrors.join(', ')}`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
scenarios.push({
|
|
65
|
+
...scenario,
|
|
66
|
+
id: this.formScenarioId(scenarioPath),
|
|
67
|
+
scenarioDirPath: scenarioPath,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return scenarios;
|
|
71
|
+
}
|
|
72
|
+
loadAndValidateScenarioManifest(scenarioManifestPath) {
|
|
73
|
+
const [scenario, error] = this.loadScenarioManifest(scenarioManifestPath);
|
|
74
|
+
if (!scenario) {
|
|
75
|
+
return [null, [error]];
|
|
76
|
+
}
|
|
77
|
+
const validationErrors = [];
|
|
78
|
+
if (!scenario.name) {
|
|
79
|
+
validationErrors.push(`Scenario at ${scenarioManifestPath} is missing a name`);
|
|
80
|
+
}
|
|
81
|
+
if (!scenario.description) {
|
|
82
|
+
validationErrors.push(`Scenario at ${scenarioManifestPath} is missing a description`);
|
|
83
|
+
}
|
|
84
|
+
return validationErrors.length === 0 ? [scenario, null] : [null, validationErrors];
|
|
85
|
+
}
|
|
86
|
+
loadScenarioManifest(scenarioManifestPath) {
|
|
87
|
+
try {
|
|
88
|
+
const scenario = JSON.parse(fs.readFileSync(scenarioManifestPath, 'utf8'));
|
|
89
|
+
return [scenario, null];
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const message = error instanceof Error ? error.message : JSON.stringify(error);
|
|
93
|
+
return [null, `Failed to parse manifest ${scenarioManifestPath}: ${message}`];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
formScenarioId(scenarioPath) {
|
|
97
|
+
return (0, node_crypto_1.createHash)('sha256').update(scenarioPath).digest('hex');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.ScenarioLoader = ScenarioLoader;
|
|
101
|
+
//# sourceMappingURL=scenario-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenario-loader.js","sourceRoot":"","sources":["../../src/scenario/scenario-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class AppMetricsPoller {
|
|
2
|
+
private readonly metricsUrl;
|
|
3
|
+
private readonly pollIntervalMs;
|
|
4
|
+
private intervalId;
|
|
5
|
+
private metricsData;
|
|
6
|
+
private isRunning;
|
|
7
|
+
private isStopped;
|
|
8
|
+
constructor(metricsUrl: string, pollIntervalMs?: number);
|
|
9
|
+
start(): void;
|
|
10
|
+
stop(): void;
|
|
11
|
+
getMetricsData(): string[];
|
|
12
|
+
private pollMetrics;
|
|
13
|
+
}
|