@react-native-oh-tpl/realm
Version:
Realm by MongoDB is an offline-first mobile database: an alternative to SQLite and key-value stores
142 lines • 6.59 kB
JavaScript
;
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2024 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMixedTypeHelpers = exports.mixedToBinding = void 0;
const binding_1 = require("../binding");
const assert_1 = require("../assert");
const indirect_1 = require("../indirect");
const Dictionary_1 = require("../collection-accessors/Dictionary");
const List_1 = require("../collection-accessors/List");
const GeoSpatial_1 = require("../GeoSpatial");
const Counter_1 = require("../Counter");
const TypeHelpers_1 = require("../TypeHelpers");
const symbols_1 = require("../symbols");
const array_buffer_1 = require("./array-buffer");
// TODO: Consider testing for expected object instance types and throw something similar to the legacy SDK:
// "Only Realm instances are supported." (which should probably have been "RealmObject")
// instead of relying on the binding to throw.
/**
* Convert an SDK value to a Binding value representation.
* @param realm The Realm used.
* @param value The value to convert.
* @param options Options needed.
* @param options.isQueryArg Whether the value to convert is a query argument used
* for `OrderedCollection.filtered()`. If so, this will be validated differently.
* @returns The `MixedArg` binding representation.
* @internal
*/
function mixedToBinding(realm, value, { isQueryArg } = { isQueryArg: false }) {
const displayedType = isQueryArg ? "a query argument" : "a Mixed value";
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) {
// Fast track pass through for the most commonly used types
return value;
}
else if (value === undefined) {
return null;
}
else if (value instanceof Date) {
return binding_1.binding.Timestamp.fromDate(value);
}
else if (value instanceof indirect_1.indirect.Object) {
if (value.objectSchema().embedded) {
throw new Error(`Using an embedded object (${value.constructor.name}) as ${displayedType} is not supported.`);
}
const otherRealm = value[symbols_1.OBJECT_REALM].internal;
assert_1.assert.isSameRealm(realm, otherRealm, "Realm object is from another Realm");
return value[symbols_1.OBJECT_INTERNAL];
}
else if (value instanceof indirect_1.indirect.Set || value instanceof Set) {
throw new Error(`Using a ${value.constructor.name} as ${displayedType} is not supported.`);
}
else if (value instanceof Counter_1.Counter) {
let errMessage = `Using a Counter as ${displayedType} is not supported.`;
errMessage += isQueryArg ? " Use 'Counter.value'." : "";
throw new Error(errMessage);
}
else {
if (isQueryArg) {
if (value instanceof indirect_1.indirect.Collection || Array.isArray(value)) {
throw new Error(`Using a ${value.constructor.name} as a query argument is not supported.`);
}
// Geospatial types can currently only be used when querying and
// are not yet supported as standalone data types in the schema.
if (typeof value === "object") {
if ((0, GeoSpatial_1.isGeoCircle)(value)) {
return (0, GeoSpatial_1.circleToBindingGeospatial)(value);
}
else if ((0, GeoSpatial_1.isGeoBox)(value)) {
return (0, GeoSpatial_1.boxToBindingGeospatial)(value);
}
else if ((0, GeoSpatial_1.isGeoPolygon)(value)) {
return (0, GeoSpatial_1.polygonToBindingGeospatial)(value);
}
}
}
// Convert typed arrays to an `ArrayBuffer`
for (const TypedArray of array_buffer_1.TYPED_ARRAY_CONSTRUCTORS) {
if (value instanceof TypedArray) {
return value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);
}
}
// Rely on the binding for any other value
return value;
}
}
exports.mixedToBinding = mixedToBinding;
/** @internal */
function mixedFromBinding(options, value) {
const { realm, getClassHelpers } = options;
if (binding_1.binding.Int64.isInt(value)) {
return binding_1.binding.Int64.intToNum(value);
}
else if (value instanceof binding_1.binding.Timestamp) {
return value.toDate();
}
else if (value instanceof binding_1.binding.Float) {
return value.value;
}
else if (value instanceof binding_1.binding.ObjLink) {
const table = binding_1.binding.Helpers.getTable(realm.internal, value.tableKey);
const linkedObj = table.getObject(value.objKey);
const { wrapObject } = getClassHelpers(value.tableKey);
return wrapObject(linkedObj);
}
else if (value instanceof binding_1.binding.List) {
const mixedType = 9 /* binding.PropertyType.Mixed */;
const typeHelpers = (0, TypeHelpers_1.getTypeHelpers)(mixedType, options);
return new indirect_1.indirect.List(realm, value, (0, List_1.createListAccessor)({ realm, typeHelpers, itemType: mixedType }), typeHelpers);
}
else if (value instanceof binding_1.binding.Dictionary) {
const mixedType = 9 /* binding.PropertyType.Mixed */;
const typeHelpers = (0, TypeHelpers_1.getTypeHelpers)(mixedType, options);
return new indirect_1.indirect.Dictionary(realm, value, (0, Dictionary_1.createDictionaryAccessor)({ realm, typeHelpers, itemType: mixedType }), typeHelpers);
}
else {
return value;
}
}
/** @internal */
function createMixedTypeHelpers(options) {
return {
toBinding: mixedToBinding.bind(null, options.realm.internal),
fromBinding: mixedFromBinding.bind(null, options),
};
}
exports.createMixedTypeHelpers = createMixedTypeHelpers;
//# sourceMappingURL=Mixed.js.map