feat(provider): publish full unit identity product

This commit is contained in:
Codex
2026-07-24 11:42:41 +03:00
parent 8cc917508e
commit abebb9fac6
13 changed files with 801 additions and 32 deletions
@@ -9,10 +9,11 @@ export const L2_EXECUTION_PLAN_SCHEMA_VERSION = "nodedc.l2-execution-plan/v1";
export const L2_GRAPH_BLUEPRINT_SCHEMA_VERSION = "nodedc.l2-graph-blueprint/v1";
export const L2_MATERIALIZATION_RECEIPT_SCHEMA_VERSION = "nodedc.l2-materialization-receipt/v1";
export const L2_MAPPING_RUNTIME_SCHEMA_VERSION = "nodedc.semantic-mapping-runtime/v1";
export const L2_EXECUTION_PLAN_COMPILER_VERSION = "1.3.0";
export const L2_EXECUTION_PLAN_COMPILER_VERSION = "1.4.0";
export const L2_EXECUTION_PLAN_SUPPORTED_COMPILER_VERSIONS = Object.freeze([
"1.1.0",
"1.2.0",
"1.3.0",
L2_EXECUTION_PLAN_COMPILER_VERSION,
]);
@@ -295,7 +295,10 @@ export function validateProviderPackage(value) {
const restricted = Array.isArray(fieldPolicy.restrictedSourcePaths)
? fieldPolicy.restrictedSourcePaths.filter(isCanonicalSourcePath)
: [];
if (mappingSourcePaths(mapping.fact).some((path) => (
if (mappingSourcePaths({
fact: mapping.fact,
derivations: mapping.derivations,
}).some((path) => (
restricted.some((restrictedPath) => (
path === restrictedPath
|| path.startsWith(`${restrictedPath}.`)
@@ -1041,7 +1044,14 @@ function validateExpression(value, path, errors) {
function validateDerivation(value, path, errors) {
if (!isPlainObject(value)) return errors.push(`${path}_must_be_object`);
rejectUnknownKeys(value, DERIVATION_KEYS, path, errors);
if (!new Set(["boolean_rule", "ordered_rules", "flag_set", "bounded_readings"]).has(value.kind)) errors.push(`${path}.kind_invalid`);
if (!new Set([
"boolean_rule",
"ordered_rules",
"flag_set",
"bounded_readings",
"bounded_string_list",
"bounded_named_values",
]).has(value.kind)) errors.push(`${path}.kind_invalid`);
requiredUniqueIdentifierArray(value.rules, `${path}.rules`, errors);
if (value.default === undefined) {
errors.push(`${path}.default_required`);
@@ -1059,6 +1069,70 @@ function validateDerivation(value, path, errors) {
}
}
}
if (value.kind === "bounded_string_list") {
validateBoundedStringListDerivation(value, path, errors);
}
if (value.kind === "bounded_named_values") {
validateBoundedNamedValuesDerivation(value, path, errors);
}
}
function validateBoundedStringListDerivation(value, path, errors) {
const parameters = isPlainObject(value.parameters) ? value.parameters : {};
const allowed = new Set(["arrayPath", "valuePath", "maxItems", "maxItemLength"]);
if (Object.keys(parameters).some((key) => !allowed.has(key))) {
errors.push(`${path}.parameters_shape_invalid`);
}
for (const key of ["arrayPath", "valuePath"]) {
if (!isCanonicalSourcePath(parameters[key])) {
errors.push(`${path}.parameters.${key}_must_be_canonical_dot_path`);
}
}
if (!Number.isInteger(parameters.maxItems) || parameters.maxItems < 1 || parameters.maxItems > 256) {
errors.push(`${path}.parameters.maxItems_invalid`);
}
if (
!Number.isInteger(parameters.maxItemLength)
|| parameters.maxItemLength < 1
|| parameters.maxItemLength > 512
) {
errors.push(`${path}.parameters.maxItemLength_invalid`);
}
if (!Array.isArray(value.default) || value.default.length !== 0) {
errors.push(`${path}.default_must_be_empty_array`);
}
}
function validateBoundedNamedValuesDerivation(value, path, errors) {
const parameters = isPlainObject(value.parameters) ? value.parameters : {};
const allowed = new Set([
"arrayPath",
"namePath",
"valuePath",
"maxItems",
"maxItemLength",
]);
if (Object.keys(parameters).some((key) => !allowed.has(key))) {
errors.push(`${path}.parameters_shape_invalid`);
}
for (const key of ["arrayPath", "namePath", "valuePath"]) {
if (!isCanonicalSourcePath(parameters[key])) {
errors.push(`${path}.parameters.${key}_must_be_canonical_dot_path`);
}
}
if (!Number.isInteger(parameters.maxItems) || parameters.maxItems < 1 || parameters.maxItems > 256) {
errors.push(`${path}.parameters.maxItems_invalid`);
}
if (
!Number.isInteger(parameters.maxItemLength)
|| parameters.maxItemLength < 1
|| parameters.maxItemLength > 512
) {
errors.push(`${path}.parameters.maxItemLength_invalid`);
}
if (!Array.isArray(value.default) || value.default.length !== 0) {
errors.push(`${path}.default_must_be_empty_array`);
}
}
function mappingDerivationReferences(value, found = new Set()) {
@@ -1087,7 +1161,11 @@ function mappingSourcePaths(value, found = []) {
if (isCanonicalSourcePath(value[key])) found.push(value[key]);
}
Object.entries(value).forEach(([key, item]) => {
if (key !== "paths" && !key.endsWith("Path")) mappingSourcePaths(item, found);
if (key !== "paths" && key.endsWith("Path") && isCanonicalSourcePath(item)) {
found.push(item);
} else if (key !== "paths" && !key.endsWith("Path")) {
mappingSourcePaths(item, found);
}
});
return found;
}