@elevasis/sdk 1.22.0 → 1.22.1
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/cli.cjs +300 -14
- package/dist/index.d.ts +1217 -220
- package/dist/index.js +386 -12
- package/dist/test-utils/index.d.ts +963 -211
- package/dist/test-utils/index.js +253 -11
- package/dist/worker/index.js +118 -11
- package/package.json +3 -3
- package/reference/claude-config/rules/operations.md +3 -3
- package/reference/claude-config/rules/organization-model.md +11 -5
- package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +7 -4
- package/reference/examples/organization-model.ts +26 -2
- package/reference/scaffold/core/organization-model.mdx +16 -11
- package/reference/scaffold/recipes/add-a-feature.md +28 -26
- package/reference/scaffold/recipes/add-a-resource.md +26 -16
- package/reference/scaffold/recipes/customize-organization-model.md +5 -3
- package/reference/scaffold/recipes/extend-lead-gen.md +9 -9
- package/reference/scaffold/recipes/index.md +1 -1
- package/reference/scaffold/reference/contracts.md +45 -7
- package/reference/scaffold/reference/glossary.md +3 -3
package/dist/index.js
CHANGED
|
@@ -895,7 +895,6 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
|
|
|
895
895
|
table: entity.table
|
|
896
896
|
}
|
|
897
897
|
} : {},
|
|
898
|
-
legacyEntityId: entity.id,
|
|
899
898
|
...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
|
|
900
899
|
...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
|
|
901
900
|
};
|
|
@@ -920,8 +919,7 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
|
|
|
920
919
|
from: legacyObjectId(entity),
|
|
921
920
|
to: legacyObjectId(targetEntity),
|
|
922
921
|
cardinality: link.kind,
|
|
923
|
-
...link.via !== void 0 ? { via: link.via } : {}
|
|
924
|
-
legacyEntityId: entity.id
|
|
922
|
+
...link.via !== void 0 ? { via: link.via } : {}
|
|
925
923
|
};
|
|
926
924
|
addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
|
|
927
925
|
source: "legacy.entities.links",
|
|
@@ -979,8 +977,7 @@ function addSystemContentProjections(index, diagnostics, sourcesById, systemPath
|
|
|
979
977
|
kind: node.type,
|
|
980
978
|
...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
|
|
981
979
|
...Object.keys(entries).length > 0 ? { entries } : {},
|
|
982
|
-
...node.data !== void 0 ? { data: node.data } : {}
|
|
983
|
-
legacyContentId: `${systemPath}:${localId}`
|
|
980
|
+
...node.data !== void 0 ? { data: node.data } : {}
|
|
984
981
|
};
|
|
985
982
|
addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
|
|
986
983
|
source: "legacy.system.content",
|
|
@@ -1535,11 +1532,20 @@ EventEmissionDescriptorSchema.extend({
|
|
|
1535
1532
|
ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
|
|
1536
1533
|
});
|
|
1537
1534
|
var ResourceOntologyBindingSchema = z.object({
|
|
1538
|
-
|
|
1535
|
+
actions: z.array(OntologyIdSchema).optional(),
|
|
1536
|
+
primaryAction: OntologyIdSchema.optional(),
|
|
1539
1537
|
reads: z.array(OntologyIdSchema).optional(),
|
|
1540
1538
|
writes: z.array(OntologyIdSchema).optional(),
|
|
1541
1539
|
usesCatalogs: z.array(OntologyIdSchema).optional(),
|
|
1542
1540
|
emits: z.array(OntologyIdSchema).optional()
|
|
1541
|
+
}).superRefine((binding, ctx) => {
|
|
1542
|
+
if (binding.primaryAction === void 0) return;
|
|
1543
|
+
if (binding.actions?.includes(binding.primaryAction)) return;
|
|
1544
|
+
ctx.addIssue({
|
|
1545
|
+
code: z.ZodIssueCode.custom,
|
|
1546
|
+
path: ["primaryAction"],
|
|
1547
|
+
message: "Resource ontology primaryAction must be included in actions"
|
|
1548
|
+
});
|
|
1543
1549
|
});
|
|
1544
1550
|
var CodeReferenceSchema = z.object({
|
|
1545
1551
|
path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
|
|
@@ -1554,6 +1560,10 @@ var ResourceEntryBaseSchema = z.object({
|
|
|
1554
1560
|
order: z.number().default(0),
|
|
1555
1561
|
/** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
|
|
1556
1562
|
systemPath: SystemPathSchema.meta({ ref: "system" }),
|
|
1563
|
+
/** Executable display title owned by the OM Resource descriptor. */
|
|
1564
|
+
title: LabelSchema.optional(),
|
|
1565
|
+
/** Executable display description owned by the OM Resource descriptor. */
|
|
1566
|
+
description: DescriptionSchema.optional(),
|
|
1557
1567
|
/** Optional role responsible for maintaining this resource. */
|
|
1558
1568
|
ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
1559
1569
|
status: ResourceGovernanceStatusSchema,
|
|
@@ -1568,8 +1578,6 @@ var ResourceEntryBaseSchema = z.object({
|
|
|
1568
1578
|
});
|
|
1569
1579
|
var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
1570
1580
|
kind: z.literal("workflow"),
|
|
1571
|
-
/** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
|
|
1572
|
-
actionKey: z.string().trim().min(1).max(255).optional(),
|
|
1573
1581
|
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
1574
1582
|
});
|
|
1575
1583
|
var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
@@ -1609,6 +1617,30 @@ var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((re
|
|
|
1609
1617
|
message: "Each resource entry id must match its map key"
|
|
1610
1618
|
}).default({});
|
|
1611
1619
|
var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
|
|
1620
|
+
function defineResource(resource) {
|
|
1621
|
+
return ResourceEntrySchema.parse(resource);
|
|
1622
|
+
}
|
|
1623
|
+
function defineResources(resources) {
|
|
1624
|
+
return Object.fromEntries(
|
|
1625
|
+
Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
function ontologyIdFrom(input) {
|
|
1629
|
+
return typeof input === "string" ? input : input.id;
|
|
1630
|
+
}
|
|
1631
|
+
function ontologyIdArrayFrom(input) {
|
|
1632
|
+
return input?.map(ontologyIdFrom);
|
|
1633
|
+
}
|
|
1634
|
+
function defineResourceOntology(input) {
|
|
1635
|
+
return ResourceOntologyBindingSchema.parse({
|
|
1636
|
+
actions: ontologyIdArrayFrom(input.actions),
|
|
1637
|
+
primaryAction: input.primaryAction === void 0 ? void 0 : ontologyIdFrom(input.primaryAction),
|
|
1638
|
+
reads: ontologyIdArrayFrom(input.reads),
|
|
1639
|
+
writes: ontologyIdArrayFrom(input.writes),
|
|
1640
|
+
usesCatalogs: ontologyIdArrayFrom(input.usesCatalogs),
|
|
1641
|
+
emits: ontologyIdArrayFrom(input.emits)
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1612
1644
|
|
|
1613
1645
|
// ../core/src/organization-model/domains/roles.ts
|
|
1614
1646
|
var RoleIdSchema = ModelIdSchema;
|
|
@@ -1789,6 +1821,170 @@ var OrgKnowledgeNodeSchema = z.object({
|
|
|
1789
1821
|
updatedAt: z.string().trim().min(1).max(50)
|
|
1790
1822
|
});
|
|
1791
1823
|
var KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
|
|
1824
|
+
var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
|
|
1825
|
+
var SecretLikeMetadataValueSchema = /(?:sk-[A-Za-z0-9_-]{12,}|pk_live_[A-Za-z0-9_-]{12,}|eyJ[A-Za-z0-9_-]{20,}|-----BEGIN (?:RSA |OPENSSH |EC )?PRIVATE KEY-----)/;
|
|
1826
|
+
var OmTopologyNodeKindSchema = z.enum([
|
|
1827
|
+
"system",
|
|
1828
|
+
"resource",
|
|
1829
|
+
"ontology",
|
|
1830
|
+
"policy",
|
|
1831
|
+
"role",
|
|
1832
|
+
"trigger",
|
|
1833
|
+
"humanCheckpoint",
|
|
1834
|
+
"externalResource"
|
|
1835
|
+
]);
|
|
1836
|
+
var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
|
|
1837
|
+
var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
|
|
1838
|
+
z.object({ kind: z.literal("system"), id: ModelIdSchema }),
|
|
1839
|
+
z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
|
|
1840
|
+
z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
|
|
1841
|
+
z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
|
|
1842
|
+
z.object({ kind: z.literal("role"), id: ModelIdSchema }),
|
|
1843
|
+
z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
|
|
1844
|
+
z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
|
|
1845
|
+
z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
|
|
1846
|
+
]);
|
|
1847
|
+
var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
|
|
1848
|
+
function visit(value, path) {
|
|
1849
|
+
if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
|
|
1850
|
+
ctx.addIssue({
|
|
1851
|
+
code: z.ZodIssueCode.custom,
|
|
1852
|
+
path,
|
|
1853
|
+
message: "Topology metadata must not contain secret-like values"
|
|
1854
|
+
});
|
|
1855
|
+
return;
|
|
1856
|
+
}
|
|
1857
|
+
if (Array.isArray(value)) {
|
|
1858
|
+
value.forEach((entry, index) => visit(entry, [...path, index]));
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
if (typeof value !== "object" || value === null) return;
|
|
1862
|
+
Object.entries(value).forEach(([key, entry]) => {
|
|
1863
|
+
if (SecretLikeMetadataKeySchema.test(key)) {
|
|
1864
|
+
ctx.addIssue({
|
|
1865
|
+
code: z.ZodIssueCode.custom,
|
|
1866
|
+
path: [...path, key],
|
|
1867
|
+
message: `Topology metadata key "${key}" looks secret-like`
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1870
|
+
visit(entry, [...path, key]);
|
|
1871
|
+
});
|
|
1872
|
+
}
|
|
1873
|
+
visit(metadata, []);
|
|
1874
|
+
});
|
|
1875
|
+
var OmTopologyRelationshipSchema = z.object({
|
|
1876
|
+
from: OmTopologyNodeRefSchema,
|
|
1877
|
+
kind: OmTopologyRelationshipKindSchema,
|
|
1878
|
+
to: OmTopologyNodeRefSchema,
|
|
1879
|
+
systemPath: SystemPathSchema.optional(),
|
|
1880
|
+
required: z.boolean().optional(),
|
|
1881
|
+
metadata: OmTopologyMetadataSchema.optional()
|
|
1882
|
+
});
|
|
1883
|
+
var OmTopologyDomainSchema = z.object({
|
|
1884
|
+
version: z.literal(1).default(1),
|
|
1885
|
+
relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
|
|
1886
|
+
}).default({ version: 1, relationships: {} });
|
|
1887
|
+
var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
|
|
1888
|
+
version: 1,
|
|
1889
|
+
relationships: {}
|
|
1890
|
+
};
|
|
1891
|
+
function idFrom(input) {
|
|
1892
|
+
return typeof input === "string" ? input : input.id;
|
|
1893
|
+
}
|
|
1894
|
+
function parseRef(kind, id) {
|
|
1895
|
+
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1896
|
+
}
|
|
1897
|
+
function isNodeRef(input) {
|
|
1898
|
+
return OmTopologyNodeRefSchema.safeParse(input).success;
|
|
1899
|
+
}
|
|
1900
|
+
function isResourceEntry(input) {
|
|
1901
|
+
if (typeof input !== "object" || input === null) return false;
|
|
1902
|
+
const candidate = input;
|
|
1903
|
+
return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
|
|
1904
|
+
}
|
|
1905
|
+
var topologyRef = {
|
|
1906
|
+
system: (system) => parseRef("system", idFrom(system)),
|
|
1907
|
+
resource: (resource) => parseRef("resource", idFrom(resource)),
|
|
1908
|
+
ontology: (record) => parseRef("ontology", idFrom(record)),
|
|
1909
|
+
policy: (policy) => parseRef("policy", idFrom(policy)),
|
|
1910
|
+
role: (role) => parseRef("role", idFrom(role)),
|
|
1911
|
+
trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
|
|
1912
|
+
humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
|
|
1913
|
+
externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
|
|
1914
|
+
};
|
|
1915
|
+
var topologyRelationship = {
|
|
1916
|
+
triggers: (from, to, options = {}) => defineTopologyRelationship({
|
|
1917
|
+
...options,
|
|
1918
|
+
from,
|
|
1919
|
+
kind: "triggers",
|
|
1920
|
+
to
|
|
1921
|
+
}),
|
|
1922
|
+
uses: (from, to, options = {}) => defineTopologyRelationship({
|
|
1923
|
+
...options,
|
|
1924
|
+
from,
|
|
1925
|
+
kind: "uses",
|
|
1926
|
+
to
|
|
1927
|
+
}),
|
|
1928
|
+
approval: (from, to, options = {}) => defineTopologyRelationship({
|
|
1929
|
+
...options,
|
|
1930
|
+
from,
|
|
1931
|
+
kind: "approval",
|
|
1932
|
+
to
|
|
1933
|
+
}),
|
|
1934
|
+
usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
|
|
1935
|
+
required: true,
|
|
1936
|
+
...options,
|
|
1937
|
+
from,
|
|
1938
|
+
kind: "uses",
|
|
1939
|
+
to: integration
|
|
1940
|
+
}),
|
|
1941
|
+
requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
|
|
1942
|
+
required: true,
|
|
1943
|
+
...options,
|
|
1944
|
+
from,
|
|
1945
|
+
kind: "approval",
|
|
1946
|
+
to: topologyRef.humanCheckpoint(checkpoint)
|
|
1947
|
+
}),
|
|
1948
|
+
checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
|
|
1949
|
+
required: true,
|
|
1950
|
+
...options,
|
|
1951
|
+
from: topologyRef.humanCheckpoint(checkpoint),
|
|
1952
|
+
kind: "triggers",
|
|
1953
|
+
to
|
|
1954
|
+
})
|
|
1955
|
+
};
|
|
1956
|
+
function compileTopologyNodeRef(input) {
|
|
1957
|
+
if (isNodeRef(input)) return input;
|
|
1958
|
+
if (isResourceEntry(input)) return topologyRef.resource(input);
|
|
1959
|
+
throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
|
|
1960
|
+
}
|
|
1961
|
+
function parseTopologyNodeRef(input) {
|
|
1962
|
+
if (typeof input !== "string") return OmTopologyNodeRefSchema.parse(input);
|
|
1963
|
+
const separatorIndex = input.indexOf(":");
|
|
1964
|
+
if (separatorIndex === -1) {
|
|
1965
|
+
throw new Error(`Topology node ref "${input}" must use <kind>:<id>`);
|
|
1966
|
+
}
|
|
1967
|
+
const kind = input.slice(0, separatorIndex);
|
|
1968
|
+
const id = input.slice(separatorIndex + 1);
|
|
1969
|
+
if (!OmTopologyNodeKindSchema.safeParse(kind).success) {
|
|
1970
|
+
throw new Error(`Topology node ref "${input}" has unsupported kind "${kind}"`);
|
|
1971
|
+
}
|
|
1972
|
+
return OmTopologyNodeRefSchema.parse({ kind, id });
|
|
1973
|
+
}
|
|
1974
|
+
function defineTopologyRelationship(input) {
|
|
1975
|
+
return OmTopologyRelationshipSchema.parse({
|
|
1976
|
+
...input,
|
|
1977
|
+
from: compileTopologyNodeRef(input.from),
|
|
1978
|
+
to: compileTopologyNodeRef(input.to)
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
function defineTopology(relationships) {
|
|
1982
|
+
const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
|
|
1983
|
+
return OmTopologyDomainSchema.parse({
|
|
1984
|
+
version: 1,
|
|
1985
|
+
relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1792
1988
|
var PolicyIdSchema = ModelIdSchema;
|
|
1793
1989
|
var PolicyApplicabilitySchema = z.object({
|
|
1794
1990
|
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
@@ -1878,6 +2074,7 @@ z.enum([
|
|
|
1878
2074
|
"systems",
|
|
1879
2075
|
"ontology",
|
|
1880
2076
|
"resources",
|
|
2077
|
+
"topology",
|
|
1881
2078
|
"actions",
|
|
1882
2079
|
"entities",
|
|
1883
2080
|
"policies",
|
|
@@ -1897,6 +2094,7 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
|
|
|
1897
2094
|
systems: { version: 1, lastModified: "2026-05-10" },
|
|
1898
2095
|
ontology: { version: 1, lastModified: "2026-05-14" },
|
|
1899
2096
|
resources: { version: 1, lastModified: "2026-05-10" },
|
|
2097
|
+
topology: { version: 1, lastModified: "2026-05-14" },
|
|
1900
2098
|
actions: { version: 1, lastModified: "2026-05-10" },
|
|
1901
2099
|
entities: { version: 1, lastModified: "2026-05-10" },
|
|
1902
2100
|
policies: { version: 1, lastModified: "2026-05-10" },
|
|
@@ -1912,6 +2110,7 @@ var OrganizationModelDomainMetadataByDomainSchema = z.object({
|
|
|
1912
2110
|
systems: OrganizationModelDomainMetadataSchema,
|
|
1913
2111
|
ontology: OrganizationModelDomainMetadataSchema,
|
|
1914
2112
|
resources: OrganizationModelDomainMetadataSchema,
|
|
2113
|
+
topology: OrganizationModelDomainMetadataSchema,
|
|
1915
2114
|
actions: OrganizationModelDomainMetadataSchema,
|
|
1916
2115
|
entities: OrganizationModelDomainMetadataSchema,
|
|
1917
2116
|
policies: OrganizationModelDomainMetadataSchema,
|
|
@@ -1930,6 +2129,7 @@ var OrganizationModelSchemaBase = z.object({
|
|
|
1930
2129
|
systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
|
|
1931
2130
|
ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
|
|
1932
2131
|
resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
|
|
2132
|
+
topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
|
|
1933
2133
|
actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
|
|
1934
2134
|
entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
|
|
1935
2135
|
policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
|
|
@@ -2272,6 +2472,25 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
|
2272
2472
|
surface: ontologyCompilation.ontology.surfaces
|
|
2273
2473
|
};
|
|
2274
2474
|
const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
|
|
2475
|
+
function topologyTargetExists(ref) {
|
|
2476
|
+
if (ref.kind === "system") return systemsById.has(ref.id);
|
|
2477
|
+
if (ref.kind === "resource") return resourcesById.has(ref.id);
|
|
2478
|
+
if (ref.kind === "ontology") return ontologyIds.has(ref.id);
|
|
2479
|
+
if (ref.kind === "policy") return policiesById.has(ref.id);
|
|
2480
|
+
if (ref.kind === "role") return rolesById.has(ref.id);
|
|
2481
|
+
return true;
|
|
2482
|
+
}
|
|
2483
|
+
Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
|
|
2484
|
+
["from", "to"].forEach((side) => {
|
|
2485
|
+
const ref = relationship[side];
|
|
2486
|
+
if (topologyTargetExists(ref)) return;
|
|
2487
|
+
addIssue(
|
|
2488
|
+
ctx,
|
|
2489
|
+
["topology", "relationships", relationshipId, side],
|
|
2490
|
+
`Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
|
|
2491
|
+
);
|
|
2492
|
+
});
|
|
2493
|
+
});
|
|
2275
2494
|
const ontologyReferenceKeyKinds = {
|
|
2276
2495
|
valueType: "value-type",
|
|
2277
2496
|
catalogType: "catalog",
|
|
@@ -2410,11 +2629,18 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
|
2410
2629
|
}
|
|
2411
2630
|
});
|
|
2412
2631
|
function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
|
|
2413
|
-
ids
|
|
2632
|
+
const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
|
|
2633
|
+
ontologyIds2.forEach((ontologyId, ontologyIndex) => {
|
|
2414
2634
|
if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
|
|
2415
2635
|
addIssue(
|
|
2416
2636
|
ctx,
|
|
2417
|
-
[
|
|
2637
|
+
[
|
|
2638
|
+
"resources",
|
|
2639
|
+
resourceId,
|
|
2640
|
+
"ontology",
|
|
2641
|
+
bindingKey,
|
|
2642
|
+
...Array.isArray(ids) ? [ontologyIndex] : []
|
|
2643
|
+
],
|
|
2418
2644
|
`Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
|
|
2419
2645
|
);
|
|
2420
2646
|
}
|
|
@@ -2423,7 +2649,8 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
|
2423
2649
|
Object.values(model.resources).forEach((resource) => {
|
|
2424
2650
|
const binding = resource.ontology;
|
|
2425
2651
|
if (binding === void 0) return;
|
|
2426
|
-
validateResourceOntologyBinding(resource.id, "
|
|
2652
|
+
validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
|
|
2653
|
+
validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
|
|
2427
2654
|
validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
|
|
2428
2655
|
validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
|
|
2429
2656
|
validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
|
|
@@ -2870,6 +3097,119 @@ function getRuntimeResources(resources) {
|
|
|
2870
3097
|
}))
|
|
2871
3098
|
];
|
|
2872
3099
|
}
|
|
3100
|
+
function hasOntologySources(organizationModel) {
|
|
3101
|
+
return organizationModel.ontology !== void 0 || organizationModel.entities !== void 0 || organizationModel.actions !== void 0 || Object.values(organizationModel.systems ?? {}).some(systemHasOntologySource);
|
|
3102
|
+
}
|
|
3103
|
+
function systemHasOntologySource(system) {
|
|
3104
|
+
if (system.ontology !== void 0 || system.content !== void 0 && Object.keys(system.content).length > 0) return true;
|
|
3105
|
+
return Object.values(system.systems ?? system.subsystems ?? {}).some(systemHasOntologySource);
|
|
3106
|
+
}
|
|
3107
|
+
function ontologyIndexForKind(index, kind) {
|
|
3108
|
+
switch (kind) {
|
|
3109
|
+
case "object":
|
|
3110
|
+
return index.objectTypes;
|
|
3111
|
+
case "link":
|
|
3112
|
+
return index.linkTypes;
|
|
3113
|
+
case "action":
|
|
3114
|
+
return index.actionTypes;
|
|
3115
|
+
case "catalog":
|
|
3116
|
+
return index.catalogTypes;
|
|
3117
|
+
case "event":
|
|
3118
|
+
return index.eventTypes;
|
|
3119
|
+
case "interface":
|
|
3120
|
+
return index.interfaceTypes;
|
|
3121
|
+
case "value-type":
|
|
3122
|
+
return index.valueTypes;
|
|
3123
|
+
case "property":
|
|
3124
|
+
return index.sharedProperties;
|
|
3125
|
+
case "group":
|
|
3126
|
+
return index.groups;
|
|
3127
|
+
case "surface":
|
|
3128
|
+
return index.surfaces;
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
function sameJson(left, right) {
|
|
3132
|
+
return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
3133
|
+
}
|
|
3134
|
+
function addOntologyBindingIssues(issues, orgName, resource, ontologyIndex) {
|
|
3135
|
+
const binding = resource.ontology;
|
|
3136
|
+
if (binding === void 0) return;
|
|
3137
|
+
if ((resource.kind === "workflow" || resource.kind === "agent") && (binding.actions?.length ?? 0) === 0) {
|
|
3138
|
+
addGovernanceIssue(
|
|
3139
|
+
issues,
|
|
3140
|
+
"missing-ontology-actions",
|
|
3141
|
+
orgName,
|
|
3142
|
+
resource.id,
|
|
3143
|
+
`[${orgName}] Resource '${resource.id}' declares ontology bindings but no ontology actions.`
|
|
3144
|
+
);
|
|
3145
|
+
}
|
|
3146
|
+
if (binding.primaryAction !== void 0 && !binding.actions?.includes(binding.primaryAction)) {
|
|
3147
|
+
addGovernanceIssue(
|
|
3148
|
+
issues,
|
|
3149
|
+
"primary-action-mismatch",
|
|
3150
|
+
orgName,
|
|
3151
|
+
resource.id,
|
|
3152
|
+
`[${orgName}] Resource '${resource.id}' primaryAction '${binding.primaryAction}' must be included in ontology.actions.`
|
|
3153
|
+
);
|
|
3154
|
+
}
|
|
3155
|
+
if (ontologyIndex === void 0) return;
|
|
3156
|
+
const validateRefs = (bindingKey, expectedKind, refs) => {
|
|
3157
|
+
const values = refs === void 0 ? [] : Array.isArray(refs) ? refs : [refs];
|
|
3158
|
+
const index = ontologyIndexForKind(ontologyIndex, expectedKind);
|
|
3159
|
+
for (const ref of values) {
|
|
3160
|
+
if (index[ref] !== void 0) continue;
|
|
3161
|
+
addGovernanceIssue(
|
|
3162
|
+
issues,
|
|
3163
|
+
"ontology-reference-missing",
|
|
3164
|
+
orgName,
|
|
3165
|
+
resource.id,
|
|
3166
|
+
`[${orgName}] Resource '${resource.id}' ontology.${bindingKey} references missing ${expectedKind} ontology record '${ref}'.`
|
|
3167
|
+
);
|
|
3168
|
+
}
|
|
3169
|
+
};
|
|
3170
|
+
validateRefs("actions", "action", binding.actions);
|
|
3171
|
+
validateRefs("primaryAction", "action", binding.primaryAction);
|
|
3172
|
+
validateRefs("reads", "object", binding.reads);
|
|
3173
|
+
validateRefs("writes", "object", binding.writes);
|
|
3174
|
+
validateRefs("usesCatalogs", "catalog", binding.usesCatalogs);
|
|
3175
|
+
validateRefs("emits", "event", binding.emits);
|
|
3176
|
+
}
|
|
3177
|
+
function addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex) {
|
|
3178
|
+
const relationships = organizationModel.topology?.relationships;
|
|
3179
|
+
if (relationships === void 0) return;
|
|
3180
|
+
const rolesById = new Set(Object.keys(organizationModel.roles ?? {}));
|
|
3181
|
+
const policiesById = new Set(Object.keys(organizationModel.policies ?? {}));
|
|
3182
|
+
const triggerIds = new Set(deployment.triggers?.map((trigger) => trigger.resourceId) ?? []);
|
|
3183
|
+
const humanCheckpointIds = new Set(deployment.humanCheckpoints?.map((checkpoint) => checkpoint.resourceId) ?? []);
|
|
3184
|
+
const externalResourceIds = new Set(deployment.externalResources?.map((external) => external.resourceId) ?? []);
|
|
3185
|
+
const topologyRefExists = (ref) => {
|
|
3186
|
+
if (ref.kind === "system") return systemsById.has(ref.id);
|
|
3187
|
+
if (ref.kind === "resource") return omResourcesById.has(ref.id);
|
|
3188
|
+
if (ref.kind === "policy") return policiesById.has(ref.id);
|
|
3189
|
+
if (ref.kind === "role") return rolesById.has(ref.id);
|
|
3190
|
+
if (ref.kind === "trigger") return triggerIds.has(ref.id);
|
|
3191
|
+
if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
|
|
3192
|
+
if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
|
|
3193
|
+
if (ref.kind === "ontology") {
|
|
3194
|
+
if (ontologyIndex === void 0) return true;
|
|
3195
|
+
return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
|
|
3196
|
+
}
|
|
3197
|
+
return false;
|
|
3198
|
+
};
|
|
3199
|
+
for (const [relationshipId, relationship] of Object.entries(relationships)) {
|
|
3200
|
+
["from", "to"].forEach((side) => {
|
|
3201
|
+
const ref = relationship[side];
|
|
3202
|
+
if (topologyRefExists(ref)) return;
|
|
3203
|
+
addGovernanceIssue(
|
|
3204
|
+
issues,
|
|
3205
|
+
"topology-reference-missing",
|
|
3206
|
+
orgName,
|
|
3207
|
+
ref.id,
|
|
3208
|
+
`[${orgName}] Topology relationship '${relationshipId}' ${side} references missing ${ref.kind} '${ref.id}'.`
|
|
3209
|
+
);
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
2873
3213
|
function validateResourceGovernance(orgName, deployment, organizationModel = deployment.organizationModel, options = {}) {
|
|
2874
3214
|
const mode = getResourceValidatorMode(options.mode);
|
|
2875
3215
|
const omResourcesMap = organizationModel?.resources;
|
|
@@ -2885,6 +3225,17 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
|
|
|
2885
3225
|
const omResourcesById = new Map(activeOmResources.map((resource) => [resource.id, resource]));
|
|
2886
3226
|
const runtimeResources = getRuntimeResources(deployment);
|
|
2887
3227
|
const runtimeResourcesById = new Map(runtimeResources.map((resource) => [resource.resourceId, resource]));
|
|
3228
|
+
const ontologyCompilation = hasOntologySources(organizationModel) ? compileOrganizationOntology(organizationModel) : void 0;
|
|
3229
|
+
const ontologyIndex = ontologyCompilation?.ontology;
|
|
3230
|
+
for (const diagnostic of ontologyCompilation?.diagnostics ?? []) {
|
|
3231
|
+
addGovernanceIssue(
|
|
3232
|
+
issues,
|
|
3233
|
+
"ontology-reference-missing",
|
|
3234
|
+
orgName,
|
|
3235
|
+
diagnostic.id,
|
|
3236
|
+
`[${orgName}] ${diagnostic.message}`
|
|
3237
|
+
);
|
|
3238
|
+
}
|
|
2888
3239
|
for (const resource of activeOmResources) {
|
|
2889
3240
|
if (!systemsById.has(resource.systemPath)) {
|
|
2890
3241
|
addGovernanceIssue(
|
|
@@ -2924,6 +3275,16 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
|
|
|
2924
3275
|
`[${orgName}] Resource '${resource.id}' system mismatch: code descriptor has '${runtimeResource.descriptor.systemPath}', OM has '${resource.systemPath}'.`
|
|
2925
3276
|
);
|
|
2926
3277
|
}
|
|
3278
|
+
if (runtimeResource.descriptor && !sameJson(runtimeResource.descriptor.ontology, resource.ontology)) {
|
|
3279
|
+
addGovernanceIssue(
|
|
3280
|
+
issues,
|
|
3281
|
+
"descriptor-mismatch",
|
|
3282
|
+
orgName,
|
|
3283
|
+
resource.id,
|
|
3284
|
+
`[${orgName}] Resource '${resource.id}' ontology descriptor mismatch between code and OM.`
|
|
3285
|
+
);
|
|
3286
|
+
}
|
|
3287
|
+
addOntologyBindingIssues(issues, orgName, resource, ontologyIndex);
|
|
2927
3288
|
}
|
|
2928
3289
|
for (const runtimeResource of runtimeResources) {
|
|
2929
3290
|
const omResource = omResourcesById.get(runtimeResource.resourceId);
|
|
@@ -2965,6 +3326,7 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
|
|
|
2965
3326
|
);
|
|
2966
3327
|
}
|
|
2967
3328
|
}
|
|
3329
|
+
addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex);
|
|
2968
3330
|
emitGovernanceIssues(issues, mode, options.onWarning);
|
|
2969
3331
|
return {
|
|
2970
3332
|
valid: issues.length === 0,
|
|
@@ -6345,6 +6707,17 @@ var ResourceRegistry = class {
|
|
|
6345
6707
|
return cache.commandView;
|
|
6346
6708
|
}
|
|
6347
6709
|
};
|
|
6710
|
+
|
|
6711
|
+
// ../core/src/platform/registry/types.ts
|
|
6712
|
+
function bindResourceDescriptor(definition) {
|
|
6713
|
+
const { resource, ...rest } = definition;
|
|
6714
|
+
return {
|
|
6715
|
+
...rest,
|
|
6716
|
+
resource,
|
|
6717
|
+
resourceId: resource.id,
|
|
6718
|
+
type: resource.kind
|
|
6719
|
+
};
|
|
6720
|
+
}
|
|
6348
6721
|
DisplayMetadataSchema.extend({
|
|
6349
6722
|
id: ModelIdSchema,
|
|
6350
6723
|
order: z.number().min(0)
|
|
@@ -7612,6 +7985,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
7612
7985
|
},
|
|
7613
7986
|
ontology: DEFAULT_ONTOLOGY_SCOPE,
|
|
7614
7987
|
resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
|
|
7988
|
+
topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
|
|
7615
7989
|
actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
|
|
7616
7990
|
entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
|
|
7617
7991
|
policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
|
|
@@ -8864,4 +9238,4 @@ function isOurReplyAction(deal) {
|
|
|
8864
9238
|
var listBuilderStageKeys = Object.keys(LEAD_GEN_STAGE_CATALOG);
|
|
8865
9239
|
var ListBuilderStageKeySchema = z.enum(listBuilderStageKeys);
|
|
8866
9240
|
|
|
8867
|
-
export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, CRM_PIPELINE_DEFINITION, CrmStageKeySchema, CrmStateKeySchema, DEFAULT_CRM_ACTIONS, EmailSchema, ExecutionError, LEAD_GEN_STAGE_CATALOG, ListBuilderStageKeySchema, ProcessingStageStatusSchema, RegistryValidationError, ResourceRegistry, StepType, ToolingError, deriveActions, validateResourceGovernance };
|
|
9241
|
+
export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, CRM_PIPELINE_DEFINITION, CrmStageKeySchema, CrmStateKeySchema, DEFAULT_CRM_ACTIONS, EmailSchema, ExecutionError, LEAD_GEN_STAGE_CATALOG, ListBuilderStageKeySchema, ProcessingStageStatusSchema, RegistryValidationError, ResourceRegistry, StepType, ToolingError, bindResourceDescriptor, defineResource, defineResourceOntology, defineResources, defineTopology, defineTopologyRelationship, deriveActions, parseTopologyNodeRef, topologyRef, topologyRelationship, validateResourceGovernance };
|