@walletpass/pass-js
Version:
Apple Wallet Pass generating and pushing updates from Node.js
49 lines • 2.02 kB
JavaScript
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2017-2026 Konstantin Vyatkin <tino@vtkn.io>
import { getW3CDateString } from './w3cdate.js';
function normalizeSemanticValue(value, onPath) {
if (value instanceof Date) {
if (!Number.isFinite(value.getTime()))
throw new TypeError(`Semantic tag Date values must be valid`);
return getW3CDateString(value);
}
if (Array.isArray(value)) {
if (onPath.has(value))
throw new TypeError(`Semantic tags must not contain cyclic references`);
onPath.add(value);
try {
return value.map(v => normalizeSemanticValue(v, onPath));
}
finally {
onPath.delete(value);
}
}
// The truthiness check excludes null, because typeof null is 'object'.
if (value && typeof value === 'object') {
if (onPath.has(value))
throw new TypeError(`Semantic tags must not contain cyclic references`);
onPath.add(value);
try {
const result = {};
for (const [key, nestedValue] of Object.entries(value))
result[key] = normalizeSemanticValue(nestedValue, onPath);
return result;
}
finally {
onPath.delete(value);
}
}
return value;
}
// Deep-copies semantic tag dictionaries, converting Date values to W3C date
// strings and throwing on cyclic input. Only values currently on the active
// recursion path count as a cycle — shared subtrees used in multiple
// branches are acyclic and serialize normally.
export function normalizeSemanticTags(tags) {
// Cast-through: the runtime walker treats any plain object as a
// `SemanticTagObject`, but the strictly-typed `SemanticTags` interface
// intentionally lacks an index signature. The narrowing is purely a
// compile-time safety net; the walk is schema-agnostic.
return normalizeSemanticValue(tags, new Set());
}
//# sourceMappingURL=semantic-tags.js.map