fix(voip-push): dynamic import @parse/node-apn — nitro bundler bricht statisches Tracing (Class extends Module-namespace)
This commit is contained in:
parent
57e0a23021
commit
848b517d22
@ -10,15 +10,13 @@ export default defineNitroConfig({
|
|||||||
// Default-publicAssets greift nicht zuverlässig wenn srcDir auf "server" zeigt.
|
// Default-publicAssets greift nicht zuverlässig wenn srcDir auf "server" zeigt.
|
||||||
publicAssets: [{ baseURL: "/", dir: "../public", maxAge: 60 * 60 }],
|
publicAssets: [{ baseURL: "/", dir: "../public", maxAge: 60 * 60 }],
|
||||||
|
|
||||||
// Supabase + @parse/node-apn + imapflow als external deps — nicht bundlen.
|
// Supabase + imapflow als external deps — nicht bundlen.
|
||||||
// node-apn + imapflow nutzen CJS-extends/inherits-Patterns, die brechen beim
|
// imapflow nutzt CJS-inherits-Pattern, bricht beim Bundlen zu ESM
|
||||||
// Bundlen zu ESM ("Class extends value [object Module] is not a constructor
|
// ("superCtor.prototype must be of type object"). @parse/node-apn wird
|
||||||
// or null" / "superCtor.prototype must be of type object"). Müssen als externe
|
// in services/voip-push.ts via dynamic import geladen (vermeidet das gleiche
|
||||||
// node_modules-Requires bleiben.
|
// Problem ohne Externalize-Eintrag).
|
||||||
externals: {
|
externals: {
|
||||||
inline: [
|
inline: [/^(?!@supabase\/supabase-js)(?!imapflow)/],
|
||||||
/^(?!@supabase\/supabase-js)(?!@parse\/node-apn)(?!imapflow)/,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
|
|
||||||
imports: {
|
imports: {
|
||||||
|
|||||||
@ -17,14 +17,22 @@
|
|||||||
* Wenn ENV-Vars fehlen: Service no-op (kein Error, nur Log-Warnung beim ersten Send).
|
* Wenn ENV-Vars fehlen: Service no-op (kein Error, nur Log-Warnung beim ersten Send).
|
||||||
* → Macht reguläre Pushes nicht kaputt wenn das VoIP-Setup noch unfertig ist.
|
* → Macht reguläre Pushes nicht kaputt wenn das VoIP-Setup noch unfertig ist.
|
||||||
*/
|
*/
|
||||||
import apn from "@parse/node-apn";
|
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
|
|
||||||
let provider: apn.Provider | null = null;
|
// node-apn dynamisch laden (await import statt static import). Grund: nitro/rollup
|
||||||
|
// bricht beim Bundlen von node-apn → undici → `Class extends value [object Module]`
|
||||||
|
// at push.mjs. Dynamic import wird nicht statisch getraced, lädt Modul zur Laufzeit
|
||||||
|
// aus node_modules wo es korrekt als CJS funktioniert.
|
||||||
|
type ApnModule = typeof import("@parse/node-apn");
|
||||||
|
type ApnProvider = InstanceType<ApnModule["Provider"]>;
|
||||||
|
type ApnNotification = InstanceType<ApnModule["Notification"]>;
|
||||||
|
|
||||||
|
let apnMod: ApnModule | null = null;
|
||||||
|
let provider: ApnProvider | null = null;
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
let topic: string | null = null;
|
let topic: string | null = null;
|
||||||
|
|
||||||
function getProvider(): apn.Provider | null {
|
async function getProvider(): Promise<ApnProvider | null> {
|
||||||
if (initialized) return provider;
|
if (initialized) return provider;
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
@ -45,8 +53,13 @@ function getProvider(): apn.Provider | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Dynamic import — vermeidet bundler statisches Tracing.
|
||||||
|
const mod = (await import("@parse/node-apn")) as unknown as ApnModule & {
|
||||||
|
default?: ApnModule;
|
||||||
|
};
|
||||||
|
apnMod = mod.default ?? mod;
|
||||||
topic = tpc;
|
topic = tpc;
|
||||||
provider = new apn.Provider({
|
provider = new apnMod.Provider({
|
||||||
pfx: p12Path,
|
pfx: p12Path,
|
||||||
passphrase: p12Pass,
|
passphrase: p12Pass,
|
||||||
production,
|
production,
|
||||||
@ -84,10 +97,10 @@ export interface VoIPCallPayload {
|
|||||||
* @returns true bei Erfolg (oder no-op wenn Service disabled), false bei Fehler.
|
* @returns true bei Erfolg (oder no-op wenn Service disabled), false bei Fehler.
|
||||||
*/
|
*/
|
||||||
export async function sendVoIPPush(payload: VoIPCallPayload): Promise<boolean> {
|
export async function sendVoIPPush(payload: VoIPCallPayload): Promise<boolean> {
|
||||||
const p = getProvider();
|
const p = await getProvider();
|
||||||
if (!p || !topic) return true; // no-op, regulärer Push übernimmt
|
if (!p || !topic || !apnMod) return true; // no-op, regulärer Push übernimmt
|
||||||
|
|
||||||
const note = new apn.Notification();
|
const note: ApnNotification = new apnMod.Notification();
|
||||||
note.topic = topic;
|
note.topic = topic;
|
||||||
note.expiry = 0; // sofort verwerfen wenn Device unreachable
|
note.expiry = 0; // sofort verwerfen wenn Device unreachable
|
||||||
note.priority = 10;
|
note.priority = 10;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user