import * as plugins from '../../plugins.js'; import { DcRouterDb } from '../classes.dcrouter-db.js'; import type { IWebPushEncryptedEnvelope } from '../../webpush/classes.webpush-crypto.js'; const getDb = () => DcRouterDb.getInstance().getDb(); @plugins.smartdata.Collection(() => getDb()) export class WebPushSpoolDoc extends plugins.smartdata.SmartDataDbDoc< WebPushSpoolDoc, WebPushSpoolDoc > { @plugins.smartdata.svDb() public id!: string; @plugins.smartdata.svDb() public schemaVersion: 1 = 1; @plugins.smartdata.svDb() public bindingId!: string; @plugins.smartdata.svDb() public lifecycleGeneration!: number; /** Credential that created this item; used only for the idempotency namespace. */ @plugins.smartdata.svDb() public credentialId!: string; @plugins.smartdata.svDb() public hmacKeyId!: string; @plugins.smartdata.svDb() public idempotencyKeyDigest!: string; @plugins.smartdata.svDb() public requestDigest!: string; @plugins.smartdata.svDb() public subscriptionId!: string; @plugins.smartdata.svDb() public endpointDigest!: string; @plugins.smartdata.svDb() public vapidKeyId!: string; @plugins.smartdata.svDb() public subscriptionEnvelope?: IWebPushEncryptedEnvelope; @plugins.smartdata.svDb() public payloadEnvelope?: IWebPushEncryptedEnvelope; @plugins.smartdata.svDb() public payloadBytes!: number; @plugins.smartdata.svDb() public ttlSeconds!: number; @plugins.smartdata.svDb() public urgency!: plugins.servezoneInterfaces.data.TWebPushUrgency; @plugins.smartdata.svDb() public topic: string | null = null; @plugins.smartdata.svDb() public state!: plugins.servezoneInterfaces.data.TWebPushDeliveryState; @plugins.smartdata.svDb() public attempts: number = 0; @plugins.smartdata.svDb() public acceptedAt!: number; @plugins.smartdata.svDb() public updatedAt!: number; @plugins.smartdata.svDb() public nextAttemptAt!: number; @plugins.smartdata.svDb() public expiresAt!: number; /** MUST BE ABSENT while the item is not leased. */ @plugins.smartdata.svDb() public leaseToken?: string; /** MUST BE ABSENT while the item is not leased. */ @plugins.smartdata.svDb() public leaseExpiresAt?: number; /** MUST BE ABSENT until cancellation races with an in-flight send. */ @plugins.smartdata.svDb() public cancelRequestedAt?: number; /** MUST BE ABSENT until an in-flight cancellation records its terminal reason. */ @plugins.smartdata.svDb() public cancelErrorCode?: string; /** MUST BE ABSENT before a terminal transition. */ @plugins.smartdata.svDb() public terminalAt?: number; @plugins.smartdata.svDb() public pushServiceStatusCode: number | null = null; @plugins.smartdata.svDb() public errorCode: string | null = null; /** MUST BE ABSENT until terminal retention begins. */ @plugins.smartdata.svDb() public purgeAt?: Date; public static getNativeCollection(): plugins.smartdata.SmartdataCollection['mongoDbCollection'] { return getDb().mongoDb.collection('WebPushSpoolDoc'); } public override async createSavableObject(): Promise { const savable = await super.createSavableObject(); for (const field of [ 'subscriptionEnvelope', 'payloadEnvelope', 'leaseToken', 'leaseExpiresAt', 'cancelRequestedAt', 'cancelErrorCode', 'terminalAt', 'purgeAt', ] as const) { if (savable[field] === undefined) delete savable[field]; } savable.topic = savable.topic ?? null; savable.pushServiceStatusCode = savable.pushServiceStatusCode ?? null; savable.errorCode = savable.errorCode ?? null; return savable; } }