@mdbase-dev/connect-dev 0.1.0-beta.27 → 0.1.0-beta.28
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/index.js +61 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -30,6 +30,9 @@ export function validateAppManifest(value, options = {}) {
|
|
|
30
30
|
const originResult = validateManifestOrigins(value, options.allowLocal === true);
|
|
31
31
|
if (!originResult.valid)
|
|
32
32
|
return originResult;
|
|
33
|
+
const capabilityResult = validateCapabilityRequirements(value);
|
|
34
|
+
if (!capabilityResult.valid)
|
|
35
|
+
return capabilityResult;
|
|
33
36
|
return validateProvisionRequirements(value);
|
|
34
37
|
}
|
|
35
38
|
export function validateDataContract(value) {
|
|
@@ -542,6 +545,63 @@ function validateProvisionRequirements(value) {
|
|
|
542
545
|
}
|
|
543
546
|
return { valid: true, issues: [] };
|
|
544
547
|
}
|
|
548
|
+
function validateCapabilityRequirements(value) {
|
|
549
|
+
const manifest = asObject(value);
|
|
550
|
+
const requirements = asObject(manifest.requirements);
|
|
551
|
+
const capabilities = asObject(requirements.capabilities);
|
|
552
|
+
if (Object.keys(capabilities).length === 0)
|
|
553
|
+
return { valid: true, issues: [] };
|
|
554
|
+
const required = Array.isArray(capabilities.required)
|
|
555
|
+
? capabilities.required.map(String)
|
|
556
|
+
: [];
|
|
557
|
+
const optional = Array.isArray(capabilities.optional)
|
|
558
|
+
? capabilities.optional.map(String)
|
|
559
|
+
: [];
|
|
560
|
+
if (new Set(required).size !== required.length) {
|
|
561
|
+
return semanticIssue("/requirements/capabilities/required", "must not contain duplicates");
|
|
562
|
+
}
|
|
563
|
+
if (new Set(optional).size !== optional.length) {
|
|
564
|
+
return semanticIssue("/requirements/capabilities/optional", "must not contain duplicates");
|
|
565
|
+
}
|
|
566
|
+
const overlap = optional.find((capability) => required.includes(capability));
|
|
567
|
+
if (overlap) {
|
|
568
|
+
return semanticIssue("/requirements/capabilities/optional", `must not repeat required capability ${overlap}`);
|
|
569
|
+
}
|
|
570
|
+
const declared = new Set([...required, ...optional]);
|
|
571
|
+
const provisions = asObject(manifest.provisions);
|
|
572
|
+
if (Array.isArray(requirements.contracts)
|
|
573
|
+
&& requirements.contracts.length > 0
|
|
574
|
+
&& requirements.access !== "full_collection"
|
|
575
|
+
&& !required.includes("definitions.contracts.current")) {
|
|
576
|
+
return semanticIssue("/requirements/capabilities/required", "must require definitions.contracts.current for contract-scoped requirements");
|
|
577
|
+
}
|
|
578
|
+
if (declared.has("definitions.type-pack.apply")) {
|
|
579
|
+
if (requirements.access !== "full_collection") {
|
|
580
|
+
return semanticIssue("/requirements/access", "must be full_collection for definitions.type-pack.apply");
|
|
581
|
+
}
|
|
582
|
+
if (!required.includes("definitions.type-pack.apply")) {
|
|
583
|
+
return semanticIssue("/requirements/capabilities/required", "must require definitions.type-pack.apply when it is declared");
|
|
584
|
+
}
|
|
585
|
+
if (!Array.isArray(provisions.type_packs) || provisions.type_packs.length === 0) {
|
|
586
|
+
return semanticIssue("/provisions/type_packs", "must contain a pack for definitions.type-pack.apply");
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
if (declared.has("notifications.background-delivery")
|
|
590
|
+
&& !Array.isArray(asObject(manifest.notifications).criteria)) {
|
|
591
|
+
return semanticIssue("/notifications/criteria", "must be declared for notifications.background-delivery");
|
|
592
|
+
}
|
|
593
|
+
const fileRequirement = asObject(requirements.files);
|
|
594
|
+
const fileActions = Array.isArray(fileRequirement.actions)
|
|
595
|
+
? new Set(fileRequirement.actions.map(String))
|
|
596
|
+
: new Set();
|
|
597
|
+
for (const action of ["list", "read", "add", "replace", "move", "delete"]) {
|
|
598
|
+
const capability = `files.${action}`;
|
|
599
|
+
if (declared.has(capability) !== fileActions.has(action)) {
|
|
600
|
+
return semanticIssue("/requirements/capabilities", `${capability} and requirements.files.actions.${action} must be declared together`);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return { valid: true, issues: [] };
|
|
604
|
+
}
|
|
545
605
|
function localManifestSchemaCandidate(value) {
|
|
546
606
|
const candidate = clone(value);
|
|
547
607
|
const object = asObject(candidate);
|
|
@@ -601,7 +661,7 @@ function sandboxDescription(value = {}) {
|
|
|
601
661
|
collection_id: value.collection_id ?? "01900000-0000-7000-8000-000000000001",
|
|
602
662
|
display_name: value.display_name ?? "Developer sandbox",
|
|
603
663
|
spec_version: value.spec_version ?? "0.3.0",
|
|
604
|
-
operations: value.operations ?? ["describe", "changes", "read", "query", "list_views", "execute_view", "read_view_source", "validate", "create", "update", "delete", "rename", "create_view_source", "update_view_source", "delete_view_source", "read_type", "create_type", "update_type", "apply_type_pack"],
|
|
664
|
+
operations: value.operations ?? ["describe", "changes", "read", "query", "list_views", "execute_view", "read_view_source", "validate", "create", "update", "delete", "rename", "create_view_source", "update_view_source", "delete_view_source", "read_type", "create_type", "update_type", "assess_type_pack", "apply_type_pack"],
|
|
605
665
|
change_cursor: value.change_cursor ?? 0,
|
|
606
666
|
types: clone(value.types ?? []),
|
|
607
667
|
contracts: clone(value.contracts ?? [])
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mdbase-dev/connect-dev",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.28",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"ajv": "^8.20.0",
|
|
28
28
|
"yaml": "^2.9.0",
|
|
29
|
-
"@mdbase-dev/connect": "0.1.0-beta.
|
|
30
|
-
"@mdbase-dev/connect-protocol": "0.1.0-beta.
|
|
29
|
+
"@mdbase-dev/connect": "0.1.0-beta.28",
|
|
30
|
+
"@mdbase-dev/connect-protocol": "0.1.0-beta.28"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^24.0.0",
|