@lilaquadrat/studio 10.0.0-beta.5 → 10.0.0-beta.51
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/eslint.config.js +146 -0
- package/lib/fastify-plugins.d.ts +4 -0
- package/lib/fastify-plugins.js +5 -0
- package/lib/fastify-plugins.js.map +1 -0
- package/lib/helpers.d.ts +4 -2
- package/lib/helpers.js +13 -2
- package/lib/helpers.js.map +1 -1
- package/lib/main.d.ts +1 -3
- package/lib/main.js +7 -3
- package/lib/main.js.map +1 -1
- package/lib/models.d.ts +4 -4
- package/lib/models.js +4 -4
- package/lib/models.js.map +1 -1
- package/lib/services.d.ts +5 -8
- package/lib/services.js +27 -9
- package/lib/services.js.map +1 -1
- package/lib/src/Immutable.class.d.ts +8 -1
- package/lib/src/Immutable.class.js +52 -8
- package/lib/src/Immutable.class.js.map +1 -1
- package/lib/src/ShareClientFactory.class.d.ts +1 -3
- package/lib/src/ShareClientFactory.class.js +1 -9
- package/lib/src/ShareClientFactory.class.js.map +1 -1
- package/lib/src/classes/models.class.js.map +1 -1
- package/lib/src/classes/modelv2.class.d.ts +2 -0
- package/lib/src/classes/modelv2.class.js +1 -1
- package/lib/src/classes/modelv2.class.js.map +1 -1
- package/lib/src/classes/mongo.class.js +4 -14
- package/lib/src/classes/mongo.class.js.map +1 -1
- package/lib/src/functions/handleError.d.ts +2 -3
- package/lib/src/functions/handleError.js +3 -16
- package/lib/src/functions/handleError.js.map +1 -1
- package/lib/src/functions/optionsHelper.d.ts +4 -4
- package/lib/src/functions/optionsHelper.js +5 -4
- package/lib/src/functions/optionsHelper.js.map +1 -1
- package/lib/src/functions/respondCode.d.ts +2 -1
- package/lib/src/functions/respondCode.js +1 -1
- package/lib/src/functions/respondCode.js.map +1 -1
- package/lib/src/helpers/ControllerHelper.d.ts +73 -0
- package/lib/src/helpers/ControllerHelper.js +242 -0
- package/lib/src/helpers/ControllerHelper.js.map +1 -0
- package/lib/src/helpers/EnvMapper.d.ts +0 -0
- package/lib/src/helpers/EnvMapper.js +1 -0
- package/lib/src/helpers/EnvMapper.js.map +1 -0
- package/lib/src/helpers/auth0config.d.ts +6 -0
- package/lib/src/helpers/auth0config.js +23 -0
- package/lib/src/helpers/auth0config.js.map +1 -0
- package/lib/src/helpers/authPlugin.d.ts +29 -0
- package/lib/src/helpers/authPlugin.js +77 -0
- package/lib/src/helpers/authPlugin.js.map +1 -0
- package/lib/src/helpers/cacheHelper.d.ts +69 -0
- package/lib/src/helpers/cacheHelper.js +235 -0
- package/lib/src/helpers/cacheHelper.js.map +1 -0
- package/lib/src/helpers/createSasToken.d.ts +0 -2
- package/lib/src/helpers/createSasToken.js +35 -32
- package/lib/src/helpers/createSasToken.js.map +1 -1
- package/lib/src/helpers/getSecrets.d.ts +1 -1
- package/lib/src/helpers/getSecrets.js +10 -12
- package/lib/src/helpers/getSecrets.js.map +1 -1
- package/lib/src/helpers/queryAssertionPlugin.d.ts +3 -0
- package/lib/src/helpers/queryAssertionPlugin.js +20 -0
- package/lib/src/helpers/queryAssertionPlugin.js.map +1 -0
- package/lib/src/helpers/safeObjectId.d.ts +1 -1
- package/lib/src/helpers/safeObjectId.js +5 -1
- package/lib/src/helpers/safeObjectId.js.map +1 -1
- package/lib/src/helpers/storageSdkFactory.d.ts +2 -0
- package/lib/src/helpers/storageSdkFactory.js +11 -0
- package/lib/src/helpers/storageSdkFactory.js.map +1 -0
- package/lib/src/helpers/studioAppPlugin.d.ts +3 -0
- package/lib/src/helpers/studioAppPlugin.js +16 -0
- package/lib/src/helpers/studioAppPlugin.js.map +1 -0
- package/lib/src/logger.js +154 -32
- package/lib/src/logger.js.map +1 -1
- package/lib/src/models/customers.model.js +14 -4
- package/lib/src/models/customers.model.js.map +1 -1
- package/lib/src/models/design.model.d.ts +4 -0
- package/lib/src/models/design.model.js +58 -0
- package/lib/src/models/design.model.js.map +1 -0
- package/lib/src/models/domain.model.js +1 -1
- package/lib/src/models/domain.model.js.map +1 -1
- package/lib/src/models/editor.model.js +7 -0
- package/lib/src/models/editor.model.js.map +1 -1
- package/lib/src/models/emailLimit.model.d.ts +4 -0
- package/lib/src/models/emailLimit.model.js +31 -0
- package/lib/src/models/emailLimit.model.js.map +1 -0
- package/lib/src/models/hosting.model.js +1 -3
- package/lib/src/models/hosting.model.js.map +1 -1
- package/lib/src/models/hostingSettings.model.js +6 -4
- package/lib/src/models/hostingSettings.model.js.map +1 -1
- package/lib/src/models/invoice.model.d.ts +4 -0
- package/lib/src/models/invoice.model.js +235 -0
- package/lib/src/models/invoice.model.js.map +1 -0
- package/lib/src/models/mailFrom.model.js +53 -10
- package/lib/src/models/mailFrom.model.js.map +1 -1
- package/lib/src/models/project.model.js +2 -4
- package/lib/src/models/project.model.js.map +1 -1
- package/lib/src/models/publish-method.model.js +79 -430
- package/lib/src/models/publish-method.model.js.map +1 -1
- package/lib/src/models/storage.model.js +11 -3
- package/lib/src/models/storage.model.js.map +1 -1
- package/lib/src/prompts/textGeneration.js +88 -0
- package/lib/src/prompts/textGeneration.js.map +1 -1
- package/lib/src/prompts/textGenerationMulti.js +78 -44
- package/lib/src/prompts/textGenerationMulti.js.map +1 -1
- package/lib/src/services/access.service.d.ts +0 -37
- package/lib/src/services/access.service.js +119 -108
- package/lib/src/services/access.service.js.map +1 -1
- package/lib/src/services/ai.service.d.ts +4 -3
- package/lib/src/services/ai.service.js +22 -29
- package/lib/src/services/ai.service.js.map +1 -1
- package/lib/src/services/auth.service.d.ts +10 -0
- package/lib/src/services/auth.service.js +63 -0
- package/lib/src/services/auth.service.js.map +1 -0
- package/lib/src/services/conf.service.d.ts +3 -31
- package/lib/src/services/conf.service.js +58 -167
- package/lib/src/services/conf.service.js.map +1 -1
- package/lib/src/services/customers.service.d.ts +8 -4
- package/lib/src/services/customers.service.js +34 -7
- package/lib/src/services/customers.service.js.map +1 -1
- package/lib/src/services/designs.service.d.ts +7 -0
- package/lib/src/services/designs.service.js +10 -0
- package/lib/src/services/designs.service.js.map +1 -0
- package/lib/src/services/domains.service.d.ts +18 -91
- package/lib/src/services/domains.service.js +91 -559
- package/lib/src/services/domains.service.js.map +1 -1
- package/lib/src/services/editor.service.d.ts +4 -0
- package/lib/src/services/editor.service.js +28 -0
- package/lib/src/services/editor.service.js.map +1 -1
- package/lib/src/services/emailLimit.service.d.ts +21 -0
- package/lib/src/services/emailLimit.service.js +51 -0
- package/lib/src/services/emailLimit.service.js.map +1 -0
- package/lib/src/services/hosting.service.d.ts +12 -24
- package/lib/src/services/hosting.service.js +32 -122
- package/lib/src/services/hosting.service.js.map +1 -1
- package/lib/src/services/hostingAdmin.service.d.ts +1 -1
- package/lib/src/services/hostingAdmin.service.js +2 -2
- package/lib/src/services/hostingAdmin.service.js.map +1 -1
- package/lib/src/services/import.service.d.ts +6 -22
- package/lib/src/services/import.service.js +63 -65
- package/lib/src/services/import.service.js.map +1 -1
- package/lib/src/services/invoices.service.d.ts +30 -0
- package/lib/src/services/invoices.service.js +265 -0
- package/lib/src/services/invoices.service.js.map +1 -0
- package/lib/src/services/jetstream.service.d.ts +5 -3
- package/lib/src/services/jetstream.service.js +63 -7
- package/lib/src/services/jetstream.service.js.map +1 -1
- package/lib/src/services/listParticipants.service.d.ts +2 -5
- package/lib/src/services/listParticipants.service.js +17 -14
- package/lib/src/services/listParticipants.service.js.map +1 -1
- package/lib/src/services/mailFrom.service.d.ts +14 -1
- package/lib/src/services/mailFrom.service.js +55 -0
- package/lib/src/services/mailFrom.service.js.map +1 -1
- package/lib/src/services/me.service.d.ts +22 -12
- package/lib/src/services/me.service.js +58 -89
- package/lib/src/services/me.service.js.map +1 -1
- package/lib/src/services/publish.service.d.ts +3 -7
- package/lib/src/services/publish.service.js +32 -32
- package/lib/src/services/publish.service.js.map +1 -1
- package/lib/src/services/publishData.service.d.ts +10 -7
- package/lib/src/services/publishData.service.js +32 -75
- package/lib/src/services/publishData.service.js.map +1 -1
- package/lib/src/services/spamAnalasys.service.d.ts +4 -4
- package/lib/src/services/spamAnalasys.service.js +36 -44
- package/lib/src/services/spamAnalasys.service.js.map +1 -1
- package/lib/src/services/storage.service.d.ts +22 -29
- package/lib/src/services/storage.service.js +123 -57
- package/lib/src/services/storage.service.js.map +1 -1
- package/lib/src/services/structures.service.d.ts +1 -1
- package/lib/src/services/upload.service.js +6 -1
- package/lib/src/services/upload.service.js.map +1 -1
- package/package.json +28 -29
- package/lib/src/AzureBlobStorage.share.d.ts +0 -19
- package/lib/src/AzureBlobStorage.share.js +0 -162
- package/lib/src/AzureBlobStorage.share.js.map +0 -1
- package/lib/src/AzureFileStorage.share.d.ts +0 -22
- package/lib/src/AzureFileStorage.share.js +0 -139
- package/lib/src/AzureFileStorage.share.js.map +0 -1
- package/lib/src/AzureVault.d.ts +0 -14
- package/lib/src/AzureVault.js +0 -28
- package/lib/src/AzureVault.js.map +0 -1
- package/lib/src/dns.challenge.class.d.ts +0 -17
- package/lib/src/dns.challenge.class.js +0 -41
- package/lib/src/dns.challenge.class.js.map +0 -1
- package/lib/src/http.challenge.class.d.ts +0 -33
- package/lib/src/http.challenge.class.js +0 -58
- package/lib/src/http.challenge.class.js.map +0 -1
- package/lib/src/models/certificate-action.model.d.ts +0 -5
- package/lib/src/models/certificate-action.model.js +0 -230
- package/lib/src/models/certificate-action.model.js.map +0 -1
- package/lib/src/models/certificate.model.d.ts +0 -4
- package/lib/src/models/certificate.model.js +0 -96
- package/lib/src/models/certificate.model.js.map +0 -1
- package/lib/src/models/editorBase.model.d.ts +0 -4
- package/lib/src/models/editorBase.model.js +0 -39
- package/lib/src/models/editorBase.model.js.map +0 -1
- package/lib/src/services/certificates.service.d.ts +0 -56
- package/lib/src/services/certificates.service.js +0 -169
- package/lib/src/services/certificates.service.js.map +0 -1
- package/lib/src/services/certificatesAction.service.d.ts +0 -41
- package/lib/src/services/certificatesAction.service.js +0 -188
- package/lib/src/services/certificatesAction.service.js.map +0 -1
- package/lib/src/services/editorBase.service.d.ts +0 -46
- package/lib/src/services/editorBase.service.js +0 -161
- package/lib/src/services/editorBase.service.js.map +0 -1
- package/lib/src/services/handleFile.service.d.ts +0 -9
- package/lib/src/services/handleFile.service.js +0 -45
- package/lib/src/services/handleFile.service.js.map +0 -1
- package/lib/src/services/media.service.d.ts +0 -35
- package/lib/src/services/media.service.js +0 -418
- package/lib/src/services/media.service.js.map +0 -1
- package/lib/src/services/share.service.d.ts +0 -6
- package/lib/src/services/share.service.js +0 -4
- package/lib/src/services/share.service.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publishData.service.js","sourceRoot":"","sources":["../../../src/services/publishData.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"publishData.service.js","sourceRoot":"","sources":["../../../src/services/publishData.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { CustomerPersonWithEmail } from '@lilaquadrat/interfaces';
|
|
2
|
-
import
|
|
2
|
+
import { GoogleGenAI } from '@google/genai';
|
|
3
3
|
export declare class SpamAnalasys {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
constructor(
|
|
4
|
+
provider: GoogleGenAI;
|
|
5
|
+
model: string;
|
|
6
|
+
constructor(key: string, model: string);
|
|
7
7
|
checkEmailDns(email: string): Promise<boolean>;
|
|
8
8
|
getDomainFromEMail(email: string): string | null;
|
|
9
9
|
check(person: CustomerPersonWithEmail, message: string): Promise<{
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import dnsCallbacks from 'dns';
|
|
2
|
-
import
|
|
2
|
+
import logger from '../logger.js';
|
|
3
|
+
import { GoogleGenAI, ThinkingLevel } from '@google/genai';
|
|
3
4
|
const dns = dnsCallbacks.promises;
|
|
4
5
|
export class SpamAnalasys {
|
|
5
|
-
constructor(
|
|
6
|
-
if (
|
|
7
|
-
this.
|
|
6
|
+
constructor(key, model) {
|
|
7
|
+
if (key) {
|
|
8
|
+
this.provider = new GoogleGenAI({
|
|
9
|
+
apiKey: key,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
logger.warn('NO_API_KEY');
|
|
8
14
|
}
|
|
9
|
-
this.
|
|
15
|
+
this.model = model;
|
|
10
16
|
}
|
|
11
17
|
async checkEmailDns(email) {
|
|
12
18
|
const domain = this.getDomainFromEMail(email);
|
|
@@ -43,51 +49,37 @@ export class SpamAnalasys {
|
|
|
43
49
|
: null;
|
|
44
50
|
}
|
|
45
51
|
async check(person, message) {
|
|
46
|
-
const
|
|
47
|
-
model:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
{
|
|
51
|
-
role: 'system',
|
|
52
|
-
content: `i will provide the data as a json in this format:
|
|
53
|
-
|
|
54
|
-
{
|
|
55
|
-
"name": "LASTNAME",
|
|
56
|
-
"prename": "FIRSTNAME",
|
|
57
|
-
"message": "MESSAGE"
|
|
58
|
-
}
|
|
52
|
+
const response = await this.provider.models.generateContent({
|
|
53
|
+
model: this.model,
|
|
54
|
+
config: {
|
|
55
|
+
systemInstruction: `You are a strict B2B Lead Validation Agent. You will receive a JSON object: {name, prename, message}.
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
Evaluate the input based on two distinct criteria:
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
1. Identity Validation:
|
|
60
|
+
- Fail if 'name' or 'prename' are empty, clearly fake (e.g., "test", "admin", "123"), contain URLs, or are obvious gibberish.
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
2. Intent Validation:
|
|
63
|
+
- Pass only if the 'message' indicates a clear, human business intent (inquiry, support, sales, partnership).
|
|
64
|
+
- Fail if the message is promotional spam (SEO/Crypto), incoherent, automated, or lacks semantic meaning.
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
"useful": BOOLEAN,
|
|
75
|
-
"explanation": "EXPLANATION"
|
|
76
|
-
}`,
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
role: 'user',
|
|
80
|
-
content: JSON.stringify({
|
|
81
|
-
name: person.name,
|
|
82
|
-
prename: person.prename,
|
|
83
|
-
message,
|
|
84
|
-
}),
|
|
66
|
+
Output Instruction:
|
|
67
|
+
Return exactly one JSON object: {useful: BOOLEAN, explanation: STRING}.
|
|
68
|
+
- 'useful': true only if BOTH criteria pass.
|
|
69
|
+
- 'explanation': A concise, single-sentence justification.`,
|
|
70
|
+
thinkingConfig: {
|
|
71
|
+
thinkingLevel: ThinkingLevel.MEDIUM,
|
|
85
72
|
},
|
|
86
|
-
|
|
73
|
+
responseMimeType: 'application/json'
|
|
74
|
+
},
|
|
75
|
+
contents: JSON.stringify({
|
|
76
|
+
name: person.name,
|
|
77
|
+
prename: person.prename,
|
|
78
|
+
message,
|
|
79
|
+
})
|
|
87
80
|
});
|
|
88
|
-
|
|
89
|
-
return response;
|
|
81
|
+
return JSON.parse(response.text);
|
|
90
82
|
}
|
|
91
83
|
}
|
|
92
|
-
export default new SpamAnalasys(process.env.
|
|
84
|
+
export default new SpamAnalasys(process.env.GOOGLE_API_KEY, process.env.AI_MODEL);
|
|
93
85
|
//# sourceMappingURL=spamAnalasys.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spamAnalasys.service.js","sourceRoot":"","sources":["../../../src/services/spamAnalasys.service.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,KAAK,CAAC;AAC/B,OAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"spamAnalasys.service.js","sourceRoot":"","sources":["../../../src/services/spamAnalasys.service.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,KAAK,CAAC;AAC/B,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE3D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC;AAElC,MAAM,OAAO,YAAY;IAMvB,YAAY,GAAW,EAAE,KAAa;QAEpC,IAAI,GAAG,EAAE,CAAC;YAER,IAAI,CAAC,QAAQ,GAAG,IAAI,WAAW,CAAC;gBAC9B,MAAM,EAAE,GAAG;aACZ,CAAC,CAAC;QAEL,CAAC;aAAM,CAAC;YAEN,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5B,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAErB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAa;QAE/B,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,OAAmB,CAAC;QACxB,IAAI,EAA2B,CAAC;QAChC,IAAI,GAAuB,CAAC;QAE5B,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAE1B,IAAI,CAAC;YAEH,OAAO,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACvC,EAAE,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAEnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,OAAO,KAAK,CAAC;QAEf,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAE7B,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAEzB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;gBAEzB,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBAAE,GAAG,GAAG,WAAW,CAAC;YAExD,CAAC,CAAC,CAAC;QAEL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QAEvB,OAAO,IAAI,CAAC;IAEd,CAAC;IAED,kBAAkB,CAAC,KAAa;QAE9B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEpC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;YAChC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YACf,CAAC,CAAC,IAAI,CAAC;IAEX,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAA+B,EAAE,OAAe;QAE1D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC;YAC1D,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE;gBACN,iBAAiB,EAAE;;;;;;;;;;;;;;2DAcgC;gBACnD,cAAc,EAAE;oBACd,aAAa,EAAE,aAAa,CAAC,MAAM;iBACpC;gBACD,gBAAgB,EAAE,kBAAkB;aACrC;YACD,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO;aACR,CAAC;SACH,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAK,CAA6C,CAAC;IAEhF,CAAC;CAEF;AAED,eAAe,IAAI,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,cAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,QAAkB,CAAC,CAAC"}
|
|
@@ -1,30 +1,8 @@
|
|
|
1
1
|
import { ObjectId } from 'mongodb';
|
|
2
|
-
import { Media, ListOfModels, MediaStats, Options, Upload,
|
|
2
|
+
import { Media, ListOfModels, MediaStats, Options, Upload, UserAppOptionsRequired, MediaMetadata, Storage, StorageFilePaths, BasicData } from '@lilaquadrat/interfaces';
|
|
3
3
|
import { type MultipartFile } from '@fastify/multipart';
|
|
4
4
|
import Immutable from '../Immutable.class.js';
|
|
5
5
|
export declare class StorageService extends Immutable<Storage> {
|
|
6
|
-
buckets: {
|
|
7
|
-
cdn: {
|
|
8
|
-
public: boolean;
|
|
9
|
-
overwrite: boolean;
|
|
10
|
-
cache: number;
|
|
11
|
-
};
|
|
12
|
-
hosting: {
|
|
13
|
-
public: boolean;
|
|
14
|
-
overwrite: boolean;
|
|
15
|
-
cache: number;
|
|
16
|
-
};
|
|
17
|
-
secure: {
|
|
18
|
-
public: boolean;
|
|
19
|
-
overwrite: boolean;
|
|
20
|
-
cache: number;
|
|
21
|
-
};
|
|
22
|
-
internal: {
|
|
23
|
-
public: boolean;
|
|
24
|
-
overwrite: boolean;
|
|
25
|
-
cache: number;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
6
|
model: import("../classes/modelv2.class.js").default<Storage, string>;
|
|
29
7
|
options: {
|
|
30
8
|
dataFolder: string;
|
|
@@ -144,11 +122,11 @@ export declare class StorageService extends Immutable<Storage> {
|
|
|
144
122
|
url: string;
|
|
145
123
|
expiresAt: number;
|
|
146
124
|
}>;
|
|
147
|
-
handleFile(uploadInternalId: ObjectId, index: number, file: MultipartFile | undefined): Promise<Stored<Upload>>;
|
|
125
|
+
handleFile(uploadInternalId: ObjectId, index: number, file: MultipartFile | undefined): Promise<import("@lilaquadrat/interfaces").Stored<Upload>>;
|
|
148
126
|
complete(upload: Upload, options?: {
|
|
149
127
|
useNode?: boolean;
|
|
150
128
|
}): Promise<StorageFilePaths>;
|
|
151
|
-
writeFile(data: MultipartFile['file'] | Upload['paths'], index: number | undefined, internalId: ObjectId, type: 'upload' | 'file', options?: {
|
|
129
|
+
writeFile(data: MultipartFile['file'] | Upload['paths'] | string, index: number | undefined, internalId: ObjectId, type: 'upload' | 'file' | 'copy', options?: {
|
|
152
130
|
useNode?: boolean;
|
|
153
131
|
}): Promise<StorageFilePaths>;
|
|
154
132
|
writeFileVersion(data: Buffer, internalId: ObjectId, version: string): Promise<StorageFilePaths>;
|
|
@@ -168,6 +146,21 @@ export declare class StorageService extends Immutable<Storage> {
|
|
|
168
146
|
skip: number;
|
|
169
147
|
limit: number;
|
|
170
148
|
}): Promise<ListOfModels<Media>>;
|
|
149
|
+
/**
|
|
150
|
+
* Get all files for a company/project with optional prefix filtering.
|
|
151
|
+
* Returns a flat list of all matching files without creating virtual folders.
|
|
152
|
+
*
|
|
153
|
+
* @param company - Company identifier
|
|
154
|
+
* @param project - Optional project identifier
|
|
155
|
+
* @param app - Optional app identifier
|
|
156
|
+
* @param prefix - Optional prefix to filter files (e.g., "folder/subfolder")
|
|
157
|
+
* @param limit - Optional pagination with skip and limit
|
|
158
|
+
* @returns Promise with all matching files and count
|
|
159
|
+
*/
|
|
160
|
+
getAllFiles(company: string, project?: string, app?: string, prefix?: string, limit?: {
|
|
161
|
+
skip: number;
|
|
162
|
+
limit: number;
|
|
163
|
+
}): Promise<ListOfModels<Storage>>;
|
|
171
164
|
getTags(company: string, project: string, search: string): Promise<string[]>;
|
|
172
165
|
single(company: string, project: string, filename: string): Promise<Media | null>;
|
|
173
166
|
content(company: string, project: string, id: ObjectId): Promise<Media | null>;
|
|
@@ -178,13 +171,13 @@ export declare class StorageService extends Immutable<Storage> {
|
|
|
178
171
|
company: string;
|
|
179
172
|
project: string | undefined;
|
|
180
173
|
}): Promise<boolean>;
|
|
181
|
-
matchSortTags(documents:
|
|
174
|
+
matchSortTags(documents: Storage[], search: RegExp | string, sort: string): string[];
|
|
182
175
|
checkAllowedSize(filesize: number, allowedSize: number): boolean;
|
|
183
176
|
stats(company: string, project: string): Promise<MediaStats>;
|
|
184
|
-
getByInternalId(internalId: ObjectId, options: Required<Options>): Promise<
|
|
177
|
+
getByInternalId(internalId: ObjectId, options: Required<Options>): Promise<BasicData<Storage> | null>;
|
|
185
178
|
getPathByFilename(filename: string, app: string, options: Required<Options>): Promise<import("mongodb").WithId<Storage> | null>;
|
|
186
|
-
getByFilename(filename: string, prefix: string | undefined,
|
|
187
|
-
removeBlob(internalId: ObjectId, options: Required<UserAppOptionsRequired>): Promise<
|
|
179
|
+
getByFilename(filename: string, prefix: string | undefined, app: string, options: Required<Options>): Promise<BasicData<Storage> | null>;
|
|
180
|
+
removeBlob(internalId: ObjectId, options: Required<UserAppOptionsRequired>): Promise<void>;
|
|
188
181
|
removeBlobVersion(parentId: ObjectId, options: Required<UserAppOptionsRequired>): Promise<void>;
|
|
189
182
|
}
|
|
190
183
|
declare const _default: StorageService;
|
|
@@ -8,31 +8,10 @@ import StorageModel from '../models/storage.model.js';
|
|
|
8
8
|
import JetStreamService from './jetstream.service.js';
|
|
9
9
|
import UploadService from './upload.service.js';
|
|
10
10
|
import filenameHelper from '../helpers/filenameHelper.js';
|
|
11
|
+
import jetstreamService from './jetstream.service.js';
|
|
11
12
|
export class StorageService extends Immutable {
|
|
12
13
|
constructor(options) {
|
|
13
14
|
super();
|
|
14
|
-
this.buckets = {
|
|
15
|
-
cdn: {
|
|
16
|
-
public: true,
|
|
17
|
-
overwrite: false,
|
|
18
|
-
cache: 31536000,
|
|
19
|
-
},
|
|
20
|
-
hosting: {
|
|
21
|
-
public: false,
|
|
22
|
-
overwrite: true,
|
|
23
|
-
cache: 0,
|
|
24
|
-
},
|
|
25
|
-
secure: {
|
|
26
|
-
public: false,
|
|
27
|
-
overwrite: false,
|
|
28
|
-
cache: 31536000,
|
|
29
|
-
},
|
|
30
|
-
internal: {
|
|
31
|
-
public: false,
|
|
32
|
-
overwrite: false,
|
|
33
|
-
cache: 31536000,
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
15
|
this.model = StorageModel;
|
|
37
16
|
this.options = options;
|
|
38
17
|
}
|
|
@@ -272,10 +251,13 @@ export class StorageService extends Immutable {
|
|
|
272
251
|
await this.concatenateFilesWithCat(data, pathAndFile.file);
|
|
273
252
|
}
|
|
274
253
|
}
|
|
275
|
-
else {
|
|
254
|
+
else if (type !== 'copy') {
|
|
276
255
|
const writeStream = fs.createWriteStream(pathAndFile.file);
|
|
277
256
|
await pipeline(data, writeStream);
|
|
278
257
|
}
|
|
258
|
+
else {
|
|
259
|
+
await fs.promises.copyFile(data, pathAndFile.file);
|
|
260
|
+
}
|
|
279
261
|
return pathAndFile;
|
|
280
262
|
}
|
|
281
263
|
async writeFileVersion(data, internalId, version) {
|
|
@@ -302,19 +284,46 @@ export class StorageService extends Immutable {
|
|
|
302
284
|
const filePaths = sortedPaths.map(single => single.path);
|
|
303
285
|
return new Promise((resolve, reject) => {
|
|
304
286
|
const outputStream = fs.createWriteStream(outputPath);
|
|
305
|
-
const
|
|
306
|
-
cat
|
|
287
|
+
const stderrChunks = [];
|
|
288
|
+
const cat = spawn('cat', filePaths, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
289
|
+
cat.stderr?.on('data', (chunk) => {
|
|
290
|
+
stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
291
|
+
});
|
|
292
|
+
cat.stdout.on('error', (error) => {
|
|
293
|
+
outputStream.destroy();
|
|
294
|
+
reject(new Error(`cat stdout error: ${error.message}`));
|
|
295
|
+
});
|
|
307
296
|
cat.on('error', (error) => {
|
|
308
|
-
|
|
297
|
+
const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();
|
|
298
|
+
const preview = filePaths.slice(0, 5).join(', ');
|
|
299
|
+
outputStream.destroy();
|
|
300
|
+
reject(new Error([
|
|
301
|
+
`cat process error: ${error.message}`,
|
|
302
|
+
error.code ? `code=${error.code}` : undefined,
|
|
303
|
+
stderr ? `stderr="${stderr}"` : undefined,
|
|
304
|
+
`files=${filePaths.length}${filePaths.length ? ` (first: ${preview}${filePaths.length > 5 ? ', ...' : ''})` : ''}`,
|
|
305
|
+
].filter(Boolean).join(' | ')));
|
|
309
306
|
});
|
|
310
|
-
cat.
|
|
311
|
-
|
|
307
|
+
cat.stdout.pipe(outputStream);
|
|
308
|
+
cat.on('close', (code, signal) => {
|
|
309
|
+
const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();
|
|
310
|
+
if (code === 0 && !signal) {
|
|
311
|
+
outputStream.end(() => resolve());
|
|
312
312
|
}
|
|
313
313
|
else {
|
|
314
|
-
|
|
314
|
+
const preview = filePaths.slice(0, 5).join(', ');
|
|
315
|
+
outputStream.destroy();
|
|
316
|
+
reject(new Error([
|
|
317
|
+
`cat process exited`,
|
|
318
|
+
`code=${code}`,
|
|
319
|
+
signal ? `signal=${signal}` : undefined,
|
|
320
|
+
stderr ? `stderr="${stderr}"` : undefined,
|
|
321
|
+
`files=${filePaths.length}${filePaths.length ? ` (first: ${preview}${filePaths.length > 5 ? ', ...' : ''})` : ''}`,
|
|
322
|
+
].filter(Boolean).join(' | ')));
|
|
315
323
|
}
|
|
316
324
|
});
|
|
317
325
|
outputStream.on('error', (error) => {
|
|
326
|
+
cat.kill('SIGKILL');
|
|
318
327
|
reject(new Error(`write stream error: ${error.message}`));
|
|
319
328
|
});
|
|
320
329
|
});
|
|
@@ -342,9 +351,7 @@ export class StorageService extends Immutable {
|
|
|
342
351
|
catch (error) {
|
|
343
352
|
if (error.code === 'ENOENT') {
|
|
344
353
|
console.warn(`File not found: ${fullPath}`);
|
|
345
|
-
return;
|
|
346
354
|
}
|
|
347
|
-
throw error;
|
|
348
355
|
}
|
|
349
356
|
}
|
|
350
357
|
/**
|
|
@@ -372,12 +379,6 @@ export class StorageService extends Immutable {
|
|
|
372
379
|
const file = [baseFolder, filename].join('/');
|
|
373
380
|
return { dir: baseFolder, file, relativePath: file };
|
|
374
381
|
}
|
|
375
|
-
// async createUpload(filename: string, size: number, chunks: number, mimetype: string, options: UserAppOptionsRequired) {
|
|
376
|
-
// const useFilename = this.sanitizeName(filename);
|
|
377
|
-
// if (await this.exists(options.company, options.project, useFilename)) throw new Error('FILE_EXISTS');
|
|
378
|
-
// if (await UploadService.uploadExists(options.company, options.project, useFilename)) throw new Error('UPLOAD_EXISTS');
|
|
379
|
-
// return UploadService.createUpload(useFilename, size, chunks, mimetype, options);
|
|
380
|
-
// }
|
|
381
382
|
static sanitizeName(name) {
|
|
382
383
|
return name.replace(/[^a-z0-9-_.]/gi, '').toLowerCase();
|
|
383
384
|
}
|
|
@@ -402,7 +403,7 @@ export class StorageService extends Immutable {
|
|
|
402
403
|
get(company, project, app, query, limit) {
|
|
403
404
|
const realQuery = { company, project, app, parent: { $exists: false } };
|
|
404
405
|
let tags;
|
|
405
|
-
if (query
|
|
406
|
+
if (query?.tags) {
|
|
406
407
|
if (!Array.isArray(query.tags)) {
|
|
407
408
|
tags = [query.tags];
|
|
408
409
|
}
|
|
@@ -411,11 +412,20 @@ export class StorageService extends Immutable {
|
|
|
411
412
|
}
|
|
412
413
|
realQuery['metadata.tags'] = { $in: tags };
|
|
413
414
|
}
|
|
414
|
-
if (query
|
|
415
|
+
if (query?.search) {
|
|
415
416
|
realQuery.filename = { $regex: query.search, $options: 'i' };
|
|
416
417
|
}
|
|
417
418
|
// If ignorePrefix is given, return all matching files without prefix filtering
|
|
418
|
-
if (query
|
|
419
|
+
if (query?.ignorePrefix) {
|
|
420
|
+
// If prefix is provided with ignorePrefix, match all files where prefix starts with the given value
|
|
421
|
+
if (query?.prefix) {
|
|
422
|
+
const prefixWithSlash = query.prefix.endsWith('/') ? query.prefix : `${query.prefix}/`;
|
|
423
|
+
const escapedPrefix = prefixWithSlash.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
424
|
+
realQuery.$or = [
|
|
425
|
+
{ prefix: query.prefix }, // Exact match
|
|
426
|
+
{ prefix: { $regex: `^${escapedPrefix}` } }, // Starts with prefix/
|
|
427
|
+
];
|
|
428
|
+
}
|
|
419
429
|
return StorageModel.db.aggregate([
|
|
420
430
|
{
|
|
421
431
|
$match: realQuery,
|
|
@@ -427,7 +437,7 @@ export class StorageService extends Immutable {
|
|
|
427
437
|
{ $sort: { _id: -1 } },
|
|
428
438
|
{ $skip: limit?.skip || 0 },
|
|
429
439
|
{ $limit: limit?.limit || 50 },
|
|
430
|
-
{ $project: { path: 0
|
|
440
|
+
{ $project: { path: 0 } },
|
|
431
441
|
{ $addFields: { type: 'file' } },
|
|
432
442
|
],
|
|
433
443
|
},
|
|
@@ -444,8 +454,8 @@ export class StorageService extends Immutable {
|
|
|
444
454
|
.then((result) => result[0] || { all: 0, data: [], count: 0 });
|
|
445
455
|
}
|
|
446
456
|
// If search or tags are given, show only files at the current level (no folders)
|
|
447
|
-
if (query
|
|
448
|
-
const isRootLevel = query
|
|
457
|
+
if (query?.search || query?.tags) {
|
|
458
|
+
const isRootLevel = query?.prefix === undefined || query?.prefix === '';
|
|
449
459
|
if (isRootLevel) {
|
|
450
460
|
// Root level: only files without prefix
|
|
451
461
|
realQuery.$or = [
|
|
@@ -469,7 +479,7 @@ export class StorageService extends Immutable {
|
|
|
469
479
|
{ $sort: { _id: -1 } },
|
|
470
480
|
{ $skip: limit?.skip || 0 },
|
|
471
481
|
{ $limit: limit?.limit || 50 },
|
|
472
|
-
{ $project: { path: 0
|
|
482
|
+
{ $project: { path: 0 } },
|
|
473
483
|
{ $addFields: { type: 'file' } },
|
|
474
484
|
],
|
|
475
485
|
},
|
|
@@ -486,7 +496,7 @@ export class StorageService extends Immutable {
|
|
|
486
496
|
.then((result) => result[0] || { all: 0, data: [], count: 0 });
|
|
487
497
|
}
|
|
488
498
|
// Treat undefined prefix same as empty string (root level)
|
|
489
|
-
const isRootLevel = query
|
|
499
|
+
const isRootLevel = query?.prefix === undefined || query?.prefix === '';
|
|
490
500
|
if (isRootLevel) {
|
|
491
501
|
// Root level: show files without prefix and extract virtual folders
|
|
492
502
|
return StorageModel.db.aggregate([
|
|
@@ -521,7 +531,7 @@ export class StorageService extends Immutable {
|
|
|
521
531
|
{ $sort: { _id: -1 } },
|
|
522
532
|
{ $skip: limit?.skip || 0 },
|
|
523
533
|
{ $limit: limit?.limit || 50 },
|
|
524
|
-
{ $project: { path: 0,
|
|
534
|
+
{ $project: { path: 0, immediateSubfolder: 0 } },
|
|
525
535
|
{ $addFields: { type: 'file' } },
|
|
526
536
|
],
|
|
527
537
|
folders: [
|
|
@@ -594,7 +604,7 @@ export class StorageService extends Immutable {
|
|
|
594
604
|
{ $sort: { _id: -1 } },
|
|
595
605
|
{ $skip: limit?.skip || 0 },
|
|
596
606
|
{ $limit: limit?.limit || 50 },
|
|
597
|
-
{ $project: { path: 0,
|
|
607
|
+
{ $project: { path: 0, immediateSubfolder: 0 } },
|
|
598
608
|
{ $addFields: { type: 'file' } },
|
|
599
609
|
],
|
|
600
610
|
folders: [
|
|
@@ -627,7 +637,61 @@ export class StorageService extends Immutable {
|
|
|
627
637
|
.toArray()
|
|
628
638
|
.then((result) => result[0] || { all: 0, data: [], count: 0 });
|
|
629
639
|
}
|
|
630
|
-
|
|
640
|
+
/**
|
|
641
|
+
* Get all files for a company/project with optional prefix filtering.
|
|
642
|
+
* Returns a flat list of all matching files without creating virtual folders.
|
|
643
|
+
*
|
|
644
|
+
* @param company - Company identifier
|
|
645
|
+
* @param project - Optional project identifier
|
|
646
|
+
* @param app - Optional app identifier
|
|
647
|
+
* @param prefix - Optional prefix to filter files (e.g., "folder/subfolder")
|
|
648
|
+
* @param limit - Optional pagination with skip and limit
|
|
649
|
+
* @returns Promise with all matching files and count
|
|
650
|
+
*/
|
|
651
|
+
getAllFiles(company, project, app, prefix, limit) {
|
|
652
|
+
const query = { company, project, app, parent: { $exists: false } };
|
|
653
|
+
// If prefix is provided, filter files with that prefix
|
|
654
|
+
if (prefix) {
|
|
655
|
+
const prefixWithSlash = prefix.endsWith('/') ? prefix : `${prefix}/`;
|
|
656
|
+
const escapedPrefix = prefixWithSlash.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
657
|
+
// Match files that start with the prefix (exact match or deeper)
|
|
658
|
+
query.$or = [
|
|
659
|
+
{ prefix }, // Exact match
|
|
660
|
+
{ prefix: { $regex: `^${escapedPrefix}` } }, // Starts with prefix/
|
|
661
|
+
];
|
|
662
|
+
}
|
|
663
|
+
// Build data pipeline stages
|
|
664
|
+
const dataPipeline = [{ $sort: { _id: -1 } }];
|
|
665
|
+
// Only add pagination if limit is provided
|
|
666
|
+
if (limit) {
|
|
667
|
+
if (limit.skip)
|
|
668
|
+
dataPipeline.push({ $skip: limit.skip });
|
|
669
|
+
if (limit.limit)
|
|
670
|
+
dataPipeline.push({ $limit: limit.limit });
|
|
671
|
+
}
|
|
672
|
+
dataPipeline.push({ $project: { history: 0 } });
|
|
673
|
+
return StorageModel.db.aggregate([
|
|
674
|
+
{
|
|
675
|
+
$match: query,
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
$facet: {
|
|
679
|
+
metadata: [{ $count: 'all' }],
|
|
680
|
+
data: dataPipeline,
|
|
681
|
+
},
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
$project: {
|
|
685
|
+
all: { $arrayElemAt: ['$metadata.all', 0] },
|
|
686
|
+
data: 1,
|
|
687
|
+
count: { $size: '$data' },
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
])
|
|
691
|
+
.toArray()
|
|
692
|
+
.then((result) => result[0] || { all: 0, data: [], count: 0 });
|
|
693
|
+
}
|
|
694
|
+
async getTags(company, project, search) {
|
|
631
695
|
let cleanSearch = search.toLowerCase().trim();
|
|
632
696
|
let sortString = cleanSearch;
|
|
633
697
|
let splitSearch = [];
|
|
@@ -639,9 +703,9 @@ export class StorageService extends Immutable {
|
|
|
639
703
|
else {
|
|
640
704
|
cleanSearch = new RegExp(`^(?!([a-z]+):).*(${cleanSearch}).*`);
|
|
641
705
|
}
|
|
642
|
-
|
|
643
|
-
.toArray()
|
|
644
|
-
|
|
706
|
+
const matchedDocuments = await StorageModel.db.find({ company, project, 'metadata.tags': { $regex: cleanSearch, $options: 'i' } }, { projection: { 'metadata.tags': 1 } })
|
|
707
|
+
.toArray();
|
|
708
|
+
return this.matchSortTags(matchedDocuments, cleanSearch, sortString);
|
|
645
709
|
}
|
|
646
710
|
single(company, project, filename) {
|
|
647
711
|
return StorageModel.db.aggregate([
|
|
@@ -757,7 +821,7 @@ export class StorageService extends Immutable {
|
|
|
757
821
|
const mergedArray = [];
|
|
758
822
|
const returnArray = [];
|
|
759
823
|
documents.forEach((document) => {
|
|
760
|
-
document.tags
|
|
824
|
+
document.metadata?.tags?.forEach((tag) => {
|
|
761
825
|
if (mergedArray.find((tagArray) => tagArray.tag === tag))
|
|
762
826
|
return;
|
|
763
827
|
if (!tag.match(search))
|
|
@@ -806,7 +870,7 @@ export class StorageService extends Immutable {
|
|
|
806
870
|
.then((value) => value[0] || { files: 0, size: 0 });
|
|
807
871
|
}
|
|
808
872
|
getByInternalId(internalId, options) {
|
|
809
|
-
return StorageModel.db.findOne({ _id: internalId, company: options.company, project: options.project });
|
|
873
|
+
return StorageModel.db.findOne({ _id: internalId, company: options.company, project: options.project }, { projection: { path: 0 } });
|
|
810
874
|
}
|
|
811
875
|
getPathByFilename(filename, app, options) {
|
|
812
876
|
const filenameObject = filenameHelper(filename);
|
|
@@ -820,13 +884,13 @@ export class StorageService extends Immutable {
|
|
|
820
884
|
projection: { path: 1, metadata: 1 },
|
|
821
885
|
});
|
|
822
886
|
}
|
|
823
|
-
getByFilename(filename, prefix,
|
|
887
|
+
getByFilename(filename, prefix, app, options) {
|
|
824
888
|
return StorageModel.db.findOne({
|
|
825
889
|
filename,
|
|
826
890
|
prefix,
|
|
827
891
|
company: options.company,
|
|
828
892
|
project: options.project,
|
|
829
|
-
|
|
893
|
+
app,
|
|
830
894
|
});
|
|
831
895
|
}
|
|
832
896
|
async removeBlob(internalId, options) {
|
|
@@ -835,14 +899,16 @@ export class StorageService extends Immutable {
|
|
|
835
899
|
throw new Error('BLOB_NOT_FOUND');
|
|
836
900
|
await fs.promises.unlink(`${this.options.dataFolder}/${storage.path}`);
|
|
837
901
|
await this.removeBlobVersion(internalId, options);
|
|
838
|
-
|
|
902
|
+
await this.delete(internalId, options.user, options.app);
|
|
903
|
+
await jetstreamService.publish(`edge.${storage.app}.removed`, storage);
|
|
839
904
|
}
|
|
840
905
|
async removeBlobVersion(parentId, options) {
|
|
841
906
|
const versions = await this.model.db.find({ parent: parentId, company: options.company, project: options.project }).toArray();
|
|
842
907
|
if (versions.length) {
|
|
843
908
|
await Promise.allSettled(versions.map(async (single) => {
|
|
844
909
|
await fs.promises.unlink(`${this.options.dataFolder}/${single.path}`);
|
|
845
|
-
|
|
910
|
+
await this.delete(single._id, options.user, options.app);
|
|
911
|
+
await jetstreamService.publish(`edge.${single.app}.removed`, single);
|
|
846
912
|
}));
|
|
847
913
|
}
|
|
848
914
|
}
|