Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
191 lines
7 KiB
Text
191 lines
7 KiB
Text
import { SerdeContext } from "@smithy/core/protocols";
|
|
import { NormalizedSchema } from "@smithy/core/schema";
|
|
import { _parseEpochTimestamp, generateIdempotencyToken } from "@smithy/core/serde";
|
|
import { fromBase64 } from "@smithy/util-base64";
|
|
import { cbor } from "./cbor";
|
|
import { dateToTag } from "./parseCborBody";
|
|
export class CborCodec extends SerdeContext {
|
|
createSerializer() {
|
|
const serializer = new CborShapeSerializer();
|
|
serializer.setSerdeContext(this.serdeContext);
|
|
return serializer;
|
|
}
|
|
createDeserializer() {
|
|
const deserializer = new CborShapeDeserializer();
|
|
deserializer.setSerdeContext(this.serdeContext);
|
|
return deserializer;
|
|
}
|
|
}
|
|
export class CborShapeSerializer extends SerdeContext {
|
|
value;
|
|
write(schema, value) {
|
|
this.value = this.serialize(schema, value);
|
|
}
|
|
serialize(schema, source) {
|
|
const ns = NormalizedSchema.of(schema);
|
|
if (source == null) {
|
|
if (ns.isIdempotencyToken()) {
|
|
return generateIdempotencyToken();
|
|
}
|
|
return source;
|
|
}
|
|
if (ns.isBlobSchema()) {
|
|
if (typeof source === "string") {
|
|
return (this.serdeContext?.base64Decoder ?? fromBase64)(source);
|
|
}
|
|
return source;
|
|
}
|
|
if (ns.isTimestampSchema()) {
|
|
if (typeof source === "number" || typeof source === "bigint") {
|
|
return dateToTag(new Date((Number(source) / 1000) | 0));
|
|
}
|
|
return dateToTag(source);
|
|
}
|
|
if (typeof source === "function" || typeof source === "object") {
|
|
const sourceObject = source;
|
|
if (ns.isListSchema() && Array.isArray(sourceObject)) {
|
|
const sparse = !!ns.getMergedTraits().sparse;
|
|
const newArray = [];
|
|
let i = 0;
|
|
for (const item of sourceObject) {
|
|
const value = this.serialize(ns.getValueSchema(), item);
|
|
if (value != null || sparse) {
|
|
newArray[i++] = value;
|
|
}
|
|
}
|
|
return newArray;
|
|
}
|
|
if (sourceObject instanceof Date) {
|
|
return dateToTag(sourceObject);
|
|
}
|
|
const newObject = {};
|
|
if (ns.isMapSchema()) {
|
|
const sparse = !!ns.getMergedTraits().sparse;
|
|
for (const key of Object.keys(sourceObject)) {
|
|
const value = this.serialize(ns.getValueSchema(), sourceObject[key]);
|
|
if (value != null || sparse) {
|
|
newObject[key] = value;
|
|
}
|
|
}
|
|
}
|
|
else if (ns.isStructSchema()) {
|
|
for (const [key, memberSchema] of ns.structIterator()) {
|
|
const value = this.serialize(memberSchema, sourceObject[key]);
|
|
if (value != null) {
|
|
newObject[key] = value;
|
|
}
|
|
}
|
|
const isUnion = ns.isUnionSchema();
|
|
if (isUnion && Array.isArray(sourceObject.$unknown)) {
|
|
const [k, v] = sourceObject.$unknown;
|
|
newObject[k] = v;
|
|
}
|
|
}
|
|
else if (ns.isDocumentSchema()) {
|
|
for (const key of Object.keys(sourceObject)) {
|
|
newObject[key] = this.serialize(ns.getValueSchema(), sourceObject[key]);
|
|
}
|
|
}
|
|
return newObject;
|
|
}
|
|
return source;
|
|
}
|
|
flush() {
|
|
const buffer = cbor.serialize(this.value);
|
|
this.value = undefined;
|
|
return buffer;
|
|
}
|
|
}
|
|
export class CborShapeDeserializer extends SerdeContext {
|
|
read(schema, bytes) {
|
|
const data = cbor.deserialize(bytes);
|
|
return this.readValue(schema, data);
|
|
}
|
|
readValue(_schema, value) {
|
|
const ns = NormalizedSchema.of(_schema);
|
|
if (ns.isTimestampSchema()) {
|
|
if (typeof value === "number") {
|
|
return _parseEpochTimestamp(value);
|
|
}
|
|
if (typeof value === "object") {
|
|
if (value.tag === 1 && "value" in value) {
|
|
return _parseEpochTimestamp(value.value);
|
|
}
|
|
}
|
|
}
|
|
if (ns.isBlobSchema()) {
|
|
if (typeof value === "string") {
|
|
return (this.serdeContext?.base64Decoder ?? fromBase64)(value);
|
|
}
|
|
return value;
|
|
}
|
|
if (typeof value === "undefined" ||
|
|
typeof value === "boolean" ||
|
|
typeof value === "number" ||
|
|
typeof value === "string" ||
|
|
typeof value === "bigint" ||
|
|
typeof value === "symbol") {
|
|
return value;
|
|
}
|
|
else if (typeof value === "object") {
|
|
if (value === null) {
|
|
return null;
|
|
}
|
|
if ("byteLength" in value) {
|
|
return value;
|
|
}
|
|
if (value instanceof Date) {
|
|
return value;
|
|
}
|
|
if (ns.isDocumentSchema()) {
|
|
return value;
|
|
}
|
|
if (ns.isListSchema()) {
|
|
const newArray = [];
|
|
const memberSchema = ns.getValueSchema();
|
|
const sparse = !!ns.getMergedTraits().sparse;
|
|
for (const item of value) {
|
|
const itemValue = this.readValue(memberSchema, item);
|
|
if (itemValue != null || sparse) {
|
|
newArray.push(itemValue);
|
|
}
|
|
}
|
|
return newArray;
|
|
}
|
|
const newObject = {};
|
|
if (ns.isMapSchema()) {
|
|
const sparse = !!ns.getMergedTraits().sparse;
|
|
const targetSchema = ns.getValueSchema();
|
|
for (const key of Object.keys(value)) {
|
|
const itemValue = this.readValue(targetSchema, value[key]);
|
|
if (itemValue != null || sparse) {
|
|
newObject[key] = itemValue;
|
|
}
|
|
}
|
|
}
|
|
else if (ns.isStructSchema()) {
|
|
const isUnion = ns.isUnionSchema();
|
|
let keys;
|
|
if (isUnion) {
|
|
keys = new Set(Object.keys(value).filter((k) => k !== "__type"));
|
|
}
|
|
for (const [key, memberSchema] of ns.structIterator()) {
|
|
if (isUnion) {
|
|
keys.delete(key);
|
|
}
|
|
if (value[key] != null) {
|
|
newObject[key] = this.readValue(memberSchema, value[key]);
|
|
}
|
|
}
|
|
if (isUnion && keys?.size === 1 && Object.keys(newObject).length === 0) {
|
|
const k = keys.values().next().value;
|
|
newObject.$unknown = [k, value[k]];
|
|
}
|
|
}
|
|
return newObject;
|
|
}
|
|
else {
|
|
return value;
|
|
}
|
|
}
|
|
}
|