Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable camelcase */
// TODO(DEVSDK-3113): Remove EventEmitter from shared types in next major version.

Check warning on line 2 in src/Types.ts

View workflow job for this annotation

GitHub Actions / Static Checks

Unexpected 'todo' comment: 'TODO(DEVSDK-3113): Remove EventEmitter...'
// eslint-disable-next-line wintertc-compat
import {EventEmitter} from 'events';
import {
Expand Down Expand Up @@ -35,7 +35,12 @@
| {kind: 'decimal_string'}
| {kind: 'object'; fields: Record<string, V2RuntimeSchema>}
| {kind: 'array'; element: V2RuntimeSchema}
| {kind: 'nullable'; inner: V2RuntimeSchema};
| {kind: 'nullable'; inner: V2RuntimeSchema}
| {
kind: 'discriminatedUnion';
discriminator: string;
variants: Record<string, V2RuntimeSchema>;
};
export type MethodSpec = {
method: string;
methodType?: string;
Expand Down
106 changes: 84 additions & 22 deletions src/V2Coercion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
import {Decimal} from './Decimal.js';
import {V2RuntimeSchema} from './Types.js';

const coerceV2RequestDiscriminatedUnion = (
data: unknown,
schema: V2RuntimeSchema & {kind: 'discriminatedUnion'}
): unknown => {
if (typeof data !== 'object' || Array.isArray(data)) {
return data;
}
const obj = data as Record<string, unknown>;
const discriminatorValue = obj[schema.discriminator];
if (
typeof discriminatorValue === 'string' &&
discriminatorValue in schema.variants
) {
return coerceV2RequestData(data, schema.variants[discriminatorValue]);
}
return data;
};

const coerceV2RequestObject = (
data: unknown,
schema: V2RuntimeSchema & {kind: 'object'}
): unknown => {
if (typeof data !== 'object' || Array.isArray(data)) {
return data;
}
const obj = data as Record<string, unknown>;
const result: Record<string, unknown> = {};
for (const key of Object.keys(obj)) {
const fieldSchema = schema.fields[key];
result[key] = fieldSchema
? coerceV2RequestData(obj[key], fieldSchema)
: obj[key];
}
return result;
};

/**
* Coerces outbound V2 request data by converting bigint (or number)
* int64_string fields to strings, matching the wire format expected by the API.
Expand Down Expand Up @@ -30,18 +66,7 @@ export const coerceV2RequestData = (
: data;

case 'object': {
if (typeof data !== 'object' || Array.isArray(data)) {
return data;
}
const obj = data as Record<string, unknown>;
const result: Record<string, unknown> = {};
for (const key of Object.keys(obj)) {
const fieldSchema = schema.fields[key];
result[key] = fieldSchema
? coerceV2RequestData(obj[key], fieldSchema)
: obj[key];
}
return result;
return coerceV2RequestObject(data, schema);
}

case 'array': {
Expand All @@ -55,9 +80,51 @@ export const coerceV2RequestData = (

case 'nullable':
return coerceV2RequestData(data, schema.inner);

case 'discriminatedUnion': {
return coerceV2RequestDiscriminatedUnion(data, schema);
}
}
};

// NOTE: these are separate from the request flavors above
// because the caller to coerceV2ResponseData expects data
// to be modified in place

const coerceV2ResponseDiscriminatedUnion = (
data: unknown,
schema: V2RuntimeSchema & {kind: 'discriminatedUnion'}
): unknown => {
if (typeof data !== 'object' || Array.isArray(data)) {
return data;
}
const obj = data as Record<string, unknown>;
const discriminatorValue = obj[schema.discriminator];
if (
typeof discriminatorValue === 'string' &&
discriminatorValue in schema.variants
) {
return coerceV2ResponseData(data, schema.variants[discriminatorValue]);
}
return data;
};

const coerceV2ResponseObject = (
data: unknown,
schema: V2RuntimeSchema & {kind: 'object'}
): unknown => {
if (typeof data !== 'object' || Array.isArray(data)) {
return data;
}
const obj = data as Record<string, unknown>;
for (const key of Object.keys(schema.fields)) {
if (key in obj) {
obj[key] = coerceV2ResponseData(obj[key], schema.fields[key]);
}
}
return obj;
};

/**
* Coerces inbound V2 response data by converting string int64_string fields
* to bigints, matching the SDK's public type contract.
Expand Down Expand Up @@ -99,16 +166,7 @@ export const coerceV2ResponseData = (
return data;

case 'object': {
if (typeof data !== 'object' || Array.isArray(data)) {
return data;
}
const obj = data as Record<string, unknown>;
for (const key of Object.keys(schema.fields)) {
if (key in obj) {
obj[key] = coerceV2ResponseData(obj[key], schema.fields[key]);
}
}
return obj;
return coerceV2ResponseObject(data, schema);
}

case 'array': {
Expand All @@ -123,5 +181,9 @@ export const coerceV2ResponseData = (

case 'nullable':
return coerceV2ResponseData(data, schema.inner);

case 'discriminatedUnion': {
return coerceV2ResponseDiscriminatedUnion(data, schema);
}
}
};
Loading
Loading