UNPKG

@mathrunet/masamune

Version:

Manages packages for the server portion (NodeJS) of the Masamune framework.

297 lines 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FirestoreModelTimestampConverter = exports.ModelTimestampConverter = void 0; exports.createTimestampFromMicroseconds = createTimestampFromMicroseconds; const model_field_value_converter_1 = require("../model_field_value_converter"); const utils_1 = require("../../utils"); const firestore_1 = require("firebase-admin/firestore"); const firestore_2 = require("@google-cloud/firestore"); const model_field_value_1 = require("../model_field_value"); /** * ModelTimestamp ModelFieldValueConverter. * * ModelTimestamp用のModelFieldValueConverter。 */ class ModelTimestampConverter extends model_field_value_converter_1.ModelFieldValueConverter { /** * ModelTimestamp ModelFieldValueConverter. * * ModelTimestamp用のModelFieldValueConverter。 */ constructor() { super(); } type = "ModelTimestamp"; convertFrom(key, value, original) { // Skip if already a ModelTimestamp instance (e.g., from FirestoreConverter) if (value instanceof model_field_value_1.ModelTimestamp) { return { [key]: value }; } if (value !== null && typeof value === "object" && "@type" in value && value["@type"] === this.type) { const time = value["@time"] ?? 0; return { [key]: new model_field_value_1.ModelTimestamp(new Date(time / 1000.0), "server"), }; } return null; } convertTo(key, value, original) { if (value instanceof model_field_value_1.ModelTimestamp) { // Pass through ModelTimestamp instance as-is; FirestoreConverter will handle it return { [key]: value }; } return null; } } exports.ModelTimestampConverter = ModelTimestampConverter; /** * Create Timestamp from microseconds. * * マイクロ秒からTimestampを作成します。 * * @param microseconds * Microseconds. * * マイクロ秒。 * * @returns {Timestamp} * Timestamp. * * Timestamp。 */ function createTimestampFromMicroseconds(microseconds) { if (microseconds >= 0) { return firestore_1.Timestamp.fromMillis(microseconds / 1000); } const seconds = Math.floor(microseconds / 1000000); const remainingMicros = microseconds - (seconds * 1000000); const nanoseconds = remainingMicros * 1000; if (nanoseconds < 0) { return new firestore_1.Timestamp(seconds - 1, nanoseconds + 1000000000); } return new firestore_1.Timestamp(seconds, nanoseconds); } /** * FirestoreConverter for [ModelTimestamp]. * * [ModelTimestamp]用のFirestoreConverter。 */ class FirestoreModelTimestampConverter extends model_field_value_converter_1.FirestoreModelFieldValueConverter { /** * FirestoreConverter for [ModelTimestamp]. * * [ModelTimestamp]用のFirestoreConverter。 */ constructor() { super(); } type = "ModelTimestamp"; convertFrom(key, value, original, firestoreInstance) { if (typeof value === "number") { const targetKey = `#${key}`; const targetMap = original[targetKey] ?? {}; const type = targetMap["@type"] ?? ""; if (type == this.type) { return { [key]: { "@type": this.type, "@time": value * 1000, // Convert milliseconds to microseconds "@now": false, "@source": "server" }, [targetKey]: null, }; } } else if (value instanceof firestore_1.Timestamp) { const targetKey = `#${key}`; const targetMap = original[targetKey] ?? {}; const type = targetMap["@type"] ?? ""; // Convert Timestamp to ModelTimestamp even without metadata (type === "") if (type == this.type || type === "") { // Return a proper ModelTimestamp instance so .value() works const instance = new model_field_value_1.ModelTimestamp(undefined, "server"); instance["@time"] = value.toMillis() * 1000; // Store microseconds for .value() to work correctly return { [key]: instance, [targetKey]: null, }; } } else if (Array.isArray(value)) { const targetKey = `#${key}`; const targetList = original[targetKey] ?? []; if (targetList != null && targetList.length > 0 && targetList.every((e) => e["@type"] === this.type)) { const res = []; for (const tmp of value) { if (typeof tmp === "number") { res.push({ "@type": this.type, "@time": tmp * 1000, // Convert milliseconds to microseconds "@now": false, "@source": "server" }); } else if (tmp instanceof firestore_1.Timestamp) { res.push({ "@type": this.type, "@time": tmp.toMillis() * 1000, // Convert milliseconds to microseconds "@now": false, "@source": "server" }); } } if (res.length > 0) { return { [key]: res, [targetKey]: null, }; } } } else if ((0, utils_1.isDynamicMap)(value)) { const targetKey = `#${key}`; const targetMap = original[targetKey] ?? {}; targetMap; if (targetMap != null) { const res = {}; for (const key in value) { const val = value[key]; const mapVal = targetMap[key] ?? {}; const type = mapVal["@type"] ?? ""; if (type != this.type) { continue; } if (typeof val === "number") { res[key] = { "@type": this.type, "@time": val * 1000, // Convert milliseconds to microseconds "@now": false, "@source": "server" }; } else if (val instanceof firestore_1.Timestamp) { res[key] = { "@type": this.type, "@time": val.toMillis() * 1000, // Convert milliseconds to microseconds "@now": false, "@source": "server" }; } } if (Object.keys(res).length > 0) { return { [key]: res, [targetKey]: null, }; } } } return null; } convertTo(key, value, _original, firestoreInstance) { if (value !== null && typeof value === "object" && "@type" in value) { const type = value["@type"] ?? ""; if (type === this.type) { const fromUser = (value["@source"] ?? "") === "user"; const val = value["@time"] ?? 0; const useNow = value["@now"] ?? false; const targetKey = `#${key}`; const result = { [targetKey]: { "@type": this.type, "@time": val, "@target": key, }, }; if (fromUser) { if (useNow) { result[key] = firestore_2.FieldValue.serverTimestamp(); } else { result[key] = createTimestampFromMicroseconds(val); } } else { result[key] = createTimestampFromMicroseconds(val); } return result; } } else if (Array.isArray(value)) { const list = value.filter((e) => e != null && typeof e === "object" && "@type" in e); if (list.length > 0 && list.every((e) => e["@type"] === this.type)) { const target = []; const res = []; const targetKey = `#${key}`; for (const entry of list) { const fromUser = (entry["@source"] ?? "") === "user"; const time = entry["@time"] ?? 0; const useNow = entry["@now"] ?? false; target.push({ "@type": this.type, "@time": time, "@target": key, }); if (fromUser) { if (useNow) { res.push(firestore_2.FieldValue.serverTimestamp()); } else { res.push(createTimestampFromMicroseconds(time)); } } else { res.push(createTimestampFromMicroseconds(time)); } } return { [targetKey]: target, [key]: res, }; } } else if ((0, utils_1.isDynamicMap)(value)) { const map = {}; for (const k in value) { const v = value[k]; if (v != null && typeof v === "object" && "@type" in v) { map[k] = v; } } if (Object.keys(map).length > 0 && Object.values(map).every((e) => e["@type"] === this.type)) { const target = {}; const res = {}; const targetKey = `#${key}`; for (const [k, entry] of Object.entries(map)) { const fromUser = (entry["@source"] ?? "") === "user"; const time = entry["@time"] ?? 0; const useNow = entry["@now"] ?? false; target[k] = { "@type": this.type, "@time": time, "@target": key, }; if (fromUser) { if (useNow) { res[k] = firestore_2.FieldValue.serverTimestamp(); } else { res[k] = createTimestampFromMicroseconds(time); } } else { res[k] = createTimestampFromMicroseconds(time); } } return { [targetKey]: target, [key]: res, }; } } return null; } } exports.FirestoreModelTimestampConverter = FirestoreModelTimestampConverter; //# sourceMappingURL=model_timestamp_converter.js.map