@flowselections/layout-maker 1.59.2 → 1.62.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist-lib/components/LivePrintstatusRegel.d.ts.map +1 -1
  2. package/dist-lib/components/LivePrintstatusRegel.js +29 -29
  3. package/dist-lib/components/PrintInstallatiesBlok.d.ts +3 -0
  4. package/dist-lib/components/PrintInstallatiesBlok.d.ts.map +1 -0
  5. package/dist-lib/components/PrintInstallatiesBlok.js +29 -0
  6. package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
  7. package/dist-lib/components/PrintQueuePage.js +27 -8
  8. package/dist-lib/components/PrintStatusBanner.d.ts.map +1 -1
  9. package/dist-lib/components/PrintStatusBanner.js +3 -1
  10. package/dist-lib/components/PrintenInstellenWizard.d.ts.map +1 -1
  11. package/dist-lib/components/PrintenInstellenWizard.js +14 -1
  12. package/dist-lib/components/PrintplekDetailPage.d.ts.map +1 -1
  13. package/dist-lib/components/PrintplekDetailPage.js +18 -5
  14. package/dist-lib/components/WerkplekOmzettingStap.d.ts.map +1 -1
  15. package/dist-lib/components/WerkplekOmzettingStap.js +2 -1
  16. package/dist-lib/components/WerkplekkenTab.d.ts.map +1 -1
  17. package/dist-lib/components/WerkplekkenTab.js +27 -3
  18. package/dist-lib/index.d.ts +2 -0
  19. package/dist-lib/index.d.ts.map +1 -1
  20. package/dist-lib/index.js +5 -3
  21. package/dist-lib/integrations/supabase/types.d.ts +441 -0
  22. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  23. package/dist-lib/lib/computerKoppeling.d.ts +47 -0
  24. package/dist-lib/lib/computerKoppeling.d.ts.map +1 -0
  25. package/dist-lib/lib/computerKoppeling.js +48 -0
  26. package/dist-lib/lib/etiketControle.d.ts +8 -0
  27. package/dist-lib/lib/etiketControle.d.ts.map +1 -1
  28. package/dist-lib/lib/etiketControle.js +7 -2
  29. package/dist-lib/lib/foutTekst.d.ts +6 -0
  30. package/dist-lib/lib/foutTekst.d.ts.map +1 -1
  31. package/dist-lib/lib/foutTekst.js +46 -16
  32. package/dist-lib/lib/layoutVerwijzingen.js +1 -1
  33. package/dist-lib/lib/printApi.d.ts +1 -1
  34. package/dist-lib/lib/printApi.d.ts.map +1 -1
  35. package/dist-lib/lib/printApi.js +5 -4
  36. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  37. package/dist-lib/lib/printQueue.server.js +16 -2
  38. package/dist-lib/lib/printService.functions.d.ts +129 -0
  39. package/dist-lib/lib/printService.functions.d.ts.map +1 -1
  40. package/dist-lib/lib/printService.functions.js +113 -2
  41. package/dist-lib/lib/printnodeStatus.d.ts +1 -0
  42. package/dist-lib/lib/printnodeStatus.d.ts.map +1 -1
  43. package/dist-lib/lib/printnodeStatus.js +4 -2
  44. package/dist-lib/lib/printnodeWebhook.d.ts +12 -0
  45. package/dist-lib/lib/printnodeWebhook.d.ts.map +1 -1
  46. package/dist-lib/lib/printnodeWebhook.js +27 -1
  47. package/dist-lib/lib/printplekken.d.ts +3 -1
  48. package/dist-lib/lib/printplekken.d.ts.map +1 -1
  49. package/dist-lib/lib/printplekken.js +6 -3
  50. package/dist-lib/lib/queueTick.d.ts.map +1 -1
  51. package/dist-lib/lib/queueTick.js +9 -0
  52. package/dist-lib/lib/runnerRegistry.server.d.ts +5 -0
  53. package/dist-lib/lib/runnerRegistry.server.d.ts.map +1 -1
  54. package/dist-lib/lib/runnerRegistry.server.js +22 -1
  55. package/dist-lib/lib/shellPoort.d.ts +21 -0
  56. package/dist-lib/lib/shellPoort.d.ts.map +1 -0
  57. package/dist-lib/lib/shellPoort.js +43 -0
  58. package/package.json +1 -1
