@skhema/method 0.1.1 → 0.3.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 +21 -0
- package/README.md +84 -27
- package/dist/definitions.d.ts +1 -2
- package/dist/definitions.js +680 -461
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/registry.d.ts +19 -19
- package/dist/registry.js +13 -12
- package/dist/types.d.ts +14 -17
- package/dist/types.js +0 -1
- package/dist/validate.d.ts +1 -2
- package/dist/validate.js +44 -43
- package/dist/vocabulary/components.d.ts +32 -0
- package/dist/vocabulary/components.js +27 -0
- package/dist/vocabulary/elements.d.ts +102 -0
- package/dist/vocabulary/elements.js +97 -0
- package/dist/vocabulary/index.d.ts +4 -0
- package/dist/vocabulary/index.js +4 -0
- package/dist/vocabulary/mapping.d.ts +130 -0
- package/dist/vocabulary/mapping.js +85 -0
- package/dist/vocabulary/utils.d.ts +14 -0
- package/dist/vocabulary/utils.js +54 -0
- package/package.json +56 -10
- package/dist/definitions.d.ts.map +0 -1
- package/dist/definitions.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
|
|
1
|
+
export * from './definitions.js';
|
|
2
|
+
export * from './registry.js';
|
|
3
|
+
export * from './types.js';
|
|
4
|
+
export * from './validate.js';
|
|
5
|
+
export * from './vocabulary/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
|
|
1
|
+
export * from './definitions.js';
|
|
2
|
+
export * from './registry.js';
|
|
3
|
+
export * from './types.js';
|
|
4
|
+
export * from './validate.js';
|
|
5
|
+
export * from './vocabulary/index.js';
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ElementDefinition } from './types.js';
|
|
2
|
+
import type { ComponentValue, ElementValue } from './vocabulary/index.js';
|
|
2
3
|
export declare function listComponents(): ({
|
|
3
4
|
readonly type: "diagnosis";
|
|
4
5
|
readonly label: "Diagnosis";
|
|
@@ -27,24 +28,23 @@ export declare function listComponents(): ({
|
|
|
27
28
|
})[];
|
|
28
29
|
export declare function listElements(): ElementDefinition[];
|
|
29
30
|
export declare function listElementRelationships(): import("./types.js").ElementRelationshipDefinition[];
|
|
30
|
-
export declare function getElementDefinition(elementType:
|
|
31
|
-
export declare function isCanonicalElementType(elementType:
|
|
32
|
-
export declare function listElementsForComponent(component:
|
|
33
|
-
export declare function getRequiredMethodSlots(elementType:
|
|
34
|
-
export declare function getOptionalMethodSlots(elementType:
|
|
35
|
-
export declare function getMethodSlotDefinition(elementType:
|
|
36
|
-
export declare function getElementRequiredSlotIds(elementType:
|
|
37
|
-
export declare function getElementOptionalSlotIds(elementType:
|
|
38
|
-
export declare function getElementSubstitutableSlotIds(elementType:
|
|
39
|
-
export declare function getElementDiagnostics(elementType:
|
|
31
|
+
export declare function getElementDefinition(elementType: ElementValue | string): ElementDefinition | null;
|
|
32
|
+
export declare function isCanonicalElementType(elementType: ElementValue | string): boolean;
|
|
33
|
+
export declare function listElementsForComponent(component: ComponentValue): ElementDefinition[];
|
|
34
|
+
export declare function getRequiredMethodSlots(elementType: ElementValue | string): import("./types.js").MethodSlotDefinition[];
|
|
35
|
+
export declare function getOptionalMethodSlots(elementType: ElementValue | string): import("./types.js").MethodSlotDefinition[];
|
|
36
|
+
export declare function getMethodSlotDefinition(elementType: ElementValue | string, slotId: string): import("./types.js").MethodSlotDefinition | null;
|
|
37
|
+
export declare function getElementRequiredSlotIds(elementType: ElementValue | string): string[];
|
|
38
|
+
export declare function getElementOptionalSlotIds(elementType: ElementValue | string): string[];
|
|
39
|
+
export declare function getElementSubstitutableSlotIds(elementType: ElementValue | string): string[];
|
|
40
|
+
export declare function getElementDiagnostics(elementType: ElementValue | string): (import("./types.js").MethodDiagnosticMessages & {
|
|
40
41
|
wrongMood?: string;
|
|
41
42
|
insufficient?: string;
|
|
42
43
|
}) | null;
|
|
43
|
-
export declare function getValidRelationshipsForElement(elementType:
|
|
44
|
-
export declare function getOutgoingRelationshipsForElement(elementType:
|
|
45
|
-
export declare function getIncomingRelationshipsForElement(elementType:
|
|
46
|
-
export declare function getUpstreamElementTypes(elementType:
|
|
47
|
-
export declare function getDownstreamElementTypes(elementType:
|
|
48
|
-
export declare function getRelationshipDefinition(source:
|
|
49
|
-
export declare function getCompletenessRelationships(elementType:
|
|
50
|
-
//# sourceMappingURL=registry.d.ts.map
|
|
44
|
+
export declare function getValidRelationshipsForElement(elementType: ElementValue | string): import("./types.js").ElementRelationshipDefinition[];
|
|
45
|
+
export declare function getOutgoingRelationshipsForElement(elementType: ElementValue | string): import("./types.js").ElementRelationshipDefinition[];
|
|
46
|
+
export declare function getIncomingRelationshipsForElement(elementType: ElementValue | string): import("./types.js").ElementRelationshipDefinition[];
|
|
47
|
+
export declare function getUpstreamElementTypes(elementType: ElementValue | string): ("key_challenge" | "supporting_fact" | "impact" | "guiding_policy" | "competitor_move" | "scope" | "constraint" | "solution" | "assumption_hypothesis" | "experiment" | "action" | "investment" | "estimate" | "baseline" | "outcome" | "performance_variable" | "capability" | "system" | "principle")[];
|
|
48
|
+
export declare function getDownstreamElementTypes(elementType: ElementValue | string): ("key_challenge" | "supporting_fact" | "impact" | "guiding_policy" | "competitor_move" | "scope" | "constraint" | "solution" | "assumption_hypothesis" | "experiment" | "action" | "investment" | "estimate" | "baseline" | "outcome" | "performance_variable" | "capability" | "system" | "principle")[];
|
|
49
|
+
export declare function getRelationshipDefinition(source: ElementValue | string, target: ElementValue | string, type?: string): import("./types.js").ElementRelationshipDefinition | null;
|
|
50
|
+
export declare function getCompletenessRelationships(elementType: ElementValue | string): import("./types.js").ElementRelationshipDefinition[];
|
package/dist/registry.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { componentDefinitions, elementDefinitions, elementRelationshipDefinitions, } from
|
|
1
|
+
import { componentDefinitions, elementDefinitions, elementRelationshipDefinitions, } from './definitions.js';
|
|
2
2
|
const elementsByType = new Map();
|
|
3
3
|
const canonicalElementTypes = new Set();
|
|
4
4
|
for (const definition of elementDefinitions) {
|
|
@@ -27,13 +27,13 @@ export function listElementsForComponent(component) {
|
|
|
27
27
|
return elementDefinitions.filter((definition) => definition.component === component);
|
|
28
28
|
}
|
|
29
29
|
export function getRequiredMethodSlots(elementType) {
|
|
30
|
-
return getElementDefinition(elementType)?.methodSlots.filter((slot) => slot.required) ?? [];
|
|
30
|
+
return (getElementDefinition(elementType)?.methodSlots.filter((slot) => slot.required) ?? []);
|
|
31
31
|
}
|
|
32
32
|
export function getOptionalMethodSlots(elementType) {
|
|
33
|
-
return getElementDefinition(elementType)?.methodSlots.filter((slot) => !slot.required) ?? [];
|
|
33
|
+
return (getElementDefinition(elementType)?.methodSlots.filter((slot) => !slot.required) ?? []);
|
|
34
34
|
}
|
|
35
35
|
export function getMethodSlotDefinition(elementType, slotId) {
|
|
36
|
-
return getElementDefinition(elementType)?.methodSlots.find((slot) => slot.id === slotId) ?? null;
|
|
36
|
+
return (getElementDefinition(elementType)?.methodSlots.find((slot) => slot.id === slotId) ?? null);
|
|
37
37
|
}
|
|
38
38
|
export function getElementRequiredSlotIds(elementType) {
|
|
39
39
|
return getRequiredMethodSlots(elementType).map((slot) => slot.id);
|
|
@@ -42,9 +42,9 @@ export function getElementOptionalSlotIds(elementType) {
|
|
|
42
42
|
return getOptionalMethodSlots(elementType).map((slot) => slot.id);
|
|
43
43
|
}
|
|
44
44
|
export function getElementSubstitutableSlotIds(elementType) {
|
|
45
|
-
return getElementDefinition(elementType)
|
|
46
|
-
.filter((slot) => slot.substitutable)
|
|
47
|
-
.map((slot) => slot.id) ?? [];
|
|
45
|
+
return (getElementDefinition(elementType)
|
|
46
|
+
?.methodSlots.filter((slot) => slot.substitutable)
|
|
47
|
+
.map((slot) => slot.id) ?? []);
|
|
48
48
|
}
|
|
49
49
|
export function getElementDiagnostics(elementType) {
|
|
50
50
|
return getElementDefinition(elementType)?.rules.diagnostics ?? null;
|
|
@@ -53,7 +53,8 @@ export function getValidRelationshipsForElement(elementType) {
|
|
|
53
53
|
const definition = getElementDefinition(elementType);
|
|
54
54
|
if (!definition)
|
|
55
55
|
return [];
|
|
56
|
-
return elementRelationshipDefinitions.filter((relationship) => relationship.source === definition.type ||
|
|
56
|
+
return elementRelationshipDefinitions.filter((relationship) => relationship.source === definition.type ||
|
|
57
|
+
relationship.target === definition.type);
|
|
57
58
|
}
|
|
58
59
|
export function getOutgoingRelationshipsForElement(elementType) {
|
|
59
60
|
const definition = getElementDefinition(elementType);
|
|
@@ -78,15 +79,15 @@ export function getRelationshipDefinition(source, target, type) {
|
|
|
78
79
|
const targetDefinition = getElementDefinition(target);
|
|
79
80
|
if (!sourceDefinition || !targetDefinition)
|
|
80
81
|
return null;
|
|
81
|
-
return elementRelationshipDefinitions.find((relationship) => relationship.source === sourceDefinition.type &&
|
|
82
|
+
return (elementRelationshipDefinitions.find((relationship) => relationship.source === sourceDefinition.type &&
|
|
82
83
|
relationship.target === targetDefinition.type &&
|
|
83
|
-
(!type || relationship.type === type)) ?? null;
|
|
84
|
+
(!type || relationship.type === type)) ?? null);
|
|
84
85
|
}
|
|
85
86
|
export function getCompletenessRelationships(elementType) {
|
|
86
87
|
const definition = getElementDefinition(elementType);
|
|
87
88
|
if (!definition)
|
|
88
89
|
return [];
|
|
89
90
|
return elementRelationshipDefinitions.filter((relationship) => relationship.requiredForCompleteness &&
|
|
90
|
-
(relationship.source === definition.type ||
|
|
91
|
+
(relationship.source === definition.type ||
|
|
92
|
+
relationship.target === definition.type));
|
|
91
93
|
}
|
|
92
|
-
//# sourceMappingURL=registry.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import type { ComponentValue
|
|
2
|
-
export type
|
|
3
|
-
export type
|
|
4
|
-
export type
|
|
5
|
-
export type
|
|
6
|
-
export type
|
|
7
|
-
export type
|
|
8
|
-
export type
|
|
9
|
-
export type RelationshipEvidenceRequirement = "explicit_link" | "semantic_alignment" | "entity_overlap" | "not_required";
|
|
10
|
-
export type RelationshipScope = "same_element" | "same_component" | "same_strategy" | "same_workspace";
|
|
1
|
+
import type { ComponentValue, ElementValue } from './vocabulary/index.js';
|
|
2
|
+
export type ExpectedMood = 'indicative' | 'imperative' | 'noun_phrase';
|
|
3
|
+
export type SlotCardinality = 'zero_or_one' | 'exactly_one' | 'zero_or_more' | 'one_or_more';
|
|
4
|
+
export type SlotEvidenceRequirement = 'explicit_span_required' | 'explicit_or_inferred' | 'not_required';
|
|
5
|
+
export type SlotInferencePolicy = 'not_allowed' | 'allowed' | 'required_when_missing';
|
|
6
|
+
export type RelationshipCardinality = 'zero_or_one' | 'one_or_one' | 'zero_or_more' | 'one_or_more';
|
|
7
|
+
export type RelationshipEvidenceRequirement = 'explicit_link' | 'semantic_alignment' | 'entity_overlap' | 'not_required';
|
|
8
|
+
export type RelationshipScope = 'same_element' | 'same_component' | 'same_strategy' | 'same_workspace';
|
|
11
9
|
export interface MethodDiagnosticMessages {
|
|
12
10
|
missing?: string;
|
|
13
11
|
weak?: string;
|
|
@@ -23,7 +21,7 @@ export interface ElementMethodRules {
|
|
|
23
21
|
};
|
|
24
22
|
}
|
|
25
23
|
export interface ComponentDefinition {
|
|
26
|
-
type:
|
|
24
|
+
type: ComponentValue;
|
|
27
25
|
label: string;
|
|
28
26
|
acronym: string;
|
|
29
27
|
position: number;
|
|
@@ -48,10 +46,10 @@ export interface SyntacticSlotDefinition {
|
|
|
48
46
|
required: boolean;
|
|
49
47
|
}
|
|
50
48
|
export interface ElementDefinition {
|
|
51
|
-
type:
|
|
49
|
+
type: ElementValue;
|
|
52
50
|
label: string;
|
|
53
51
|
acronym: string;
|
|
54
|
-
component:
|
|
52
|
+
component: ComponentValue;
|
|
55
53
|
position: number;
|
|
56
54
|
expectedMood: ExpectedMood;
|
|
57
55
|
aliases?: string[];
|
|
@@ -62,8 +60,8 @@ export interface ElementDefinition {
|
|
|
62
60
|
rules: ElementMethodRules;
|
|
63
61
|
}
|
|
64
62
|
export interface ElementRelationshipDefinition {
|
|
65
|
-
source:
|
|
66
|
-
target:
|
|
63
|
+
source: ElementValue;
|
|
64
|
+
target: ElementValue;
|
|
67
65
|
type: string;
|
|
68
66
|
label: string;
|
|
69
67
|
description: string;
|
|
@@ -73,11 +71,10 @@ export interface ElementRelationshipDefinition {
|
|
|
73
71
|
scope: RelationshipScope[];
|
|
74
72
|
diagnostics: MethodDiagnosticMessages;
|
|
75
73
|
}
|
|
76
|
-
export type MethodSpecIssueSeverity =
|
|
74
|
+
export type MethodSpecIssueSeverity = 'error' | 'warning';
|
|
77
75
|
export interface MethodSpecIssue {
|
|
78
76
|
severity: MethodSpecIssueSeverity;
|
|
79
77
|
code: string;
|
|
80
78
|
message: string;
|
|
81
79
|
path: string;
|
|
82
80
|
}
|
|
83
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
CHANGED
package/dist/validate.d.ts
CHANGED
package/dist/validate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { elementDefinitions, elementRelationshipDefinitions, } from './definitions.js';
|
|
2
|
+
import { COMPONENT_TYPES, ELEMENT_TYPES, SKHEMA_MAPPING, } from './vocabulary/index.js';
|
|
3
3
|
const canonicalElementTypes = new Set(Object.values(ELEMENT_TYPES).map((element) => element.value));
|
|
4
4
|
const canonicalComponentTypes = new Set(Object.values(COMPONENT_TYPES).map((component) => component.value));
|
|
5
5
|
function issue(severity, code, path, message) {
|
|
@@ -9,31 +9,31 @@ function validateSlot(element, slot, index) {
|
|
|
9
9
|
const path = `elements.${element.type}.methodSlots.${index}`;
|
|
10
10
|
const issues = [];
|
|
11
11
|
if (!slot.id) {
|
|
12
|
-
issues.push(issue(
|
|
12
|
+
issues.push(issue('error', 'slot_id_missing', path, 'Method slot id is required.'));
|
|
13
13
|
}
|
|
14
14
|
if (!slot.label) {
|
|
15
|
-
issues.push(issue(
|
|
15
|
+
issues.push(issue('error', 'slot_label_missing', path, 'Method slot label is required.'));
|
|
16
16
|
}
|
|
17
17
|
if (!slot.description) {
|
|
18
|
-
issues.push(issue(
|
|
18
|
+
issues.push(issue('error', 'slot_description_missing', path, 'Method slot description is required.'));
|
|
19
19
|
}
|
|
20
20
|
if (!slot.cardinality) {
|
|
21
|
-
issues.push(issue(
|
|
21
|
+
issues.push(issue('error', 'slot_cardinality_missing', path, 'Method slot cardinality is required.'));
|
|
22
22
|
}
|
|
23
23
|
if (!slot.evidence) {
|
|
24
|
-
issues.push(issue(
|
|
24
|
+
issues.push(issue('error', 'slot_evidence_missing', path, 'Method slot evidence requirement is required.'));
|
|
25
25
|
}
|
|
26
26
|
if (!slot.inference) {
|
|
27
|
-
issues.push(issue(
|
|
27
|
+
issues.push(issue('error', 'slot_inference_missing', path, 'Method slot inference policy is required.'));
|
|
28
28
|
}
|
|
29
29
|
if (!Array.isArray(slot.acceptedEntityTypes)) {
|
|
30
|
-
issues.push(issue(
|
|
30
|
+
issues.push(issue('error', 'slot_entity_types_invalid', path, 'Method slot acceptedEntityTypes must be an array.'));
|
|
31
31
|
}
|
|
32
|
-
if (!slot.diagnostics || typeof slot.diagnostics !==
|
|
33
|
-
issues.push(issue(
|
|
32
|
+
if (!slot.diagnostics || typeof slot.diagnostics !== 'object') {
|
|
33
|
+
issues.push(issue('error', 'slot_diagnostics_missing', path, 'Method slot diagnostics are required.'));
|
|
34
34
|
}
|
|
35
35
|
if (slot.required && !slot.diagnostics?.missing) {
|
|
36
|
-
issues.push(issue(
|
|
36
|
+
issues.push(issue('warning', 'slot_missing_diagnostic_absent', path, 'Required method slots should provide a missing diagnostic.'));
|
|
37
37
|
}
|
|
38
38
|
return issues;
|
|
39
39
|
}
|
|
@@ -41,41 +41,41 @@ function validateElementDefinition(element) {
|
|
|
41
41
|
const path = `elements.${element.type}`;
|
|
42
42
|
const issues = [];
|
|
43
43
|
if (!canonicalElementTypes.has(element.type)) {
|
|
44
|
-
issues.push(issue(
|
|
44
|
+
issues.push(issue('error', 'element_not_canonical', path, `${element.type} is not in the Skhema method vocabulary.`));
|
|
45
45
|
}
|
|
46
46
|
if (!canonicalComponentTypes.has(element.component)) {
|
|
47
|
-
issues.push(issue(
|
|
47
|
+
issues.push(issue('error', 'component_not_canonical', path, `${element.component} is not in the Skhema method vocabulary.`));
|
|
48
48
|
}
|
|
49
49
|
if (!element.expectedMood) {
|
|
50
|
-
issues.push(issue(
|
|
50
|
+
issues.push(issue('error', 'expected_mood_missing', path, 'Expected mood is required.'));
|
|
51
51
|
}
|
|
52
52
|
if (element.syntacticSlots.length === 0) {
|
|
53
|
-
issues.push(issue(
|
|
53
|
+
issues.push(issue('error', 'syntactic_slots_missing', path, 'At least one syntactic slot is required.'));
|
|
54
54
|
}
|
|
55
55
|
if (element.methodSlots.length === 0) {
|
|
56
|
-
issues.push(issue(
|
|
56
|
+
issues.push(issue('error', 'method_slots_missing', path, 'At least one method slot is required.'));
|
|
57
57
|
}
|
|
58
58
|
if (element.rules.examplesRequired && element.examples.length === 0) {
|
|
59
|
-
issues.push(issue(
|
|
59
|
+
issues.push(issue('warning', 'examples_missing', path, 'Element definitions should include examples.'));
|
|
60
60
|
}
|
|
61
61
|
if (!element.rules) {
|
|
62
|
-
issues.push(issue(
|
|
62
|
+
issues.push(issue('error', 'element_rules_missing', path, 'Element method rules are required.'));
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
|
-
if (typeof element.rules.examplesRequired !==
|
|
66
|
-
issues.push(issue(
|
|
65
|
+
if (typeof element.rules.examplesRequired !== 'boolean') {
|
|
66
|
+
issues.push(issue('error', 'element_examples_rule_missing', path, 'examplesRequired rule is required.'));
|
|
67
67
|
}
|
|
68
|
-
if (typeof element.rules.minimumRequiredSlots !==
|
|
69
|
-
issues.push(issue(
|
|
68
|
+
if (typeof element.rules.minimumRequiredSlots !== 'number') {
|
|
69
|
+
issues.push(issue('error', 'element_minimum_required_slots_missing', path, 'minimumRequiredSlots rule is required.'));
|
|
70
70
|
}
|
|
71
|
-
if (typeof element.rules.allowInference !==
|
|
72
|
-
issues.push(issue(
|
|
71
|
+
if (typeof element.rules.allowInference !== 'boolean') {
|
|
72
|
+
issues.push(issue('error', 'element_inference_rule_missing', path, 'allowInference rule is required.'));
|
|
73
73
|
}
|
|
74
74
|
if (!element.rules.diagnostics?.wrongMood) {
|
|
75
|
-
issues.push(issue(
|
|
75
|
+
issues.push(issue('error', 'element_wrong_mood_diagnostic_missing', path, 'wrongMood diagnostic is required.'));
|
|
76
76
|
}
|
|
77
77
|
if (!element.rules.diagnostics?.insufficient) {
|
|
78
|
-
issues.push(issue(
|
|
78
|
+
issues.push(issue('error', 'element_insufficient_diagnostic_missing', path, 'insufficient diagnostic is required.'));
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
for (const [index, slot] of element.methodSlots.entries()) {
|
|
@@ -87,28 +87,30 @@ function validateRelationship(relationship, index) {
|
|
|
87
87
|
const path = `relationships.${index}`;
|
|
88
88
|
const issues = [];
|
|
89
89
|
if (!canonicalElementTypes.has(relationship.source)) {
|
|
90
|
-
issues.push(issue(
|
|
90
|
+
issues.push(issue('error', 'relationship_source_not_canonical', path, `${relationship.source} is not in the Skhema method vocabulary.`));
|
|
91
91
|
}
|
|
92
92
|
if (!canonicalElementTypes.has(relationship.target)) {
|
|
93
|
-
issues.push(issue(
|
|
93
|
+
issues.push(issue('error', 'relationship_target_not_canonical', path, `${relationship.target} is not in the Skhema method vocabulary.`));
|
|
94
94
|
}
|
|
95
95
|
if (!relationship.type) {
|
|
96
|
-
issues.push(issue(
|
|
96
|
+
issues.push(issue('error', 'relationship_type_missing', path, 'Relationship type is required.'));
|
|
97
97
|
}
|
|
98
98
|
if (!relationship.cardinality) {
|
|
99
|
-
issues.push(issue(
|
|
99
|
+
issues.push(issue('error', 'relationship_cardinality_missing', path, 'Relationship cardinality is required.'));
|
|
100
100
|
}
|
|
101
101
|
if (!relationship.evidence) {
|
|
102
|
-
issues.push(issue(
|
|
102
|
+
issues.push(issue('error', 'relationship_evidence_missing', path, 'Relationship evidence is required.'));
|
|
103
103
|
}
|
|
104
104
|
if (!Array.isArray(relationship.scope) || relationship.scope.length === 0) {
|
|
105
|
-
issues.push(issue(
|
|
105
|
+
issues.push(issue('error', 'relationship_scope_missing', path, 'Relationship scope is required.'));
|
|
106
106
|
}
|
|
107
|
-
if (!relationship.diagnostics ||
|
|
108
|
-
|
|
107
|
+
if (!relationship.diagnostics ||
|
|
108
|
+
typeof relationship.diagnostics !== 'object') {
|
|
109
|
+
issues.push(issue('error', 'relationship_diagnostics_missing', path, 'Relationship diagnostics are required.'));
|
|
109
110
|
}
|
|
110
|
-
if (relationship.requiredForCompleteness &&
|
|
111
|
-
|
|
111
|
+
if (relationship.requiredForCompleteness &&
|
|
112
|
+
!relationship.diagnostics.missing) {
|
|
113
|
+
issues.push(issue('warning', 'relationship_missing_diagnostic_absent', path, 'Completeness relationships should provide a missing diagnostic.'));
|
|
112
114
|
}
|
|
113
115
|
return issues;
|
|
114
116
|
}
|
|
@@ -117,32 +119,31 @@ export function validateMethodSpec() {
|
|
|
117
119
|
const definedElementTypes = new Set(elementDefinitions.map((element) => element.type));
|
|
118
120
|
for (const element of Object.values(ELEMENT_TYPES)) {
|
|
119
121
|
if (!definedElementTypes.has(element.value)) {
|
|
120
|
-
issues.push(issue(
|
|
122
|
+
issues.push(issue('error', 'canonical_element_missing', `elements.${element.value}`, `${element.value} is missing an element definition in @skhema/method.`));
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
for (const [component, schemaElements] of Object.entries(SKHEMA_MAPPING.elementFlow)) {
|
|
124
126
|
for (const schemaElement of schemaElements) {
|
|
125
127
|
const definition = elementDefinitions.find((element) => element.type === schemaElement.value);
|
|
126
128
|
if (definition && definition.component !== component) {
|
|
127
|
-
issues.push(issue(
|
|
129
|
+
issues.push(issue('error', 'component_assignment_mismatch', `elements.${definition.type}.component`, `${definition.type} should be assigned to ${component}.`));
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
for (const element of elementDefinitions) {
|
|
132
134
|
issues.push(...validateElementDefinition(element));
|
|
133
135
|
}
|
|
134
|
-
for (const [index, relationship] of elementRelationshipDefinitions.entries()) {
|
|
136
|
+
for (const [index, relationship,] of elementRelationshipDefinitions.entries()) {
|
|
135
137
|
issues.push(...validateRelationship(relationship, index));
|
|
136
138
|
}
|
|
137
139
|
return issues;
|
|
138
140
|
}
|
|
139
141
|
export function assertValidMethodSpec() {
|
|
140
|
-
const errors = validateMethodSpec().filter((candidate) => candidate.severity ===
|
|
142
|
+
const errors = validateMethodSpec().filter((candidate) => candidate.severity === 'error');
|
|
141
143
|
if (errors.length === 0)
|
|
142
144
|
return;
|
|
143
145
|
const summary = errors
|
|
144
146
|
.map((candidate) => `${candidate.code} at ${candidate.path}: ${candidate.message}`)
|
|
145
|
-
.join(
|
|
147
|
+
.join('\n');
|
|
146
148
|
throw new Error(`Invalid @skhema/method specification:\n${summary}`);
|
|
147
149
|
}
|
|
148
|
-
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const COMPONENT_TYPES: {
|
|
2
|
+
readonly DIAGNOSIS: {
|
|
3
|
+
readonly value: "diagnosis";
|
|
4
|
+
readonly label: "Diagnosis";
|
|
5
|
+
readonly acronym: "BD";
|
|
6
|
+
};
|
|
7
|
+
readonly METHOD: {
|
|
8
|
+
readonly value: "method";
|
|
9
|
+
readonly label: "Method & Positioning";
|
|
10
|
+
readonly acronym: "MP";
|
|
11
|
+
};
|
|
12
|
+
readonly INITIATIVES: {
|
|
13
|
+
readonly value: "initiatives";
|
|
14
|
+
readonly label: "Portfolio of Initiatives";
|
|
15
|
+
readonly acronym: "PI";
|
|
16
|
+
};
|
|
17
|
+
readonly MEASURES: {
|
|
18
|
+
readonly value: "measures";
|
|
19
|
+
readonly label: "Measures";
|
|
20
|
+
readonly acronym: "M";
|
|
21
|
+
};
|
|
22
|
+
readonly SUPPORT: {
|
|
23
|
+
readonly value: "support";
|
|
24
|
+
readonly label: "Support Structures";
|
|
25
|
+
readonly acronym: "SS";
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export type ComponentType = (typeof COMPONENT_TYPES)[keyof typeof COMPONENT_TYPES];
|
|
29
|
+
export type ComponentTypeKey = keyof typeof COMPONENT_TYPES;
|
|
30
|
+
export type ComponentValue = ComponentType['value'];
|
|
31
|
+
export type ComponentLabel = ComponentType['label'];
|
|
32
|
+
export type ComponentAcronym = ComponentType['acronym'];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const COMPONENT_TYPES = {
|
|
2
|
+
DIAGNOSIS: {
|
|
3
|
+
value: 'diagnosis',
|
|
4
|
+
label: 'Diagnosis',
|
|
5
|
+
acronym: 'BD',
|
|
6
|
+
},
|
|
7
|
+
METHOD: {
|
|
8
|
+
value: 'method',
|
|
9
|
+
label: 'Method & Positioning',
|
|
10
|
+
acronym: 'MP',
|
|
11
|
+
},
|
|
12
|
+
INITIATIVES: {
|
|
13
|
+
value: 'initiatives',
|
|
14
|
+
label: 'Portfolio of Initiatives',
|
|
15
|
+
acronym: 'PI',
|
|
16
|
+
},
|
|
17
|
+
MEASURES: {
|
|
18
|
+
value: 'measures',
|
|
19
|
+
label: 'Measures',
|
|
20
|
+
acronym: 'M',
|
|
21
|
+
},
|
|
22
|
+
SUPPORT: {
|
|
23
|
+
value: 'support',
|
|
24
|
+
label: 'Support Structures',
|
|
25
|
+
acronym: 'SS',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export declare const ELEMENT_TYPES: {
|
|
2
|
+
readonly KEY_CHALLENGE: {
|
|
3
|
+
readonly value: "key_challenge";
|
|
4
|
+
readonly label: "Key Challenge";
|
|
5
|
+
readonly acronym: "CHL";
|
|
6
|
+
};
|
|
7
|
+
readonly SUPPORTING_FACT: {
|
|
8
|
+
readonly value: "supporting_fact";
|
|
9
|
+
readonly label: "Supporting Fact";
|
|
10
|
+
readonly acronym: "FCT";
|
|
11
|
+
};
|
|
12
|
+
readonly IMPACT: {
|
|
13
|
+
readonly value: "impact";
|
|
14
|
+
readonly label: "Impact";
|
|
15
|
+
readonly acronym: "IMP";
|
|
16
|
+
};
|
|
17
|
+
readonly GUIDING_POLICY: {
|
|
18
|
+
readonly value: "guiding_policy";
|
|
19
|
+
readonly label: "Guiding Policy";
|
|
20
|
+
readonly acronym: "POL";
|
|
21
|
+
};
|
|
22
|
+
readonly COMPETITOR_MOVE: {
|
|
23
|
+
readonly value: "competitor_move";
|
|
24
|
+
readonly label: "Competitor Move";
|
|
25
|
+
readonly acronym: "CMV";
|
|
26
|
+
};
|
|
27
|
+
readonly SCOPE: {
|
|
28
|
+
readonly value: "scope";
|
|
29
|
+
readonly label: "Scope";
|
|
30
|
+
readonly acronym: "SCP";
|
|
31
|
+
};
|
|
32
|
+
readonly CONSTRAINT: {
|
|
33
|
+
readonly value: "constraint";
|
|
34
|
+
readonly label: "Constraint";
|
|
35
|
+
readonly acronym: "CST";
|
|
36
|
+
};
|
|
37
|
+
readonly SOLUTION: {
|
|
38
|
+
readonly value: "solution";
|
|
39
|
+
readonly label: "Solution";
|
|
40
|
+
readonly acronym: "SOL";
|
|
41
|
+
};
|
|
42
|
+
readonly ASSUMPTION_HYPOTHESIS: {
|
|
43
|
+
readonly value: "assumption_hypothesis";
|
|
44
|
+
readonly label: "Assumption Hypothesis";
|
|
45
|
+
readonly acronym: "HYP";
|
|
46
|
+
};
|
|
47
|
+
readonly EXPERIMENT: {
|
|
48
|
+
readonly value: "experiment";
|
|
49
|
+
readonly label: "Experiment";
|
|
50
|
+
readonly acronym: "EXP";
|
|
51
|
+
};
|
|
52
|
+
readonly ACTION: {
|
|
53
|
+
readonly value: "action";
|
|
54
|
+
readonly label: "Action";
|
|
55
|
+
readonly acronym: "ACT";
|
|
56
|
+
};
|
|
57
|
+
readonly INVESTMENT: {
|
|
58
|
+
readonly value: "investment";
|
|
59
|
+
readonly label: "Investment";
|
|
60
|
+
readonly acronym: "INV";
|
|
61
|
+
};
|
|
62
|
+
readonly ESTIMATE: {
|
|
63
|
+
readonly value: "estimate";
|
|
64
|
+
readonly label: "Estimate";
|
|
65
|
+
readonly acronym: "EST";
|
|
66
|
+
};
|
|
67
|
+
readonly BASELINE: {
|
|
68
|
+
readonly value: "baseline";
|
|
69
|
+
readonly label: "Baseline";
|
|
70
|
+
readonly acronym: "BSL";
|
|
71
|
+
};
|
|
72
|
+
readonly OUTCOME: {
|
|
73
|
+
readonly value: "outcome";
|
|
74
|
+
readonly label: "Outcome";
|
|
75
|
+
readonly acronym: "OCM";
|
|
76
|
+
};
|
|
77
|
+
readonly PERFORMANCE_VARIABLE: {
|
|
78
|
+
readonly value: "performance_variable";
|
|
79
|
+
readonly label: "Performance Variable";
|
|
80
|
+
readonly acronym: "VAR";
|
|
81
|
+
};
|
|
82
|
+
readonly CAPABILITY: {
|
|
83
|
+
readonly value: "capability";
|
|
84
|
+
readonly label: "Capability";
|
|
85
|
+
readonly acronym: "CAP";
|
|
86
|
+
};
|
|
87
|
+
readonly SYSTEM: {
|
|
88
|
+
readonly value: "system";
|
|
89
|
+
readonly label: "System";
|
|
90
|
+
readonly acronym: "SYS";
|
|
91
|
+
};
|
|
92
|
+
readonly PRINCIPLE: {
|
|
93
|
+
readonly value: "principle";
|
|
94
|
+
readonly label: "Principle";
|
|
95
|
+
readonly acronym: "PRN";
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
export type ElementType = (typeof ELEMENT_TYPES)[keyof typeof ELEMENT_TYPES];
|
|
99
|
+
export type ElementTypeKey = keyof typeof ELEMENT_TYPES;
|
|
100
|
+
export type ElementValue = ElementType['value'];
|
|
101
|
+
export type ElementLabel = ElementType['label'];
|
|
102
|
+
export type ElementAcronym = ElementType['acronym'];
|