Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TypeScript] Untyped Nodes #1084

Merged
merged 14 commits into from
Mar 20, 2024
2 changes: 1 addition & 1 deletion packages/abstractions/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
7 changes: 7 additions & 0 deletions packages/abstractions/src/serialization/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
21 changes: 21 additions & 0 deletions packages/abstractions/src/serialization/untypedArray.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { isUntypedNode, UntypedNode } from "./untypedNode";

export interface UntypedArray extends UntypedNode {
andrueastman marked this conversation as resolved.
Show resolved Hide resolved
getValue(): UntypedNode[];
}

export function isUntypedArray(node: UntypedNode): node is UntypedArray {
const proposedNode = node as UntypedArray;
return (
proposedNode &&
proposedNode.value instanceof Array &&
proposedNode.value.every((item) => isUntypedNode(item))
);
}

export function createUntypedArray(value: UntypedNode[]): UntypedArray {
return {
value: value,
getValue: () => value as UntypedNode[],
};
}
17 changes: 17 additions & 0 deletions packages/abstractions/src/serialization/untypedBoolean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { UntypedNode } from "./untypedNode";

export interface UntypedBoolean extends UntypedNode {
getValue(): boolean;
}

export function isUntypedBoolean(node: UntypedNode): node is UntypedBoolean {
baywet marked this conversation as resolved.
Show resolved Hide resolved
const proposedNode = node as UntypedBoolean;
return proposedNode && typeof proposedNode.value === "boolean";
}

export function createUntypedBoolean(value: boolean): UntypedBoolean {
return {
value: value,
getValue: () => value as boolean,
};
}
40 changes: 40 additions & 0 deletions packages/abstractions/src/serialization/untypedNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* 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<string, (node: ParseNode) => void> {
return deserializeIntoUntypedNode;
}

export function isUntypedNode(node: any): node is UntypedNode {
const potentialNode = node as UntypedNode;
return potentialNode && potentialNode.getValue !== undefined;
}

export function deserializeIntoUntypedNode(
untypedNode: Partial<UntypedNode> | undefined = {},
): Record<string, (node: ParseNode) => void> {
return {
value: (n) => {
untypedNode.value = null;
},
getValue: (n) => {
untypedNode.getValue = () => untypedNode.value;
},
};
}

export function serializeUntypedNode(
_writer: SerializationWriter,
_errorDetails: Partial<UntypedNode> | undefined = {},
): void {
return;
}
16 changes: 16 additions & 0 deletions packages/abstractions/src/serialization/untypedNull.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { UntypedNode } from "./untypedNode";

export interface UntypedNull extends UntypedNode {
getValue(): null;
}

export function isUntypedNull(node: UntypedNode): node is UntypedNull {
return node.value === null;
}

export function createUntypedNull(): UntypedNull {
return {
value: null,
getValue: () => null,
};
}
17 changes: 17 additions & 0 deletions packages/abstractions/src/serialization/untypedNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { UntypedNode } from "./untypedNode";

export interface UntypedNumber extends UntypedNode {
getValue(): number;
}

export function isUntypedNumber(node: UntypedNode): node is UntypedNumber {
const proposedNode = node as UntypedNumber;
return proposedNode && typeof proposedNode.value === "number";
}

export function createUntypedNumber(value: number): UntypedNumber {
return {
value: value,
getValue: () => value as number,
};
}
22 changes: 22 additions & 0 deletions packages/abstractions/src/serialization/untypedObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { isUntypedNode, UntypedNode } from "./untypedNode";

export interface UntypedObject extends UntypedNode {
getValue(): Record<string, UntypedNode> ;
}

export function isUntypedObject(node: UntypedNode): node is UntypedObject {
const proposedNode = node as UntypedObject;
return (
proposedNode &&
proposedNode.value instanceof Object &&
proposedNode.value instanceof Array === false &&
Object.values(proposedNode.value).every((item) => isUntypedNode(item))
);
}

export function createUntypedObject(value: Record<string, UntypedNode>): UntypedObject {
return {
value: value,
getValue: () => value as Record<string, UntypedNode>,
};
}
17 changes: 17 additions & 0 deletions packages/abstractions/src/serialization/untypedString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { UntypedNode } from "./untypedNode";

export interface UntypedString extends UntypedNode {
getValue(): string;
}

export function isUntypedString(node: UntypedNode): node is UntypedString {
const proposedNode = node as UntypedString;
return proposedNode && typeof proposedNode.value === "string";
}

export function createUntypedString(value: string): UntypedString {
return {
value: value,
getValue: () => value as string,
};
}
4 changes: 2 additions & 2 deletions packages/authentication/azure/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/authentication/spfx/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions packages/http/fetch/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions packages/serialization/form/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down Expand Up @@ -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"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/serialization/json/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down Expand Up @@ -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"
},
Expand Down
48 changes: 48 additions & 0 deletions packages/serialization/json/src/jsonParseNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ import {
TimeOnly,
isBackingStoreEnabled,
toFirstCharacterUpper,
isUntypedNode,
UntypedNode,
UntypedArray,
UntypedBoolean,
UntypedNumber,
UntypedObject,
UntypedString,
createUntypedNodeFromDiscriminatorValue,
UntypedNull,
createUntypedBoolean,
createUntypedString,
createUntypedNumber,
createUntypedArray,
createUntypedObject,
createUntypedNull,
} from "@microsoft/kiota-abstractions";

export class JsonParseNode implements ParseNode {
Expand Down Expand Up @@ -78,6 +93,39 @@ export class JsonParseNode implements ParseNode {
parsableFactory: ParsableFactory<T>,
): T => {
const temp: T = {} as T;
if (isUntypedNode(parsableFactory(this)(temp))) {
const valueType = typeof this._jsonNode;
let value: T = temp;
if (valueType === "boolean") {
value = createUntypedBoolean(this._jsonNode as boolean) as any as T;
} else if (valueType === "string") {
value = createUntypedString(this._jsonNode as string) as any as T;
} else if (valueType === "number") {
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
(this._jsonNode as any[]).forEach((x) => {
nodes.push(
new JsonParseNode(x).getObjectValue(
baywet marked this conversation as resolved.
Show resolved Hide resolved
createUntypedNodeFromDiscriminatorValue,
),
);
});
value = createUntypedArray(nodes) as any as T;
} else if (this._jsonNode && valueType === "object") {
const properties: Record<string, UntypedNode> = {};
Object.entries(this._jsonNode as any).forEach(([k, v]) => {
properties[k] = new JsonParseNode(v).getObjectValue(
andrueastman marked this conversation as resolved.
Show resolved Hide resolved
createUntypedNodeFromDiscriminatorValue,
);
});
value = createUntypedObject(properties) as any as T;
} else if (!this._jsonNode) {
value = createUntypedNull() as any as T;
}
return value;
}
const enableBackingStore = isBackingStoreEnabled(parsableFactory(this)(temp));
const value: T = enableBackingStore ? new Proxy(temp, createBackedModelProxyHandler<T>()) : temp;
if (this.onBeforeAssignFieldValues) {
Expand Down
Loading
Loading