@@ -243,10 +243,11 @@ export const webhookStatus = createServerFn({ method: "POST" })
243
243
  const { leesKoppeling, veiligeStatus } = await import("./printnodeWebhookBeheer.server.js");
244
244
  const { data: m } = await supabaseAdmin
245
245
  .from("printnode_webhook_meldingen")
246
- .select("ontvangen_op, http_status, soorten, printnode_ids, gematcht, niet_gematcht")
246
+ .select("ontvangen_op, http_status, soorten, printnode_ids, gematcht, niet_gematcht, antwoord")
247
247
  .order("id", { ascending: false })
248
248
  .limit(5);
249
- const meldingen = (Array.isArray(m) ? m : []);
249
+ const { meldingWeergave } = await import("./printnodeWebhook.js");
250
+ const meldingen = (Array.isArray(m) ? m : []).map(({ antwoord, ...r }) => ({ ...r, weergave: meldingWeergave({ ...r, antwoord }) }));
250
251
  return { ok: true, ...veiligeStatus(await leesKoppeling(supabaseAdmin)), meldingen };
251
252
  }
252
253
  catch (e) {
@@ -273,3 +274,113 @@ export const webhookOpnieuwKoppelen = createServerFn({ method: "POST" })
273
274
  const u = await koppelWebhook(supabaseAdmin, { oorsprong });
274
275
  return u.ok ? { ok: true } : { ok: false, reden: u.reden ?? "Koppelen mislukt." };
275
276
  });
