319 lines
10 KiB
JavaScript
319 lines
10 KiB
JavaScript
import { geliosProviderPackageV12 } from "../v12/package.mjs";
|
|
|
|
export const GELIOS_PROVIDER_PACKAGE_ID = "gelios.provider.v13";
|
|
export const GELIOS_PROVIDER_PACKAGE_VERSION = "13.0.0";
|
|
export const GELIOS_UNIT_CONTACTS_DATA_PRODUCT_ID = "fleet.units.contacts.current.v2";
|
|
export const GELIOS_UNIT_CONTACTS_DATA_PRODUCT_VERSION = "2.0.0";
|
|
export const GELIOS_UNIT_CONTACTS_ONTOLOGY_REVISION = "ontology.map.moving_object.v3";
|
|
|
|
const UNITS_CAPABILITY_ID = "gelios.units.identity.read";
|
|
const USERS_CAPABILITY_ID = "gelios.users.directory.read";
|
|
const FIELD_POLICY_ID = "gelios.units.contacts.fields.v2";
|
|
const COLLECTION_PROFILE_ID = "gelios.units.contacts.warm.v2";
|
|
const MAPPING_ID = "gelios.units.to.fleet.units.contacts.current.v2";
|
|
const TEMPLATE_ID = "gelios.units.contacts.l2.v2";
|
|
|
|
const contactFields = Object.freeze([
|
|
"available_user_emails",
|
|
"available_user_ids",
|
|
"available_user_legal_names",
|
|
"available_user_logins",
|
|
"available_user_phones",
|
|
"device_imei",
|
|
"device_phone_primary",
|
|
"device_phone_secondary",
|
|
"display_name",
|
|
"provider_creator_email",
|
|
"provider_creator_id",
|
|
"provider_creator_legal_name",
|
|
"provider_creator_login",
|
|
"provider_creator_phone",
|
|
]);
|
|
|
|
const value = structuredClone(geliosProviderPackageV12);
|
|
const unitsCapability = value.capabilities.find(
|
|
(capability) => capability.id === UNITS_CAPABILITY_ID,
|
|
);
|
|
const templateBase = value.l2Templates.find(
|
|
(template) => template.id === "gelios.units.identity.l2.v1",
|
|
);
|
|
if (!unitsCapability) throw new Error("gelios_v13_units_capability_missing");
|
|
if (!templateBase) throw new Error("gelios_v13_template_base_missing");
|
|
|
|
value.id = GELIOS_PROVIDER_PACKAGE_ID;
|
|
value.version = GELIOS_PROVIDER_PACKAGE_VERSION;
|
|
value.manifest = {
|
|
...value.manifest,
|
|
id: "gelios.provider.manifest.v13",
|
|
version: GELIOS_PROVIDER_PACKAGE_VERSION,
|
|
capabilityIds: [...value.manifest.capabilityIds, USERS_CAPABILITY_ID],
|
|
fieldPolicyIds: [...value.manifest.fieldPolicyIds, FIELD_POLICY_ID],
|
|
collectionProfileIds: [...value.manifest.collectionProfileIds, COLLECTION_PROFILE_ID],
|
|
dataProductIds: [...value.manifest.dataProductIds, GELIOS_UNIT_CONTACTS_DATA_PRODUCT_ID],
|
|
mappingContractIds: [...value.manifest.mappingContractIds, MAPPING_ID],
|
|
l2TemplateIds: [...value.manifest.l2TemplateIds, TEMPLATE_ID],
|
|
};
|
|
|
|
value.capabilities.push({
|
|
...structuredClone(unitsCapability),
|
|
id: USERS_CAPABILITY_ID,
|
|
request: {
|
|
...structuredClone(unitsCapability.request),
|
|
path: "/api/v1/users",
|
|
query: {
|
|
incladmpan: false,
|
|
inclavfun: false,
|
|
inclbillinf: false,
|
|
inclextra: false,
|
|
inclexs: false,
|
|
inclmon: false,
|
|
inclsmtp: false,
|
|
o1: "userIdAsc",
|
|
pl: 500,
|
|
po: 0,
|
|
},
|
|
response: {
|
|
collectionPaths: ["items"],
|
|
pagination: {
|
|
mode: "offset",
|
|
limitParameter: "pl",
|
|
offsetParameter: "po",
|
|
pageSize: 500,
|
|
itemsPath: "items",
|
|
totalPath: "paginationMetadata.totalCount",
|
|
maxPages: 10,
|
|
maxItems: 5000,
|
|
maxResponseBytes: 16 * 1024 * 1024,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
value.fieldPolicies.push({
|
|
id: FIELD_POLICY_ID,
|
|
version: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_VERSION,
|
|
dataProductId: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_ID,
|
|
targetFields: [...contactFields],
|
|
unknownSourceFields: "drop",
|
|
dynamicSourceFields: "drop_until_classified",
|
|
restrictedSourcePaths: [
|
|
"commands",
|
|
"currentUserAccess",
|
|
"customFields",
|
|
"driver",
|
|
"extraInfo",
|
|
"hwDecryptKey",
|
|
"lastMsg",
|
|
"lastSensorsVal",
|
|
"maintenancePlan",
|
|
"preSetCommandGroup",
|
|
"sensors",
|
|
"stationaryLat",
|
|
"stationaryLon",
|
|
"storageInfo",
|
|
],
|
|
});
|
|
|
|
value.collectionProfiles.push({
|
|
id: COLLECTION_PROFILE_ID,
|
|
version: GELIOS_PROVIDER_PACKAGE_VERSION,
|
|
mode: "realtime",
|
|
schedule: { intervalMs: 5 * 60 * 1000 },
|
|
capabilityIds: [UNITS_CAPABILITY_ID, USERS_CAPABILITY_ID],
|
|
dataProductId: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_ID,
|
|
mappingContractId: MAPPING_ID,
|
|
fieldPolicyId: FIELD_POLICY_ID,
|
|
l2TemplateId: TEMPLATE_ID,
|
|
entityScope: {
|
|
mode: "all_visible_to_credential",
|
|
refresh: "each_collection_run",
|
|
businessEntityFilter: "forbidden",
|
|
},
|
|
batching: { maxFacts: 5000 },
|
|
cardinality: {
|
|
maxCurrentEntities: 5000,
|
|
onExceed: "require_partitioned_data_product",
|
|
},
|
|
retry: { maxAttempts: 4, backoff: "fixed_delay", delayMs: 2000 },
|
|
});
|
|
|
|
value.dataProducts.push({
|
|
id: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_ID,
|
|
version: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_VERSION,
|
|
ontologyRevision: GELIOS_UNIT_CONTACTS_ONTOLOGY_REVISION,
|
|
deliveryMode: "snapshot+patch",
|
|
semanticTypes: ["map.moving_object"],
|
|
fields: [...contactFields],
|
|
fieldContracts: {
|
|
available_user_emails: optional("string_array"),
|
|
available_user_ids: optional("string_array"),
|
|
available_user_legal_names: optional("string_array"),
|
|
available_user_logins: optional("string_array"),
|
|
available_user_phones: optional("string_array"),
|
|
device_imei: optional("string"),
|
|
device_phone_primary: optional("string"),
|
|
device_phone_secondary: optional("string"),
|
|
display_name: { type: "string", required: true },
|
|
provider_creator_email: optional("string"),
|
|
provider_creator_id: optional("string"),
|
|
provider_creator_legal_name: optional("string"),
|
|
provider_creator_login: optional("string"),
|
|
provider_creator_phone: optional("string"),
|
|
},
|
|
history: { mode: "none", retentionDays: 1 },
|
|
});
|
|
|
|
value.mappingContracts.push({
|
|
schemaVersion: "nodedc.semantic-mapping/v1",
|
|
id: MAPPING_ID,
|
|
version: GELIOS_PROVIDER_PACKAGE_VERSION,
|
|
sourceCapabilityId: UNITS_CAPABILITY_ID,
|
|
fieldPolicyId: FIELD_POLICY_ID,
|
|
target: {
|
|
dataProductId: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_ID,
|
|
version: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_VERSION,
|
|
ontologyRevision: GELIOS_UNIT_CONTACTS_ONTOLOGY_REVISION,
|
|
semanticType: "map.moving_object",
|
|
},
|
|
derivations: {
|
|
available_user_emails: responseLookupList("availableToUsers", "email"),
|
|
available_user_ids: boundedStringList("availableToUsers", "id"),
|
|
available_user_legal_names: responseLookupList("availableToUsers", "legalName"),
|
|
available_user_logins: boundedStringList("availableToUsers", "login"),
|
|
available_user_phones: responseLookupList("availableToUsers", "phone"),
|
|
provider_creator_email: responseLookupFirst("creator.id", "email"),
|
|
provider_creator_legal_name: responseLookupFirst("creator.id", "legalName"),
|
|
provider_creator_phone: responseLookupFirst("creator.id", "phone"),
|
|
},
|
|
fact: {
|
|
sourceId: {
|
|
strategy: "first_non_empty",
|
|
paths: ["id", "unit_id", "unitId"],
|
|
coerce: "string",
|
|
prefix: "gelios-unit-",
|
|
},
|
|
semanticType: { constant: "map.moving_object" },
|
|
observedAt: {
|
|
strategy: "first_non_empty",
|
|
paths: ["updatedAt"],
|
|
coerce: "unix_or_iso_timestamp",
|
|
fallback: "collection_received_at",
|
|
},
|
|
attributes: {
|
|
available_user_emails: { derive: "available_user_emails" },
|
|
available_user_ids: { derive: "available_user_ids" },
|
|
available_user_legal_names: { derive: "available_user_legal_names" },
|
|
available_user_logins: { derive: "available_user_logins" },
|
|
available_user_phones: { derive: "available_user_phones" },
|
|
device_imei: stringField(["imei"]),
|
|
device_phone_primary: stringField(["phone"]),
|
|
device_phone_secondary: stringField(["phone2"]),
|
|
display_name: stringField(["name", "unit_name", "title", "label"], false),
|
|
provider_creator_email: { derive: "provider_creator_email", omitIfMissing: true },
|
|
provider_creator_id: stringField(["creator.id"]),
|
|
provider_creator_legal_name: {
|
|
derive: "provider_creator_legal_name",
|
|
omitIfMissing: true,
|
|
},
|
|
provider_creator_login: stringField(["creator.login"]),
|
|
provider_creator_phone: { derive: "provider_creator_phone", omitIfMissing: true },
|
|
},
|
|
},
|
|
});
|
|
|
|
value.l2Templates.push({
|
|
...structuredClone(templateBase),
|
|
id: TEMPLATE_ID,
|
|
version: GELIOS_PROVIDER_PACKAGE_VERSION,
|
|
steps: [
|
|
{ id: "collection.trigger", kind: "collection_trigger", collectionProfileDriven: true },
|
|
{ id: "provider.fetch-units", kind: "provider_request", capabilityId: UNITS_CAPABILITY_ID },
|
|
{ id: "provider.fetch-users", kind: "provider_request", capabilityId: USERS_CAPABILITY_ID },
|
|
{ id: "provider.extract-units", kind: "extract_items", capabilityId: UNITS_CAPABILITY_ID },
|
|
{ id: "ontology.map", kind: "semantic_mapping", mappingContractId: MAPPING_ID },
|
|
{
|
|
id: "data-product.publish",
|
|
kind: "data_product_publish",
|
|
dataProductId: GELIOS_UNIT_CONTACTS_DATA_PRODUCT_ID,
|
|
nodeType: "n8n-nodes-ndc.ndcDataProductPublish",
|
|
},
|
|
],
|
|
});
|
|
|
|
export const geliosProviderPackageV13 = deepFreeze(value);
|
|
|
|
function optional(type) {
|
|
return { type, required: false };
|
|
}
|
|
|
|
function stringField(paths, omitIfMissing = true) {
|
|
return {
|
|
strategy: "first_non_empty",
|
|
paths,
|
|
coerce: "string",
|
|
...(omitIfMissing ? { omitIfMissing: true } : {}),
|
|
};
|
|
}
|
|
|
|
function boundedStringList(arrayPath, valuePath) {
|
|
return {
|
|
kind: "bounded_string_list",
|
|
rules: ["array.string_values"],
|
|
default: [],
|
|
parameters: {
|
|
arrayPath,
|
|
valuePath,
|
|
maxItems: 256,
|
|
maxItemLength: 512,
|
|
},
|
|
};
|
|
}
|
|
|
|
function responseLookupList(sourceArrayPath, valuePath) {
|
|
return {
|
|
kind: "bounded_response_lookup",
|
|
rules: ["response.lookup.list"],
|
|
default: [],
|
|
parameters: {
|
|
responseCapabilityId: USERS_CAPABILITY_ID,
|
|
responseCollectionPath: "items",
|
|
responseKeyPath: "id",
|
|
sourceArrayPath,
|
|
sourceKeyPath: "id",
|
|
valuePath,
|
|
resultMode: "list",
|
|
maxResponseItems: 5000,
|
|
maxSourceKeys: 256,
|
|
maxItems: 256,
|
|
maxItemLength: 512,
|
|
},
|
|
};
|
|
}
|
|
|
|
function responseLookupFirst(sourceKeyPath, valuePath) {
|
|
return {
|
|
kind: "bounded_response_lookup",
|
|
rules: ["response.lookup.first"],
|
|
default: "",
|
|
parameters: {
|
|
responseCapabilityId: USERS_CAPABILITY_ID,
|
|
responseCollectionPath: "items",
|
|
responseKeyPath: "id",
|
|
sourceKeyPath,
|
|
valuePath,
|
|
resultMode: "first",
|
|
maxResponseItems: 5000,
|
|
maxSourceKeys: 1,
|
|
maxItems: 1,
|
|
maxItemLength: 512,
|
|
},
|
|
};
|
|
}
|
|
|
|
function deepFreeze(input) {
|
|
if (!input || typeof input !== "object" || Object.isFrozen(input)) return input;
|
|
Object.freeze(input);
|
|
for (const child of Object.values(input)) deepFreeze(child);
|
|
return input;
|
|
}
|