@cosmicdrift/kumiko-bundled-features 0.310.0 → 0.312.0
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.
- package/package.json +9 -9
- package/src/__tests__/extension-points-typed.test.ts +4 -0
- package/src/audit/__tests__/escape-hatch-audit.integration.test.ts +16 -12
- package/src/delivery/__tests__/delivery.integration.test.ts +21 -29
- package/src/document-ingest-foundation/__tests__/feature.integration.test.ts +621 -43
- package/src/document-ingest-foundation/__tests__/feature.test.ts +20 -3
- package/src/document-ingest-foundation/__tests__/providers.test.ts +204 -0
- package/src/document-ingest-foundation/boot-checks.ts +58 -0
- package/src/document-ingest-foundation/changes.json +18 -0
- package/src/document-ingest-foundation/events.ts +3 -0
- package/src/document-ingest-foundation/executor.ts +12 -0
- package/src/document-ingest-foundation/feature.ts +125 -72
- package/src/document-ingest-foundation/file-ref-liveness.ts +10 -0
- package/src/document-ingest-foundation/forget-extract-with-file-ref.ts +84 -0
- package/src/document-ingest-foundation/index.ts +17 -0
- package/src/document-ingest-foundation/providers.ts +78 -0
- package/src/document-ingest-foundation/tenant-destroy-hook.ts +3 -7
- package/src/document-ingest-foundation/write-document-extract.ts +48 -0
- package/src/inbound-provider-imap/__tests__/plugin-mocked.test.ts +10 -12
- package/src/jobs/__tests__/projection-rebuild-job.integration.test.ts +11 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-bundled-features",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.312.0",
|
|
4
4
|
"description": "Built-in features — tenant, user, auth, delivery. The stuff you'd rewrite anyway, already typed.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -133,12 +133,12 @@
|
|
|
133
133
|
"./workflow-runner": "./src/workflow-runner/index.ts"
|
|
134
134
|
},
|
|
135
135
|
"dependencies": {
|
|
136
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
137
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
138
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
139
|
-
"@cosmicdrift/kumiko-renderer": "0.
|
|
140
|
-
"@cosmicdrift/kumiko-renderer-web": "0.
|
|
141
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
136
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.312.0",
|
|
137
|
+
"@cosmicdrift/kumiko-framework": "0.312.0",
|
|
138
|
+
"@cosmicdrift/kumiko-headless": "0.312.0",
|
|
139
|
+
"@cosmicdrift/kumiko-renderer": "0.312.0",
|
|
140
|
+
"@cosmicdrift/kumiko-renderer-web": "0.312.0",
|
|
141
|
+
"@cosmicdrift/kumiko-types": "0.312.0",
|
|
142
142
|
"@mollie/api-client": "^4.5.0",
|
|
143
143
|
"@node-rs/argon2": "^2.0.2",
|
|
144
144
|
"@types/mailparser": "^3.4.6",
|
|
@@ -167,8 +167,8 @@
|
|
|
167
167
|
],
|
|
168
168
|
"devDependencies": {
|
|
169
169
|
"@testing-library/user-event": "^14.6.1",
|
|
170
|
-
"@cosmicdrift/kumiko-locale-de": "0.
|
|
171
|
-
"@cosmicdrift/kumiko-locale-es": "0.
|
|
170
|
+
"@cosmicdrift/kumiko-locale-de": "0.312.0",
|
|
171
|
+
"@cosmicdrift/kumiko-locale-es": "0.312.0",
|
|
172
172
|
"jsqr": "^1.4.0"
|
|
173
173
|
}
|
|
174
174
|
}
|
|
@@ -11,6 +11,7 @@ import { authFoundationFeature } from "../auth-foundation/feature";
|
|
|
11
11
|
import { billingFoundationFeature } from "../billing-foundation/feature";
|
|
12
12
|
import { createCustomFieldsFeature } from "../custom-fields/feature";
|
|
13
13
|
import { createDeliveryFeature } from "../delivery/feature";
|
|
14
|
+
import { documentIngestFoundationFeature } from "../document-ingest-foundation/feature";
|
|
14
15
|
import { createFileDerivativesFeature } from "../file-derivatives/feature";
|
|
15
16
|
import { fileFoundationFeature } from "../file-foundation/feature";
|
|
16
17
|
import { inboundMailFoundationFeature } from "../inbound-mail-foundation/feature";
|
|
@@ -44,6 +45,7 @@ const TYPED_EXTENSION_POINTS = [
|
|
|
44
45
|
"deliveryChannel",
|
|
45
46
|
"subscriptionProvider",
|
|
46
47
|
"mailTransport",
|
|
48
|
+
"documentIngestProvider",
|
|
47
49
|
] as const satisfies readonly (keyof KumikoExtensionOptionsMap)[];
|
|
48
50
|
|
|
49
51
|
const UNTYPED_BY_DESIGN: Record<string, string> = {
|
|
@@ -59,6 +61,7 @@ const DECLARING_FEATURE_DIRS = [
|
|
|
59
61
|
"billing-foundation",
|
|
60
62
|
"custom-fields",
|
|
61
63
|
"delivery",
|
|
64
|
+
"document-ingest-foundation",
|
|
62
65
|
"file-derivatives",
|
|
63
66
|
"file-foundation",
|
|
64
67
|
"inbound-mail-foundation",
|
|
@@ -97,6 +100,7 @@ function allRegistrarExtensionNames(): readonly string[] {
|
|
|
97
100
|
billingFoundationFeature,
|
|
98
101
|
createCustomFieldsFeature(),
|
|
99
102
|
createDeliveryFeature(),
|
|
103
|
+
documentIngestFoundationFeature,
|
|
100
104
|
createFileDerivativesFeature(),
|
|
101
105
|
fileFoundationFeature,
|
|
102
106
|
inboundMailFoundationFeature,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type TestStack,
|
|
13
13
|
testTenantId,
|
|
14
14
|
} from "@cosmicdrift/kumiko-framework/stack";
|
|
15
|
+
import { waitFor } from "@cosmicdrift/kumiko-framework/testing";
|
|
15
16
|
import * as z from "zod";
|
|
16
17
|
import { createConfigFeature } from "../../config";
|
|
17
18
|
import { createTenantFeature } from "../../tenant";
|
|
@@ -71,18 +72,21 @@ type AuditRow = {
|
|
|
71
72
|
type AuditResponse = { rows: AuditRow[]; nextBefore: string | null };
|
|
72
73
|
|
|
73
74
|
async function pollForEscapeHatchRow(): Promise<AuditRow> {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
let row: AuditRow | undefined;
|
|
76
|
+
await waitFor(
|
|
77
|
+
async () => {
|
|
78
|
+
const res = await stack.http.queryOk<AuditResponse>(
|
|
79
|
+
AuditQueries.list,
|
|
80
|
+
{ eventType: ESCAPE_HATCH_USED_EVENT },
|
|
81
|
+
adminOfSameTenant,
|
|
82
|
+
);
|
|
83
|
+
row = res.rows[0];
|
|
84
|
+
return row !== undefined;
|
|
85
|
+
},
|
|
86
|
+
{ delays: Array(40).fill(50) },
|
|
87
|
+
);
|
|
88
|
+
if (row === undefined) throw new Error("escape-hatch-used audit row did not appear within 2s");
|
|
89
|
+
return row;
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
describe("createEscapeHatchAuditSink — persists audit:event:escape-hatch-used", () => {
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
testTenantId,
|
|
27
27
|
unsafePushTables,
|
|
28
28
|
} from "@cosmicdrift/kumiko-framework/stack";
|
|
29
|
+
import { waitFor } from "@cosmicdrift/kumiko-framework/testing";
|
|
29
30
|
import * as z from "zod";
|
|
30
31
|
import { createChannelEmailFeature } from "../../channel-email/feature";
|
|
31
32
|
import { createInMemoryTransport, type EmailMessage } from "../../channel-email/types";
|
|
@@ -1502,21 +1503,6 @@ describe("flow 16: repeated unsubscribe clicks are idempotent", () => {
|
|
|
1502
1503
|
// non-string `to` as a broadcast target ("tenant" in to).
|
|
1503
1504
|
const asyncRecipient = "7";
|
|
1504
1505
|
|
|
1505
|
-
async function waitFor(check: () => Promise<void>, timeoutMs = 10000): Promise<void> {
|
|
1506
|
-
const start = Date.now();
|
|
1507
|
-
let lastErr: unknown;
|
|
1508
|
-
for (;;) {
|
|
1509
|
-
try {
|
|
1510
|
-
await check();
|
|
1511
|
-
return;
|
|
1512
|
-
} catch (err) {
|
|
1513
|
-
lastErr = err;
|
|
1514
|
-
if (Date.now() - start > timeoutMs) throw lastErr;
|
|
1515
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
1506
|
function makeStubRunner(): {
|
|
1521
1507
|
runner: JobRunner;
|
|
1522
1508
|
dispatched: Array<{
|
|
@@ -1580,13 +1566,16 @@ describe("flow 17: async render→send pipeline", () => {
|
|
|
1580
1566
|
|
|
1581
1567
|
// Email: queued → render job → send job → sent. Proves the framework
|
|
1582
1568
|
// jobRunner-into-job-ctx injection (render dispatches send) end-to-end.
|
|
1583
|
-
await waitFor(
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1569
|
+
await waitFor(
|
|
1570
|
+
async () => {
|
|
1571
|
+
const rows = await selectMany(db, deliveryAttemptsTable, {
|
|
1572
|
+
notificationType: "app:notify:async-e2e",
|
|
1573
|
+
channel: "email",
|
|
1574
|
+
});
|
|
1575
|
+
expect(rows.some((r) => r["status"] === "sent")).toBe(true);
|
|
1576
|
+
},
|
|
1577
|
+
{ delays: Array(40).fill(250) },
|
|
1578
|
+
);
|
|
1590
1579
|
const email = emailTransport.sent.find((m) => m.to === testEmail(asyncRecipient));
|
|
1591
1580
|
expect(email).toBeDefined();
|
|
1592
1581
|
expect(email?.subject).toBe("Async Subject");
|
|
@@ -1594,13 +1583,16 @@ describe("flow 17: async render→send pipeline", () => {
|
|
|
1594
1583
|
expect(email?.html).toContain("<!DOCTYPE html>");
|
|
1595
1584
|
|
|
1596
1585
|
// Push: no render step → dispatched straight to delivery.send.
|
|
1597
|
-
await waitFor(
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1586
|
+
await waitFor(
|
|
1587
|
+
async () => {
|
|
1588
|
+
const rows = await selectMany(db, deliveryAttemptsTable, {
|
|
1589
|
+
notificationType: "app:notify:async-e2e",
|
|
1590
|
+
channel: "push",
|
|
1591
|
+
});
|
|
1592
|
+
expect(rows.some((r) => r["status"] === "sent")).toBe(true);
|
|
1593
|
+
},
|
|
1594
|
+
{ delays: Array(40).fill(250) },
|
|
1595
|
+
);
|
|
1604
1596
|
expect(
|
|
1605
1597
|
pushTransport.sent.find((m) => m.token === testPushToken(asyncRecipient)),
|
|
1606
1598
|
).toBeDefined();
|