277
+ /**
278
+ * Printinstallaties en of de Shell print. Alleen beheerders zien de lijst;
279
+ * iedereen ziet de stilstandmelding.
280
+ */
281
+ export const printInstallaties = createServerFn({ method: "POST" })
282
+ .middleware([requireSupabaseAuth])
283
+ .handler(async ({ context }) => {
284
+ const ctx = context;
285
+ const { supabaseAdmin } = await import("../integrations/supabase/client.server.js");
286
+ const { maskeerAdres, normaliseerAdres } = await import("./shellPoort.js");
287
+ const db = supabaseAdmin;
288
+ const { data: cfg } = await db.from("module_runtime_config").select("value").eq("key", "shell_base_url").maybeSingle();
289
+ const shell = normaliseerAdres(cfg?.value);
290
+ const { data: r } = await db
291
+ .from("print_queue_runners")
292
+ .select("basis_url, module_versie, laatst_gezien, laatste_ok, actief, created_at")
293
+ .order("laatst_gezien", { ascending: false });
294
+ const runners = (Array.isArray(r) ? r : []);
295
+ const shellRij = shell ? runners.find((x) => normaliseerAdres(x.basis_url) === shell) ?? null : null;
296
+ const grens = Date.now() - 5 * 60 * 1000;
297
+ const shellLaatst = shellRij ? shellRij.laatste_ok ?? shellRij.created_at : null;
298
+ const stil = !shell
299
+ ? { stil: true, reden: "geen_shell_adres", sinds: null }
300
+ : !shellRij
301
+ ? { stil: true, reden: "shell_niet_aangemeld", sinds: null }
302
+ : shellLaatst && new Date(shellLaatst).getTime() < grens
303
+ ? { stil: true, reden: "shell_reageert_niet", sinds: shellLaatst }
304
+ : { stil: false, reden: null, sinds: null };
305
+ const rollen = await Promise.all(["admin", "superadmin", "developer"].map((rol) => ctx.supabase.rpc("has_role", { _user_id: ctx.userId, _role: rol }).then((x) => x.data === true)));
306
+ if (!rollen.some(Boolean))
307
+ return { ok: true, beheer: false, ...stil, installaties: [] };
308
+ const sinds = new Date(Date.now() - 7 * 86400000).toISOString();
309
+ const installaties = await Promise.all(runners.map(async (x) => {
310
+ const { count } = await db
311
+ .from("print_jobs")
312
+ .select("id", { count: "exact", head: true })
313
+ .eq("verwerkt_door_runner", x.basis_url)
314
+ .gte("created_at", sinds);
315
+ return {
316
+ adres: maskeerAdres(x.basis_url),
317
+ versie: x.module_versie,
318
+ laatstActief: x.laatst_gezien,
319
+ actief: x.actief,
320
+ isShell: !!shell && normaliseerAdres(x.basis_url) === shell,
321
+ opdrachten7d: count ?? 0,
322
+ };
323
+ }));
324
+ return { ok: true, beheer: true, ...stil, installaties };
325
+ });
326
+ // ---------------------------------------------------------------------------
327
+ // Computers koppelen op PrintNode-id
328
+ // ---------------------------------------------------------------------------
329
+ async function isBeheerderCtx(ctx) {
330
+ const rollen = await Promise.all(["admin", "superadmin", "developer"].map((rol) => ctx.supabase.rpc("has_role", { _user_id: ctx.userId, _role: rol }).then((x) => x.data === true)));
331
+ return rollen.some(Boolean);
332
+ }
333
+ /** Stap A: alleen lezen. Voorstel per printplek-computer. */
334
+ export const computerKoppelVoorstel = createServerFn({ method: "POST" })
335
+ .middleware([requireSupabaseAuth])
336
+ .handler(async ({ context }) => {
337
+ const ctx = context;
338
+ const { haalComputers } = await import("./printService.server.js");
339
+ const { maakKoppelVoorstel } = await import("./computerKoppeling.js");
340
+ let live;
341
+ try {
342
+ live = await haalComputers();
343
+ }
344
+ catch (e) {
345
+ return { ok: false, fout: e instanceof Error ? e.message : "Computers ophalen mislukt", rijen: [] };
346
+ }
347
+ const { data, error } = await ctx.supabase
348
+ .from("print_plek_computers")
349
+ .select("id, print_plek_id, computer_naam, printnode_computer_id");
350
+ if (error)
351
+ return { ok: false, fout: error.message, rijen: [] };
352
+ return { ok: true, rijen: maakKoppelVoorstel(Array.isArray(data) ? data : [], live) };
353
+ });
354
+ /**
355
+ * Koppelt één printplek-computer aan een PrintNode-id (stap B per rij, of de
356
+ * knop "Koppelen"). Controleert live dat het id bestaat en dezelfde naam heeft.
357
+ */
358
+ export const koppelComputerOpId = createServerFn({ method: "POST" })
359
+ .middleware([requireSupabaseAuth])
360
+ .inputValidator((d) => ({
361
+ rijId: String(d?.rijId ?? ""),
362
+ printnodeId: String(d?.printnodeId ?? ""),
363
+ }))
364
+ .handler(async ({ context, data }) => {
365
+ const ctx = context;
366
+ if (!(await isBeheerderCtx(ctx)))
367
+ return { ok: false, fout: "Alleen een beheerder kan computers koppelen." };
368
+ if (!data.rijId || !/^\d+$/.test(data.printnodeId))
369
+ return { ok: false, fout: "Ongeldige computer." };
370
+ const { haalComputers } = await import("./printService.server.js");
371
+ const live = await haalComputers();
372
+ const pc = live.find((c) => String(c.id) === data.printnodeId);
373
+ if (!pc)
374
+ return { ok: false, fout: "Deze computer is niet (meer) bekend bij de printdienst." };
375
+ const { data: rij } = await ctx.supabase
376
+ .from("print_plek_computers").select("computer_naam").eq("id", data.rijId).maybeSingle();
377
+ if (!rij)
378
+ return { ok: false, fout: "Deze computer staat niet op een printplek." };
379
+ if (String(rij.computer_naam).trim() !== pc.naam.trim())
380
+ return { ok: false, fout: "De naam in de printdienst komt niet overeen. Koppel opnieuw via Computer toevoegen." };
381
+ const { error } = await ctx.supabase
382
+ .from("print_plek_computers").update({ printnode_computer_id: Number(pc.id) }).eq("id", data.rijId);
383
+ if (error)
384
+ return { ok: false, fout: /duplicate|unique/i.test(error.message) ? "Deze computer is al aan een andere printplek gekoppeld." : error.message };
385
+ return { ok: true };
386
+ });
@@ -3,6 +3,7 @@ interface JobVoorLabel {
3
3
  status: string;
4
4
  printnode_status?: string | null;
5
5
  foutcode?: string | null;
6
+ foutmelding?: string | null;
6
7
  }
7
8
  /** Label voor de statuskolom van de wachtrij. */
