@n8n/backend-module-apps 0.0.0-tp-setup → 0.1.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/LICENSE.md +88 -0
- package/dist/app-artifact.entity.d.ts +0 -1
- package/dist/app.repository.d.ts +3 -8
- package/dist/app.repository.js +7 -35
- package/dist/app.repository.js.map +1 -1
- package/dist/apps.module.d.ts +0 -1
- package/dist/apps.module.js +0 -10
- package/dist/apps.module.js.map +1 -1
- package/dist/apps.service.d.ts +2 -3
- package/dist/apps.service.js +5 -8
- package/dist/apps.service.js.map +1 -1
- package/dist/build.tsbuildinfo +1 -1
- package/dist/index.d.ts +1 -6
- package/dist/index.js +1 -12
- package/dist/index.js.map +1 -1
- package/package.json +27 -35
- package/dist/app-artifact.repository.d.ts +0 -15
- package/dist/app-artifact.repository.js +0 -104
- package/dist/app-artifact.repository.js.map +0 -1
- package/dist/app-artifact.service.d.ts +0 -20
- package/dist/app-artifact.service.js +0 -118
- package/dist/app-artifact.service.js.map +0 -1
- package/dist/app-retention.service.d.ts +0 -16
- package/dist/app-retention.service.js +0 -74
- package/dist/app-retention.service.js.map +0 -1
- package/dist/app-storage-cleanup.task.d.ts +0 -17
- package/dist/app-storage-cleanup.task.js +0 -57
- package/dist/app-storage-cleanup.task.js.map +0 -1
- package/dist/app-storage-lock.d.ts +0 -1
- package/dist/app-storage-lock.js +0 -8
- package/dist/app-storage-lock.js.map +0 -1
- package/dist/app-version.repository.d.ts +0 -18
- package/dist/app-version.repository.js +0 -90
- package/dist/app-version.repository.js.map +0 -1
- package/dist/app-version.service.d.ts +0 -30
- package/dist/app-version.service.js +0 -124
- package/dist/app-version.service.js.map +0 -1
- package/dist/apps.config.d.ts +0 -8
- package/dist/apps.config.js +0 -54
- package/dist/apps.config.js.map +0 -1
- package/dist/storage/app-archive.d.ts +0 -16
- package/dist/storage/app-archive.js +0 -180
- package/dist/storage/app-archive.js.map +0 -1
- package/dist/storage/app-blob-store.d.ts +0 -21
- package/dist/storage/app-blob-store.js +0 -93
- package/dist/storage/app-blob-store.js.map +0 -1
- package/dist/storage/app-version-stores.d.ts +0 -20
- package/dist/storage/app-version-stores.js +0 -10
- package/dist/storage/app-version-stores.js.map +0 -1
- package/dist/storage/snapshot-app-version-stores.d.ts +0 -30
- package/dist/storage/snapshot-app-version-stores.js +0 -122
- package/dist/storage/snapshot-app-version-stores.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
export { App } from './app.entity';
|
|
2
2
|
export { AppVersion } from './app-version.entity';
|
|
3
|
-
export { AppArtifact
|
|
3
|
+
export { AppArtifact } from './app-artifact.entity';
|
|
4
4
|
export { AppRepository } from './app.repository';
|
|
5
5
|
export { AppsService } from './apps.service';
|
|
6
|
-
export { AppVersionService } from './app-version.service';
|
|
7
|
-
export { AppVersionRepository } from './app-version.repository';
|
|
8
|
-
export { AppArtifactService } from './app-artifact.service';
|
|
9
|
-
export { AppArtifactRepository } from './app-artifact.repository';
|
|
10
|
-
export { AppSourceVersionStore, AppBuildResultStore, type AppFiles, type NewSourceVersion, } from './storage/app-version-stores';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.AppsService = exports.AppRepository = exports.AppArtifact = exports.AppVersion = exports.App = void 0;
|
|
4
4
|
var app_entity_1 = require("./app.entity");
|
|
5
5
|
Object.defineProperty(exports, "App", { enumerable: true, get: function () { return app_entity_1.App; } });
|
|
6
6
|
var app_version_entity_1 = require("./app-version.entity");
|
|
@@ -11,15 +11,4 @@ var app_repository_1 = require("./app.repository");
|
|
|
11
11
|
Object.defineProperty(exports, "AppRepository", { enumerable: true, get: function () { return app_repository_1.AppRepository; } });
|
|
12
12
|
var apps_service_1 = require("./apps.service");
|
|
13
13
|
Object.defineProperty(exports, "AppsService", { enumerable: true, get: function () { return apps_service_1.AppsService; } });
|
|
14
|
-
var app_version_service_1 = require("./app-version.service");
|
|
15
|
-
Object.defineProperty(exports, "AppVersionService", { enumerable: true, get: function () { return app_version_service_1.AppVersionService; } });
|
|
16
|
-
var app_version_repository_1 = require("./app-version.repository");
|
|
17
|
-
Object.defineProperty(exports, "AppVersionRepository", { enumerable: true, get: function () { return app_version_repository_1.AppVersionRepository; } });
|
|
18
|
-
var app_artifact_service_1 = require("./app-artifact.service");
|
|
19
|
-
Object.defineProperty(exports, "AppArtifactService", { enumerable: true, get: function () { return app_artifact_service_1.AppArtifactService; } });
|
|
20
|
-
var app_artifact_repository_1 = require("./app-artifact.repository");
|
|
21
|
-
Object.defineProperty(exports, "AppArtifactRepository", { enumerable: true, get: function () { return app_artifact_repository_1.AppArtifactRepository; } });
|
|
22
|
-
var app_version_stores_1 = require("./storage/app-version-stores");
|
|
23
|
-
Object.defineProperty(exports, "AppSourceVersionStore", { enumerable: true, get: function () { return app_version_stores_1.AppSourceVersionStore; } });
|
|
24
|
-
Object.defineProperty(exports, "AppBuildResultStore", { enumerable: true, get: function () { return app_version_stores_1.AppBuildResultStore; } });
|
|
25
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAAmC;AAA1B,iGAAA,GAAG,OAAA;AACZ,2DAAkD;AAAzC,gHAAA,UAAU,OAAA;AACnB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAAmC;AAA1B,iGAAA,GAAG,OAAA;AACZ,2DAAkD;AAAzC,gHAAA,UAAU,OAAA;AACnB,6DAAoD;AAA3C,kHAAA,WAAW,OAAA;AACpB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,+CAA6C;AAApC,2GAAA,WAAW,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n8n/backend-module-apps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,6 +19,30 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"dist/**/*"
|
|
21
21
|
],
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@n8n/api-types": "1.45.0",
|
|
24
|
+
"@n8n/backend-common": "1.45.0",
|
|
25
|
+
"@n8n/backend-services": "1.5.0",
|
|
26
|
+
"@n8n/db": "1.45.0",
|
|
27
|
+
"@n8n/decorators": "1.45.0",
|
|
28
|
+
"@n8n/di": "0.17.0",
|
|
29
|
+
"@n8n/errors": "0.15.0",
|
|
30
|
+
"@n8n/typeorm": "0.12.0",
|
|
31
|
+
"uuid": "11.1.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@n8n/oxlint-config": "0.0.1",
|
|
35
|
+
"@n8n/typescript-config": "1.12.0",
|
|
36
|
+
"@n8n/vitest-config": "1.24.0",
|
|
37
|
+
"@types/express": "^5.0.1",
|
|
38
|
+
"oxlint": "1.78.0",
|
|
39
|
+
"oxlint-tsgolint": "^0.21.1",
|
|
40
|
+
"typescript": "7.0.2",
|
|
41
|
+
"vite": "^8.0.2",
|
|
42
|
+
"vitest": "5.0.1",
|
|
43
|
+
"vitest-mock-extended": "^3.1.0"
|
|
44
|
+
},
|
|
45
|
+
"license": "LicenseRef-n8n-sustainable-use",
|
|
22
46
|
"scripts": {
|
|
23
47
|
"clean": "rimraf dist .turbo",
|
|
24
48
|
"dev": "pnpm watch",
|
|
@@ -33,37 +57,5 @@
|
|
|
33
57
|
"test": "vitest run",
|
|
34
58
|
"test:unit": "vitest run",
|
|
35
59
|
"test:dev": "vitest --silent=false"
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
"@n8n/api-types": "workspace:*",
|
|
39
|
-
"@n8n/backend-common": "workspace:*",
|
|
40
|
-
"@n8n/backend-services": "workspace:*",
|
|
41
|
-
"@n8n/blob-storage": "workspace:*",
|
|
42
|
-
"@n8n/config": "workspace:*",
|
|
43
|
-
"@n8n/db": "workspace:*",
|
|
44
|
-
"@n8n/decorators": "workspace:*",
|
|
45
|
-
"@n8n/di": "workspace:*",
|
|
46
|
-
"@n8n/errors": "workspace:*",
|
|
47
|
-
"@n8n/typeorm": "workspace:*",
|
|
48
|
-
"n8n-core": "workspace:*",
|
|
49
|
-
"tar": "catalog:",
|
|
50
|
-
"uuid": "catalog:"
|
|
51
|
-
},
|
|
52
|
-
"peerDependencies": {
|
|
53
|
-
"zod": "catalog:"
|
|
54
|
-
},
|
|
55
|
-
"devDependencies": {
|
|
56
|
-
"@n8n/oxlint-config": "workspace:*",
|
|
57
|
-
"@n8n/typescript-config": "workspace:*",
|
|
58
|
-
"@n8n/vitest-config": "workspace:*",
|
|
59
|
-
"@types/express": "catalog:",
|
|
60
|
-
"oxlint": "catalog:",
|
|
61
|
-
"oxlint-tsgolint": "catalog:",
|
|
62
|
-
"typescript": "catalog:typescript",
|
|
63
|
-
"vite": "catalog:",
|
|
64
|
-
"vitest": "catalog:",
|
|
65
|
-
"vitest-mock-extended": "catalog:",
|
|
66
|
-
"zod": "catalog:"
|
|
67
|
-
},
|
|
68
|
-
"license": "LicenseRef-n8n-sustainable-use"
|
|
69
|
-
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { BaseRepository, TransactionRunner, type OperationContext } from '@n8n/db';
|
|
2
|
-
import { DataSource } from '@n8n/typeorm';
|
|
3
|
-
import { AppArtifact, type AppArtifactRef } from './app-artifact.entity';
|
|
4
|
-
import type { AppBlob } from './storage/app-blob-store';
|
|
5
|
-
export declare class AppArtifactRepository extends BaseRepository<AppArtifact> {
|
|
6
|
-
constructor(dataSource: DataSource, txRunner: TransactionRunner);
|
|
7
|
-
reserve(appId: string, blob: AppBlob, sizeBytes: number, ctx: OperationContext): Promise<AppArtifact>;
|
|
8
|
-
totalSize(ctx: OperationContext): Promise<number>;
|
|
9
|
-
findArtifact(id: number, ctx?: OperationContext): Promise<AppArtifact | null>;
|
|
10
|
-
completeUpload(ref: AppArtifactRef, oldestAllowed: Date, ctx: OperationContext): Promise<boolean>;
|
|
11
|
-
isReferenced(id: number, ctx: OperationContext): Promise<boolean>;
|
|
12
|
-
storeDatabaseContent(ref: AppArtifactRef, body: Buffer, ctx: OperationContext): Promise<void>;
|
|
13
|
-
findUnused(pendingBefore: Date, afterId: number): Promise<AppArtifact[]>;
|
|
14
|
-
removeUnused(ref: AppArtifactRef, ctx: OperationContext): Promise<void>;
|
|
15
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AppArtifactRepository = void 0;
|
|
13
|
-
const db_1 = require("@n8n/db");
|
|
14
|
-
const di_1 = require("@n8n/di");
|
|
15
|
-
const errors_1 = require("@n8n/errors");
|
|
16
|
-
const typeorm_1 = require("@n8n/typeorm");
|
|
17
|
-
const app_artifact_entity_1 = require("./app-artifact.entity");
|
|
18
|
-
const app_version_entity_1 = require("./app-version.entity");
|
|
19
|
-
let AppArtifactRepository = class AppArtifactRepository extends db_1.BaseRepository {
|
|
20
|
-
constructor(dataSource, txRunner) {
|
|
21
|
-
super(app_artifact_entity_1.AppArtifact, dataSource.manager, txRunner);
|
|
22
|
-
}
|
|
23
|
-
async reserve(appId, blob, sizeBytes, ctx) {
|
|
24
|
-
return await this.managerFor(ctx).save(app_artifact_entity_1.AppArtifact, {
|
|
25
|
-
...blob,
|
|
26
|
-
appId,
|
|
27
|
-
sizeBytes,
|
|
28
|
-
uploadStatus: 'pending',
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
async totalSize(ctx) {
|
|
32
|
-
return (await this.managerFor(ctx).sum(app_artifact_entity_1.AppArtifact, 'sizeBytes')) ?? 0;
|
|
33
|
-
}
|
|
34
|
-
async findArtifact(id, ctx = {}) {
|
|
35
|
-
return await this.managerFor(ctx).findOneBy(app_artifact_entity_1.AppArtifact, { id });
|
|
36
|
-
}
|
|
37
|
-
async completeUpload(ref, oldestAllowed, ctx) {
|
|
38
|
-
const result = await this.managerFor(ctx).update(app_artifact_entity_1.AppArtifact, {
|
|
39
|
-
id: ref.id,
|
|
40
|
-
appId: ref.appId,
|
|
41
|
-
storageKey: ref.storageKey,
|
|
42
|
-
uploadStatus: 'pending',
|
|
43
|
-
createdAt: (0, typeorm_1.MoreThanOrEqual)(oldestAllowed),
|
|
44
|
-
}, { uploadStatus: 'completed' });
|
|
45
|
-
return result.affected === 1;
|
|
46
|
-
}
|
|
47
|
-
async isReferenced(id, ctx) {
|
|
48
|
-
return await this.managerFor(ctx).exists(app_version_entity_1.AppVersion, {
|
|
49
|
-
where: [{ sourceArtifactId: id }, { bundleArtifactId: id }],
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
async storeDatabaseContent(ref, body, ctx) {
|
|
53
|
-
const manager = this.managerFor(ctx);
|
|
54
|
-
const artifact = await manager.findOneBy(app_artifact_entity_1.AppArtifact, {
|
|
55
|
-
id: ref.id,
|
|
56
|
-
appId: ref.appId,
|
|
57
|
-
storageKey: ref.storageKey,
|
|
58
|
-
storedAt: 'db',
|
|
59
|
-
uploadStatus: 'pending',
|
|
60
|
-
});
|
|
61
|
-
if (!artifact)
|
|
62
|
-
throw new errors_1.ConflictError('App artifact upload expired. Save the artifact again.');
|
|
63
|
-
await manager.insert(db_1.BinaryDataFile, {
|
|
64
|
-
fileId: artifact.storageKey,
|
|
65
|
-
sourceType: 'app_artifact',
|
|
66
|
-
sourceId: String(artifact.id),
|
|
67
|
-
data: body,
|
|
68
|
-
fileSize: body.length,
|
|
69
|
-
mimeType: 'application/gzip',
|
|
70
|
-
fileName: 'artifact.tgz',
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
async findUnused(pendingBefore, afterId) {
|
|
74
|
-
const query = this.createQueryBuilder('artifact');
|
|
75
|
-
const references = query
|
|
76
|
-
.subQuery()
|
|
77
|
-
.select('1')
|
|
78
|
-
.from(app_version_entity_1.AppVersion, 'version')
|
|
79
|
-
.where('version.sourceArtifactId = artifact.id OR version.bundleArtifactId = artifact.id');
|
|
80
|
-
return await query
|
|
81
|
-
.where(`NOT EXISTS ${references.getQuery()}`)
|
|
82
|
-
.andWhere('artifact.id > :afterId', { afterId })
|
|
83
|
-
.andWhere('(artifact.uploadStatus = :completed OR artifact.createdAt < :pendingBefore)', {
|
|
84
|
-
completed: 'completed',
|
|
85
|
-
pendingBefore,
|
|
86
|
-
})
|
|
87
|
-
.orderBy('artifact.id', 'ASC')
|
|
88
|
-
.take(100)
|
|
89
|
-
.getMany();
|
|
90
|
-
}
|
|
91
|
-
async removeUnused(ref, ctx) {
|
|
92
|
-
await this.managerFor(ctx).delete(app_artifact_entity_1.AppArtifact, {
|
|
93
|
-
id: ref.id,
|
|
94
|
-
appId: ref.appId,
|
|
95
|
-
storageKey: ref.storageKey,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
exports.AppArtifactRepository = AppArtifactRepository;
|
|
100
|
-
exports.AppArtifactRepository = AppArtifactRepository = __decorate([
|
|
101
|
-
(0, di_1.Service)(),
|
|
102
|
-
__metadata("design:paramtypes", [typeorm_1.DataSource, db_1.TransactionRunner])
|
|
103
|
-
], AppArtifactRepository);
|
|
104
|
-
//# sourceMappingURL=app-artifact.repository.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-artifact.repository.js","sourceRoot":"","sources":["../src/app-artifact.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@n8n/backend-common';
|
|
2
|
-
import { DbLockService, type OperationContext } from '@n8n/db';
|
|
3
|
-
import type { AppArtifact, AppArtifactRef } from './app-artifact.entity';
|
|
4
|
-
import { AppArtifactRepository } from './app-artifact.repository';
|
|
5
|
-
import { AppsConfig } from './apps.config';
|
|
6
|
-
import { AppBlobStore } from './storage/app-blob-store';
|
|
7
|
-
export declare class AppArtifactService {
|
|
8
|
-
private readonly repository;
|
|
9
|
-
private readonly blobs;
|
|
10
|
-
private readonly config;
|
|
11
|
-
private readonly locks;
|
|
12
|
-
private readonly logger;
|
|
13
|
-
constructor(repository: AppArtifactRepository, blobs: AppBlobStore, config: AppsConfig, locks: DbLockService, logger: Logger);
|
|
14
|
-
upload(appId: string, body: Buffer): Promise<AppArtifact>;
|
|
15
|
-
completeUpload(ref: AppArtifactRef, ctx: OperationContext): Promise<void>;
|
|
16
|
-
read(id: number): Promise<Buffer>;
|
|
17
|
-
discard(artifact: AppArtifact): Promise<void>;
|
|
18
|
-
cleanup(signal?: AbortSignal): Promise<void>;
|
|
19
|
-
private deleteUnused;
|
|
20
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AppArtifactService = void 0;
|
|
13
|
-
const backend_common_1 = require("@n8n/backend-common");
|
|
14
|
-
const db_1 = require("@n8n/db");
|
|
15
|
-
const di_1 = require("@n8n/di");
|
|
16
|
-
const errors_1 = require("@n8n/errors");
|
|
17
|
-
const app_artifact_repository_1 = require("./app-artifact.repository");
|
|
18
|
-
const app_storage_lock_1 = require("./app-storage-lock");
|
|
19
|
-
const apps_config_1 = require("./apps.config");
|
|
20
|
-
const app_blob_store_1 = require("./storage/app-blob-store");
|
|
21
|
-
const UPLOAD_LIFETIME_MS = 30 * 60 * 1000;
|
|
22
|
-
let AppArtifactService = class AppArtifactService {
|
|
23
|
-
constructor(repository, blobs, config, locks, logger) {
|
|
24
|
-
this.repository = repository;
|
|
25
|
-
this.blobs = blobs;
|
|
26
|
-
this.config = config;
|
|
27
|
-
this.locks = locks;
|
|
28
|
-
this.logger = logger;
|
|
29
|
-
}
|
|
30
|
-
async upload(appId, body) {
|
|
31
|
-
if (body.length > this.config.maxArtifactSizeBytes) {
|
|
32
|
-
throw new errors_1.BadRequestError('App artifact exceeds the compressed size limit. Reduce its size or increase the artifact limit.');
|
|
33
|
-
}
|
|
34
|
-
const artifact = await this.locks.withLockContext(1010, async (ctx) => {
|
|
35
|
-
if ((await this.repository.totalSize(ctx)) + body.length > this.config.maxStorageBytes) {
|
|
36
|
-
throw new errors_1.BadRequestError('App artifact storage limit reached. Free storage space or increase the app storage limit.');
|
|
37
|
-
}
|
|
38
|
-
return await this.repository.reserve(appId, this.blobs.newBlob(), body.length, ctx);
|
|
39
|
-
});
|
|
40
|
-
try {
|
|
41
|
-
await this.blobs.write(artifact, body);
|
|
42
|
-
if (artifact.createdAt.getTime() < Date.now() - UPLOAD_LIFETIME_MS)
|
|
43
|
-
throw new errors_1.ConflictError('App artifact upload expired. Save the artifact again.');
|
|
44
|
-
return artifact;
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
await this.deleteUnused(artifact, true);
|
|
48
|
-
throw error;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
async completeUpload(ref, ctx) {
|
|
52
|
-
if (!(await this.repository.completeUpload(ref, new Date(Date.now() - UPLOAD_LIFETIME_MS), ctx))) {
|
|
53
|
-
throw new errors_1.ConflictError('App artifact upload expired or was already completed. Save the artifact again.');
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
async read(id) {
|
|
57
|
-
const artifact = await this.repository.findArtifact(id);
|
|
58
|
-
if (!artifact || artifact.uploadStatus !== 'completed')
|
|
59
|
-
throw new errors_1.NotFoundError('App artifact not found.');
|
|
60
|
-
if (artifact.sizeBytes > this.config.maxArtifactSizeBytes)
|
|
61
|
-
throw new errors_1.BadRequestError('App artifact exceeds the compressed size limit.');
|
|
62
|
-
const body = await this.blobs.read(artifact);
|
|
63
|
-
if (!body)
|
|
64
|
-
throw new errors_1.NotFoundError('App artifact content not found.');
|
|
65
|
-
if (body.length !== artifact.sizeBytes)
|
|
66
|
-
throw new errors_1.UnexpectedError('App artifact size does not match its record.');
|
|
67
|
-
return body;
|
|
68
|
-
}
|
|
69
|
-
async discard(artifact) {
|
|
70
|
-
await this.deleteUnused(artifact, true);
|
|
71
|
-
}
|
|
72
|
-
async cleanup(signal) {
|
|
73
|
-
const pendingBefore = new Date(Date.now() - UPLOAD_LIFETIME_MS);
|
|
74
|
-
let afterId = 0;
|
|
75
|
-
while (true) {
|
|
76
|
-
signal?.throwIfAborted();
|
|
77
|
-
const artifacts = await this.repository.findUnused(pendingBefore, afterId);
|
|
78
|
-
if (!artifacts.length)
|
|
79
|
-
return;
|
|
80
|
-
for (const artifact of artifacts) {
|
|
81
|
-
signal?.throwIfAborted();
|
|
82
|
-
await this.deleteUnused(artifact);
|
|
83
|
-
}
|
|
84
|
-
afterId = artifacts[artifacts.length - 1].id;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
async deleteUnused(ref, writeSettled = false) {
|
|
88
|
-
try {
|
|
89
|
-
const artifact = await this.locks.withLockContext(1010, async (ctx) => {
|
|
90
|
-
const row = await this.repository.findArtifact(ref.id, ctx);
|
|
91
|
-
if (!row || row.storageKey !== ref.storageKey || row.appId !== ref.appId)
|
|
92
|
-
return writeSettled ? ref : null;
|
|
93
|
-
if (await this.repository.isReferenced(ref.id, ctx))
|
|
94
|
-
return null;
|
|
95
|
-
if (!writeSettled &&
|
|
96
|
-
row.uploadStatus === 'pending' &&
|
|
97
|
-
row.createdAt.getTime() >= Date.now() - UPLOAD_LIFETIME_MS)
|
|
98
|
-
return null;
|
|
99
|
-
return row;
|
|
100
|
-
}, { subKey: (0, app_storage_lock_1.appStorageLockSubKey)(ref.appId) });
|
|
101
|
-
if (!artifact)
|
|
102
|
-
return;
|
|
103
|
-
await this.blobs.delete(artifact);
|
|
104
|
-
await this.locks.withLockContext(1010, async (ctx) => {
|
|
105
|
-
await this.repository.removeUnused(ref, ctx);
|
|
106
|
-
}, { subKey: (0, app_storage_lock_1.appStorageLockSubKey)(ref.appId) });
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
this.logger.warn('Could not delete an unused app artifact.', { artifactId: ref.id, error });
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
exports.AppArtifactService = AppArtifactService;
|
|
114
|
-
exports.AppArtifactService = AppArtifactService = __decorate([
|
|
115
|
-
(0, di_1.Service)(),
|
|
116
|
-
__metadata("design:paramtypes", [app_artifact_repository_1.AppArtifactRepository, app_blob_store_1.AppBlobStore, apps_config_1.AppsConfig, db_1.DbLockService, backend_common_1.Logger])
|
|
117
|
-
], AppArtifactService);
|
|
118
|
-
//# sourceMappingURL=app-artifact.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-artifact.service.js","sourceRoot":"","sources":["../src/app-artifact.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { DbLockService } from '@n8n/db';
|
|
2
|
-
import { AppVersionRepository } from './app-version.repository';
|
|
3
|
-
import { AppRepository } from './app.repository';
|
|
4
|
-
import { AppsConfig } from './apps.config';
|
|
5
|
-
import { AppSourceVersionStore, AppBuildResultStore } from './storage/app-version-stores';
|
|
6
|
-
export declare class AppRetentionService {
|
|
7
|
-
private readonly apps;
|
|
8
|
-
private readonly versions;
|
|
9
|
-
private readonly config;
|
|
10
|
-
private readonly locks;
|
|
11
|
-
private readonly sourceVersions;
|
|
12
|
-
private readonly buildResults;
|
|
13
|
-
constructor(apps: AppRepository, versions: AppVersionRepository, config: AppsConfig, locks: DbLockService, sourceVersions: AppSourceVersionStore, buildResults: AppBuildResultStore);
|
|
14
|
-
prune(appId: string, signal?: AbortSignal): Promise<void>;
|
|
15
|
-
private oldestExcess;
|
|
16
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AppRetentionService = void 0;
|
|
13
|
-
const db_1 = require("@n8n/db");
|
|
14
|
-
const di_1 = require("@n8n/di");
|
|
15
|
-
const app_storage_lock_1 = require("./app-storage-lock");
|
|
16
|
-
const app_version_repository_1 = require("./app-version.repository");
|
|
17
|
-
const app_repository_1 = require("./app.repository");
|
|
18
|
-
const apps_config_1 = require("./apps.config");
|
|
19
|
-
const app_version_stores_1 = require("./storage/app-version-stores");
|
|
20
|
-
let AppRetentionService = class AppRetentionService {
|
|
21
|
-
constructor(apps, versions, config, locks, sourceVersions, buildResults) {
|
|
22
|
-
this.apps = apps;
|
|
23
|
-
this.versions = versions;
|
|
24
|
-
this.config = config;
|
|
25
|
-
this.locks = locks;
|
|
26
|
-
this.sourceVersions = sourceVersions;
|
|
27
|
-
this.buildResults = buildResults;
|
|
28
|
-
}
|
|
29
|
-
async prune(appId, signal) {
|
|
30
|
-
signal?.throwIfAborted();
|
|
31
|
-
await this.locks.withLockContext(1010, async (ctx) => {
|
|
32
|
-
const app = await this.apps.findById(appId, ctx);
|
|
33
|
-
if (!app)
|
|
34
|
-
return;
|
|
35
|
-
const versions = await this.versions.listForRetention(appId, ctx);
|
|
36
|
-
const protectedIds = new Set([app.draftVersionId, app.publishedVersionId]);
|
|
37
|
-
for (const version of versions) {
|
|
38
|
-
if (version.buildStatus === 'queued' || version.buildStatus === 'running')
|
|
39
|
-
protectedIds.add(version.id);
|
|
40
|
-
}
|
|
41
|
-
const built = versions.filter((version) => version.hasBundle);
|
|
42
|
-
if (built[0])
|
|
43
|
-
protectedIds.add(built[0].id);
|
|
44
|
-
const bundlesToRemove = this.oldestExcess(built.map(({ id }) => id), protectedIds, this.config.maxBundlesPerApp);
|
|
45
|
-
await this.buildResults.removeBundles(bundlesToRemove, ctx);
|
|
46
|
-
const removedBundles = new Set(bundlesToRemove);
|
|
47
|
-
for (const version of built) {
|
|
48
|
-
if (!removedBundles.has(version.id))
|
|
49
|
-
protectedIds.add(version.id);
|
|
50
|
-
}
|
|
51
|
-
const versionsToRemove = this.oldestExcess(versions.map(({ id }) => id), protectedIds, this.config.maxVersionsPerApp);
|
|
52
|
-
await this.sourceVersions.removeVersions(versionsToRemove, ctx);
|
|
53
|
-
}, { subKey: (0, app_storage_lock_1.appStorageLockSubKey)(appId) });
|
|
54
|
-
}
|
|
55
|
-
oldestExcess(newestFirst, protectedIds, limit) {
|
|
56
|
-
const keep = new Set(newestFirst.filter((id) => protectedIds.has(id)));
|
|
57
|
-
const remove = [];
|
|
58
|
-
for (const id of newestFirst) {
|
|
59
|
-
if (keep.has(id))
|
|
60
|
-
continue;
|
|
61
|
-
if (keep.size < limit)
|
|
62
|
-
keep.add(id);
|
|
63
|
-
else
|
|
64
|
-
remove.push(id);
|
|
65
|
-
}
|
|
66
|
-
return remove.reverse();
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
exports.AppRetentionService = AppRetentionService;
|
|
70
|
-
exports.AppRetentionService = AppRetentionService = __decorate([
|
|
71
|
-
(0, di_1.Service)(),
|
|
72
|
-
__metadata("design:paramtypes", [app_repository_1.AppRepository, app_version_repository_1.AppVersionRepository, apps_config_1.AppsConfig, db_1.DbLockService, app_version_stores_1.AppSourceVersionStore, app_version_stores_1.AppBuildResultStore])
|
|
73
|
-
], AppRetentionService);
|
|
74
|
-
//# sourceMappingURL=app-retention.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-retention.service.js","sourceRoot":"","sources":["../src/app-retention.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@n8n/backend-common';
|
|
2
|
-
import { SystemTask } from '@n8n/decorators';
|
|
3
|
-
import type { SystemTaskSchedule } from '@n8n/decorators';
|
|
4
|
-
import { AppArtifactService } from './app-artifact.service';
|
|
5
|
-
import { AppRetentionService } from './app-retention.service';
|
|
6
|
-
import { AppRepository } from './app.repository';
|
|
7
|
-
export declare class AppStorageCleanupTask implements SystemTask {
|
|
8
|
-
private readonly apps;
|
|
9
|
-
private readonly retention;
|
|
10
|
-
private readonly artifacts;
|
|
11
|
-
private readonly logger;
|
|
12
|
-
readonly name = "app-storage-cleanup";
|
|
13
|
-
readonly schedule: SystemTaskSchedule;
|
|
14
|
-
readonly target: import("@n8n/decorators").ClusterTarget;
|
|
15
|
-
constructor(apps: AppRepository, retention: AppRetentionService, artifacts: AppArtifactService, logger: Logger);
|
|
16
|
-
run(signal: AbortSignal): Promise<void>;
|
|
17
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
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
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AppStorageCleanupTask = void 0;
|
|
13
|
-
const backend_common_1 = require("@n8n/backend-common");
|
|
14
|
-
const decorators_1 = require("@n8n/decorators");
|
|
15
|
-
const app_artifact_service_1 = require("./app-artifact.service");
|
|
16
|
-
const app_retention_service_1 = require("./app-retention.service");
|
|
17
|
-
const app_repository_1 = require("./app.repository");
|
|
18
|
-
let AppStorageCleanupTask = class AppStorageCleanupTask {
|
|
19
|
-
constructor(apps, retention, artifacts, logger) {
|
|
20
|
-
this.apps = apps;
|
|
21
|
-
this.retention = retention;
|
|
22
|
-
this.artifacts = artifacts;
|
|
23
|
-
this.logger = logger;
|
|
24
|
-
this.name = 'app-storage-cleanup';
|
|
25
|
-
this.schedule = (0, decorators_1.intervalFromSeconds)(15 * 60);
|
|
26
|
-
this.target = (0, decorators_1.clusterTarget)({
|
|
27
|
-
scheduler: { retryOnFailure: true },
|
|
28
|
-
leaderTimer: { retryDelaySeconds: 60 },
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
async run(signal) {
|
|
32
|
-
let after;
|
|
33
|
-
while (true) {
|
|
34
|
-
signal.throwIfAborted();
|
|
35
|
-
const ids = await this.apps.listIdsAfter(after);
|
|
36
|
-
if (!ids.length)
|
|
37
|
-
break;
|
|
38
|
-
for (const id of ids) {
|
|
39
|
-
try {
|
|
40
|
-
await this.retention.prune(id, signal);
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
signal.throwIfAborted();
|
|
44
|
-
this.logger.warn('Could not prune app history.', { appId: id, error });
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
after = ids.at(-1);
|
|
48
|
-
}
|
|
49
|
-
await this.artifacts.cleanup(signal);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
exports.AppStorageCleanupTask = AppStorageCleanupTask;
|
|
53
|
-
exports.AppStorageCleanupTask = AppStorageCleanupTask = __decorate([
|
|
54
|
-
(0, decorators_1.SystemTask)(),
|
|
55
|
-
__metadata("design:paramtypes", [app_repository_1.AppRepository, app_retention_service_1.AppRetentionService, app_artifact_service_1.AppArtifactService, backend_common_1.Logger])
|
|
56
|
-
], AppStorageCleanupTask);
|
|
57
|
-
//# sourceMappingURL=app-storage-cleanup.task.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-storage-cleanup.task.js","sourceRoot":"","sources":["../src/app-storage-cleanup.task.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,wDAA6C;AAC7C,gDAAiF;AAGjF,iEAA4D;AAC5D,mEAA8D;AAC9D,qDAAiD;AAG1C,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAQjC,YACkB,IAAmB,EACnB,SAA8B,EAC9B,SAA6B,EAC7B,MAAc;QAHd,SAAI,GAAJ,IAAI,CAAe;QACnB,cAAS,GAAT,SAAS,CAAqB;QAC9B,cAAS,GAAT,SAAS,CAAoB;QAC7B,WAAM,GAAN,MAAM,CAAQ;QAXvB,SAAI,GAAG,qBAAqB,CAAC;QAC7B,aAAQ,GAAuB,IAAA,gCAAmB,EAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5D,WAAM,GAAG,IAAA,0BAAa,EAAC;YAC/B,SAAS,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;YACnC,WAAW,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE;SACtC,CAAC,CAAC;IAOA,CAAC;IAEJ,KAAK,CAAC,GAAG,CAAC,MAAmB;QAC5B,IAAI,KAAyB,CAAC;QAC9B,OAAO,IAAI,EAAE,CAAC;YACb,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,MAAM;gBAAE,MAAM;YACvB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACJ,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBACxC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,MAAM,CAAC,cAAc,EAAE,CAAC;oBACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBACxE,CAAC;YACF,CAAC;YACD,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;CACD,CAAA;;gCAjCY,qBAAqB;IADjC,IAAA,uBAAU,GAAE;qCAUY,8BAAa,EACR,2CAAmB,EACnB,yCAAkB,EACrB,uBAAM;GAZpB,qBAAqB,CAiCjC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function appStorageLockSubKey(appId: string): number;
|
package/dist/app-storage-lock.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.appStorageLockSubKey = appStorageLockSubKey;
|
|
4
|
-
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
function appStorageLockSubKey(appId) {
|
|
6
|
-
return (0, node_crypto_1.createHash)('sha256').update(appId).digest().readInt32BE(0);
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=app-storage-lock.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-storage-lock.js","sourceRoot":"","sources":["../src/app-storage-lock.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AAEzC,8BAAqC,KAAa;IACjD,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { BaseRepository, TransactionRunner, type OperationContext } from '@n8n/db';
|
|
2
|
-
import { DataSource } from '@n8n/typeorm';
|
|
3
|
-
import { AppVersion } from './app-version.entity';
|
|
4
|
-
export declare class AppVersionRepository extends BaseRepository<AppVersion> {
|
|
5
|
-
constructor(dataSource: DataSource, txRunner: TransactionRunner);
|
|
6
|
-
insertVersion(data: Pick<AppVersion, 'id' | 'appId' | 'sourceArtifactId' | 'label'>, ctx: OperationContext): Promise<void>;
|
|
7
|
-
findVersionById(versionId: string, ctx?: OperationContext): Promise<AppVersion | null>;
|
|
8
|
-
listForApp(appId: string, ctx?: OperationContext): Promise<AppVersion[]>;
|
|
9
|
-
listForRetention(appId: string, ctx: OperationContext): Promise<{
|
|
10
|
-
id: string;
|
|
11
|
-
buildStatus: "failed" | "queued" | "running" | "succeeded";
|
|
12
|
-
hasBundle: boolean;
|
|
13
|
-
}[]>;
|
|
14
|
-
attachBundle(versionId: string, artifactId: number, ctx: OperationContext): Promise<boolean>;
|
|
15
|
-
setLabel(versionId: string, label: string | null, ctx?: OperationContext): Promise<AppVersion | null>;
|
|
16
|
-
clearBundles(versionIds: string[], ctx: OperationContext): Promise<void>;
|
|
17
|
-
removeVersions(versionIds: string[], ctx: OperationContext): Promise<void>;
|
|
18
|
-
}
|