Skip to main content

Check a supplier export with JavaScript or TypeScript

You receive a supplier's CMD export at a dealership. Check raw JSON with the schema validator first: a separate prerequisite, not an SDK feature. Then read, check and write the document. This complete example contains one fictional Party, without a VIN or globally required address/GLN.

Install a local package​

@pobbd/cmd-sdk@0.26.0 is an independent ESM package for Node.js 24+ and browsers supporting ES2022 and BigInt. There is no CommonJS build. Build a local archive from the checkout:

cd packages/javascript/sdk
npm ci --ignore-scripts
npm run build
npm pack

The archive is packages/javascript/sdk/pobbd-cmd-sdk-0.26.0.tgz. From an existing consumer project's directory, install its absolute local path:

npm install /absolute/path/to/packages/javascript/sdk/pobbd-cmd-sdk-0.26.0.tgz

The SDK has no runtime dependencies. Its build pins TypeScript 7.0.2 and Prettier 3.9.10 as development tools; formatting does not generate DTOs. These steps assume neither a repository clone URL nor registry installation.

Read, check, write​

Save as export-check.mjs in that installed consumer:

import { read, validate, write } from '@pobbd/cmd-sdk';

const json = `
{
"parties": [
{
"id": "party_example",
"organization_name": "Fictional supplier"
}
]
}
`;
const bundle = read(json, 'type', '0.26');
const violations = validate(bundle);
if (violations.length !== 0) {
throw new Error(JSON.stringify(violations));
}
console.log(bundle.parties[0].organization_name);
console.log(write(bundle));

Run node export-check.mjs. Expect Fictional supplier, then JSON containing the same Party. Inspect violations through code, path, parameters and message; some callback codes are null. Reject or quarantine failed exports before storage. Reading alone proves neither semantic validity nor company identity.

For typed construction, use exported DTO types and hydrate the object before validation. A structurally similar plain object is not a hydrated SDK bundle:

import { hydrate, normalize, validate } from '@pobbd/cmd-sdk';
import type { TypeBundle } from '@pobbd/cmd-sdk';

const bundle: TypeBundle = hydrate('TypeBundle', {
parties: [{
id: 'party_example',
organization_name: 'Fictional supplier',
}],
});
if (validate(bundle).length !== 0) {
throw new Error('Invalid supplier export');
}
console.log(normalize(bundle));

The literal profile in read(json, 'type', '0.26') selects TypeBundle. A dynamic profile string returns the Bundle union. Types are exported from the installed package alongside declarations; runtime enum values remain wire strings.

Use self-hosted browser modules​

Copy all emitted dist/ files, preserving names and relative .js imports, to a self-hosted cmd-sdk/ directory beside this HTML document. Serve both via HTTP with JavaScript MIME types. No CDN or Node runtime import is needed:

<script type="module">
import { read, validate } from './cmd-sdk/index.js';

const bundle = read(
'{"parties":[{"id":"party_example","organization_name":"Fictional supplier"}]}',
'type',
'0.26',
);
document.body.textContent = JSON.stringify(validate(bundle));
</script>

Expect [] for this valid export. The library fetches no supplier data, schemas or external catalogs. Configure browser serving in your application; the SDK supplies no production server.

Keep strict input and presence​

read(json, profile, version) accepts only type, instance, recall and wire version 0.26, not package version 0.26.0. hydrate(dtoName, input) uses the same strict nested decoder and copies/freezes DTOs and collections. Malformed JSON throws a parsing error; decoding failures throw HydrationError with a property path. Unknown keys/enums, missing required keys, wrong scalar kinds and unsafe/nonfinite numbers are rejected. Handle these failures separately from semantic violations.

Optional absence, explicit null, empty collections and zero stay distinct under normalize(bundle) and write(bundle). Required-nullable keys Vehicle.first_registration and VehicleDamage.component cannot be omitted. Preserving a null does not establish schema nullability. No inferred defaults are inserted. Number spelling, member order and duplicate-member occurrences are not round-trip guarantees. Integral 6.0 is accepted as an integer; numeric strings are not. Numeric magnitude is limited to 9007199254740991; BigInt is used internally for instant comparisons, not as a JSON field type.

Choose partial or closed graph checks​

validate(bundle) checks fields and a document-local partial graph. Visible contradictions fail; references outside the supplied data may remain unresolved. validateGraph(keyedBundles, false) checks several documents in partial mode. Object keys label violation paths.

For closed checks, use validateGraph(keyedBundles): the default mode, also selected by a second argument of true. Supply every required referenced record. A Source pointing to party_example may pass partial checks without its Party but fails closed checks until a compatible Party is supplied. The Party-only example passes both. Neither mode fetches references or interprets ID prefixes. Validation boundaries explain storage-owned limits.

Apply the receiver's agreement​

validateContract(payload, references, trustedContract, context) checks bilateral completeness after core and closed-graph prerequisites. The receiver selects a trusted hydrated DataContract and independently configured ContractContext, never a weaker policy selected by incoming data_contracts. All six exact bindings are required:

BindingExpected value
contract_id, contract_versionTrusted agreement and immutable revision
publisher_party_id, consumer_party_idSupplier and receiving dealer, in order
profile, cmd_versionAgreed wire profile and 0.26

The entire logical definition is immutable under an ID/version. Alternatives are inclusive OR; every requirement in a chosen alternative must hold for every selected target. min_occurs prevents empty target sets from passing accidentally. FIELD paths traverse declared nested DTO properties, not collections, references or expressions. IDENTIFIER checks compare supplied Party assertions, not external issuance. Address and GLN requirements belong to an agreement, not every Party. See agreement semantics and the complete wire/PHP walkthrough; it is not a JavaScript API sample.

Query dated history​

new VehicleHistory(instanceBundles) requires hydrated instance bundles and checks their partial graph. equipment(vehicleId, item, asOf), damageStatus(vehicleId, damageId, asOf) and component(vehicleId, component, asOf) return the wire unions Presence, RepairStatus and ComponentGrade. Supply a real YYYY-MM-DD date.

Undated evidence is not backdated. Equipment intervals are half-open; conflicting latest equally ranked observations return UNKNOWN. Unknown does not prove absence. History semantics describe the dated rules.

The SDK performs no database/registry lookup, identity certification, invoice validation or automatic version migration. Project licensing does not grant rights to supplier exports; source-data boundaries still apply.