8
9
  export declare function printnodeStatusLabel(j: JobVoorLabel): string;
@@ -1 +1 @@
1
- {"version":3,"file":"printnodeStatus.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeStatus.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMzD,CAAC;AAEF,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAa5D;AAED,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,aAAsD,CAAC;AAEpF,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,IAAI,CAI3F;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAI/G"}
1
+ {"version":3,"file":"printnodeStatus.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeStatus.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMzD,CAAC;AAEF,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAe5D;AAED,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,aAAsD,CAAC;AAEpF,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,IAAI,CAI3F;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAI/G"}
@@ -17,9 +17,11 @@ export function printnodeStatusLabel(j) {
17
17
  return "Geannuleerd";
18
18
  if (j.foutcode === "AANLEVERING_MISLUKT")
19
19
  return "Mislukt — geen document";
20
- if (j.foutcode === "FORMAAT_PAST_NIET")
20
+ // Oudere rijen hebben een andere foutcode, maar de melding begint met de code.
21
+ const fm = String(j.foutmelding ?? "");
22
+ if (j.foutcode === "FORMAAT_PAST_NIET" || fm.startsWith("FORMAAT_PAST_NIET"))
21
23
  return "Geweigerd – past niet";
22
- if (j.foutcode === "GEEN_GELADEN_ETIKET")
24
+ if (j.foutcode === "GEEN_GELADEN_ETIKET" || fm.startsWith("GEEN_GELADEN_ETIKET"))
23
25
  return "Geweigerd – geen etiket geladen";
24
26
  const pn = String(j.printnode_status ?? "").toLowerCase();
25
27
  if (pn && PRINTNODE_STATUS_LABEL[pn])
@@ -11,6 +11,18 @@ export declare function controleerSecret(request: Request, secret: string, _veld
11
11
  export declare function secretKlopt(request: Request, secret: string): boolean;
12
12
  /** Details van een geweigerde aanroep. Bevat nooit (een deel van) het geheim. */
13
13
  export declare function afwijzingDetails(request: Request): Promise<Record<string, unknown>>;
14
+ /**
15
+ * Herkent de oude verbindingstest (modules vóór 1.59.0): inhoud "[]", geen
16
+ * geheimkop en geen User-Agent. PrintNode stuurt altijd het geheim mee.
17
+ */
18
+ export declare function isOudeZelftest(d: Record<string, unknown> | null | undefined): boolean;
19
+ /** Korte, leesbare omschrijving van één vastgelegde melding (voor Details voor beheer). */
20
+ export declare function meldingWeergave(m: {
21
+ http_status: number;
22
+ soorten?: string[] | null;
23
+ gematcht?: number | null;
24
+ antwoord?: unknown;
25
+ }): string;
14
26
  /**
15
27
  * Afhandeling van een webhookaanroep. Het geheim komt uit de eigen
16
28
  * koppelingstabel (servicerol). `secretVoorTest` alleen voor tests.
@@ -1 +1 @@
1
- {"version":3,"file":"printnodeWebhook.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeWebhook.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAWxC,8EAA8E;AAC9E,eAAO,MAAM,UAAU,+BAA+B,CAAC;AAEvD,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAGtC;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAErE;AA8BD,iFAAiF;AACjF,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CASzF;AASD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,EAAE,EACN,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,QAAQ,CAAC,CAmFnB;AAED,2EAA2E;AAC3E,wBAAsB,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrD"}
1
+ {"version":3,"file":"printnodeWebhook.d.ts","sourceRoot":"","sources":["../../src/lib/printnodeWebhook.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAWxC,8EAA8E;AAC9E,eAAO,MAAM,UAAU,+BAA+B,CAAC;AAEvD,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAGtC;AAED,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAErE;AA8BD,iFAAiF;AACjF,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CASzF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAErF;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,CAAC,EAAE;IACjC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC9F,GAAG,MAAM,CAaT;AASD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,EAAE,EACN,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,QAAQ,CAAC,CAqFnB;AAED,2EAA2E;AAC3E,wBAAsB,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrD"}
@@ -66,6 +66,30 @@ export async function afwijzingDetails(request) {
66
66
  content_type: (request.headers.get("content-type") ?? "").slice(0, 60) || null,
67
67
  };
68
68
  }
69
+ /**
70
+ * Herkent de oude verbindingstest (modules vóór 1.59.0): inhoud "[]", geen
71
+ * geheimkop en geen User-Agent. PrintNode stuurt altijd het geheim mee.
72
+ */
73
+ export function isOudeZelftest(d) {
74
+ return !!d && d["secret_kop_aanwezig"] === false && !d["user_agent"] && Number(d["inhoud_lengte"] ?? 99) <= 2;
75
+ }
76
+ /** Korte, leesbare omschrijving van één vastgelegde melding (voor Details voor beheer). */
77
+ export function meldingWeergave(m) {
78
+ const soorten = Array.isArray(m.soorten) ? m.soorten : [];
79
+ const a = (m.antwoord && typeof m.antwoord === "object" ? m.antwoord : {});
80
+ if (m.http_status === 401) {
81
+ const d = (a["details"] && typeof a["details"] === "object" ? a["details"] : null);
82
+ if (soorten.includes("oude_zelftest") || isOudeZelftest(d)) {
83
+ return "Oude verbindingstest van een andere installatie (niet van PrintNode) — geweigerd";
84
+ }
85
+ return "Geweigerd: geheim ontbreekt of klopt niet";
86
+ }
87
+ if (m.http_status === 200 && (soorten.includes("zelftest") || soorten.length === 0))
88
+ return "Verbindingstest ✓";
89
+ if (m.http_status === 200)
90
+ return `Melding van PrintNode ✓ · ${m.gematcht ?? 0} bijgewerkt`;
91
+ return `Antwoord ${m.http_status}`;
92
+ }
69
93
  async function soortenUit(request) {
70
94
  try {
71
95
  const b = JSON.parse(await request.clone().text());
@@ -99,7 +123,9 @@ export async function behandelPrintNodeWebhook(request, db, secretVoorTest, opti
99
123
  if (!controleerSecret(request, secret).ok) {
100
124
  // Vastleggen wát er binnenkwam, zonder het geheim zelf: alleen of de kop er
101
125
  // was, hoe lang de inhoud is en welke soort melding het was.
102
- await noteer(db, { http_status: 401, soorten: await soortenUit(request), antwoord: { fout: "Ongeldig secret", details: await afwijzingDetails(request) } }, uitTabel);
126
+ const details = await afwijzingDetails(request);
127
+ const soorten401 = isOudeZelftest(details) ? ["oude_zelftest"] : await soortenUit(request);
128
+ await noteer(db, { http_status: 401, soorten: soorten401, antwoord: { fout: "Ongeldig secret", details } }, uitTabel);
103
129
  return Response.json({ ok: false, fout: "Ongeldig secret" }, { status: 401 });
104
130
  }
105
131
  // Eigen zelftest (geheim klopt): 200 + OK-kop, maar geen bewijs van PrintNode.
@@ -8,6 +8,8 @@ export interface PrintplekComputer {
8
8
  id: string;
9
9
  print_plek_id: string;
10
10
  computer_naam: string;
11
+ /** Vast PrintNode-computer-id; leeg = nog niet op id gekoppeld. */
12
+ printnode_computer_id?: number | string | null;
11
13
  }
12
14
  export interface PrintplekDocumentPrinter {
13
15
  id: string;
@@ -68,7 +70,7 @@ export declare function printplekVerwijderImpact(id: string): Promise<PrintplekI
68
70
  */
69
71
  export declare function verwijderPrintplek(id: string): Promise<PrintplekImpact>;
70
72
  /** Zet een computer (werkplek) bij een printplek. Een computer hoort bij één plek. */
71
- export declare function koppelComputerAanPrintplek(printPlekId: string, computerNaam: string): Promise<void>;
73
+ export declare function koppelComputerAanPrintplek(printPlekId: string, computerNaam: string, printnodeComputerId?: string | number | null): Promise<void>;
72
74
  export declare function ontkoppelComputer(computerNaam: string): Promise<void>;
73
75
  /** Legt vast welke printer een documentsoort op deze printplek gebruikt. */
74
76
  export declare function zetPrintplekPrinter(printPlekId: string, documenttype: string, printerId: string | null, papierformaat?: string | null): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"printplekken.d.ts","sourceRoot":"","sources":["../../src/lib/printplekken.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAQD,0EAA0E;AAC1E,wBAAgB,eAAe;;;;;;;;;EAqC9B;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAO9D;AAED,2EAA2E;AAC3E,wBAAgB,0BAA0B;;;;EAczC;AAMD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQxF;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,iBAI1E;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAYD,4DAA4D;AAC5D,wBAAsB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAInF;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAI7E;AAED,sFAAsF;AACtF,wBAAsB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,iBAMzF;AAED,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,iBAM3D;AAED,4EAA4E;AAC5E,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,iBAuB9B;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,iBAYf;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAO/D;AAED,iEAAiE;AACjE,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ5F;AAMD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKxB;AAMD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAM9E;AAED,wBAAgB,sBAAsB;;;EAOrC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,aAAa,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,iBAc/G;AAED,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,iBAM1D;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iBAYvG;AAMD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAOtF;AAED,yEAAyE;AACzE,wBAAsB,4BAA4B,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAOxF;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAW/E;AAED,sFAAsF;AACtF,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,mCAO3E;AAED,oEAAoE;AACpE,wBAAsB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxF;AAED,wDAAwD;AACxD,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO/E;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;;;;;;2BAoBxD,MAAM;;;EA0B9B"}
1
+ {"version":3,"file":"printplekken.d.ts","sourceRoot":"","sources":["../../src/lib/printplekken.ts"],"names":[],"mappings":"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"}
@@ -32,7 +32,7 @@ export function usePrintplekken() {
32
32
  ]);
33
33
  const eersteFout = p.error ?? c.error ?? r.error ?? k.error ?? t.error;
34
34
  setFout(eersteFout
35
- ? "Printplekken konden niet worden geladen. Voer sql/print-schema.sql uit in deze shell."
35
+ ? "Printplekken konden niet worden geladen. Neem contact op met Flow Selections."
36
36
  : null);
37
37
  setPlekken(arr(p.data));
38
38
  setComputers(arr(c.data));
@@ -117,8 +117,11 @@ export async function verwijderPrintplek(id) {
117
117
  return naarImpact(data);
118
118
  }
119
119
  /** Zet een computer (werkplek) bij een printplek. Een computer hoort bij één plek. */
120
- export async function koppelComputerAanPrintplek(printPlekId, computerNaam) {
121
- const { error } = await supabase.from("print_plek_computers").upsert({ print_plek_id: printPlekId, computer_naam: computerNaam.trim() }, { onConflict: "computer_naam" });
120
+ export async function koppelComputerAanPrintplek(printPlekId, computerNaam, printnodeComputerId) {
121
+ const rij = { print_plek_id: printPlekId, computer_naam: computerNaam.trim() };
122
+ if (printnodeComputerId != null && /^\d+$/.test(String(printnodeComputerId)))
123
+ rij.printnode_computer_id = Number(printnodeComputerId);
124
+ const { error } = await supabase.from("print_plek_computers").upsert(rij, { onConflict: "computer_naam" });
122
125
  if (error)
123
126
  throw error;
124
127
  }
@@ -1 +1 @@
1
- {"version":3,"file":"queueTick.d.ts","sourceRoot":"","sources":["../../src/lib/queueTick.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAiBxC;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyFzF"}
1
+ {"version":3,"file":"queueTick.d.ts","sourceRoot":"","sources":["../../src/lib/queueTick.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,KAAK,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAiBxC;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAmGzF"}
@@ -81,6 +81,15 @@ export async function behandelQueueTick(request, supabase) {
81
81
  return Response.json({ ok: false, fout: configFout }, { status: 500 });
82
82
  }
83
83
  void meldRunnerAan(supabase);
84
+ // Alleen de Shell verwerkt de printwachtrij. Andere installaties (ook
85
+ // voorbeeldomgevingen met nieuwere code) slaan over; geen stille wissel.
86
+ const { controleerShellPoort } = await import("./runnerRegistry.server.js");
87
+ const poort = await controleerShellPoort(supabase);
88
+ if (!poort.mag) {
89
+ if (poort.reden !== "niet_de_shell")
90
+ console.warn(`[printwachtrij] ${poort.tekst}`);
91
+ return Response.json({ ok: true, overgeslagen: poort.tekst, reden: poort.reden });
92
+ }
84
93
  // Lege shell: standaardlayouts aanmaken (servicerol), zodat een nieuwe klant
85
94
  // meteen kan printen zonder dat iemand een pagina opent of op een knop drukt.
86
95
  try {
@@ -6,6 +6,11 @@ export declare function eigenBasisUrl(): string | null;
6
6
  * minuten iets en laat fouten nooit doorwerken in de aanroeper.
7
7
  */
8
8
  export declare function meldRunnerAan(db: PrintDb): Promise<void>;
9
+ /**
10
+ * Mag deze installatie de printwachtrij verwerken? Alleen de Shell
11
+ * (shell_base_url uit module_runtime_config), met optioneel min_print_versie.
12
+ */
13
+ export declare function controleerShellPoort(db: PrintDb): Promise<import("./shellPoort.js").PoortUitkomst>;
9
14
  /** Controleert of de meegegeven sleutel bij een geregistreerde shell hoort. */
10
15
  export declare function isRunnerSleutel(db: PrintDb, sleutel: string): Promise<boolean>;
11
16
  //# sourceMappingURL=runnerRegistry.server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runnerRegistry.server.d.ts","sourceRoot":"","sources":["../../src/lib/runnerRegistry.server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,8DAA8D;AAC9D,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAS7C;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC9D;AAED,+EAA+E;AAC/E,wBAAsB,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAapF"}
1
+ {"version":3,"file":"runnerRegistry.server.d.ts","sourceRoot":"","sources":["../../src/lib/runnerRegistry.server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,8DAA8D;AAC9D,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAS7C;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC9D;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,OAAO,iDAcrD;AAED,+EAA+E;AAC/E,wBAAsB,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAapF"}
@@ -34,6 +34,7 @@ export async function meldRunnerAan(db) {
34
34
  return;
35
35
  laatsteUrl = basis;
36
36
  laatsteMelding = nu;
37
+ const { MODULE_VERSIE } = await import("./shellPoort.js");
37
38
  try {
38
39
  const { data } = await db
39
40
  .from("print_queue_runners")
@@ -43,7 +44,7 @@ export async function meldRunnerAan(db) {
43
44
  if (data?.id) {
44
45
  await db
45
46
  .from("print_queue_runners")
46
- .update({ laatst_gezien: new Date().toISOString(), actief: true })
47
+ .update({ laatst_gezien: new Date().toISOString(), actief: true, module_versie: MODULE_VERSIE })
47
48
  .eq("id", data.id);
48
49
  return;
49
50
  }
@@ -51,6 +52,7 @@ export async function meldRunnerAan(db) {
51
52
  basis_url: basis,
52
53
  laatst_gezien: new Date().toISOString(),
53
54
  actief: true,
55
+ module_versie: MODULE_VERSIE,
54
56
  });
55
57
  }
56
58
  catch {
@@ -58,6 +60,25 @@ export async function meldRunnerAan(db) {
58
60
  laatsteMelding = 0;
59
61
  }
60
62
  }
63
+ /**
64
+ * Mag deze installatie de printwachtrij verwerken? Alleen de Shell
65
+ * (shell_base_url uit module_runtime_config), met optioneel min_print_versie.
66
+ */
67
+ export async function controleerShellPoort(db) {
68
+ const { beoordeelPoort, MODULE_VERSIE } = await import("./shellPoort.js");
69
+ const { data } = await db
70
+ .from("module_runtime_config")
71
+ .select("key, value")
72
+ .in("key", ["shell_base_url", "min_print_versie"]);
73
+ const rijen = Array.isArray(data) ? data : [];
74
+ const waarde = (k) => rijen.find((r) => r.key === k)?.value ?? null;
75
+ return beoordeelPoort({
76
+ shellAdres: waarde("shell_base_url"),
77
+ eigenAdres: eigenBasisUrl(),
78
+ versie: MODULE_VERSIE,
79
+ minVersie: waarde("min_print_versie"),
80
+ });
81
+ }
61
82
  /** Controleert of de meegegeven sleutel bij een geregistreerde shell hoort. */
62
83
  export async function isRunnerSleutel(db, sleutel) {
63
84
  if (!sleutel || sleutel.length < 20)
@@ -0,0 +1,21 @@
1
+ /** Moduleversie van deze code. Gelijk houden aan package.json (test bewaakt dit). */
2
+ export declare const MODULE_VERSIE = "1.62.0";
3
+ export declare function normaliseerAdres(u: unknown): string | null;
4
+ /** -1 als a < b, 0 als gelijk, 1 als a > b (alleen cijfers, punt-gescheiden). */
5
+ export declare function vergelijkVersie(a: string, b: string): number;
6
+ export type PoortUitkomst = {
7
+ mag: true;
8
+ } | {
9
+ mag: false;
10
+ reden: "geen_shell_adres" | "niet_de_shell" | "versie_te_oud" | "eigen_adres_onbekend";
11
+ tekst: string;
12
+ };
13
+ export declare function beoordeelPoort(input: {
14
+ shellAdres: unknown;
15
+ eigenAdres: string | null;
16
+ versie: string;
17
+ minVersie?: unknown;
18
+ }): PoortUitkomst;
19
+ /** Gemaskeerd adres: alleen de eerste 4 tekens van de naam. */
20
+ export declare function maskeerAdres(u: string): string;
21
+ //# sourceMappingURL=shellPoort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellPoort.d.ts","sourceRoot":"","sources":["../../src/lib/shellPoort.ts"],"names":[],"mappings":"AAMA,qFAAqF;AACrF,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAG1D;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ5D;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,GACb;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,GAAG,eAAe,GAAG,sBAAsB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1H,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,aAAa,CAWhB;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI9C"}
@@ -0,0 +1,43 @@
1
+ // ============================================================================
2
+ // src/lib/shellPoort.ts — wie mag de printwachtrij verwerken? Alleen de Shell:
3
+ // de installatie waarvan het adres gelijk is aan shell_base_url uit de eigen
4
+ // database. Niets vast in code; ontbreekt het adres, dan wordt er niet geprint.
5
+ // ============================================================================
6
+ /** Moduleversie van deze code. Gelijk houden aan package.json (test bewaakt dit). */
7
+ export const MODULE_VERSIE = "1.62.0";
8
+ export function normaliseerAdres(u) {
9
+ const s = String(u ?? "").trim().replace(/\/+$/, "").toLowerCase();
10
+ return s || null;
11
+ }
12
+ /** -1 als a < b, 0 als gelijk, 1 als a > b (alleen cijfers, punt-gescheiden). */
13
+ export function vergelijkVersie(a, b) {
14
+ const pa = a.split(".").map((x) => parseInt(x, 10) || 0);
15
+ const pb = b.split(".").map((x) => parseInt(x, 10) || 0);
16
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
17
+ const d = (pa[i] ?? 0) - (pb[i] ?? 0);
18
+ if (d !== 0)
19
+ return d < 0 ? -1 : 1;
20
+ }
21
+ return 0;
22
+ }
23
+ export function beoordeelPoort(input) {
24
+ const shell = normaliseerAdres(input.shellAdres);
25
+ if (!shell)
26
+ return { mag: false, reden: "geen_shell_adres", tekst: "overgeslagen: er is geen Shell-adres ingesteld, dus er wordt niet geprint" };
27
+ const eigen = normaliseerAdres(input.eigenAdres);
28
+ if (!eigen)
29
+ return { mag: false, reden: "eigen_adres_onbekend", tekst: "overgeslagen: eigen adres onbekend" };
30
+ if (eigen !== shell)
31
+ return { mag: false, reden: "niet_de_shell", tekst: "overgeslagen: niet de Shell" };
32
+ const min = String(input.minVersie ?? "").trim().replace(/^"|"$/g, "");
33
+ if (min && vergelijkVersie(input.versie, min) < 0)
34
+ return { mag: false, reden: "versie_te_oud", tekst: `overgeslagen: versie ${input.versie} is ouder dan de minimale versie ${min}` };
35
+ return { mag: true };
36
+ }
37
+ /** Gemaskeerd adres: alleen de eerste 4 tekens van de naam. */
38
+ export function maskeerAdres(u) {
39
+ const m = /^(https?:\/\/)([^./]+)(\.[^/]*)?/i.exec(u.trim());
40
+ if (!m)
41
+ return "…";
42
+ return `${m[1]}${m[2].slice(0, 4)}…${m[3] ?? ""}`;
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/layout-maker",
3
- "version": "1.59.2",
3
+ "version": "1.62.1",
4
4
  "flowselections": {
5
5
  "moduleId": "layout-maker",
6
6
  "pages": [