Skip to content

Commit

Permalink
Add support for Headers
Browse files Browse the repository at this point in the history
  • Loading branch information
lxsmnsyc committed Apr 9, 2023
1 parent d598849 commit 3ee4191
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 23 deletions.
31 changes: 29 additions & 2 deletions packages/seroval/src/tree/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
SerovalAggregateErrorNode,
SerovalArrayNode,
SerovalErrorNode,
SerovalHeadersNode,
SerovalIterableNode,
SerovalMapNode,
SerovalNode,
Expand Down Expand Up @@ -310,7 +311,7 @@ async function generateAggregateErrorNode(
id: number,
current: AggregateError,
): Promise<SerovalAggregateErrorNode> {
const options = getErrorOptions(ctx, current);
const options = getErrorOptions(ctx, current, true);
const optionsNode = options
? await generateProperties(ctx, options)
: undefined;
Expand All @@ -333,7 +334,7 @@ async function generateErrorNode(
id: number,
current: Error,
): Promise<SerovalErrorNode> {
const options = getErrorOptions(ctx, current);
const options = getErrorOptions(ctx, current, false);
const optionsNode = options
? await generateProperties(ctx, options)
: undefined;
Expand All @@ -351,6 +352,30 @@ async function generateErrorNode(
};
}

async function generateHeadersNode(
ctx: ParserContext,
id: number,
current: Headers,
): Promise<SerovalHeadersNode> {
assert(ctx.features & Feature.WebAPI, 'Unsupported type "File"');
const items: [string, string][] = [];
current.forEach((value, key) => {
items.push([key, value]);
});
return {
t: SerovalNodeType.Headers,
i: id,
s: undefined,
l: items.length,
c: undefined,
m: undefined,
d: undefined,
a: await generateNodeList(ctx, items),
f: undefined,
b: undefined,
};
}

async function parse<T>(
ctx: ParserContext,
current: T,
Expand Down Expand Up @@ -465,6 +490,8 @@ async function parse<T>(
return createBlobNode(ctx, id, current as unknown as Blob);
case File:
return createFileNode(ctx, id, current as unknown as File);
case Headers:
return generateHeadersNode(ctx, id, current as unknown as Headers);
default:
break;
}
Expand Down
70 changes: 64 additions & 6 deletions packages/seroval/src/tree/deserialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import {
SerovalBigIntTypedArrayNode,
SerovalBlobNode,
SerovalDataViewNode,
SerovalDateNode,
SerovalErrorNode,
SerovalFileNode,
SerovalHeadersNode,
SerovalIterableNode,
SerovalMapNode,
SerovalNode,
Expand All @@ -24,8 +26,12 @@ import {
SerovalObjectNode,
SerovalObjectRecordNode,
SerovalPromiseNode,
SerovalReferenceNode,
SerovalRegExpNode,
SerovalSetNode,
SerovalTypedArrayNode,
SerovalURLNode,
SerovalURLSearchParamsNode,
} from './types';

function assignIndexedValue<T>(
Expand All @@ -37,9 +43,15 @@ function assignIndexedValue<T>(
return value;
}

type SerovalNodeListNode =
| SerovalArrayNode
| SerovalIterableNode
| SerovalAggregateErrorNode
| SerovalHeadersNode;

function deserializeNodeList(
ctx: SerializationContext,
node: SerovalArrayNode | SerovalIterableNode | SerovalAggregateErrorNode,
node: SerovalNodeListNode,
result: unknown[],
) {
let item: SerovalNode;
Expand Down Expand Up @@ -243,6 +255,41 @@ function deserializeIterable(
return deserializeDictionary(ctx, node, result);
}

function deserializeDate(
ctx: SerializationContext,
node: SerovalDateNode,
) {
return assignIndexedValue(ctx, node.i, new Date(node.s));
}

function deserializeRegExp(
ctx: SerializationContext,
node: SerovalRegExpNode,
) {
return assignIndexedValue(ctx, node.i, new RegExp(node.c, node.m));
}

function deserializeURL(
ctx: SerializationContext,
node: SerovalURLNode,
) {
return assignIndexedValue(ctx, node.i, new URL(deserializeString(node.s)));
}

function deserializeURLSearchParams(
ctx: SerializationContext,
node: SerovalURLSearchParamsNode,
) {
return assignIndexedValue(ctx, node.i, new URLSearchParams(deserializeString(node.s)));
}

function deserializeReference(
ctx: SerializationContext,
node: SerovalReferenceNode,
) {
return assignIndexedValue(ctx, node.i, getReference(deserializeString(node.s)));
}

function deserializeDataView(
ctx: SerializationContext,
node: SerovalDataViewNode,
Expand Down Expand Up @@ -281,6 +328,15 @@ function deserializeFile(
return result;
}

function deserializeHeaders(
ctx: SerializationContext,
node: SerovalHeadersNode,
) {
const values: [string, string][] = [];
deserializeNodeList(ctx, node, values);
return assignIndexedValue(ctx, node.i, new Headers(values));
}

export default function deserializeTree(
ctx: SerializationContext,
node: SerovalNode,
Expand Down Expand Up @@ -314,9 +370,9 @@ export default function deserializeTree(
case SerovalNodeType.NullConstructor:
return deserializeNullConstructor(ctx, node);
case SerovalNodeType.Date:
return assignIndexedValue(ctx, node.i, new Date(node.s));
return deserializeDate(ctx, node);
case SerovalNodeType.RegExp:
return assignIndexedValue(ctx, node.i, new RegExp(node.c, node.m));
return deserializeRegExp(ctx, node);
case SerovalNodeType.Set:
return deserializeSet(ctx, node);
case SerovalNodeType.Map:
Expand All @@ -339,15 +395,17 @@ export default function deserializeTree(
case SerovalNodeType.WKSymbol:
return SYMBOL_REF[node.s];
case SerovalNodeType.URL:
return assignIndexedValue(ctx, node.i, new URL(deserializeString(node.s)));
return deserializeURL(ctx, node);
case SerovalNodeType.URLSearchParams:
return assignIndexedValue(ctx, node.i, new URLSearchParams(deserializeString(node.s)));
return deserializeURLSearchParams(ctx, node);
case SerovalNodeType.Reference:
return assignIndexedValue(ctx, node.i, getReference(deserializeString(node.s)));
return deserializeReference(ctx, node);
case SerovalNodeType.Blob:
return deserializeBlob(ctx, node);
case SerovalNodeType.File:
return deserializeFile(ctx, node);
case SerovalNodeType.Headers:
return deserializeHeaders(ctx, node);
default:
throw new Error('Unsupported type');
}
Expand Down
72 changes: 64 additions & 8 deletions packages/seroval/src/tree/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ import {
SerovalDataViewNode,
SerovalBlobNode,
SerovalFileNode,
SerovalHeadersNode,
SerovalRegExpNode,
SerovalDateNode,
SerovalURLNode,
SerovalURLSearchParamsNode,
SerovalReferenceNode,
} from './types';

function getAssignmentExpression(assignment: Assignment): string {
Expand Down Expand Up @@ -216,9 +222,15 @@ function isIndexedValueInStack(
return node.t === SerovalNodeType.IndexedValue && ctx.stack.includes(node.i);
}

type SerovalNodeListNode =
| SerovalArrayNode
| SerovalIterableNode
| SerovalAggregateErrorNode
| SerovalHeadersNode;

function serializeNodeList(
ctx: SerializationContext,
node: SerovalArrayNode | SerovalIterableNode | SerovalAggregateErrorNode,
node: SerovalNodeListNode,
) {
// This is different than Map and Set
// because we also need to serialize
Expand Down Expand Up @@ -572,6 +584,41 @@ function serializeIterable(
return serializeDictionary(ctx, node.i, node.d, serialized);
}

function serializeDate(
ctx: SerializationContext,
node: SerovalDateNode,
) {
return assignIndexedValue(ctx, node.i, 'new Date("' + node.s + '")');
}

function serializeRegExp(
ctx: SerializationContext,
node: SerovalRegExpNode,
) {
return assignIndexedValue(ctx, node.i, '/' + node.c + '/' + node.m);
}

function serializeURL(
ctx: SerializationContext,
node: SerovalURLNode,
) {
return assignIndexedValue(ctx, node.i, 'new URL("' + node.s + '")');
}

function serializeURLSearchParams(
ctx: SerializationContext,
node: SerovalURLSearchParamsNode,
) {
return assignIndexedValue(ctx, node.i, node.s ? 'new URLSearchParams("' + node.s + '")' : 'new URLSearchParams');
}

function serializeReference(
ctx: SerializationContext,
node: SerovalReferenceNode,
) {
return assignIndexedValue(ctx, node.i, GLOBAL_KEY + '.get("' + node.s + '")');
}

function serializeDataView(
ctx: SerializationContext,
node: SerovalDataViewNode,
Expand All @@ -597,6 +644,13 @@ function serializeFile(
return assignIndexedValue(ctx, node.i, 'new File(' + args + ')');
}

function serializeHeaders(
ctx: SerializationContext,
node: SerovalHeadersNode,
) {
return assignIndexedValue(ctx, node.i, 'new Headers(' + serializeNodeList(ctx, node) + ')');
}

export default function serializeTree(
ctx: SerializationContext,
node: SerovalNode,
Expand Down Expand Up @@ -631,9 +685,9 @@ export default function serializeTree(
case SerovalNodeType.NullConstructor:
return serializeNullConstructor(ctx, node);
case SerovalNodeType.Date:
return assignIndexedValue(ctx, node.i, 'new Date("' + node.s + '")');
return serializeDate(ctx, node);
case SerovalNodeType.RegExp:
return assignIndexedValue(ctx, node.i, '/' + node.c + '/' + node.m);
return serializeRegExp(ctx, node);
case SerovalNodeType.Set:
return serializeSet(ctx, node);
case SerovalNodeType.Map:
Expand All @@ -656,15 +710,17 @@ export default function serializeTree(
case SerovalNodeType.WKSymbol:
return SYMBOL_STRING[node.s];
case SerovalNodeType.URL:
return assignIndexedValue(ctx, node.i, 'new URL("' + node.s + '")');
return serializeURL(ctx, node);
case SerovalNodeType.URLSearchParams:
return assignIndexedValue(ctx, node.i, node.s ? 'new URLSearchParams("' + node.s + '")' : 'new URLSearchParams');
return serializeURLSearchParams(ctx, node);
case SerovalNodeType.Reference:
return assignIndexedValue(ctx, node.i, GLOBAL_KEY + '.get("' + node.s + '")');
return serializeReference(ctx, node);
case SerovalNodeType.Blob:
return assignIndexedValue(ctx, node.i, serializeBlob(ctx, node));
return serializeBlob(ctx, node);
case SerovalNodeType.File:
return assignIndexedValue(ctx, node.i, serializeFile(ctx, node));
return serializeFile(ctx, node);
case SerovalNodeType.Headers:
return serializeHeaders(ctx, node);
default:
throw new Error('Unsupported type');
}
Expand Down
6 changes: 6 additions & 0 deletions packages/seroval/src/tree/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function getErrorConstructor(errorName: string) {
export function getErrorOptions(
ctx: ParserContext,
error: Error,
isAggregate: boolean,
) {
let options: Record<string, any> | undefined;
const constructor = getErrorConstructorName(error);
Expand All @@ -63,6 +64,11 @@ export function getErrorOptions(
options = options || {};
options[name] = error[name as keyof Error];
}
} else if (name === 'errors') {
if (!isAggregate) {
options = options || {};
options[name] = error[name as keyof Error];
}
} else {
options = options || {};
options[name] = error[name as keyof Error];
Expand Down
Loading

0 comments on commit 3ee4191

Please sign in to comment.