/** * ------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ import { DateOnly, Duration, TimeOnly, createBackedModelProxyHandler, createUntypedArray, createUntypedBoolean, createUntypedNodeFromDiscriminatorValue, createUntypedNull, createUntypedNumber, createUntypedObject, createUntypedString, inNodeEnv, isBackingStoreEnabled, isUntypedNode, parseGuidString, getEnumValueFromStringValue } from "@microsoft/kiota-abstractions"; export class JsonParseNode { /** * Creates an instance of JsonParseNode. * @param _jsonNode - The JSON node to parse. * @param backingStoreFactory - The factory to create backing stores. */ constructor(_jsonNode, backingStoreFactory) { this._jsonNode = _jsonNode; this.backingStoreFactory = backingStoreFactory; this.getStringValue = () => (typeof this._jsonNode === "string" ? this._jsonNode : undefined); this.getChildNode = (identifier) => (this._jsonNode && typeof this._jsonNode === "object" && this._jsonNode[identifier] !== undefined ? new JsonParseNode(this._jsonNode[identifier], this.backingStoreFactory) : undefined); this.getBooleanValue = () => (typeof this._jsonNode === "boolean" ? this._jsonNode : undefined); this.getNumberValue = () => (typeof this._jsonNode === "number" ? this._jsonNode : undefined); this.getGuidValue = () => parseGuidString(this.getStringValue()); this.getDateValue = () => (this._jsonNode ? new Date(this._jsonNode) : undefined); this.getDateOnlyValue = () => DateOnly.parse(this.getStringValue()); this.getTimeOnlyValue = () => TimeOnly.parse(this.getStringValue()); this.getDurationValue = () => Duration.parse(this.getStringValue()); this.getCollectionOfPrimitiveValues = () => { if (!Array.isArray(this._jsonNode)) { return undefined; } return this._jsonNode.map((x) => { const currentParseNode = new JsonParseNode(x, this.backingStoreFactory); const typeOfX = typeof x; if (typeOfX === "boolean") { return currentParseNode.getBooleanValue(); } else if (typeOfX === "string") { return currentParseNode.getStringValue(); } else if (typeOfX === "number") { return currentParseNode.getNumberValue(); } else if (x instanceof Date) { return currentParseNode.getDateValue(); } else if (x instanceof DateOnly) { return currentParseNode.getDateValue(); } else if (x instanceof TimeOnly) { return currentParseNode.getDateValue(); } else if (x instanceof Duration) { return currentParseNode.getDateValue(); } else { throw new Error(`encountered an unknown type during deserialization ${typeof x}`); } }); }; this.getCollectionOfObjectValues = (method) => { if (!Array.isArray(this._jsonNode)) { return undefined; } return this._jsonNode ? this._jsonNode.map((x) => new JsonParseNode(x, this.backingStoreFactory)).map((x) => x.getObjectValue(method)) : undefined; }; this.getObjectValue = (parsableFactory) => { const temp = {}; if (isUntypedNode(parsableFactory(this)(temp))) { const valueType = typeof this._jsonNode; let value = temp; if (valueType === "boolean") { value = createUntypedBoolean(this._jsonNode); } else if (valueType === "string") { value = createUntypedString(this._jsonNode); } else if (valueType === "number") { value = createUntypedNumber(this._jsonNode); } else if (Array.isArray(this._jsonNode)) { const nodes = []; this._jsonNode.forEach((x) => { nodes.push(new JsonParseNode(x, this.backingStoreFactory).getObjectValue(createUntypedNodeFromDiscriminatorValue)); }); value = createUntypedArray(nodes); } else if (this._jsonNode && valueType === "object") { const properties = {}; Object.entries(this._jsonNode).forEach(([k, v]) => { properties[k] = new JsonParseNode(v, this.backingStoreFactory).getObjectValue(createUntypedNodeFromDiscriminatorValue); }); value = createUntypedObject(properties); } else if (!this._jsonNode) { value = createUntypedNull(); } return value; } const enableBackingStore = isBackingStoreEnabled(parsableFactory(this)(temp)); const objectValue = enableBackingStore && this.backingStoreFactory ? new Proxy(temp, createBackedModelProxyHandler(this.backingStoreFactory)) : temp; if (this.onBeforeAssignFieldValues) { this.onBeforeAssignFieldValues(objectValue); } this.assignFieldValues(objectValue, parsableFactory); if (this.onAfterAssignFieldValues) { this.onAfterAssignFieldValues(objectValue); } return objectValue; }; this.assignFieldValues = (model, parsableFactory) => { const fields = parsableFactory(this)(model); if (!this._jsonNode) return; Object.entries(this._jsonNode).forEach(([k, v]) => { var _a; const deserializer = fields[k]; if (deserializer) { deserializer(new JsonParseNode(v, this.backingStoreFactory)); } else { // there is no real way to test if the model is actually a holder or not // additional properties const modelDataHolder = model; (_a = modelDataHolder.additionalData) !== null && _a !== void 0 ? _a : (modelDataHolder.additionalData = {}); modelDataHolder.additionalData[k] = v; } }); }; this.getCollectionOfEnumValues = (type) => { if (Array.isArray(this._jsonNode)) { return this._jsonNode .map((x) => { const node = new JsonParseNode(x, this.backingStoreFactory); return node.getEnumValue(type); }) .filter(Boolean); } return []; }; this.getEnumValue = (type) => { const rawValue = this.getStringValue(); if (!rawValue) { return undefined; } return getEnumValueFromStringValue(rawValue, type); }; } getByteArrayValue() { const strValue = this.getStringValue(); if (strValue && strValue.length > 0) { /** * Node.js Buffer objects created via Buffer.from() use a shared memory pool * and may be subject to reuse/recycling, which can lead to unexpected behavior. * * For consistent behavior across environments: * - In Node: We convert the base64 string to a Buffer first, then create a new * Uint8Array from it to ensure we have a stable, independent copy * - In browsers: We convert the string directly using TextEncoder * * TODO: Consider standardizing on a cross-platform UInt8Array.fromBase64 (after the API is stabilized across browsers) * in the future instead of the current environment-specific approach */ return inNodeEnv() ? new Uint8Array(Buffer.from(strValue, "base64")).buffer : new TextEncoder().encode(strValue); } return undefined; } } //# sourceMappingURL=jsonParseNode.js.map