convex
Version:
Client for the Convex Cloud
334 lines (333 loc) • 11.1 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var value_exports = {};
__export(value_exports, {
base64ToBigInt: () => base64ToBigInt,
bigIntToBase64: () => bigIntToBase64,
convexOrUndefinedToJson: () => convexOrUndefinedToJson,
convexToJson: () => convexToJson,
jsonToConvex: () => jsonToConvex,
modernBase64ToBigInt: () => modernBase64ToBigInt,
modernBigIntToBase64: () => modernBigIntToBase64,
patchValueToJson: () => patchValueToJson,
slowBase64ToBigInt: () => slowBase64ToBigInt,
slowBigIntToBase64: () => slowBigIntToBase64,
stringifyValueForError: () => stringifyValueForError
});
module.exports = __toCommonJS(value_exports);
var Base64 = __toESM(require("./base64.js"), 1);
var import_common = require("../common/index.js");
const LITTLE_ENDIAN = true;
const MIN_INT64 = BigInt("-9223372036854775808");
const MAX_INT64 = BigInt("9223372036854775807");
const ZERO = BigInt("0");
const EIGHT = BigInt("8");
const TWOFIFTYSIX = BigInt("256");
function isSpecial(n) {
return Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0);
}
function slowBigIntToBase64(value) {
if (value < ZERO) {
value -= MIN_INT64 + MIN_INT64;
}
let hex = value.toString(16);
if (hex.length % 2 === 1) hex = "0" + hex;
const bytes = new Uint8Array(new ArrayBuffer(8));
let i = 0;
for (const hexByte of hex.match(/.{2}/g).reverse()) {
bytes.set([parseInt(hexByte, 16)], i++);
value >>= EIGHT;
}
return Base64.fromByteArray(bytes);
}
function slowBase64ToBigInt(encoded) {
const integerBytes = Base64.toByteArray(encoded);
if (integerBytes.byteLength !== 8) {
throw new Error(
`Received ${integerBytes.byteLength} bytes, expected 8 for $integer`
);
}
let value = ZERO;
let power = ZERO;
for (const byte of integerBytes) {
value += BigInt(byte) * TWOFIFTYSIX ** power;
power++;
}
if (value > MAX_INT64) {
value += MIN_INT64 + MIN_INT64;
}
return value;
}
function modernBigIntToBase64(value) {
if (value < MIN_INT64 || MAX_INT64 < value) {
throw new Error(
`BigInt ${value} does not fit into a 64-bit signed integer.`
);
}
const buffer = new ArrayBuffer(8);
new DataView(buffer).setBigInt64(0, value, true);
return Base64.fromByteArray(new Uint8Array(buffer));
}
function modernBase64ToBigInt(encoded) {
const integerBytes = Base64.toByteArray(encoded);
if (integerBytes.byteLength !== 8) {
throw new Error(
`Received ${integerBytes.byteLength} bytes, expected 8 for $integer`
);
}
const intBytesView = new DataView(integerBytes.buffer);
return intBytesView.getBigInt64(0, true);
}
const bigIntToBase64 = DataView.prototype.setBigInt64 ? modernBigIntToBase64 : slowBigIntToBase64;
const base64ToBigInt = DataView.prototype.getBigInt64 ? modernBase64ToBigInt : slowBase64ToBigInt;
const MAX_IDENTIFIER_LEN = 1024;
function validateObjectField(k) {
if (k.length > MAX_IDENTIFIER_LEN) {
throw new Error(
`Field name ${k} exceeds maximum field name length ${MAX_IDENTIFIER_LEN}.`
);
}
if (k.startsWith("$")) {
throw new Error(`Field name ${k} starts with a '$', which is reserved.`);
}
for (let i = 0; i < k.length; i += 1) {
const charCode = k.charCodeAt(i);
if (charCode < 32 || charCode >= 127) {
throw new Error(
`Field name ${k} has invalid character '${k[i]}': Field names can only contain non-control ASCII characters`
);
}
}
}
function jsonToConvex(value) {
if (value === null) {
return value;
}
if (typeof value === "boolean") {
return value;
}
if (typeof value === "number") {
return value;
}
if (typeof value === "string") {
return value;
}
if (Array.isArray(value)) {
return value.map((value2) => jsonToConvex(value2));
}
if (typeof value !== "object") {
throw new Error(`Unexpected type of ${value}`);
}
const entries = Object.entries(value);
if (entries.length === 1) {
const key = entries[0][0];
if (key === "$bytes") {
if (typeof value.$bytes !== "string") {
throw new Error(`Malformed $bytes field on ${value}`);
}
return Base64.toByteArray(value.$bytes).buffer;
}
if (key === "$integer") {
if (typeof value.$integer !== "string") {
throw new Error(`Malformed $integer field on ${value}`);
}
return base64ToBigInt(value.$integer);
}
if (key === "$float") {
if (typeof value.$float !== "string") {
throw new Error(`Malformed $float field on ${value}`);
}
const floatBytes = Base64.toByteArray(value.$float);
if (floatBytes.byteLength !== 8) {
throw new Error(
`Received ${floatBytes.byteLength} bytes, expected 8 for $float`
);
}
const floatBytesView = new DataView(floatBytes.buffer);
const float = floatBytesView.getFloat64(0, LITTLE_ENDIAN);
if (!isSpecial(float)) {
throw new Error(`Float ${float} should be encoded as a number`);
}
return float;
}
if (key === "$set") {
throw new Error(
`Received a Set which is no longer supported as a Convex type.`
);
}
if (key === "$map") {
throw new Error(
`Received a Map which is no longer supported as a Convex type.`
);
}
}
const out = {};
for (const [k, v] of Object.entries(value)) {
validateObjectField(k);
out[k] = jsonToConvex(v);
}
return out;
}
const MAX_VALUE_FOR_ERROR_LEN = 16384;
function stringifyValueForError(value) {
const str = JSON.stringify(value, (_key, value2) => {
if (value2 === void 0) {
return "undefined";
}
if (typeof value2 === "bigint") {
return `${value2.toString()}n`;
}
return value2;
});
if (str.length > MAX_VALUE_FOR_ERROR_LEN) {
const rest = "[...truncated]";
let truncateAt = MAX_VALUE_FOR_ERROR_LEN - rest.length;
const codePoint = str.codePointAt(truncateAt - 1);
if (codePoint !== void 0 && codePoint > 65535) {
truncateAt -= 1;
}
return str.substring(0, truncateAt) + rest;
}
return str;
}
function convexToJsonInternal(value, originalValue, context, includeTopLevelUndefined) {
if (value === void 0) {
const contextText = context && ` (present at path ${context} in original object ${stringifyValueForError(
originalValue
)})`;
throw new Error(
`undefined is not a valid Convex value${contextText}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`
);
}
if (value === null) {
return value;
}
if (typeof value === "bigint") {
if (value < MIN_INT64 || MAX_INT64 < value) {
throw new Error(
`BigInt ${value} does not fit into a 64-bit signed integer.`
);
}
return { $integer: bigIntToBase64(value) };
}
if (typeof value === "number") {
if (isSpecial(value)) {
const buffer = new ArrayBuffer(8);
new DataView(buffer).setFloat64(0, value, LITTLE_ENDIAN);
return { $float: Base64.fromByteArray(new Uint8Array(buffer)) };
} else {
return value;
}
}
if (typeof value === "boolean") {
return value;
}
if (typeof value === "string") {
return value;
}
if (value instanceof ArrayBuffer) {
return { $bytes: Base64.fromByteArray(new Uint8Array(value)) };
}
if (Array.isArray(value)) {
return value.map(
(value2, i) => convexToJsonInternal(value2, originalValue, context + `[${i}]`, false)
);
}
if (value instanceof Set) {
throw new Error(
errorMessageForUnsupportedType(context, "Set", [...value], originalValue)
);
}
if (value instanceof Map) {
throw new Error(
errorMessageForUnsupportedType(context, "Map", [...value], originalValue)
);
}
if (!(0, import_common.isSimpleObject)(value)) {
const theType = value?.constructor?.name;
const typeName = theType ? `${theType} ` : "";
throw new Error(
errorMessageForUnsupportedType(context, typeName, value, originalValue)
);
}
const out = {};
const entries = Object.entries(value);
entries.sort(([k1, _v1], [k2, _v2]) => k1 === k2 ? 0 : k1 < k2 ? -1 : 1);
for (const [k, v] of entries) {
if (v !== void 0) {
validateObjectField(k);
out[k] = convexToJsonInternal(v, originalValue, context + `.${k}`, false);
} else if (includeTopLevelUndefined) {
validateObjectField(k);
out[k] = convexOrUndefinedToJsonInternal(
v,
originalValue,
context + `.${k}`
);
}
}
return out;
}
function errorMessageForUnsupportedType(context, typeName, value, originalValue) {
if (context) {
return `${typeName}${stringifyValueForError(
value
)} is not a supported Convex type (present at path ${context} in original object ${stringifyValueForError(
originalValue
)}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`;
} else {
return `${typeName}${stringifyValueForError(
value
)} is not a supported Convex type.`;
}
}
function convexOrUndefinedToJsonInternal(value, originalValue, context) {
if (value === void 0) {
return { $undefined: null };
} else {
if (originalValue === void 0) {
throw new Error(
`Programming error. Current value is ${stringifyValueForError(
value
)} but original value is undefined`
);
}
return convexToJsonInternal(value, originalValue, context, false);
}
}
function convexToJson(value) {
return convexToJsonInternal(value, value, "", false);
}
function convexOrUndefinedToJson(value) {
return convexOrUndefinedToJsonInternal(value, value, "");
}
function patchValueToJson(value) {
return convexToJsonInternal(value, value, "", true);
}
//# sourceMappingURL=value.js.map