From f63c21db87e656bf6fcc5b525aa627a46777a697 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Tue, 20 Feb 2024 11:22:29 +0300 Subject: [PATCH 1/9] WIP untyped nodes. Reverted linting changes. --- package-lock.json | 2 +- packages/abstractions/package.json | 2 +- .../abstractions/src/serialization/index.ts | 7 +++ .../src/serialization/untypedArray.ts | 10 ++++ .../src/serialization/untypedBoolean.ts | 9 ++++ .../src/serialization/untypedNode.ts | 32 +++++++++++++ .../src/serialization/untypedNull.ts | 9 ++++ .../src/serialization/untypedNumber.ts | 9 ++++ .../src/serialization/untypedObject.ts | 13 +++++ .../src/serialization/untypedString.ts | 9 ++++ .../json/src/jsonSerializationWriter.ts | 48 ++++++++++++++++++- 11 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 packages/abstractions/src/serialization/untypedArray.ts create mode 100644 packages/abstractions/src/serialization/untypedBoolean.ts create mode 100644 packages/abstractions/src/serialization/untypedNode.ts create mode 100644 packages/abstractions/src/serialization/untypedNull.ts create mode 100644 packages/abstractions/src/serialization/untypedNumber.ts create mode 100644 packages/abstractions/src/serialization/untypedObject.ts create mode 100644 packages/abstractions/src/serialization/untypedString.ts diff --git a/package-lock.json b/package-lock.json index cf8c85f59b..9d138ac435 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13245,7 +13245,7 @@ }, "packages/abstractions": { "name": "@microsoft/kiota-abstractions", - "version": "1.0.0-preview.43", + "version": "1.0.0-preview.44", "license": "MIT", "dependencies": { "@opentelemetry/api": "^1.7.0", diff --git a/packages/abstractions/package.json b/packages/abstractions/package.json index 07dcfbc684..d7f6568c6e 100644 --- a/packages/abstractions/package.json +++ b/packages/abstractions/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-abstractions", - "version": "1.0.0-preview.43", + "version": "1.0.0-preview.44", "description": "Core abstractions for kiota generated libraries in TypeScript and JavaScript", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", diff --git a/packages/abstractions/src/serialization/index.ts b/packages/abstractions/src/serialization/index.ts index e5235b6d07..30196f7e22 100644 --- a/packages/abstractions/src/serialization/index.ts +++ b/packages/abstractions/src/serialization/index.ts @@ -12,3 +12,10 @@ export * from "./serializationWriterFactory"; export * from "./serializationWriterFactoryRegistry"; export * from "./serializationWriterProxyFactory"; export * from "./serializationFunctionTypes"; +export * from "./untypedNode"; +export * from "./untypedNumber"; +export * from "./untypedArray"; +export * from "./untypedNull"; +export * from "./untypedObject"; +export * from "./untypedString"; +export * from "./untypedBoolean"; diff --git a/packages/abstractions/src/serialization/untypedArray.ts b/packages/abstractions/src/serialization/untypedArray.ts new file mode 100644 index 0000000000..a92ec12129 --- /dev/null +++ b/packages/abstractions/src/serialization/untypedArray.ts @@ -0,0 +1,10 @@ +import { isUntypedNode, type UntypedNode } from "./untypedNode"; + +export interface UntypedArray extends UntypedNode { + getValue(): UntypedNode[]; +} + +export function isUntypedArray(node: UntypedNode): node is UntypedArray { + const value = (node as UntypedArray).value; + return value instanceof Array && value.every((item) => isUntypedNode(item)); +} diff --git a/packages/abstractions/src/serialization/untypedBoolean.ts b/packages/abstractions/src/serialization/untypedBoolean.ts new file mode 100644 index 0000000000..9bcfa0ecb9 --- /dev/null +++ b/packages/abstractions/src/serialization/untypedBoolean.ts @@ -0,0 +1,9 @@ +import type { UntypedNode } from "./untypedNode"; + +export interface UntypedBoolean extends UntypedNode { + getValue(): boolean; +} + +export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { + return typeof (node as UntypedBoolean).value === "boolean"; +} diff --git a/packages/abstractions/src/serialization/untypedNode.ts b/packages/abstractions/src/serialization/untypedNode.ts new file mode 100644 index 0000000000..2cffdbbf92 --- /dev/null +++ b/packages/abstractions/src/serialization/untypedNode.ts @@ -0,0 +1,32 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import type { Parsable } from "./parsable"; +import type { ParseNode } from "./parseNode"; +import type { SerializationWriter } from "./serializationWriter"; + +export interface UntypedNode extends Parsable { + getValue(): any; + value?: any; +} + +export function createUntypedNodeFromDiscriminatorValue( + _parseNode: ParseNode | undefined, +): (instance?: Parsable) => Record void> { + return deserializeIntoUntypedNode; +} + +export function isUntypedNode(node: any): node is UntypedNode { + return (node as UntypedNode).getValue !== undefined; +} + +export function deserializeIntoUntypedNode( + _untypedNode: Partial | undefined = {}, +): Record void> { + return {}; +} + +export function serializeUntypedNode( + _writer: SerializationWriter, + _errorDetails: Partial | undefined = {}, +): void { + return; +} diff --git a/packages/abstractions/src/serialization/untypedNull.ts b/packages/abstractions/src/serialization/untypedNull.ts new file mode 100644 index 0000000000..01808f9f70 --- /dev/null +++ b/packages/abstractions/src/serialization/untypedNull.ts @@ -0,0 +1,9 @@ +import type { UntypedNode } from "./untypedNode"; + +export interface UntypedNull extends UntypedNode { + getValue(): null; +} + +export function isUntypedNull(node: UntypedNode): node is UntypedNull { + return (node as UntypedNull).value === null; +} diff --git a/packages/abstractions/src/serialization/untypedNumber.ts b/packages/abstractions/src/serialization/untypedNumber.ts new file mode 100644 index 0000000000..4eb140d2c8 --- /dev/null +++ b/packages/abstractions/src/serialization/untypedNumber.ts @@ -0,0 +1,9 @@ +import type { UntypedNode } from "./untypedNode"; + +export interface UntypedNumber extends UntypedNode { + getValue(): number; +} + +export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { + return typeof (node as UntypedNumber).value === "number"; +} diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts new file mode 100644 index 0000000000..5bee476bda --- /dev/null +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -0,0 +1,13 @@ +import { isUntypedNode, type UntypedNode } from "./untypedNode"; + +export interface UntypedObject extends UntypedNode { + getValue(): Record; +} + +export function isUntypedObject(node: UntypedNode): node is UntypedObject { + const value = (node as UntypedObject).value; + return ( + value instanceof Object && + Object.values(value).every((item) => isUntypedNode(item)) + ); +} diff --git a/packages/abstractions/src/serialization/untypedString.ts b/packages/abstractions/src/serialization/untypedString.ts new file mode 100644 index 0000000000..2c6844cb3e --- /dev/null +++ b/packages/abstractions/src/serialization/untypedString.ts @@ -0,0 +1,9 @@ +import type { UntypedNode } from "./untypedNode"; + +export interface UntypedString extends UntypedNode { + getValue(): string; +} + +export function isUntypedString(node: UntypedNode): node is UntypedString { + return typeof (node as UntypedString).value === "string"; +} diff --git a/packages/serialization/json/src/jsonSerializationWriter.ts b/packages/serialization/json/src/jsonSerializationWriter.ts index 529e3832e7..89e3750b41 100644 --- a/packages/serialization/json/src/jsonSerializationWriter.ts +++ b/packages/serialization/json/src/jsonSerializationWriter.ts @@ -2,10 +2,19 @@ import { DateOnly, Duration, + isUntypedNode, type ModelSerializerFunction, type Parsable, type SerializationWriter, - TimeOnly} from "@microsoft/kiota-abstractions"; + TimeOnly, + type UntypedNode, +} from "@microsoft/kiota-abstractions"; +import { isUntypedArray } from "@microsoft/kiota-abstractions/src/serialization/untypedArray"; +import { isUntypedBoolean } from "@microsoft/kiota-abstractions/src/serialization/untypedBoolean"; +import { isUntypedNull } from "@microsoft/kiota-abstractions/src/serialization/untypedNull"; +import { isUntypedNumber } from "@microsoft/kiota-abstractions/src/serialization/untypedNumber"; +import { isUntypedObject } from "@microsoft/kiota-abstractions/src/serialization/untypedObject"; +import { isUntypedString } from "@microsoft/kiota-abstractions/src/serialization/untypedString"; import type { Guid } from "guid-typescript"; export class JsonSerializationWriter implements SerializationWriter { @@ -103,6 +112,43 @@ export class JsonSerializationWriter implements SerializationWriter { value: T, serializerMethod: ModelSerializerFunction, ): void { + if (isUntypedNode(value)) { + const untypedNode = value as UntypedNode; + if (isUntypedBoolean(untypedNode)) { + this.writeBooleanValue(key, untypedNode.getValue()); + } else if (isUntypedString(untypedNode)) { + this.writeStringValue(key, untypedNode.getValue()); + } else if (isUntypedNull(untypedNode)) { + this.writeNullValue(key); + } else if (isUntypedNumber(untypedNode)) { + this.writeNumberValue(key, untypedNode.getValue()); + } else if (isUntypedObject(untypedNode)) { + const value = untypedNode.getValue(); + this.writer.push(`{`); + for (const key in value) { + this.writeObjectValue( + key, + value[key] as unknown as T, + serializerMethod, + ); + this.writer.push(JsonSerializationWriter.propertySeparator); + } + this.writer.push(`}`); + } else if (isUntypedArray(untypedNode)) { + const value = untypedNode.getValue(); + this.writer.push(`[`); + value.forEach((v, idx) => { + this.writeObjectValue(undefined, v as unknown as T, serializerMethod); + idx + 1 < value.length && + this.writer.push(JsonSerializationWriter.propertySeparator); + }); + this.writer.push(`]`); + } else { + this.writeAnyValue(key, untypedNode.getValue()); + } + return; // nothing to do here, the value has been written + } + if (key) { this.writePropertyName(key); } From 99c25d4f343356f20180577ac2b4b1fc92e05141 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Tue, 20 Feb 2024 21:09:38 +0300 Subject: [PATCH 2/9] More updates --- .../src/serialization/untypedArray.ts | 11 ++++-- .../src/serialization/untypedBoolean.ts | 11 ++++-- .../src/serialization/untypedNode.ts | 9 +++-- .../src/serialization/untypedNull.ts | 11 ++++-- .../src/serialization/untypedNumber.ts | 11 ++++-- .../src/serialization/untypedObject.ts | 11 ++++-- .../src/serialization/untypedString.ts | 11 ++++-- .../serialization/json/src/jsonParseNode.ts | 34 +++++++++++++++++++ 8 files changed, 89 insertions(+), 20 deletions(-) diff --git a/packages/abstractions/src/serialization/untypedArray.ts b/packages/abstractions/src/serialization/untypedArray.ts index a92ec12129..1ad4a03ba4 100644 --- a/packages/abstractions/src/serialization/untypedArray.ts +++ b/packages/abstractions/src/serialization/untypedArray.ts @@ -1,7 +1,12 @@ -import { isUntypedNode, type UntypedNode } from "./untypedNode"; +import { isUntypedNode, UntypedNode } from "./untypedNode"; -export interface UntypedArray extends UntypedNode { - getValue(): UntypedNode[]; +export class UntypedArray extends UntypedNode { + constructor(value: UntypedNode[]) { + super(value); + } + getValue(): UntypedNode[] { + return this.value as UntypedNode[]; + } } export function isUntypedArray(node: UntypedNode): node is UntypedArray { diff --git a/packages/abstractions/src/serialization/untypedBoolean.ts b/packages/abstractions/src/serialization/untypedBoolean.ts index 9bcfa0ecb9..7f3298e0b2 100644 --- a/packages/abstractions/src/serialization/untypedBoolean.ts +++ b/packages/abstractions/src/serialization/untypedBoolean.ts @@ -1,7 +1,12 @@ -import type { UntypedNode } from "./untypedNode"; +import { UntypedNode } from "./untypedNode"; -export interface UntypedBoolean extends UntypedNode { - getValue(): boolean; +export class UntypedBoolean extends UntypedNode { + constructor(value: boolean) { + super(value); + } + getValue(): boolean { + return this.value as boolean; + } } export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { diff --git a/packages/abstractions/src/serialization/untypedNode.ts b/packages/abstractions/src/serialization/untypedNode.ts index 2cffdbbf92..86abddfc8d 100644 --- a/packages/abstractions/src/serialization/untypedNode.ts +++ b/packages/abstractions/src/serialization/untypedNode.ts @@ -3,8 +3,13 @@ import type { Parsable } from "./parsable"; import type { ParseNode } from "./parseNode"; import type { SerializationWriter } from "./serializationWriter"; -export interface UntypedNode extends Parsable { - getValue(): any; +export class UntypedNode implements Parsable { + constructor(value?: any) { + this.value = value; + } + getValue(): any { + return this.value; + } value?: any; } diff --git a/packages/abstractions/src/serialization/untypedNull.ts b/packages/abstractions/src/serialization/untypedNull.ts index 01808f9f70..a08aa2959a 100644 --- a/packages/abstractions/src/serialization/untypedNull.ts +++ b/packages/abstractions/src/serialization/untypedNull.ts @@ -1,7 +1,12 @@ -import type { UntypedNode } from "./untypedNode"; +import { UntypedNode } from "./untypedNode"; -export interface UntypedNull extends UntypedNode { - getValue(): null; +export class UntypedNull extends UntypedNode { + constructor() { + super(null); + } + getValue(): null { + return null; + } } export function isUntypedNull(node: UntypedNode): node is UntypedNull { diff --git a/packages/abstractions/src/serialization/untypedNumber.ts b/packages/abstractions/src/serialization/untypedNumber.ts index 4eb140d2c8..619de1066e 100644 --- a/packages/abstractions/src/serialization/untypedNumber.ts +++ b/packages/abstractions/src/serialization/untypedNumber.ts @@ -1,7 +1,12 @@ -import type { UntypedNode } from "./untypedNode"; +import { UntypedNode } from "./untypedNode"; -export interface UntypedNumber extends UntypedNode { - getValue(): number; +export class UntypedNumber extends UntypedNode { + constructor(value: number) { + super(value); + } + getValue(): number { + return this.value as number; + } } export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts index 5bee476bda..c36ec8551f 100644 --- a/packages/abstractions/src/serialization/untypedObject.ts +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -1,7 +1,12 @@ -import { isUntypedNode, type UntypedNode } from "./untypedNode"; +import { isUntypedNode, UntypedNode } from "./untypedNode"; -export interface UntypedObject extends UntypedNode { - getValue(): Record; +export class UntypedObject extends UntypedNode { + constructor(value: Record) { + super(value); + } + getValue(): Record { + return this.value as Record; + } } export function isUntypedObject(node: UntypedNode): node is UntypedObject { diff --git a/packages/abstractions/src/serialization/untypedString.ts b/packages/abstractions/src/serialization/untypedString.ts index 2c6844cb3e..dbadfef24c 100644 --- a/packages/abstractions/src/serialization/untypedString.ts +++ b/packages/abstractions/src/serialization/untypedString.ts @@ -1,7 +1,12 @@ -import type { UntypedNode } from "./untypedNode"; +import { UntypedNode } from "./untypedNode"; -export interface UntypedString extends UntypedNode { - getValue(): string; +export class UntypedString extends UntypedNode { + constructor(value: string) { + super(value); + } + getValue(): string { + return this.value as string; + } } export function isUntypedString(node: UntypedNode): node is UntypedString { diff --git a/packages/serialization/json/src/jsonParseNode.ts b/packages/serialization/json/src/jsonParseNode.ts index c9278ff999..16fb83fcfa 100644 --- a/packages/serialization/json/src/jsonParseNode.ts +++ b/packages/serialization/json/src/jsonParseNode.ts @@ -9,7 +9,13 @@ import { TimeOnly, isBackingStoreEnabled, toFirstCharacterUpper, + isUntypedNode, } from "@microsoft/kiota-abstractions"; +import { UntypedArray } from "@microsoft/kiota-abstractions/src/serialization/untypedArray"; +import { UntypedBoolean, UntypedNode } from "@microsoft/kiota-abstractions/src/serialization/untypedBoolean"; +import { UntypedNumber } from "@microsoft/kiota-abstractions/src/serialization/untypedNumber"; +import { UntypedObject } from "@microsoft/kiota-abstractions/src/serialization/untypedObject"; +import { UntypedString } from "@microsoft/kiota-abstractions/src/serialization/untypedString"; export class JsonParseNode implements ParseNode { /** @@ -72,6 +78,34 @@ export class JsonParseNode implements ParseNode { parsableFactory: ParsableFactory, ): T => { const temp: T = {} as T; + if (isUntypedNode(parsableFactory(this)(temp))) { + const valueType = typeof temp; + let value: T = temp; + if (valueType === "boolean") { + value = new UntypedBoolean(value as any as boolean) as any as T; + } else if (valueType === "string") { + value = new UntypedString(value as any as string) as any as T; + } else if (valueType === "number") { + value = new UntypedNumber(value as any as number) as any as T; + } else if (Array.isArray(value)) { + const nodes: UntypedNode[] = []; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + value.forEach((v, idx) => { + const currentParseNode = new JsonParseNode(v); + const untypedNode: UntypedNode = + currentParseNode.getObjectValue(parsableFactory); + nodes.push(untypedNode); + }); + value = new UntypedArray(nodes) as any as T; + } else if (valueType === "object") { + const properties: Record = {}; + Object.entries(this._jsonNode as any).forEach(([k, v]) => { + properties[k] = new JsonParseNode(v).getObjectValue(parsableFactory); + }); + value = new UntypedObject(properties) as any as T; + } + return value; + } const enableBackingStore = isBackingStoreEnabled(parsableFactory(this)(temp)); const value: T = enableBackingStore ? new Proxy(temp, createBackedModelProxyHandler()) : temp; if (this.onBeforeAssignFieldValues) { From 1b9b50b1f1e4d184626e437acb3cc32bf7e37805 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Tue, 20 Feb 2024 21:15:05 +0300 Subject: [PATCH 3/9] Fixes compile issue. Todo add tests --- .../serialization/json/src/jsonParseNode.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/serialization/json/src/jsonParseNode.ts b/packages/serialization/json/src/jsonParseNode.ts index 16fb83fcfa..ddf9aeb13f 100644 --- a/packages/serialization/json/src/jsonParseNode.ts +++ b/packages/serialization/json/src/jsonParseNode.ts @@ -10,12 +10,14 @@ import { isBackingStoreEnabled, toFirstCharacterUpper, isUntypedNode, + UntypedNode, + UntypedArray, + UntypedBoolean, + UntypedNumber, + UntypedObject, + UntypedString, + createUntypedNodeFromDiscriminatorValue, } from "@microsoft/kiota-abstractions"; -import { UntypedArray } from "@microsoft/kiota-abstractions/src/serialization/untypedArray"; -import { UntypedBoolean, UntypedNode } from "@microsoft/kiota-abstractions/src/serialization/untypedBoolean"; -import { UntypedNumber } from "@microsoft/kiota-abstractions/src/serialization/untypedNumber"; -import { UntypedObject } from "@microsoft/kiota-abstractions/src/serialization/untypedObject"; -import { UntypedString } from "@microsoft/kiota-abstractions/src/serialization/untypedString"; export class JsonParseNode implements ParseNode { /** @@ -92,15 +94,18 @@ export class JsonParseNode implements ParseNode { // eslint-disable-next-line @typescript-eslint/no-unused-vars value.forEach((v, idx) => { const currentParseNode = new JsonParseNode(v); - const untypedNode: UntypedNode = - currentParseNode.getObjectValue(parsableFactory); + const untypedNode: UntypedNode = currentParseNode.getObjectValue( + createUntypedNodeFromDiscriminatorValue, + ); nodes.push(untypedNode); }); value = new UntypedArray(nodes) as any as T; } else if (valueType === "object") { const properties: Record = {}; Object.entries(this._jsonNode as any).forEach(([k, v]) => { - properties[k] = new JsonParseNode(v).getObjectValue(parsableFactory); + properties[k] = new JsonParseNode(v).getObjectValue( + createUntypedNodeFromDiscriminatorValue, + ); }); value = new UntypedObject(properties) as any as T; } From a10ebaa94fc348fbf60ee09e793cafb7875fb741 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Sun, 25 Feb 2024 20:18:13 +0300 Subject: [PATCH 4/9] todo add deserialization tests --- .../src/serialization/untypedNode.ts | 3 +- .../src/serialization/untypedObject.ts | 1 + .../json/src/jsonSerializationWriter.ts | 47 ++++++++++---- .../test/common/jsonSerializationWriter.ts | 52 ++++++++++++++++ .../json/test/common/untypedTestEntiy.ts | 62 +++++++++++++++++++ 5 files changed, 152 insertions(+), 13 deletions(-) create mode 100644 packages/serialization/json/test/common/untypedTestEntiy.ts diff --git a/packages/abstractions/src/serialization/untypedNode.ts b/packages/abstractions/src/serialization/untypedNode.ts index 86abddfc8d..2d8eeec8cc 100644 --- a/packages/abstractions/src/serialization/untypedNode.ts +++ b/packages/abstractions/src/serialization/untypedNode.ts @@ -20,7 +20,8 @@ export function createUntypedNodeFromDiscriminatorValue( } export function isUntypedNode(node: any): node is UntypedNode { - return (node as UntypedNode).getValue !== undefined; + const potentialNode = node as UntypedNode; + return potentialNode && potentialNode.getValue !== undefined; } export function deserializeIntoUntypedNode( diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts index c36ec8551f..4207b70cae 100644 --- a/packages/abstractions/src/serialization/untypedObject.ts +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -13,6 +13,7 @@ export function isUntypedObject(node: UntypedNode): node is UntypedObject { const value = (node as UntypedObject).value; return ( value instanceof Object && + value instanceof Array === false && Object.values(value).every((item) => isUntypedNode(item)) ); } diff --git a/packages/serialization/json/src/jsonSerializationWriter.ts b/packages/serialization/json/src/jsonSerializationWriter.ts index 89e3750b41..0abd0e2b0f 100644 --- a/packages/serialization/json/src/jsonSerializationWriter.ts +++ b/packages/serialization/json/src/jsonSerializationWriter.ts @@ -8,13 +8,13 @@ import { type SerializationWriter, TimeOnly, type UntypedNode, + isUntypedBoolean, + isUntypedString, + isUntypedNull, + isUntypedNumber, + isUntypedObject, + isUntypedArray, } from "@microsoft/kiota-abstractions"; -import { isUntypedArray } from "@microsoft/kiota-abstractions/src/serialization/untypedArray"; -import { isUntypedBoolean } from "@microsoft/kiota-abstractions/src/serialization/untypedBoolean"; -import { isUntypedNull } from "@microsoft/kiota-abstractions/src/serialization/untypedNull"; -import { isUntypedNumber } from "@microsoft/kiota-abstractions/src/serialization/untypedNumber"; -import { isUntypedObject } from "@microsoft/kiota-abstractions/src/serialization/untypedObject"; -import { isUntypedString } from "@microsoft/kiota-abstractions/src/serialization/untypedString"; import type { Guid } from "guid-typescript"; export class JsonSerializationWriter implements SerializationWriter { @@ -124,17 +124,31 @@ export class JsonSerializationWriter implements SerializationWriter { this.writeNumberValue(key, untypedNode.getValue()); } else if (isUntypedObject(untypedNode)) { const value = untypedNode.getValue(); - this.writer.push(`{`); + if (key && value) { + this.writePropertyName(key); + } + value && this.writer.push(`{`); for (const key in value) { this.writeObjectValue( key, value[key] as unknown as T, serializerMethod, ); - this.writer.push(JsonSerializationWriter.propertySeparator); } - this.writer.push(`}`); + if ( + this.writer.length > 0 && + this.writer[this.writer.length - 1] === + JsonSerializationWriter.propertySeparator + ) { + //removing the last separator + this.writer.pop(); + } + value && this.writer.push(`}`); + key && this.writer.push(JsonSerializationWriter.propertySeparator); } else if (isUntypedArray(untypedNode)) { + if (key) { + this.writePropertyName(key); + } const value = untypedNode.getValue(); this.writer.push(`[`); value.forEach((v, idx) => { @@ -142,19 +156,28 @@ export class JsonSerializationWriter implements SerializationWriter { idx + 1 < value.length && this.writer.push(JsonSerializationWriter.propertySeparator); }); + if ( + this.writer.length > 0 && + this.writer[this.writer.length - 1] === + JsonSerializationWriter.propertySeparator + ) { + //removing the last separator + this.writer.pop(); + } this.writer.push(`]`); + key && this.writer.push(JsonSerializationWriter.propertySeparator); } else { this.writeAnyValue(key, untypedNode.getValue()); } return; // nothing to do here, the value has been written } - if (key) { + if (key && value) { this.writePropertyName(key); } this.onBeforeObjectSerialization && this.onBeforeObjectSerialization(value as unknown as Parsable); - this.writer.push(`{`); + value && this.writer.push(`{`); this.onStartObjectSerialization && this.onStartObjectSerialization(value as unknown as Parsable, this); @@ -170,7 +193,7 @@ export class JsonSerializationWriter implements SerializationWriter { //removing the last separator this.writer.pop(); } - this.writer.push(`}`); + value && this.writer.push(`}`); key && this.writer.push(JsonSerializationWriter.propertySeparator); } diff --git a/packages/serialization/json/test/common/jsonSerializationWriter.ts b/packages/serialization/json/test/common/jsonSerializationWriter.ts index 03b62bd1dd..c92bea83e3 100644 --- a/packages/serialization/json/test/common/jsonSerializationWriter.ts +++ b/packages/serialization/json/test/common/jsonSerializationWriter.ts @@ -6,6 +6,8 @@ import { serializeTestParser, type TestParser, } from "./testEntity"; +import { UntypedTestEntity, serializeUntypedTestEntity } from "./untypedTestEntiy"; +import { UntypedArray, UntypedBoolean, UntypedNull, UntypedNumber, UntypedObject, UntypedString } from "@microsoft/kiota-abstractions"; describe("JsonParseNode", () => { it("Test object serialization", async () => { @@ -76,4 +78,54 @@ describe("JsonParseNode", () => { const result = JSON.parse(contentAsStr); assert.equal(result.testComplexString, "BÅ‚onie"); }); + it("serializes untyped nodes as expected", async () => { + const inputObject: UntypedTestEntity = { + id: "1", + title: "title", + location: new UntypedObject({ + address: new UntypedObject({ + city: new UntypedString("Redmond"), + postalCode: new UntypedString("98052"), + state: new UntypedString("Washington"), + street: new UntypedString("NE 36th St"), + }), + coordinates: new UntypedObject({ + latitude: new UntypedNumber(47.678581), + longitude: new UntypedNumber(-122.131577), + }), + displayName: new UntypedString("Microsoft Building 25"), + floorCount: new UntypedNumber(50), + hasReception: new UntypedBoolean(true), + contact: new UntypedNull(), + }), + keywords: new UntypedArray([ + new UntypedObject({ + created: new UntypedString("2023-07-26T10:41:26Z"), + label: new UntypedString("Keyword1"), + termGuid: new UntypedString("10e9cc83-b5a4-4c8d-8dab-4ada1252dd70"), + wssId: new UntypedNumber(6442450941), + }), + new UntypedObject({ + created: new UntypedString("2023-07-26T10:51:26Z"), + label: new UntypedString("Keyword2"), + termGuid: new UntypedString("2cae6c6a-9bb8-4a78-afff-81b88e735fef"), + wssId: new UntypedNumber(6442450942), + }), + ]), + additionalData: { + extra: new UntypedObject({ + createdDateTime: new UntypedString("2024-01-15T00:00:00+00:00"), + }), + }, + }; + const writer = new JsonSerializationWriter(); + writer.writeObjectValue("", inputObject, serializeUntypedTestEntity); + const serializedContent = writer.getSerializedContent(); + const decoder = new TextDecoder(); + const contentAsStr = decoder.decode(serializedContent); + assert.equal( + '{"id":"1","title":"title","location":{"address":{"city":"Redmond","postalCode":"98052","state":"Washington","street":"NE 36th St"},"coordinates":{"latitude":47.678581,"longitude":-122.131577},"displayName":"Microsoft Building 25","floorCount":50,"hasReception":true,"contact":null},"keywords":[{"created":"2023-07-26T10:41:26Z","label":"Keyword1","termGuid":"10e9cc83-b5a4-4c8d-8dab-4ada1252dd70","wssId":6442450941},{"created":"2023-07-26T10:51:26Z","label":"Keyword2","termGuid":"2cae6c6a-9bb8-4a78-afff-81b88e735fef","wssId":6442450942}],"extra":{"value":{"createdDateTime":{"value":"2024-01-15T00:00:00+00:00"}}}}', + contentAsStr, + ); + }); }); diff --git a/packages/serialization/json/test/common/untypedTestEntiy.ts b/packages/serialization/json/test/common/untypedTestEntiy.ts new file mode 100644 index 0000000000..c22dfd98c4 --- /dev/null +++ b/packages/serialization/json/test/common/untypedTestEntiy.ts @@ -0,0 +1,62 @@ +import { + createUntypedNodeFromDiscriminatorValue, + SerializationWriter, + type ParseNode, + type UntypedNode, +} from "@microsoft/kiota-abstractions"; + +export interface UntypedTestEntity { + id?: string | undefined; + title?: string | undefined; + location?: UntypedNode | undefined; + keywords?: UntypedNode | undefined; + detail?: UntypedNode | undefined; + additionalData?: Record; +} + +export function createUntypedTestEntityFromDiscriminatorValue( + parseNode: ParseNode | undefined, +) { + if (!parseNode) throw new Error("parseNode cannot be undefined"); + return deserializeUntypedTestEntity; +} + +export function deserializeUntypedTestEntity( + untypedTestEntity: UntypedTestEntity | undefined = {}, +): Record void> { + return { + id: (n) => { + untypedTestEntity.id = n.getStringValue(); + }, + title: (n) => { + untypedTestEntity.title = n.getStringValue(); + }, + location: (n) => { + untypedTestEntity.location = n.getObjectValue( + createUntypedNodeFromDiscriminatorValue, + ) as UntypedNode; + }, + keywords: (n) => { + untypedTestEntity.keywords = n.getObjectValue( + createUntypedNodeFromDiscriminatorValue, + ) as UntypedNode; + }, + detail: (n) => { + untypedTestEntity.detail = n.getObjectValue( + createUntypedNodeFromDiscriminatorValue, + ) as UntypedNode; + }, + }; +} + +export function serializeUntypedTestEntity( + writer: SerializationWriter, + untypedTestEntity: UntypedTestEntity | undefined = {}, +): void { + writer.writeStringValue("id", untypedTestEntity.id); + writer.writeStringValue("title", untypedTestEntity.title); + writer.writeObjectValue("location", untypedTestEntity.location); + writer.writeObjectValue("keywords", untypedTestEntity.keywords); + writer.writeObjectValue("detail", untypedTestEntity.detail); + writer.writeAdditionalData(untypedTestEntity.additionalData); +} From 8b7ccbddc42c688419bdca101b09348719b72a54 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Sun, 25 Feb 2024 21:54:18 +0300 Subject: [PATCH 5/9] Untyped nodes in typescript --- .../src/serialization/untypedArray.ts | 8 ++- .../src/serialization/untypedBoolean.ts | 2 +- .../src/serialization/untypedNode.ts | 11 ++- .../src/serialization/untypedNull.ts | 2 +- .../src/serialization/untypedNumber.ts | 2 +- .../src/serialization/untypedObject.ts | 2 +- .../src/serialization/untypedString.ts | 2 +- .../serialization/json/src/jsonParseNode.ts | 25 ++++--- .../json/test/common/JsonParseNode.ts | 71 ++++++++++++++++++- .../json/test/common/untypedTestEntiy.ts | 12 ++-- 10 files changed, 110 insertions(+), 27 deletions(-) diff --git a/packages/abstractions/src/serialization/untypedArray.ts b/packages/abstractions/src/serialization/untypedArray.ts index 1ad4a03ba4..c53139f8fc 100644 --- a/packages/abstractions/src/serialization/untypedArray.ts +++ b/packages/abstractions/src/serialization/untypedArray.ts @@ -10,6 +10,10 @@ export class UntypedArray extends UntypedNode { } export function isUntypedArray(node: UntypedNode): node is UntypedArray { - const value = (node as UntypedArray).value; - return value instanceof Array && value.every((item) => isUntypedNode(item)); + const proposedNode = node as UntypedArray; + return ( + proposedNode && + proposedNode.value instanceof Array && + proposedNode.value.every((item) => isUntypedNode(item)) + ); } diff --git a/packages/abstractions/src/serialization/untypedBoolean.ts b/packages/abstractions/src/serialization/untypedBoolean.ts index 7f3298e0b2..79abf2591b 100644 --- a/packages/abstractions/src/serialization/untypedBoolean.ts +++ b/packages/abstractions/src/serialization/untypedBoolean.ts @@ -10,5 +10,5 @@ export class UntypedBoolean extends UntypedNode { } export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { - return typeof (node as UntypedBoolean).value === "boolean"; + return typeof (node as UntypedBoolean)?.value === "boolean"; } diff --git a/packages/abstractions/src/serialization/untypedNode.ts b/packages/abstractions/src/serialization/untypedNode.ts index 2d8eeec8cc..cfee04d59a 100644 --- a/packages/abstractions/src/serialization/untypedNode.ts +++ b/packages/abstractions/src/serialization/untypedNode.ts @@ -25,9 +25,16 @@ export function isUntypedNode(node: any): node is UntypedNode { } export function deserializeIntoUntypedNode( - _untypedNode: Partial | undefined = {}, + untypedNode: Partial | undefined = {}, ): Record void> { - return {}; + return { + value: (n) => { + untypedNode.value = null; + }, + getValue: (n) => { + untypedNode.getValue = () => untypedNode.value; + }, + }; } export function serializeUntypedNode( diff --git a/packages/abstractions/src/serialization/untypedNull.ts b/packages/abstractions/src/serialization/untypedNull.ts index a08aa2959a..ef76f43ba1 100644 --- a/packages/abstractions/src/serialization/untypedNull.ts +++ b/packages/abstractions/src/serialization/untypedNull.ts @@ -10,5 +10,5 @@ export class UntypedNull extends UntypedNode { } export function isUntypedNull(node: UntypedNode): node is UntypedNull { - return (node as UntypedNull).value === null; + return (node as UntypedNull)?.value === null; } diff --git a/packages/abstractions/src/serialization/untypedNumber.ts b/packages/abstractions/src/serialization/untypedNumber.ts index 619de1066e..3aecf6a36b 100644 --- a/packages/abstractions/src/serialization/untypedNumber.ts +++ b/packages/abstractions/src/serialization/untypedNumber.ts @@ -10,5 +10,5 @@ export class UntypedNumber extends UntypedNode { } export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { - return typeof (node as UntypedNumber).value === "number"; + return typeof (node as UntypedNumber)?.value === "number"; } diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts index 4207b70cae..f2dd4d6705 100644 --- a/packages/abstractions/src/serialization/untypedObject.ts +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -10,7 +10,7 @@ export class UntypedObject extends UntypedNode { } export function isUntypedObject(node: UntypedNode): node is UntypedObject { - const value = (node as UntypedObject).value; + const value = (node as UntypedObject)?.value; return ( value instanceof Object && value instanceof Array === false && diff --git a/packages/abstractions/src/serialization/untypedString.ts b/packages/abstractions/src/serialization/untypedString.ts index dbadfef24c..058d1d1f43 100644 --- a/packages/abstractions/src/serialization/untypedString.ts +++ b/packages/abstractions/src/serialization/untypedString.ts @@ -10,5 +10,5 @@ export class UntypedString extends UntypedNode { } export function isUntypedString(node: UntypedNode): node is UntypedString { - return typeof (node as UntypedString).value === "string"; + return typeof (node as UntypedString)?.value === "string"; } diff --git a/packages/serialization/json/src/jsonParseNode.ts b/packages/serialization/json/src/jsonParseNode.ts index ddf9aeb13f..da15d4db18 100644 --- a/packages/serialization/json/src/jsonParseNode.ts +++ b/packages/serialization/json/src/jsonParseNode.ts @@ -17,6 +17,7 @@ import { UntypedObject, UntypedString, createUntypedNodeFromDiscriminatorValue, + UntypedNull, } from "@microsoft/kiota-abstractions"; export class JsonParseNode implements ParseNode { @@ -81,26 +82,26 @@ export class JsonParseNode implements ParseNode { ): T => { const temp: T = {} as T; if (isUntypedNode(parsableFactory(this)(temp))) { - const valueType = typeof temp; + const valueType = typeof this._jsonNode; let value: T = temp; if (valueType === "boolean") { - value = new UntypedBoolean(value as any as boolean) as any as T; + value = new UntypedBoolean(this._jsonNode as boolean) as any as T; } else if (valueType === "string") { - value = new UntypedString(value as any as string) as any as T; + value = new UntypedString(this._jsonNode as string) as any as T; } else if (valueType === "number") { - value = new UntypedNumber(value as any as number) as any as T; - } else if (Array.isArray(value)) { + value = new UntypedNumber(this._jsonNode as number) as any as T; + } else if (Array.isArray(this._jsonNode)) { const nodes: UntypedNode[] = []; // eslint-disable-next-line @typescript-eslint/no-unused-vars - value.forEach((v, idx) => { - const currentParseNode = new JsonParseNode(v); - const untypedNode: UntypedNode = currentParseNode.getObjectValue( - createUntypedNodeFromDiscriminatorValue, + (this._jsonNode as any[]).forEach((x) => { + nodes.push( + new JsonParseNode(x).getObjectValue( + createUntypedNodeFromDiscriminatorValue, + ), ); - nodes.push(untypedNode); }); value = new UntypedArray(nodes) as any as T; - } else if (valueType === "object") { + } else if (this._jsonNode && valueType === "object") { const properties: Record = {}; Object.entries(this._jsonNode as any).forEach(([k, v]) => { properties[k] = new JsonParseNode(v).getObjectValue( @@ -108,6 +109,8 @@ export class JsonParseNode implements ParseNode { ); }); value = new UntypedObject(properties) as any as T; + } else if (!this._jsonNode) { + value = new UntypedNull() as any as T; } return value; } diff --git a/packages/serialization/json/test/common/JsonParseNode.ts b/packages/serialization/json/test/common/JsonParseNode.ts index 84d379ff68..7591dda878 100644 --- a/packages/serialization/json/test/common/JsonParseNode.ts +++ b/packages/serialization/json/test/common/JsonParseNode.ts @@ -1,5 +1,4 @@ import { assert } from "chai"; - import { JsonParseNode } from "../../src/index"; import { createTestParserFromDiscriminatorValue, @@ -7,6 +6,8 @@ import { createTestBackedModelFromDiscriminatorValue, type TestParser } from "./testEntity"; +import { UntypedTestEntity, createUntypedTestEntityFromDiscriminatorValue } from "./untypedTestEntiy"; +import { UntypedNode, UntypedObject, isUntypedArray, isUntypedBoolean, isUntypedNode, isUntypedNumber, isUntypedObject } from "@microsoft/kiota-abstractions"; describe("JsonParseNode", () => { it("jsonParseNode:initializes", async () => { @@ -169,4 +170,72 @@ describe("JsonParseNode", () => { assert.equal(jsonObjectStr, resultStr); }); + it("untyped nodes are deserialized correctly", async () => { + const jsonObject = { + id: "1", + title: "title", + location: { + address: { + city: "Redmond", + postalCode: "98052", + state: "Washington", + street: "NE 36th St", + }, + coordinates: { + latitude: 47.678581, + longitude: -122.131577, + }, + displayName: "Microsoft Building 25", + floorCount: 50, + hasReception: true, + contact: null, + }, + keywords: [ + { + created: "2023-07-26T10:41:26Z", + label: "Keyword1", + termGuid: "10e9cc83-b5a4-4c8d-8dab-4ada1252dd70", + wssId: 6442450941, + }, + { + created: "2023-07-26T10:51:26Z", + label: "Keyword2", + termGuid: "2cae6c6a-9bb8-4a78-afff-81b88e735fef", + wssId: 6442450942, + }, + ], + extra: { + value: { + createdDateTime: { + value: "2024-01-15T00:00:00+00:00", + }, + }, + }, + }; + + const result = new JsonParseNode(jsonObject).getObjectValue( + createUntypedTestEntityFromDiscriminatorValue, + ) as UntypedTestEntity; + assert.equal(result.id, "1"); + assert.equal(result.title, "title"); + assert.isNotNull(result.location); + assert.isTrue(isUntypedNode(result.location)); + const location = result.location as UntypedObject; + const locationProperties = location.getValue(); + assert.isTrue(isUntypedObject(location)); + assert.isTrue(isUntypedObject(locationProperties["address"])); + assert.isTrue(isUntypedObject(locationProperties["coordinates"])); + assert.isTrue(isUntypedBoolean(locationProperties["hasReception"])); + assert.isTrue(isUntypedNumber(locationProperties["floorCount"])); + assert.isTrue(isUntypedBoolean(locationProperties["hasReception"])); + assert.equal(locationProperties["hasReception"].getValue(), true); + assert.equal(locationProperties["contact"].getValue(), null); + assert.equal(locationProperties["floorCount"].getValue(), 50); + const keywords = result.keywords as UntypedNode; + assert.isTrue(isUntypedArray(keywords)); + assert.equal( + locationProperties["displayName"].getValue(), + "Microsoft Building 25", + ); + }); }); diff --git a/packages/serialization/json/test/common/untypedTestEntiy.ts b/packages/serialization/json/test/common/untypedTestEntiy.ts index c22dfd98c4..87e1e817b0 100644 --- a/packages/serialization/json/test/common/untypedTestEntiy.ts +++ b/packages/serialization/json/test/common/untypedTestEntiy.ts @@ -32,19 +32,19 @@ export function deserializeUntypedTestEntity( untypedTestEntity.title = n.getStringValue(); }, location: (n) => { - untypedTestEntity.location = n.getObjectValue( + untypedTestEntity.location = n.getObjectValue( createUntypedNodeFromDiscriminatorValue, - ) as UntypedNode; + ); }, keywords: (n) => { - untypedTestEntity.keywords = n.getObjectValue( + untypedTestEntity.keywords = n.getObjectValue( createUntypedNodeFromDiscriminatorValue, - ) as UntypedNode; + ); }, detail: (n) => { - untypedTestEntity.detail = n.getObjectValue( + untypedTestEntity.detail = n.getObjectValue( createUntypedNodeFromDiscriminatorValue, - ) as UntypedNode; + ); }, }; } From b8b9b307b971cf128a6c29de7cc1a7c76d57523a Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Mon, 4 Mar 2024 14:27:46 +0300 Subject: [PATCH 6/9] Bumps versions --- packages/abstractions/package.json | 2 +- packages/authentication/azure/package.json | 4 ++-- packages/authentication/spfx/package.json | 4 ++-- packages/http/fetch/package.json | 4 ++-- packages/serialization/form/package.json | 4 ++-- packages/serialization/json/package.json | 4 ++-- packages/serialization/multipart/package.json | 4 ++-- packages/serialization/text/package.json | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/abstractions/package.json b/packages/abstractions/package.json index d13619279c..e982155fc2 100644 --- a/packages/abstractions/package.json +++ b/packages/abstractions/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-abstractions", - "version": "1.0.0-preview.44", + "version": "1.0.0-preview.45", "description": "Core abstractions for kiota generated libraries in TypeScript and JavaScript", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", diff --git a/packages/authentication/azure/package.json b/packages/authentication/azure/package.json index 4e53917e39..f5236aa01b 100644 --- a/packages/authentication/azure/package.json +++ b/packages/authentication/azure/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-authentication-azure", - "version": "1.0.0-preview.39", + "version": "1.0.0-preview.40", "description": "Authentication provider for Kiota using Azure Identity", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", @@ -30,7 +30,7 @@ "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { "@azure/core-auth": "^1.5.0", - "@microsoft/kiota-abstractions": "^1.0.0-preview.44", + "@microsoft/kiota-abstractions": "^1.0.0-preview.45", "@opentelemetry/api": "^1.7.0", "tslib": "^2.6.2" }, diff --git a/packages/authentication/spfx/package.json b/packages/authentication/spfx/package.json index eb13de96ac..899a12bffd 100644 --- a/packages/authentication/spfx/package.json +++ b/packages/authentication/spfx/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-authentication-spfx", - "version": "1.0.0-preview.34", + "version": "1.0.0-preview.35", "description": "Authentication provider for using Kiota in SPFx solutions", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.44", + "@microsoft/kiota-abstractions": "^1.0.0-preview.45", "@microsoft/sp-http": "^1.15.2", "@opentelemetry/api": "^1.7.0", "tslib": "^2.6.2" diff --git a/packages/http/fetch/package.json b/packages/http/fetch/package.json index 7727f05d88..7a08a1162e 100644 --- a/packages/http/fetch/package.json +++ b/packages/http/fetch/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-http-fetchlibrary", - "version": "1.0.0-preview.43", + "version": "1.0.0-preview.44", "description": "Kiota request adapter implementation with fetch", "keywords": [ "Kiota", @@ -38,7 +38,7 @@ "test:cjs": "mocha 'dist/cjs/test/common/**/*.js' && mocha 'dist/cjs/test/node/**/*.js'" }, "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.44", + "@microsoft/kiota-abstractions": "^1.0.0-preview.45", "@opentelemetry/api": "^1.7.0", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" diff --git a/packages/serialization/form/package.json b/packages/serialization/form/package.json index 0922efaa65..f6e8268086 100644 --- a/packages/serialization/form/package.json +++ b/packages/serialization/form/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-form", - "version": "1.0.0-preview.33", + "version": "1.0.0-preview.34", "description": "Implementation of Kiota Serialization interfaces for URI from encoded", "main": "dist/cjs/src/index.js", "browser": { @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.44", + "@microsoft/kiota-abstractions": "^1.0.0-preview.45", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" }, diff --git a/packages/serialization/json/package.json b/packages/serialization/json/package.json index 3675c71f7e..0fb156fc6a 100644 --- a/packages/serialization/json/package.json +++ b/packages/serialization/json/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-json", - "version": "1.0.0-preview.44", + "version": "1.0.0-preview.45", "description": "Implementation of Kiota Serialization interfaces for JSON", "main": "dist/cjs/src/index.js", "browser": { @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.44", + "@microsoft/kiota-abstractions": "^1.0.0-preview.45", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" }, diff --git a/packages/serialization/multipart/package.json b/packages/serialization/multipart/package.json index 0379802326..80cf0ee7e7 100644 --- a/packages/serialization/multipart/package.json +++ b/packages/serialization/multipart/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-multipart", - "version": "1.0.0-preview.23", + "version": "1.0.0-preview.24", "description": "Implementation of Kiota Serialization interfaces for multipart form data", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.44", + "@microsoft/kiota-abstractions": "^1.0.0-preview.45", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" }, diff --git a/packages/serialization/text/package.json b/packages/serialization/text/package.json index 270f7fca6d..e56578e712 100644 --- a/packages/serialization/text/package.json +++ b/packages/serialization/text/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-text", - "version": "1.0.0-preview.41", + "version": "1.0.0-preview.42", "description": "Implementation of Kiota Serialization interfaces for text", "main": "dist/cjs/src/index.js", "browser": { @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.44", + "@microsoft/kiota-abstractions": "^1.0.0-preview.45", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" }, From 58623f6dae78b614ce4dd5efb25b484bab845e11 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Tue, 19 Mar 2024 15:08:45 +0300 Subject: [PATCH 7/9] Move to interfaces test --- .../src/serialization/untypedArray.ts | 16 +++--- .../src/serialization/untypedBoolean.ts | 16 +++--- .../src/serialization/untypedNode.ts | 9 +--- .../src/serialization/untypedNull.ts | 18 ++++--- .../src/serialization/untypedNumber.ts | 16 +++--- .../src/serialization/untypedObject.ts | 16 +++--- .../src/serialization/untypedString.ts | 16 +++--- .../serialization/json/src/jsonParseNode.ts | 18 ++++--- .../test/common/jsonSerializationWriter.ts | 54 +++++++++---------- 9 files changed, 96 insertions(+), 83 deletions(-) diff --git a/packages/abstractions/src/serialization/untypedArray.ts b/packages/abstractions/src/serialization/untypedArray.ts index c53139f8fc..dd05f69e72 100644 --- a/packages/abstractions/src/serialization/untypedArray.ts +++ b/packages/abstractions/src/serialization/untypedArray.ts @@ -1,12 +1,7 @@ import { isUntypedNode, UntypedNode } from "./untypedNode"; -export class UntypedArray extends UntypedNode { - constructor(value: UntypedNode[]) { - super(value); - } - getValue(): UntypedNode[] { - return this.value as UntypedNode[]; - } +export interface UntypedArray extends UntypedNode { + getValue(): UntypedNode[]; } export function isUntypedArray(node: UntypedNode): node is UntypedArray { @@ -17,3 +12,10 @@ export function isUntypedArray(node: UntypedNode): node is UntypedArray { proposedNode.value.every((item) => isUntypedNode(item)) ); } + +export function createUntypedArray(value: UntypedNode[]): UntypedArray { + return { + value: value, + getValue: () => value as UntypedNode[], + }; +} \ No newline at end of file diff --git a/packages/abstractions/src/serialization/untypedBoolean.ts b/packages/abstractions/src/serialization/untypedBoolean.ts index 79abf2591b..e6d2a61c21 100644 --- a/packages/abstractions/src/serialization/untypedBoolean.ts +++ b/packages/abstractions/src/serialization/untypedBoolean.ts @@ -1,14 +1,16 @@ import { UntypedNode } from "./untypedNode"; -export class UntypedBoolean extends UntypedNode { - constructor(value: boolean) { - super(value); - } - getValue(): boolean { - return this.value as boolean; - } +export interface UntypedBoolean extends UntypedNode { + getValue(): boolean; } export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { return typeof (node as UntypedBoolean)?.value === "boolean"; } + +export function createUntypedBoolean(value: boolean): UntypedBoolean { + return { + value: value, + getValue: () => value as boolean, + }; +} \ No newline at end of file diff --git a/packages/abstractions/src/serialization/untypedNode.ts b/packages/abstractions/src/serialization/untypedNode.ts index cfee04d59a..6cc2b258de 100644 --- a/packages/abstractions/src/serialization/untypedNode.ts +++ b/packages/abstractions/src/serialization/untypedNode.ts @@ -3,13 +3,8 @@ import type { Parsable } from "./parsable"; import type { ParseNode } from "./parseNode"; import type { SerializationWriter } from "./serializationWriter"; -export class UntypedNode implements Parsable { - constructor(value?: any) { - this.value = value; - } - getValue(): any { - return this.value; - } +export interface UntypedNode extends Parsable { + getValue(): any value?: any; } diff --git a/packages/abstractions/src/serialization/untypedNull.ts b/packages/abstractions/src/serialization/untypedNull.ts index ef76f43ba1..0282b34620 100644 --- a/packages/abstractions/src/serialization/untypedNull.ts +++ b/packages/abstractions/src/serialization/untypedNull.ts @@ -1,14 +1,16 @@ import { UntypedNode } from "./untypedNode"; -export class UntypedNull extends UntypedNode { - constructor() { - super(null); - } - getValue(): null { - return null; - } +export interface UntypedNull extends UntypedNode { + getValue(): null; } export function isUntypedNull(node: UntypedNode): node is UntypedNull { - return (node as UntypedNull)?.value === null; + return node.value === null; +} + +export function createUntypedNull(): UntypedNull { + return { + value: null, + getValue: () => null, + }; } diff --git a/packages/abstractions/src/serialization/untypedNumber.ts b/packages/abstractions/src/serialization/untypedNumber.ts index 3aecf6a36b..af34eaca23 100644 --- a/packages/abstractions/src/serialization/untypedNumber.ts +++ b/packages/abstractions/src/serialization/untypedNumber.ts @@ -1,14 +1,16 @@ import { UntypedNode } from "./untypedNode"; -export class UntypedNumber extends UntypedNode { - constructor(value: number) { - super(value); - } - getValue(): number { - return this.value as number; - } +export interface UntypedNumber extends UntypedNode { + getValue(): number; } export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { return typeof (node as UntypedNumber)?.value === "number"; } + +export function createUntypedNumber(value: number): UntypedNumber { + return { + value: value, + getValue: () => value as number, + }; +} \ No newline at end of file diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts index f2dd4d6705..491facc92d 100644 --- a/packages/abstractions/src/serialization/untypedObject.ts +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -1,12 +1,7 @@ import { isUntypedNode, UntypedNode } from "./untypedNode"; -export class UntypedObject extends UntypedNode { - constructor(value: Record) { - super(value); - } - getValue(): Record { - return this.value as Record; - } +export interface UntypedObject extends UntypedNode { + getValue(): Record ; } export function isUntypedObject(node: UntypedNode): node is UntypedObject { @@ -17,3 +12,10 @@ export function isUntypedObject(node: UntypedNode): node is UntypedObject { Object.values(value).every((item) => isUntypedNode(item)) ); } + +export function createUntypedObject(value: Record): UntypedObject { + return { + value: value, + getValue: () => value as Record, + }; +} \ No newline at end of file diff --git a/packages/abstractions/src/serialization/untypedString.ts b/packages/abstractions/src/serialization/untypedString.ts index 058d1d1f43..aa65d6c2ae 100644 --- a/packages/abstractions/src/serialization/untypedString.ts +++ b/packages/abstractions/src/serialization/untypedString.ts @@ -1,14 +1,16 @@ import { UntypedNode } from "./untypedNode"; -export class UntypedString extends UntypedNode { - constructor(value: string) { - super(value); - } - getValue(): string { - return this.value as string; - } +export interface UntypedString extends UntypedNode { + getValue(): string; } export function isUntypedString(node: UntypedNode): node is UntypedString { return typeof (node as UntypedString)?.value === "string"; } + +export function createUntypedString(value: string): UntypedString { + return { + value: value, + getValue: () => value as string, + }; +} \ No newline at end of file diff --git a/packages/serialization/json/src/jsonParseNode.ts b/packages/serialization/json/src/jsonParseNode.ts index da15d4db18..29857866ea 100644 --- a/packages/serialization/json/src/jsonParseNode.ts +++ b/packages/serialization/json/src/jsonParseNode.ts @@ -18,6 +18,12 @@ import { UntypedString, createUntypedNodeFromDiscriminatorValue, UntypedNull, + createUntypedBoolean, + createUntypedString, + createUntypedNumber, + createUntypedArray, + createUntypedObject, + createUntypedNull, } from "@microsoft/kiota-abstractions"; export class JsonParseNode implements ParseNode { @@ -85,11 +91,11 @@ export class JsonParseNode implements ParseNode { const valueType = typeof this._jsonNode; let value: T = temp; if (valueType === "boolean") { - value = new UntypedBoolean(this._jsonNode as boolean) as any as T; + value = createUntypedBoolean(this._jsonNode as boolean) as any as T; } else if (valueType === "string") { - value = new UntypedString(this._jsonNode as string) as any as T; + value = createUntypedString(this._jsonNode as string) as any as T; } else if (valueType === "number") { - value = new UntypedNumber(this._jsonNode as number) as any as T; + value = createUntypedNumber(this._jsonNode as number) as any as T; } else if (Array.isArray(this._jsonNode)) { const nodes: UntypedNode[] = []; // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -100,7 +106,7 @@ export class JsonParseNode implements ParseNode { ), ); }); - value = new UntypedArray(nodes) as any as T; + value = createUntypedArray(nodes) as any as T; } else if (this._jsonNode && valueType === "object") { const properties: Record = {}; Object.entries(this._jsonNode as any).forEach(([k, v]) => { @@ -108,9 +114,9 @@ export class JsonParseNode implements ParseNode { createUntypedNodeFromDiscriminatorValue, ); }); - value = new UntypedObject(properties) as any as T; + value = createUntypedObject(properties) as any as T; } else if (!this._jsonNode) { - value = new UntypedNull() as any as T; + value = createUntypedNull() as any as T; } return value; } diff --git a/packages/serialization/json/test/common/jsonSerializationWriter.ts b/packages/serialization/json/test/common/jsonSerializationWriter.ts index c92bea83e3..24c0069dc7 100644 --- a/packages/serialization/json/test/common/jsonSerializationWriter.ts +++ b/packages/serialization/json/test/common/jsonSerializationWriter.ts @@ -7,7 +7,7 @@ import { type TestParser, } from "./testEntity"; import { UntypedTestEntity, serializeUntypedTestEntity } from "./untypedTestEntiy"; -import { UntypedArray, UntypedBoolean, UntypedNull, UntypedNumber, UntypedObject, UntypedString } from "@microsoft/kiota-abstractions"; +import { UntypedArray, UntypedBoolean, UntypedNull, UntypedNumber, UntypedObject, UntypedString, createUntypedArray, createUntypedBoolean, createUntypedNull, createUntypedNumber, createUntypedObject, createUntypedString } from "@microsoft/kiota-abstractions"; describe("JsonParseNode", () => { it("Test object serialization", async () => { @@ -82,39 +82,39 @@ describe("JsonParseNode", () => { const inputObject: UntypedTestEntity = { id: "1", title: "title", - location: new UntypedObject({ - address: new UntypedObject({ - city: new UntypedString("Redmond"), - postalCode: new UntypedString("98052"), - state: new UntypedString("Washington"), - street: new UntypedString("NE 36th St"), + location: createUntypedObject({ + address: createUntypedObject({ + city: createUntypedString("Redmond"), + postalCode: createUntypedString("98052"), + state: createUntypedString("Washington"), + street: createUntypedString("NE 36th St"), }), - coordinates: new UntypedObject({ - latitude: new UntypedNumber(47.678581), - longitude: new UntypedNumber(-122.131577), + coordinates: createUntypedObject({ + latitude: createUntypedNumber(47.678581), + longitude: createUntypedNumber(-122.131577), }), - displayName: new UntypedString("Microsoft Building 25"), - floorCount: new UntypedNumber(50), - hasReception: new UntypedBoolean(true), - contact: new UntypedNull(), + displayName: createUntypedString("Microsoft Building 25"), + floorCount: createUntypedNumber(50), + hasReception: createUntypedBoolean(true), + contact: createUntypedNull(), }), - keywords: new UntypedArray([ - new UntypedObject({ - created: new UntypedString("2023-07-26T10:41:26Z"), - label: new UntypedString("Keyword1"), - termGuid: new UntypedString("10e9cc83-b5a4-4c8d-8dab-4ada1252dd70"), - wssId: new UntypedNumber(6442450941), + keywords: createUntypedArray([ + createUntypedObject({ + created: createUntypedString("2023-07-26T10:41:26Z"), + label: createUntypedString("Keyword1"), + termGuid: createUntypedString("10e9cc83-b5a4-4c8d-8dab-4ada1252dd70"), + wssId: createUntypedNumber(6442450941), }), - new UntypedObject({ - created: new UntypedString("2023-07-26T10:51:26Z"), - label: new UntypedString("Keyword2"), - termGuid: new UntypedString("2cae6c6a-9bb8-4a78-afff-81b88e735fef"), - wssId: new UntypedNumber(6442450942), + createUntypedObject({ + created: createUntypedString("2023-07-26T10:51:26Z"), + label: createUntypedString("Keyword2"), + termGuid: createUntypedString("2cae6c6a-9bb8-4a78-afff-81b88e735fef"), + wssId: createUntypedNumber(6442450942), }), ]), additionalData: { - extra: new UntypedObject({ - createdDateTime: new UntypedString("2024-01-15T00:00:00+00:00"), + extra: createUntypedObject({ + createdDateTime: createUntypedString("2024-01-15T00:00:00+00:00"), }), }, }; From b0ac7548e8f60af2a58048bf66c3d89d306998bd Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Tue, 19 Mar 2024 20:05:32 +0300 Subject: [PATCH 8/9] Updates version and release notes --- packages/abstractions/package.json | 2 +- .../abstractions/src/serialization/untypedBoolean.ts | 3 ++- packages/abstractions/src/serialization/untypedNumber.ts | 3 ++- packages/abstractions/src/serialization/untypedObject.ts | 9 +++++---- packages/abstractions/src/serialization/untypedString.ts | 3 ++- packages/authentication/azure/package.json | 4 ++-- packages/authentication/spfx/package.json | 4 ++-- packages/http/fetch/package.json | 4 ++-- packages/serialization/form/package.json | 4 ++-- packages/serialization/json/package.json | 4 ++-- packages/serialization/multipart/package.json | 4 ++-- packages/serialization/text/package.json | 4 ++-- 12 files changed, 26 insertions(+), 22 deletions(-) diff --git a/packages/abstractions/package.json b/packages/abstractions/package.json index dfaadcf646..1e6fcd7097 100644 --- a/packages/abstractions/package.json +++ b/packages/abstractions/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-abstractions", - "version": "1.0.0-preview.47", + "version": "1.0.0-preview.48", "description": "Core abstractions for kiota generated libraries in TypeScript and JavaScript", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", diff --git a/packages/abstractions/src/serialization/untypedBoolean.ts b/packages/abstractions/src/serialization/untypedBoolean.ts index e6d2a61c21..4698582941 100644 --- a/packages/abstractions/src/serialization/untypedBoolean.ts +++ b/packages/abstractions/src/serialization/untypedBoolean.ts @@ -5,7 +5,8 @@ export interface UntypedBoolean extends UntypedNode { } export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { - return typeof (node as UntypedBoolean)?.value === "boolean"; + const proposedNode = node as UntypedBoolean; + return proposedNode && typeof proposedNode.value === "boolean"; } export function createUntypedBoolean(value: boolean): UntypedBoolean { diff --git a/packages/abstractions/src/serialization/untypedNumber.ts b/packages/abstractions/src/serialization/untypedNumber.ts index af34eaca23..ec225cd4d6 100644 --- a/packages/abstractions/src/serialization/untypedNumber.ts +++ b/packages/abstractions/src/serialization/untypedNumber.ts @@ -5,7 +5,8 @@ export interface UntypedNumber extends UntypedNode { } export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { - return typeof (node as UntypedNumber)?.value === "number"; + const proposedNode = node as UntypedNumber; + return proposedNode && typeof proposedNode.value === "number"; } export function createUntypedNumber(value: number): UntypedNumber { diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts index 491facc92d..c3022a917a 100644 --- a/packages/abstractions/src/serialization/untypedObject.ts +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -5,11 +5,12 @@ export interface UntypedObject extends UntypedNode { } export function isUntypedObject(node: UntypedNode): node is UntypedObject { - const value = (node as UntypedObject)?.value; + const proposedNode = node as UntypedObject; return ( - value instanceof Object && - value instanceof Array === false && - Object.values(value).every((item) => isUntypedNode(item)) + proposedNode && + proposedNode.value instanceof Object && + proposedNode.value instanceof Array === false && + Object.values(proposedNode.value).every((item) => isUntypedNode(item)) ); } diff --git a/packages/abstractions/src/serialization/untypedString.ts b/packages/abstractions/src/serialization/untypedString.ts index aa65d6c2ae..57c7b92344 100644 --- a/packages/abstractions/src/serialization/untypedString.ts +++ b/packages/abstractions/src/serialization/untypedString.ts @@ -5,7 +5,8 @@ export interface UntypedString extends UntypedNode { } export function isUntypedString(node: UntypedNode): node is UntypedString { - return typeof (node as UntypedString)?.value === "string"; + const proposedNode = node as UntypedString; + return proposedNode && typeof proposedNode.value === "string"; } export function createUntypedString(value: string): UntypedString { diff --git a/packages/authentication/azure/package.json b/packages/authentication/azure/package.json index 6a355c27e5..62e883df92 100644 --- a/packages/authentication/azure/package.json +++ b/packages/authentication/azure/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-authentication-azure", - "version": "1.0.0-preview.42", + "version": "1.0.0-preview.43", "description": "Authentication provider for Kiota using Azure Identity", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", @@ -30,7 +30,7 @@ "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { "@azure/core-auth": "^1.5.0", - "@microsoft/kiota-abstractions": "^1.0.0-preview.47", + "@microsoft/kiota-abstractions": "^1.0.0-preview.48", "@opentelemetry/api": "^1.7.0", "tslib": "^2.6.2" }, diff --git a/packages/authentication/spfx/package.json b/packages/authentication/spfx/package.json index 4a17696a72..2f5a0d859b 100644 --- a/packages/authentication/spfx/package.json +++ b/packages/authentication/spfx/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-authentication-spfx", - "version": "1.0.0-preview.37", + "version": "1.0.0-preview.38", "description": "Authentication provider for using Kiota in SPFx solutions", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.47", + "@microsoft/kiota-abstractions": "^1.0.0-preview.48", "@microsoft/sp-http": "^1.15.2", "@opentelemetry/api": "^1.7.0", "tslib": "^2.6.2" diff --git a/packages/http/fetch/package.json b/packages/http/fetch/package.json index 74efcfb446..6bd63ccc05 100644 --- a/packages/http/fetch/package.json +++ b/packages/http/fetch/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-http-fetchlibrary", - "version": "1.0.0-preview.46", + "version": "1.0.0-preview.47", "description": "Kiota request adapter implementation with fetch", "keywords": [ "Kiota", @@ -38,7 +38,7 @@ "test:cjs": "mocha 'dist/cjs/test/common/**/*.js' && mocha 'dist/cjs/test/node/**/*.js'" }, "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.47", + "@microsoft/kiota-abstractions": "^1.0.0-preview.48", "@opentelemetry/api": "^1.7.0", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" diff --git a/packages/serialization/form/package.json b/packages/serialization/form/package.json index 0e655bfcbe..cc37d61925 100644 --- a/packages/serialization/form/package.json +++ b/packages/serialization/form/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-form", - "version": "1.0.0-preview.36", + "version": "1.0.0-preview.37", "description": "Implementation of Kiota Serialization interfaces for URI from encoded", "main": "dist/cjs/src/index.js", "browser": { @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.47", + "@microsoft/kiota-abstractions": "^1.0.0-preview.48", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" }, diff --git a/packages/serialization/json/package.json b/packages/serialization/json/package.json index 5f35f5adc5..aaef5c5e21 100644 --- a/packages/serialization/json/package.json +++ b/packages/serialization/json/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-json", - "version": "1.0.0-preview.47", + "version": "1.0.0-preview.48", "description": "Implementation of Kiota Serialization interfaces for JSON", "main": "dist/cjs/src/index.js", "browser": { @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.47", + "@microsoft/kiota-abstractions": "^1.0.0-preview.48", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" }, diff --git a/packages/serialization/multipart/package.json b/packages/serialization/multipart/package.json index d73c8e88a5..3794a48644 100644 --- a/packages/serialization/multipart/package.json +++ b/packages/serialization/multipart/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-multipart", - "version": "1.0.0-preview.26", + "version": "1.0.0-preview.27", "description": "Implementation of Kiota Serialization interfaces for multipart form data", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", @@ -40,7 +40,7 @@ "tslib": "^2.6.2" }, "devDependencies": { - "@microsoft/kiota-serialization-json": "^1.0.0-preview.47" + "@microsoft/kiota-serialization-json": "^1.0.0-preview.48" }, "publishConfig": { "access": "public" diff --git a/packages/serialization/text/package.json b/packages/serialization/text/package.json index f3fe6fdf9d..5929e9fba9 100644 --- a/packages/serialization/text/package.json +++ b/packages/serialization/text/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/kiota-serialization-text", - "version": "1.0.0-preview.44", + "version": "1.0.0-preview.45", "description": "Implementation of Kiota Serialization interfaces for text", "main": "dist/cjs/src/index.js", "browser": { @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/microsoft/kiota-typescript#readme", "dependencies": { - "@microsoft/kiota-abstractions": "^1.0.0-preview.47", + "@microsoft/kiota-abstractions": "^1.0.0-preview.48", "guid-typescript": "^1.0.9", "tslib": "^2.6.2" }, From 47be78f6c8a5b70bbf9c5fc6d2b3000312df19c8 Mon Sep 17 00:00:00 2001 From: Andrew Omondi Date: Wed, 20 Mar 2024 14:24:47 +0300 Subject: [PATCH 9/9] Fixes doc comments from PR review. --- .../src/serialization/untypedArray.ts | 18 ++++++++++++-- .../src/serialization/untypedBoolean.ts | 18 ++++++++++++-- .../src/serialization/untypedNode.ts | 23 +++++++++++++++++- .../src/serialization/untypedNull.ts | 15 +++++++++++- .../src/serialization/untypedNumber.ts | 18 ++++++++++++-- .../src/serialization/untypedObject.ts | 24 +++++++++++++++---- .../src/serialization/untypedString.ts | 18 ++++++++++++-- 7 files changed, 120 insertions(+), 14 deletions(-) diff --git a/packages/abstractions/src/serialization/untypedArray.ts b/packages/abstractions/src/serialization/untypedArray.ts index dd05f69e72..d976491950 100644 --- a/packages/abstractions/src/serialization/untypedArray.ts +++ b/packages/abstractions/src/serialization/untypedArray.ts @@ -1,9 +1,18 @@ import { isUntypedNode, UntypedNode } from "./untypedNode"; +/** Defines an interface for defining an untyped array. */ export interface UntypedArray extends UntypedNode { + /** + * Gets the value of the UntypedNode as an array of UntypedNodes. + */ getValue(): UntypedNode[]; } +/** + * Type guard to assert that an UntypedNode instance is an UntypedArray. + * @param node The UntypedNode to check. + * @return boolean indicating if the node is an UntypedArray. + */ export function isUntypedArray(node: UntypedNode): node is UntypedArray { const proposedNode = node as UntypedArray; return ( @@ -13,9 +22,14 @@ export function isUntypedArray(node: UntypedNode): node is UntypedArray { ); } +/** + * Factory to create an UntypedArray from an array of UntypedNodes. + * @param value The value to create from. + * @return The created UntypedArray. + */ export function createUntypedArray(value: UntypedNode[]): UntypedArray { return { value: value, - getValue: () => value as UntypedNode[], + getValue: () => value as UntypedNode[], }; -} \ No newline at end of file +} diff --git a/packages/abstractions/src/serialization/untypedBoolean.ts b/packages/abstractions/src/serialization/untypedBoolean.ts index 4698582941..9e71190d23 100644 --- a/packages/abstractions/src/serialization/untypedBoolean.ts +++ b/packages/abstractions/src/serialization/untypedBoolean.ts @@ -1,17 +1,31 @@ import { UntypedNode } from "./untypedNode"; +/** Defines an interface for defining an untyped boolean. */ export interface UntypedBoolean extends UntypedNode { + /** + * Gets the value of the UntypedNode as a boolean value. + */ getValue(): boolean; } +/** + * Type guard to assert that an UntypedNode instance is an UntypedBoolean. + * @param node The UntypedNode to check. + * @return boolean indicating if the node is an UntypedBoolean. + */ export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean { const proposedNode = node as UntypedBoolean; return proposedNode && typeof proposedNode.value === "boolean"; } +/** + * Factory to create an UntypedBoolean from a boolean. + * @param value The boolean value to create from. + * @return The created UntypedBoolean. + */ export function createUntypedBoolean(value: boolean): UntypedBoolean { return { value: value, - getValue: () => value as boolean, + getValue: () => value as boolean, }; -} \ No newline at end of file +} diff --git a/packages/abstractions/src/serialization/untypedNode.ts b/packages/abstractions/src/serialization/untypedNode.ts index 6cc2b258de..314d4b9eaf 100644 --- a/packages/abstractions/src/serialization/untypedNode.ts +++ b/packages/abstractions/src/serialization/untypedNode.ts @@ -3,22 +3,40 @@ import type { Parsable } from "./parsable"; import type { ParseNode } from "./parseNode"; import type { SerializationWriter } from "./serializationWriter"; +/** Defines the base interface for defining an untyped node. */ export interface UntypedNode extends Parsable { - getValue(): any + /** + * Gets the value of the UntypedNode. + */ + getValue(): any; + /** + * The value represented by the UntypedNode. + */ value?: any; } +/** + * Factory to create an UntypedNode from a string during deserialization. + */ export function createUntypedNodeFromDiscriminatorValue( _parseNode: ParseNode | undefined, ): (instance?: Parsable) => Record void> { return deserializeIntoUntypedNode; } +/** + * Type guard to assert that an object instance is an UntypedNode. + * @param node The object to check. + * @return boolean indicating if the node is an UntypedNode. + */ export function isUntypedNode(node: any): node is UntypedNode { const potentialNode = node as UntypedNode; return potentialNode && potentialNode.getValue !== undefined; } +/** + * The deserialization implementation for UntypedNode. + */ export function deserializeIntoUntypedNode( untypedNode: Partial | undefined = {}, ): Record void> { @@ -32,6 +50,9 @@ export function deserializeIntoUntypedNode( }; } +/** + * The serialization implementation for UntypedNode. + */ export function serializeUntypedNode( _writer: SerializationWriter, _errorDetails: Partial | undefined = {}, diff --git a/packages/abstractions/src/serialization/untypedNull.ts b/packages/abstractions/src/serialization/untypedNull.ts index 0282b34620..bd7076c705 100644 --- a/packages/abstractions/src/serialization/untypedNull.ts +++ b/packages/abstractions/src/serialization/untypedNull.ts @@ -1,16 +1,29 @@ import { UntypedNode } from "./untypedNode"; +/** Defines the interface for defining an untyped null value. */ export interface UntypedNull extends UntypedNode { + /** + * Gets the value of the UntypedNode as null. + */ getValue(): null; } +/** + * Type guard to assert that an object instance is an UntypedNull. + * @param node The object to check. + * @return boolean indicating if the node is an UntypedNull. + */ export function isUntypedNull(node: UntypedNode): node is UntypedNull { return node.value === null; } +/** + * Factory to create an UntypedNull from a boolean. + * @return The created UntypedNull. + */ export function createUntypedNull(): UntypedNull { return { value: null, - getValue: () => null, + getValue: () => null, }; } diff --git a/packages/abstractions/src/serialization/untypedNumber.ts b/packages/abstractions/src/serialization/untypedNumber.ts index ec225cd4d6..42822e1dfc 100644 --- a/packages/abstractions/src/serialization/untypedNumber.ts +++ b/packages/abstractions/src/serialization/untypedNumber.ts @@ -1,17 +1,31 @@ import { UntypedNode } from "./untypedNode"; +/** Defines the interface for defining an untyped number value. */ export interface UntypedNumber extends UntypedNode { + /** + * Gets the value of the UntypedNode as a number. + */ getValue(): number; } +/** + * Type guard to assert that an object instance is an UntypedNumber. + * @param node The object to check. + * @return boolean indicating if the node is an UntypedNumber. + */ export function isUntypedNumber(node: UntypedNode): node is UntypedNumber { const proposedNode = node as UntypedNumber; return proposedNode && typeof proposedNode.value === "number"; } +/** + * Factory to create an UntypedNumber from a number. + * @param value The number value to create from. + * @return The created UntypedNumber. + */ export function createUntypedNumber(value: number): UntypedNumber { return { value: value, - getValue: () => value as number, + getValue: () => value as number, }; -} \ No newline at end of file +} diff --git a/packages/abstractions/src/serialization/untypedObject.ts b/packages/abstractions/src/serialization/untypedObject.ts index c3022a917a..83c57f4513 100644 --- a/packages/abstractions/src/serialization/untypedObject.ts +++ b/packages/abstractions/src/serialization/untypedObject.ts @@ -1,9 +1,18 @@ import { isUntypedNode, UntypedNode } from "./untypedNode"; +/** Defines the interface for defining an untyped object value. */ export interface UntypedObject extends UntypedNode { - getValue(): Record ; + /** + * Gets the value of the UntypedNode as a Record. + */ + getValue(): Record; } +/** + * Type guard to assert that an object instance is an UntypedObject. + * @param node The object to check. + * @return boolean indicating if the node is an UntypedObject. + */ export function isUntypedObject(node: UntypedNode): node is UntypedObject { const proposedNode = node as UntypedObject; return ( @@ -14,9 +23,16 @@ export function isUntypedObject(node: UntypedNode): node is UntypedObject { ); } -export function createUntypedObject(value: Record): UntypedObject { +/** + * Factory to create an UntypedObject from a Record. + * @param value The Record value to create from. + * @return The created UntypedObject. + */ +export function createUntypedObject( + value: Record, +): UntypedObject { return { value: value, - getValue: () => value as Record, + getValue: () => value as Record, }; -} \ No newline at end of file +} diff --git a/packages/abstractions/src/serialization/untypedString.ts b/packages/abstractions/src/serialization/untypedString.ts index 57c7b92344..cbcbd6300b 100644 --- a/packages/abstractions/src/serialization/untypedString.ts +++ b/packages/abstractions/src/serialization/untypedString.ts @@ -1,17 +1,31 @@ import { UntypedNode } from "./untypedNode"; +/** Defines the interface for defining an untyped string value. */ export interface UntypedString extends UntypedNode { + /** + * Gets the value of the UntypedNode as a Record. + */ getValue(): string; } +/** + * Type guard to assert that an object instance is an UntypedString. + * @param node The object to check. + * @return boolean indicating if the node is an UntypedString. + */ export function isUntypedString(node: UntypedNode): node is UntypedString { const proposedNode = node as UntypedString; return proposedNode && typeof proposedNode.value === "string"; } +/** + * Factory to create an UntypedString from a string. + * @param value The string value to create from. + * @return The created UntypedString. + */ export function createUntypedString(value: string): UntypedString { return { value: value, - getValue: () => value as string, + getValue: () => value as string, }; -} \ No newline at end of file +}