@dcl/content-validator 2.1.1-20220621133633.commit-24da31f → 2.1.1-20220623134639.commit-ca80e03
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/content-validator.api.json +104 -217
- package/dist/the-graph-client/the-graph-client.d.ts.map +1 -1
- package/dist/the-graph-client/the-graph-client.js +7 -13
- package/dist/the-graph-client/the-graph-client.js.map +1 -1
- package/dist/types.d.ts +11 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -16
- package/dist/types.js.map +1 -1
- package/dist/validations/ADR51.d.ts +3 -5
- package/dist/validations/ADR51.d.ts.map +1 -1
- package/dist/validations/ADR51.js +4 -0
- package/dist/validations/ADR51.js.map +1 -1
- package/dist/validations/access-checker/access.d.ts.map +1 -1
- package/dist/validations/access-checker/access.js +5 -3
- package/dist/validations/access-checker/access.js.map +1 -1
- package/dist/validations/access-checker/emotes.d.ts +3 -0
- package/dist/validations/access-checker/emotes.d.ts.map +1 -0
- package/dist/validations/access-checker/emotes.js +13 -0
- package/dist/validations/access-checker/emotes.js.map +1 -0
- package/dist/validations/access-checker/items/collection-asset.d.ts +15 -0
- package/dist/validations/access-checker/items/collection-asset.d.ts.map +1 -0
- package/dist/validations/access-checker/items/collection-asset.js +133 -0
- package/dist/validations/access-checker/items/collection-asset.js.map +1 -0
- package/dist/validations/access-checker/items/items.d.ts +13 -0
- package/dist/validations/access-checker/items/items.d.ts.map +1 -0
- package/dist/validations/access-checker/items/items.js +68 -0
- package/dist/validations/access-checker/items/items.js.map +1 -0
- package/dist/validations/access-checker/items/off-chain-asset.d.ts +3 -0
- package/dist/validations/access-checker/items/off-chain-asset.d.ts.map +1 -0
- package/dist/validations/access-checker/items/off-chain-asset.js +17 -0
- package/dist/validations/access-checker/items/off-chain-asset.js.map +1 -0
- package/dist/validations/access-checker/items/third-party-asset.d.ts +3 -0
- package/dist/validations/access-checker/items/third-party-asset.d.ts.map +1 -0
- package/dist/validations/access-checker/items/third-party-asset.js +107 -0
- package/dist/validations/access-checker/items/third-party-asset.js.map +1 -0
- package/dist/validations/access-checker/profiles.d.ts.map +1 -1
- package/dist/validations/access-checker/profiles.js +3 -3
- package/dist/validations/access-checker/profiles.js.map +1 -1
- package/dist/validations/access-checker/scenes.d.ts.map +1 -1
- package/dist/validations/access-checker/scenes.js +3 -3
- package/dist/validations/access-checker/scenes.js.map +1 -1
- package/dist/validations/access-checker/wearables.d.ts +0 -18
- package/dist/validations/access-checker/wearables.d.ts.map +1 -1
- package/dist/validations/access-checker/wearables.js +9 -308
- package/dist/validations/access-checker/wearables.js.map +1 -1
- package/dist/validations/content.d.ts +3 -0
- package/dist/validations/content.d.ts.map +1 -1
- package/dist/validations/content.js +30 -17
- package/dist/validations/content.js.map +1 -1
- package/dist/validations/index.d.ts +4 -23
- package/dist/validations/index.d.ts.map +1 -1
- package/dist/validations/index.js +4 -31
- package/dist/validations/index.js.map +1 -1
- package/dist/validations/ipfs-hashing.d.ts.map +1 -1
- package/dist/validations/ipfs-hashing.js +3 -6
- package/dist/validations/ipfs-hashing.js.map +1 -1
- package/dist/validations/items/emotes.d.ts +5 -0
- package/dist/validations/items/emotes.d.ts.map +1 -0
- package/dist/validations/items/emotes.js +35 -0
- package/dist/validations/items/emotes.js.map +1 -0
- package/dist/validations/items/items.d.ts +10 -0
- package/dist/validations/items/items.d.ts.map +1 -0
- package/dist/validations/items/items.js +79 -0
- package/dist/validations/items/items.js.map +1 -0
- package/dist/validations/{wearable.d.ts → items/wearables.d.ts} +2 -5
- package/dist/validations/items/wearables.d.ts.map +1 -0
- package/dist/validations/items/wearables.js +32 -0
- package/dist/validations/items/wearables.js.map +1 -0
- package/dist/validations/metadata-schema.d.ts +2 -5
- package/dist/validations/metadata-schema.d.ts.map +1 -1
- package/dist/validations/metadata-schema.js +37 -7
- package/dist/validations/metadata-schema.js.map +1 -1
- package/dist/validations/profile.d.ts.map +1 -1
- package/dist/validations/profile.js +8 -18
- package/dist/validations/profile.js.map +1 -1
- package/dist/validations/size.d.ts.map +1 -1
- package/dist/validations/size.js +4 -3
- package/dist/validations/size.js.map +1 -1
- package/dist/validations/timestamps.d.ts +21 -0
- package/dist/validations/timestamps.d.ts.map +1 -0
- package/dist/validations/timestamps.js +24 -0
- package/dist/validations/timestamps.js.map +1 -0
- package/dist/validations/validations.d.ts +9 -0
- package/dist/validations/validations.d.ts.map +1 -0
- package/dist/validations/validations.js +47 -0
- package/dist/validations/validations.js.map +1 -0
- package/package.json +4 -3
- package/dist/validations/wearable.d.ts.map +0 -1
- package/dist/validations/wearable.js +0 -110
- package/dist/validations/wearable.js.map +0 -1
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.content = void 0;
|
|
3
|
+
exports.content = exports.allContentFilesCorrespondToAtLeastOneAvatarSnapshotAfterADR45 = exports.allHashesInUploadedFilesAreReportedInTheEntity = exports.allHashesWereUploadedOrStored = void 0;
|
|
4
4
|
const schemas_1 = require("@dcl/schemas");
|
|
5
|
-
const _1 = require(".");
|
|
6
5
|
const types_1 = require("../types");
|
|
6
|
+
const validations_1 = require("./validations");
|
|
7
7
|
const correspondsToASnapshot = (fileName, hash, metadata) => {
|
|
8
8
|
const fileNameWithoutExtension = fileName.replace(/.[^/.]+$/, '');
|
|
9
9
|
if (!metadata || !metadata.avatars)
|
|
10
10
|
return false;
|
|
11
11
|
return metadata.avatars.some((avatar) => Object.entries(avatar.avatar.snapshots).some((key) => key[0] === fileNameWithoutExtension && key[1] === hash));
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* @public
|
|
16
|
-
*/
|
|
17
|
-
exports.content = {
|
|
18
|
-
validate: async ({ externalCalls }, deployment) => {
|
|
13
|
+
exports.allHashesWereUploadedOrStored = {
|
|
14
|
+
async validate(components, deployment) {
|
|
19
15
|
const { entity, files } = deployment;
|
|
20
16
|
const errors = [];
|
|
21
17
|
if (entity.content) {
|
|
22
|
-
const alreadyStoredHashes = await externalCalls.isContentStoredAlready(entity.content?.map((file) => file.hash) ?? []);
|
|
18
|
+
const alreadyStoredHashes = await components.externalCalls.isContentStoredAlready(entity.content?.map((file) => file.hash) ?? []);
|
|
23
19
|
for (const { hash } of entity.content) {
|
|
24
20
|
// Validate that all hashes in entity were uploaded, or were already stored on the service
|
|
25
21
|
if (!(files.has(hash) || alreadyStoredHashes.get(hash))) {
|
|
@@ -27,6 +23,13 @@ exports.content = {
|
|
|
27
23
|
}
|
|
28
24
|
}
|
|
29
25
|
}
|
|
26
|
+
return (0, types_1.fromErrors)(...errors);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.allHashesInUploadedFilesAreReportedInTheEntity = {
|
|
30
|
+
async validate(components, deployment) {
|
|
31
|
+
const { entity, files } = deployment;
|
|
32
|
+
const errors = [];
|
|
30
33
|
// Validate that all hashes that belong to uploaded files are actually reported on the entity
|
|
31
34
|
const entityHashes = new Set(entity.content?.map(({ hash }) => hash) ?? []);
|
|
32
35
|
for (const [hash] of files) {
|
|
@@ -34,17 +37,27 @@ exports.content = {
|
|
|
34
37
|
errors.push(`This hash was uploaded but is not referenced in the entity: ${hash}`);
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
return (0, types_1.fromErrors)(...errors);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
exports.allContentFilesCorrespondToAtLeastOneAvatarSnapshotAfterADR45 = (0, validations_1.validationAfterADR45)({
|
|
44
|
+
async validate(components, deployment) {
|
|
45
|
+
const { entity } = deployment;
|
|
46
|
+
const errors = [];
|
|
47
|
+
for (const { file, hash } of entity.content ?? []) {
|
|
48
|
+
// Validate all content files correspond to at least one avatar snapshot
|
|
49
|
+
if (entity.type === schemas_1.EntityType.PROFILE) {
|
|
50
|
+
if (!correspondsToASnapshot(file, hash, entity.metadata)) {
|
|
51
|
+
errors.push(`This file is not expected: '${file}' or its hash is invalid: '${hash}'. Please, include only valid snapshot files.`);
|
|
44
52
|
}
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
55
|
return (0, types_1.fromErrors)(...errors);
|
|
48
56
|
}
|
|
49
|
-
};
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* Validate that uploaded and reported hashes are corrects and files corresponds to snapshots
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
exports.content = (0, validations_1.validationGroup)(exports.allHashesWereUploadedOrStored, exports.allHashesInUploadedFilesAreReportedInTheEntity, exports.allContentFilesCorrespondToAtLeastOneAvatarSnapshotAfterADR45);
|
|
50
63
|
//# sourceMappingURL=content.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/validations/content.ts"],"names":[],"mappings":";;;AAAA,0CAA0D;AAC1D,
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/validations/content.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
/**
|
|
3
|
-
* @public
|
|
4
|
-
*/
|
|
5
|
-
export declare const validateInRow: (components: ContentValidatorComponents, deployment: DeploymentToValidate, ...validations: Validation[]) => Promise<ValidationResponse>;
|
|
6
|
-
/**
|
|
7
|
-
* 1652191200000 = 2022-05-10T14:00:00Z
|
|
8
|
-
* @public
|
|
9
|
-
*/
|
|
10
|
-
export declare const ADR_45_TIMESTAMP: number;
|
|
11
|
-
/**
|
|
12
|
-
* 1658275200000 = 2022-07-20T00:00:00Z
|
|
13
|
-
* @public
|
|
14
|
-
*/
|
|
15
|
-
export declare const ADR_75_TIMESTAMP: number;
|
|
16
|
-
/**
|
|
17
|
-
* DCL Launch Day
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
export declare const LEGACY_CONTENT_MIGRATION_TIMESTAMP = 1582167600000;
|
|
1
|
+
import { DeploymentToValidate, ExternalCalls } from '../types';
|
|
21
2
|
/**
|
|
22
3
|
* @public
|
|
23
4
|
*/
|
|
@@ -26,15 +7,15 @@ export declare const calculateDeploymentSize: (deployment: DeploymentToValidate,
|
|
|
26
7
|
* Stateful validations that are run on a deployment.
|
|
27
8
|
* @public
|
|
28
9
|
*/
|
|
29
|
-
export declare const statefulValidations: readonly [Validation, Validation, Validation, Validation, Validation, Validation];
|
|
10
|
+
export declare const statefulValidations: readonly [import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation];
|
|
30
11
|
/**
|
|
31
12
|
* Stateless validations that are run on a deployment.
|
|
32
13
|
* @public
|
|
33
14
|
*/
|
|
34
|
-
export declare const statelessValidations: readonly [Validation, Validation, Validation];
|
|
15
|
+
export declare const statelessValidations: readonly [import("../types").Validation, import("../types").Validation, import("../types").Validation];
|
|
35
16
|
/**
|
|
36
17
|
* All validations that are run on a deployment.
|
|
37
18
|
* @public
|
|
38
19
|
*/
|
|
39
|
-
export declare const validations: readonly [Validation, Validation, Validation, Validation, Validation, Validation, Validation, Validation, Validation];
|
|
20
|
+
export declare const validations: readonly [import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation, import("../types").Validation];
|
|
40
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validations/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAY9D;;GAEG;AACH,eAAO,MAAM,uBAAuB,eACtB,oBAAoB,iBACjB,aAAa,KAC3B,QAAQ,MAAM,GAAG,MAAM,CAazB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,oOAAwE,CAAA;AAExG;;;GAGG;AACH,eAAO,MAAM,oBAAoB,wGAAoD,CAAA;AAErF;;;GAGG;AACH,eAAO,MAAM,WAAW,iUAA6D,CAAA"}
|
|
@@ -1,43 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validations = exports.statelessValidations = exports.statefulValidations = exports.calculateDeploymentSize =
|
|
4
|
-
const types_1 = require("../types");
|
|
3
|
+
exports.validations = exports.statelessValidations = exports.statefulValidations = exports.calculateDeploymentSize = void 0;
|
|
5
4
|
const access_1 = require("./access-checker/access");
|
|
6
5
|
const content_1 = require("./content");
|
|
7
6
|
const entity_structure_1 = require("./entity-structure");
|
|
8
7
|
const ipfs_hashing_1 = require("./ipfs-hashing");
|
|
8
|
+
const emotes_1 = require("./items/emotes");
|
|
9
|
+
const wearables_1 = require("./items/wearables");
|
|
9
10
|
const metadata_schema_1 = require("./metadata-schema");
|
|
10
11
|
const profile_1 = require("./profile");
|
|
11
12
|
const signature_1 = require("./signature");
|
|
12
13
|
const size_1 = require("./size");
|
|
13
|
-
const wearable_1 = require("./wearable");
|
|
14
|
-
/**
|
|
15
|
-
* @public
|
|
16
|
-
*/
|
|
17
|
-
const validateInRow = async (components, deployment, ...validations) => {
|
|
18
|
-
for (const validation of validations) {
|
|
19
|
-
const response = await validation.validate(components, deployment);
|
|
20
|
-
if (!response.ok)
|
|
21
|
-
return response;
|
|
22
|
-
}
|
|
23
|
-
return types_1.OK;
|
|
24
|
-
};
|
|
25
|
-
exports.validateInRow = validateInRow;
|
|
26
|
-
/**
|
|
27
|
-
* 1652191200000 = 2022-05-10T14:00:00Z
|
|
28
|
-
* @public
|
|
29
|
-
*/
|
|
30
|
-
exports.ADR_45_TIMESTAMP = process.env.ADR_45_TIMESTAMP ? parseInt(process.env.ADR_45_TIMESTAMP) : 1652191200000;
|
|
31
|
-
/**
|
|
32
|
-
* 1658275200000 = 2022-07-20T00:00:00Z
|
|
33
|
-
* @public
|
|
34
|
-
*/
|
|
35
|
-
exports.ADR_75_TIMESTAMP = process.env.ADR_75_TIMESTAMP ? parseInt(process.env.ADR_75_TIMESTAMP) : 1658275200000;
|
|
36
|
-
/**
|
|
37
|
-
* DCL Launch Day
|
|
38
|
-
* @public
|
|
39
|
-
*/
|
|
40
|
-
exports.LEGACY_CONTENT_MIGRATION_TIMESTAMP = 1582167600000;
|
|
41
14
|
/**
|
|
42
15
|
* @public
|
|
43
16
|
*/
|
|
@@ -62,7 +35,7 @@ exports.calculateDeploymentSize = calculateDeploymentSize;
|
|
|
62
35
|
* Stateful validations that are run on a deployment.
|
|
63
36
|
* @public
|
|
64
37
|
*/
|
|
65
|
-
exports.statefulValidations = [signature_1.signature, access_1.access, size_1.size,
|
|
38
|
+
exports.statefulValidations = [signature_1.signature, access_1.access, size_1.size, wearables_1.wearable, emotes_1.emote, profile_1.profile, content_1.content];
|
|
66
39
|
/**
|
|
67
40
|
* Stateless validations that are run on a deployment.
|
|
68
41
|
* @public
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validations/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validations/index.ts"],"names":[],"mappings":";;;AACA,oDAAgD;AAChD,uCAAmC;AACnC,yDAAoD;AACpD,iDAA4C;AAC5C,2CAAsC;AACtC,iDAA4C;AAC5C,uDAA4C;AAC5C,uCAAmC;AACnC,2CAAuC;AACvC,iCAA6B;AAE7B;;GAEG;AACI,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAgC,EAChC,aAA4B,EACF,EAAE;IAC5B,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,KAAK,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE;QACrF,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC/C,IAAI,YAAY,EAAE;YAChB,SAAS,IAAI,YAAY,CAAC,UAAU,CAAA;SACrC;aAAM;YACL,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAA;YAClE,IAAI,WAAW,KAAK,SAAS;gBAAE,OAAO,0CAA0C,IAAI,EAAE,CAAA;YACtF,SAAS,IAAI,WAAW,CAAA;SACzB;KACF;IACD,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAhBY,QAAA,uBAAuB,2BAgBnC;AAED;;;GAGG;AACU,QAAA,mBAAmB,GAAG,CAAC,qBAAS,EAAE,eAAM,EAAE,WAAI,EAAE,oBAAQ,EAAE,cAAK,EAAE,iBAAO,EAAE,iBAAO,CAAU,CAAA;AAExG;;;GAGG;AACU,QAAA,oBAAoB,GAAG,CAAC,kCAAe,EAAE,0BAAW,EAAE,0BAAQ,CAAU,CAAA;AAErF;;;GAGG;AACU,QAAA,WAAW,GAAG,CAAC,GAAG,4BAAoB,EAAE,GAAG,2BAAmB,CAAU,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipfs-hashing.d.ts","sourceRoot":"","sources":["../../src/validations/ipfs-hashing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ipfs-hashing.d.ts","sourceRoot":"","sources":["../../src/validations/ipfs-hashing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,UAAU,EAAE,MAAM,UAAU,CAAA;AAGjD;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,UAaxB,CAAA"}
|
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ipfsHashing = void 0;
|
|
4
4
|
const schemas_1 = require("@dcl/schemas");
|
|
5
|
-
const _1 = require(".");
|
|
6
|
-
const __1 = require("..");
|
|
7
5
|
const types_1 = require("../types");
|
|
6
|
+
const validations_1 = require("./validations");
|
|
8
7
|
/**
|
|
9
8
|
* Validate that all hashes used by the entity were actually IPFS hashes
|
|
10
9
|
* @public
|
|
11
10
|
*/
|
|
12
|
-
exports.ipfsHashing = {
|
|
11
|
+
exports.ipfsHashing = (0, validations_1.validationAfterADR45)({
|
|
13
12
|
validate: (components, deployment) => {
|
|
14
13
|
const { entity } = deployment;
|
|
15
|
-
if (entity.timestamp < _1.ADR_45_TIMESTAMP)
|
|
16
|
-
return __1.OK;
|
|
17
14
|
const hashesInContent = entity.content?.map(({ hash }) => hash) ?? [];
|
|
18
15
|
const allHashes = [entity.id, ...hashesInContent];
|
|
19
16
|
const errors = allHashes
|
|
@@ -21,5 +18,5 @@ exports.ipfsHashing = {
|
|
|
21
18
|
.map((hash) => `This hash '${hash}' is not valid. It should be IPFS v2 format.`);
|
|
22
19
|
return (0, types_1.fromErrors)(...errors);
|
|
23
20
|
}
|
|
24
|
-
};
|
|
21
|
+
});
|
|
25
22
|
//# sourceMappingURL=ipfs-hashing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipfs-hashing.js","sourceRoot":"","sources":["../../src/validations/ipfs-hashing.ts"],"names":[],"mappings":";;;AAAA,0CAAqC;
|
|
1
|
+
{"version":3,"file":"ipfs-hashing.js","sourceRoot":"","sources":["../../src/validations/ipfs-hashing.ts"],"names":[],"mappings":";;;AAAA,0CAAqC;AAErC,oCAAiD;AACjD,+CAAoD;AAEpD;;;GAGG;AACU,QAAA,WAAW,GAAe,IAAA,kCAAoB,EAAC;IAC1D,QAAQ,EAAE,CAAC,UAAsC,EAAE,UAAU,EAAE,EAAE;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;QAE7B,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QACrE,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,eAAe,CAAC,CAAA;QAEjD,MAAM,MAAM,GAAG,SAAS;aACrB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,gBAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,IAAI,8CAA8C,CAAC,CAAA;QAElF,OAAO,IAAA,kBAAU,EAAC,GAAG,MAAM,CAAC,CAAA;IAC9B,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emotes.d.ts","sourceRoot":"","sources":["../../../src/validations/items/emotes.ts"],"names":[],"mappings":"AACA,OAAO,EAAwD,UAAU,EAAoB,MAAM,aAAa,CAAA;AAIhH,eAAO,MAAM,oBAAoB,EAAE,UAQlC,CAAA;AAED,eAAO,MAAM,0BAA0B,EAAE,UAiBxC,CAAA;AAED,eAAO,MAAM,KAAK,EAAE,UAGnB,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emote = exports.emoteRepresentationContent = exports.wasCreatedAfterADR74 = void 0;
|
|
4
|
+
const schemas_1 = require("@dcl/schemas");
|
|
5
|
+
const types_1 = require("../../types");
|
|
6
|
+
const timestamps_1 = require("../timestamps");
|
|
7
|
+
const validations_1 = require("../validations");
|
|
8
|
+
exports.wasCreatedAfterADR74 = {
|
|
9
|
+
validate(components, deployment) {
|
|
10
|
+
return deployment.entity.timestamp < timestamps_1.ADR_74_TIMESTAMP
|
|
11
|
+
? (0, types_1.validationFailed)(`The emote timestamp ${deployment.entity.timestamp} is before ADR 74. Emotes did not exist before ADR 74.`)
|
|
12
|
+
: types_1.OK;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
exports.emoteRepresentationContent = {
|
|
16
|
+
validate: async (components, deployment) => {
|
|
17
|
+
const { entity } = deployment;
|
|
18
|
+
const metadata = entity.metadata;
|
|
19
|
+
const representations = metadata?.emoteDataADR74?.representations;
|
|
20
|
+
if (!representations || representations.length === 0)
|
|
21
|
+
return (0, types_1.validationFailed)('No emote representations found');
|
|
22
|
+
if (!entity.content || entity.content.length === 0)
|
|
23
|
+
return (0, types_1.validationFailed)('No content found');
|
|
24
|
+
for (const representation of representations) {
|
|
25
|
+
for (const representationContent of representation.contents) {
|
|
26
|
+
if (!entity.content.find((content) => content.file === representationContent)) {
|
|
27
|
+
return (0, types_1.validationFailed)(`Representation content: '${representationContent}' is not one of the content files`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return types_1.OK;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
exports.emote = (0, validations_1.validationForType)(schemas_1.EntityType.EMOTE, (0, validations_1.validationGroup)(exports.wasCreatedAfterADR74, exports.emoteRepresentationContent));
|
|
35
|
+
//# sourceMappingURL=emotes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emotes.js","sourceRoot":"","sources":["../../../src/validations/items/emotes.ts"],"names":[],"mappings":";;;AAAA,0CAAgD;AAChD,uCAAgH;AAChH,8CAAgD;AAChD,gDAAmE;AAEtD,QAAA,oBAAoB,GAAe;IAC9C,QAAQ,CAAC,UAAsC,EAAE,UAAgC;QAC/E,OAAO,UAAU,CAAC,MAAM,CAAC,SAAS,GAAG,6BAAgB;YACnD,CAAC,CAAC,IAAA,wBAAgB,EACd,uBAAuB,UAAU,CAAC,MAAM,CAAC,SAAS,wDAAwD,CAC3G;YACH,CAAC,CAAC,UAAE,CAAA;IACR,CAAC;CACF,CAAA;AAEY,QAAA,0BAA0B,GAAe;IACpD,QAAQ,EAAE,KAAK,EAAE,UAAsC,EAAE,UAAU,EAAE,EAAE;QACrE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;QAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAiB,CAAA;QACzC,MAAM,eAAe,GAAG,QAAQ,EAAE,cAAc,EAAE,eAAe,CAAA;QACjE,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAA,wBAAgB,EAAC,gCAAgC,CAAC,CAAA;QAC/G,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAA,wBAAgB,EAAC,kBAAkB,CAAC,CAAA;QAE/F,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE;YAC5C,KAAK,MAAM,qBAAqB,IAAI,cAAc,CAAC,QAAQ,EAAE;gBAC3D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,qBAAqB,CAAC,EAAE;oBAC7E,OAAO,IAAA,wBAAgB,EAAC,4BAA4B,qBAAqB,mCAAmC,CAAC,CAAA;iBAC9G;aACF;SACF;QACD,OAAO,UAAE,CAAA;IACX,CAAC;CACF,CAAA;AAEY,QAAA,KAAK,GAAe,IAAA,+BAAiB,EAChD,oBAAU,CAAC,KAAK,EAChB,IAAA,6BAAe,EAAC,4BAAoB,EAAE,kCAA0B,CAAC,CAClE,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Validation } from '../../types';
|
|
2
|
+
/** Validate item files size, excluding thumbnail, is less than expected */
|
|
3
|
+
export declare const deploymentMaxSizeExcludingThumbnailIsNotExceeded: Validation;
|
|
4
|
+
export declare const thumbnailMaxSizeIsNotExceeded: Validation;
|
|
5
|
+
/**
|
|
6
|
+
* Validate that given item deployment includes the thumbnail and doesn't exceed file sizes
|
|
7
|
+
* * @public
|
|
8
|
+
*/
|
|
9
|
+
export declare const items: Validation;
|
|
10
|
+
//# sourceMappingURL=items.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../../../src/validations/items/items.ts"],"names":[],"mappings":"AAIA,OAAO,EAAM,UAAU,EAAoB,MAAM,aAAa,CAAA;AAI9D,2EAA2E;AAC3E,eAAO,MAAM,gDAAgD,EAAE,UA0B9D,CAAA;AAID,eAAO,MAAM,6BAA6B,EAAE,UAkC3C,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,UAGnB,CAAA"}
|
|
@@ -0,0 +1,79 @@
|
|
|
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.items = exports.thumbnailMaxSizeIsNotExceeded = exports.deploymentMaxSizeExcludingThumbnailIsNotExceeded = void 0;
|
|
7
|
+
const schemas_1 = require("@dcl/schemas");
|
|
8
|
+
const sharp_1 = __importDefault(require("sharp"));
|
|
9
|
+
const __1 = require("..");
|
|
10
|
+
const types_1 = require("../../types");
|
|
11
|
+
const ADR51_1 = require("../ADR51");
|
|
12
|
+
const validations_1 = require("../validations");
|
|
13
|
+
/** Validate item files size, excluding thumbnail, is less than expected */
|
|
14
|
+
exports.deploymentMaxSizeExcludingThumbnailIsNotExceeded = {
|
|
15
|
+
validate: async ({ externalCalls }, deployment) => {
|
|
16
|
+
const entity = deployment.entity;
|
|
17
|
+
const maxSizeInMB = ADR51_1.entityParameters[entity.type]?.maxSizeInMB;
|
|
18
|
+
if (!maxSizeInMB)
|
|
19
|
+
return (0, types_1.validationFailed)(`Type ${entity.type} is not supported yet`);
|
|
20
|
+
const modelSizeInMB = maxSizeInMB - maxThumbnailSizeInB / 1024;
|
|
21
|
+
const metadata = entity.metadata;
|
|
22
|
+
const thumbnailHash = entity.content?.find(({ file }) => file === metadata.thumbnail)?.hash;
|
|
23
|
+
if (!thumbnailHash)
|
|
24
|
+
return (0, types_1.validationFailed)("Couldn't find the thumbnail hash");
|
|
25
|
+
const totalDeploymentSizeInB = await (0, __1.calculateDeploymentSize)(deployment, externalCalls);
|
|
26
|
+
if (typeof totalDeploymentSizeInB === 'string')
|
|
27
|
+
return (0, types_1.validationFailed)(totalDeploymentSizeInB);
|
|
28
|
+
const thumbnailSize = deployment.files.get(thumbnailHash)?.byteLength ?? 0;
|
|
29
|
+
const modelSize = totalDeploymentSizeInB - thumbnailSize;
|
|
30
|
+
if (modelSize > modelSizeInMB * 1024 * 1024)
|
|
31
|
+
return (0, types_1.validationFailed)(`The deployment is too big. The maximum allowed size for ${entity.type} model files is ${modelSizeInMB} MB. You can upload up to ${modelSizeInMB * 1024 * 1024} bytes but you tried to upload ${modelSize}.`);
|
|
32
|
+
return types_1.OK;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
/** Validate that given item deployment includes a thumbnail with valid format and size */
|
|
36
|
+
const maxThumbnailSizeInB = 1024;
|
|
37
|
+
exports.thumbnailMaxSizeIsNotExceeded = {
|
|
38
|
+
validate: async ({ externalCalls, logs }, deployment) => {
|
|
39
|
+
const logger = logs.getLogger(`${deployment.entity.type} validator`);
|
|
40
|
+
// read thumbnail field from metadata
|
|
41
|
+
const metadata = deployment.entity.metadata;
|
|
42
|
+
const hash = deployment.entity.content?.find(({ file }) => file === metadata.thumbnail)?.hash;
|
|
43
|
+
if (!hash)
|
|
44
|
+
return (0, types_1.validationFailed)(`Couldn't find hash for thumbnail file with name: ${metadata.thumbnail}`);
|
|
45
|
+
const errors = [];
|
|
46
|
+
// check size
|
|
47
|
+
const thumbnailBuffer = deployment.files.get(hash);
|
|
48
|
+
if (!thumbnailBuffer) {
|
|
49
|
+
const isHashStored = (await externalCalls.isContentStoredAlready([hash])).get(hash) ?? false;
|
|
50
|
+
if (!isHashStored) {
|
|
51
|
+
return (0, types_1.validationFailed)(`Couldn't find thumbnail file with hash: ${hash}`);
|
|
52
|
+
}
|
|
53
|
+
// otherwise, thumbnail was already uploaded and won't be validated again
|
|
54
|
+
logger.debug(`Thumbnail file with hash: ${hash} is not in the deployment, but it is already stored`);
|
|
55
|
+
return types_1.OK;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const { width, height, format } = await (0, sharp_1.default)(thumbnailBuffer).metadata();
|
|
59
|
+
if (!format || format !== 'png')
|
|
60
|
+
errors.push(`Invalid or unknown image format. Only 'PNG' format is accepted.`);
|
|
61
|
+
if (!width || !height) {
|
|
62
|
+
errors.push(`Couldn't validate thumbnail size for file ${metadata.thumbnail}`);
|
|
63
|
+
}
|
|
64
|
+
else if (width > maxThumbnailSizeInB || height > maxThumbnailSizeInB) {
|
|
65
|
+
errors.push(`Invalid thumbnail image size (width = ${width} / height = ${height})`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
errors.push(`Couldn't parse thumbnail, please check image format.`);
|
|
70
|
+
}
|
|
71
|
+
return errors.length > 0 ? (0, types_1.validationFailed)(...errors) : types_1.OK;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Validate that given item deployment includes the thumbnail and doesn't exceed file sizes
|
|
76
|
+
* * @public
|
|
77
|
+
*/
|
|
78
|
+
exports.items = (0, validations_1.conditionalValidation)((deployment) => deployment.entity.type === schemas_1.EntityType.WEARABLE || deployment.entity.type === schemas_1.EntityType.EMOTE, (0, validations_1.validationAfterADR45)((0, validations_1.validationGroup)(exports.thumbnailMaxSizeIsNotExceeded, exports.deploymentMaxSizeExcludingThumbnailIsNotExceeded)));
|
|
79
|
+
//# sourceMappingURL=items.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"items.js","sourceRoot":"","sources":["../../../src/validations/items/items.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { Validation } from '
|
|
1
|
+
import { Validation } from '../../types';
|
|
2
2
|
/** Validate wearable representations are referencing valid content */
|
|
3
3
|
export declare const wearableRepresentationContent: Validation;
|
|
4
|
-
/** Validate wearable files size, excluding thumbnail, is less than expected */
|
|
5
|
-
export declare const wearableSize: Validation;
|
|
6
|
-
export declare const wearableThumbnail: Validation;
|
|
7
4
|
/**
|
|
8
5
|
* Validate that given wearable deployment includes the thumbnail and doesn't exceed file sizes
|
|
9
6
|
* * @public
|
|
10
7
|
*/
|
|
11
8
|
export declare const wearable: Validation;
|
|
12
|
-
//# sourceMappingURL=
|
|
9
|
+
//# sourceMappingURL=wearables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wearables.d.ts","sourceRoot":"","sources":["../../../src/validations/items/wearables.ts"],"names":[],"mappings":"AACA,OAAO,EAAkC,UAAU,EAAoB,MAAM,aAAa,CAAA;AAG1F,sEAAsE;AACtE,eAAO,MAAM,6BAA6B,EAAE,UAiB3C,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,UAAkF,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wearable = exports.wearableRepresentationContent = void 0;
|
|
4
|
+
const schemas_1 = require("@dcl/schemas");
|
|
5
|
+
const types_1 = require("../../types");
|
|
6
|
+
const validations_1 = require("../validations");
|
|
7
|
+
/** Validate wearable representations are referencing valid content */
|
|
8
|
+
exports.wearableRepresentationContent = {
|
|
9
|
+
validate: async (components, deployment) => {
|
|
10
|
+
const { entity } = deployment;
|
|
11
|
+
const wearableMetadata = entity.metadata;
|
|
12
|
+
const representations = wearableMetadata?.data?.representations;
|
|
13
|
+
if (!representations || representations.length === 0)
|
|
14
|
+
return (0, types_1.validationFailed)('No wearable representations found');
|
|
15
|
+
if (!entity.content || entity.content.length === 0)
|
|
16
|
+
return (0, types_1.validationFailed)('No content found');
|
|
17
|
+
for (const representation of representations) {
|
|
18
|
+
for (const representationContent of representation.contents) {
|
|
19
|
+
if (!entity.content.find((content) => content.file === representationContent)) {
|
|
20
|
+
return (0, types_1.validationFailed)(`Representation content: '${representationContent}' is not one of the content files`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return types_1.OK;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Validate that given wearable deployment includes the thumbnail and doesn't exceed file sizes
|
|
29
|
+
* * @public
|
|
30
|
+
*/
|
|
31
|
+
exports.wearable = (0, validations_1.validationForType)(schemas_1.EntityType.WEARABLE, exports.wearableRepresentationContent);
|
|
32
|
+
//# sourceMappingURL=wearables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wearables.js","sourceRoot":"","sources":["../../../src/validations/items/wearables.ts"],"names":[],"mappings":";;;AAAA,0CAAmD;AACnD,uCAA0F;AAC1F,gDAAkD;AAElD,sEAAsE;AACzD,QAAA,6BAA6B,GAAe;IACvD,QAAQ,EAAE,KAAK,EAAE,UAAsC,EAAE,UAAU,EAAE,EAAE;QACrE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;QAC7B,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAoB,CAAA;QACpD,MAAM,eAAe,GAAG,gBAAgB,EAAE,IAAI,EAAE,eAAe,CAAA;QAC/D,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAA,wBAAgB,EAAC,mCAAmC,CAAC,CAAA;QAClH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAA,wBAAgB,EAAC,kBAAkB,CAAC,CAAA;QAE/F,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE;YAC5C,KAAK,MAAM,qBAAqB,IAAI,cAAc,CAAC,QAAQ,EAAE;gBAC3D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,qBAAqB,CAAC,EAAE;oBAC7E,OAAO,IAAA,wBAAgB,EAAC,4BAA4B,qBAAqB,mCAAmC,CAAC,CAAA;iBAC9G;aACF;SACF;QACD,OAAO,UAAE,CAAA;IACX,CAAC;CACF,CAAA;AAED;;;GAGG;AACU,QAAA,QAAQ,GAAe,IAAA,+BAAiB,EAAC,oBAAU,CAAC,QAAQ,EAAE,qCAA6B,CAAC,CAAA"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @public
|
|
4
|
-
*/
|
|
5
|
-
export declare const metadata: import("../types").Validation;
|
|
1
|
+
import { Validation } from '../types';
|
|
2
|
+
export declare const metadata: Validation;
|
|
6
3
|
//# sourceMappingURL=metadata-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata-schema.d.ts","sourceRoot":"","sources":["../../src/validations/metadata-schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"metadata-schema.d.ts","sourceRoot":"","sources":["../../src/validations/metadata-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAwD,UAAU,EAAoB,MAAM,UAAU,CAAA;AA2D7G,eAAO,MAAM,QAAQ,EAAE,UAGtB,CAAA"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.metadata = void 0;
|
|
4
|
-
const
|
|
5
|
-
const _1 = require(".");
|
|
4
|
+
const schemas_1 = require("@dcl/schemas");
|
|
6
5
|
const types_1 = require("../types");
|
|
6
|
+
const ADR51_1 = require("./ADR51");
|
|
7
|
+
const timestamps_1 = require("./timestamps");
|
|
8
|
+
const validations_1 = require("./validations");
|
|
7
9
|
/**
|
|
8
10
|
* Validate entities metadata against its corresponding schema
|
|
9
11
|
* @public
|
|
10
12
|
*/
|
|
11
|
-
|
|
12
|
-
async
|
|
13
|
-
if (deployment.entity.timestamp <= _1.ADR_45_TIMESTAMP)
|
|
14
|
-
return types_1.OK;
|
|
13
|
+
const metadataSchemaIsValid = {
|
|
14
|
+
async validate(components, deployment) {
|
|
15
15
|
const { type, metadata } = deployment.entity;
|
|
16
16
|
const validator = ADR51_1.entityParameters[type].validate;
|
|
17
17
|
if (validator(metadata)) {
|
|
@@ -20,5 +20,35 @@ exports.metadata = (0, types_1.conditionalValidation)({
|
|
|
20
20
|
const errors = validator.errors?.map(($) => '' + $.message) || [];
|
|
21
21
|
return (0, types_1.validationFailed)(`The metadata for this entity type (${deployment.entity.type}) is not valid.`, ...errors);
|
|
22
22
|
}
|
|
23
|
-
}
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* This map contains one ADR timeline per entity type. In a timeline, each element has
|
|
26
|
+
* a number and a timestamp. The number corresponds to the number of an ADR and the timestamp
|
|
27
|
+
* to the creation of that ADR. Each timeline is sorted by timestamp.
|
|
28
|
+
* The idea behind this is the ability to version schemas over the time, but run validations
|
|
29
|
+
* according with the deployment original time. (Imagining starting a Content Server from scratch,
|
|
30
|
+
* it will have to sync deployments since the launcha date).
|
|
31
|
+
* See ADR 74 for more details of schema versioning.
|
|
32
|
+
*/
|
|
33
|
+
const ADRMetadataVersionTimelines = {
|
|
34
|
+
emote: [{ number: 74, timestamp: timestamps_1.ADR_74_TIMESTAMP }].sort((v1, v2) => v1.timestamp - v2.timestamp),
|
|
35
|
+
scene: [],
|
|
36
|
+
profile: [],
|
|
37
|
+
wearable: [],
|
|
38
|
+
store: []
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* This validation is being ran only for emotes currently
|
|
42
|
+
*/
|
|
43
|
+
const metadataVersionIsCorrectForTimestamp = {
|
|
44
|
+
validate(components, deployment) {
|
|
45
|
+
const entity = deployment.entity;
|
|
46
|
+
const adrNumber = ADRMetadataVersionTimelines[entity.type].find((v) => v.timestamp < entity.timestamp)?.number;
|
|
47
|
+
const expectedDataField = `${entity.type}DataADR${adrNumber}`;
|
|
48
|
+
return `${expectedDataField}` in deployment.entity.metadata
|
|
49
|
+
? types_1.OK
|
|
50
|
+
: (0, types_1.validationFailed)(`'emoteData' field version is incorrect. It must be: '${expectedDataField} but it is: ${deployment.entity.metadata} `);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
exports.metadata = (0, validations_1.validationGroup)((0, validations_1.validationAfterADR45)(metadataSchemaIsValid), (0, validations_1.validationAfterADR74)((0, validations_1.validationForType)(schemas_1.EntityType.EMOTE, metadataVersionIsCorrectForTimestamp)));
|
|
24
54
|
//# sourceMappingURL=metadata-schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata-schema.js","sourceRoot":"","sources":["../../src/validations/metadata-schema.ts"],"names":[],"mappings":";;;AAAA,mCAA0C;AAC1C,
|
|
1
|
+
{"version":3,"file":"metadata-schema.js","sourceRoot":"","sources":["../../src/validations/metadata-schema.ts"],"names":[],"mappings":";;;AAAA,0CAAyC;AACzC,oCAA6G;AAC7G,mCAA0C;AAC1C,6CAA+C;AAC/C,+CAA8G;AAE9G;;;GAGG;AACH,MAAM,qBAAqB,GAAe;IACxC,KAAK,CAAC,QAAQ,CAAC,UAAsC,EAAE,UAAU;QAC/D,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,MAAM,CAAA;QAC5C,MAAM,SAAS,GAAG,wBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAA;QACjD,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE;YACvB,OAAO,UAAE,CAAA;SACV;QACD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACjE,OAAO,IAAA,wBAAgB,EAAC,sCAAsC,UAAU,CAAC,MAAM,CAAC,IAAI,iBAAiB,EAAE,GAAG,MAAM,CAAC,CAAA;IACnH,CAAC;CACF,CAAA;AAOD;;;;;;;;GAQG;AACH,MAAM,2BAA2B,GAA8B;IAC7D,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,6BAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC;IAClG,KAAK,EAAE,EAAE;IACT,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,EAAE;IACZ,KAAK,EAAE,EAAE;CACV,CAAA;AAED;;GAEG;AACH,MAAM,oCAAoC,GAAe;IACvD,QAAQ,CAAC,UAAsC,EAAE,UAAgC;QAC/E,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;QAChC,MAAM,SAAS,GAAG,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;QAC9G,MAAM,iBAAiB,GAAG,GAAG,MAAM,CAAC,IAAI,UAAU,SAAS,EAAE,CAAA;QAC7D,OAAO,GAAG,iBAAiB,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ;YACzD,CAAC,CAAC,UAAE;YACJ,CAAC,CAAC,IAAA,wBAAgB,EACd,wDAAwD,iBAAiB,eAAe,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,CACtH,CAAA;IACP,CAAC;CACF,CAAA;AAEY,QAAA,QAAQ,GAAe,IAAA,6BAAe,EACjD,IAAA,kCAAoB,EAAC,qBAAqB,CAAC,EAC3C,IAAA,kCAAoB,EAAC,IAAA,+BAAiB,EAAC,oBAAU,CAAC,KAAK,EAAE,oCAAoC,CAAC,CAAC,CAChG,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/validations/profile.ts"],"names":[],"mappings":"AAGA,OAAO,EAAM,UAAU,EAAoB,MAAM,UAAU,CAAA;AAM3D,eAAO,MAAM,UAAU,aAAc,MAAM,KAAG,OAAqC,CAAA;AAEnF,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/validations/profile.ts"],"names":[],"mappings":"AAGA,OAAO,EAAM,UAAU,EAAoB,MAAM,UAAU,CAAA;AAM3D,eAAO,MAAM,UAAU,aAAc,MAAM,KAAG,OAAqC,CAAA;AAEnF,eAAO,MAAM,aAAa,EAAE,UA8B1B,CAAA;AAEF,eAAO,MAAM,YAAY,EAAE,UAgBzB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,UAAgG,CAAA"}
|
|
@@ -5,18 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.profile = exports.wearableUrns = exports.faceThumbnail = exports.isOldEmote = void 0;
|
|
7
7
|
const schemas_1 = require("@dcl/schemas");
|
|
8
|
+
const urn_resolver_1 = require("@dcl/urn-resolver");
|
|
8
9
|
const sharp_1 = __importDefault(require("sharp"));
|
|
9
|
-
const _1 = require(".");
|
|
10
10
|
const types_1 = require("../types");
|
|
11
|
-
const
|
|
11
|
+
const validations_1 = require("./validations");
|
|
12
12
|
/** Validate that given profile deployment includes a face256 thumbnail with valid size */
|
|
13
13
|
const defaultThumbnailSize = 256;
|
|
14
14
|
const isOldEmote = (wearable) => /^[a-z]+$/i.test(wearable);
|
|
15
15
|
exports.isOldEmote = isOldEmote;
|
|
16
|
-
exports.faceThumbnail = {
|
|
16
|
+
exports.faceThumbnail = (0, validations_1.validationAfterADR45)({
|
|
17
17
|
validate: async ({ externalCalls }, deployment) => {
|
|
18
|
-
if (deployment.entity.timestamp < _1.ADR_45_TIMESTAMP)
|
|
19
|
-
return types_1.OK;
|
|
20
18
|
const errors = [];
|
|
21
19
|
const allAvatars = deployment.entity.metadata?.avatars ?? [];
|
|
22
20
|
for (const avatar of allAvatars) {
|
|
@@ -48,11 +46,9 @@ exports.faceThumbnail = {
|
|
|
48
46
|
}
|
|
49
47
|
return errors.length > 0 ? (0, types_1.validationFailed)(...errors) : types_1.OK;
|
|
50
48
|
}
|
|
51
|
-
};
|
|
52
|
-
exports.wearableUrns = {
|
|
49
|
+
});
|
|
50
|
+
exports.wearableUrns = (0, validations_1.validationAfterADR75)({
|
|
53
51
|
validate: async (components, deployment) => {
|
|
54
|
-
if (deployment.entity.timestamp < _1.ADR_75_TIMESTAMP)
|
|
55
|
-
return types_1.OK;
|
|
56
52
|
const allAvatars = deployment.entity.metadata?.avatars ?? [];
|
|
57
53
|
for (const avatar of allAvatars) {
|
|
58
54
|
for (const pointer of avatar.avatar.wearables) {
|
|
@@ -60,21 +56,15 @@ exports.wearableUrns = {
|
|
|
60
56
|
continue;
|
|
61
57
|
const parsed = await (0, urn_resolver_1.parseUrn)(pointer);
|
|
62
58
|
if (!parsed)
|
|
63
|
-
return (0, types_1.validationFailed)(`
|
|
59
|
+
return (0, types_1.validationFailed)(`Each profile pointer should be a urn, for example (urn:decentraland:{protocol}:collections-v2:{contract(0x[a-fA-F0-9]+)}:{name}). Invalid pointer: (${pointer})`);
|
|
64
60
|
}
|
|
65
61
|
}
|
|
66
62
|
return types_1.OK;
|
|
67
63
|
}
|
|
68
|
-
};
|
|
64
|
+
});
|
|
69
65
|
/**
|
|
70
66
|
* Validate that given profile deployment includes the face256 file with the correct size
|
|
71
67
|
* * @public
|
|
72
68
|
*/
|
|
73
|
-
exports.profile =
|
|
74
|
-
validate: async (components, deployment) => {
|
|
75
|
-
if (deployment.entity.type !== schemas_1.EntityType.PROFILE)
|
|
76
|
-
return types_1.OK;
|
|
77
|
-
return (0, _1.validateInRow)(components, deployment, exports.faceThumbnail, exports.wearableUrns);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
69
|
+
exports.profile = (0, validations_1.validationForType)(schemas_1.EntityType.PROFILE, (0, validations_1.validationGroup)(exports.faceThumbnail, exports.wearableUrns));
|
|
80
70
|
//# sourceMappingURL=profile.js.map
|