@cosmicdrift/kumiko-server-runtime 0.269.2 → 0.273.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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-server-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.273.0",
|
|
4
4
|
"description": "Production server-boot runtime for Kumiko apps: connections, schema-drift-gate, seeds, lifecycle, graceful shutdown. Symmetric to kumiko-dev-server's runDevApp, without dev/scaffold/codegen tooling.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
84
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
83
|
+
"@cosmicdrift/kumiko-bundled-features": "0.273.0",
|
|
84
|
+
"@cosmicdrift/kumiko-framework": "0.273.0",
|
|
85
85
|
"temporal-polyfill": "^0.3.2"
|
|
86
86
|
},
|
|
87
87
|
"publishConfig": {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { createAuditFeature } from "@cosmicdrift/kumiko-bundled-features/audit";
|
|
2
3
|
import { createDeliveryFeature } from "@cosmicdrift/kumiko-bundled-features/delivery";
|
|
3
4
|
import { createSecretsFeature } from "@cosmicdrift/kumiko-bundled-features/secrets";
|
|
4
5
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
@@ -137,4 +138,26 @@ describe("buildBootExtraContext — framework-default provider autowire", () =>
|
|
|
137
138
|
});
|
|
138
139
|
expect(ctx["secrets"]).toBeDefined();
|
|
139
140
|
});
|
|
141
|
+
|
|
142
|
+
test("audit feature mounted → _escapeHatchAuditSink wired", () => {
|
|
143
|
+
const ctx = buildBootExtraContext({
|
|
144
|
+
db: fakeDb,
|
|
145
|
+
features: [createAuditFeature()],
|
|
146
|
+
envSource: {},
|
|
147
|
+
registry,
|
|
148
|
+
hasAuth: false,
|
|
149
|
+
});
|
|
150
|
+
expect(typeof ctx["_escapeHatchAuditSink"]).toBe("function");
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test("no audit feature → _escapeHatchAuditSink not wired", () => {
|
|
154
|
+
const ctx = buildBootExtraContext({
|
|
155
|
+
db: fakeDb,
|
|
156
|
+
features: [otherFeature],
|
|
157
|
+
envSource: {},
|
|
158
|
+
registry,
|
|
159
|
+
hasAuth: false,
|
|
160
|
+
});
|
|
161
|
+
expect(ctx["_escapeHatchAuditSink"]).toBeUndefined();
|
|
162
|
+
});
|
|
140
163
|
});
|
|
@@ -124,11 +124,11 @@ const attachDispatcherFeature = defineFeature("jobattach", (r) => {
|
|
|
124
124
|
});
|
|
125
125
|
return crud.create(event.payload, event.user, ctx.db);
|
|
126
126
|
},
|
|
127
|
-
{ access: { openToAll:
|
|
127
|
+
{ access: { openToAll: { reason: "test handler callable by any signed-in test user" } } },
|
|
128
128
|
);
|
|
129
129
|
|
|
130
130
|
r.queryHandler("list", z.object({}), async (_query, ctx) => selectMany(ctx.db, attachNoteTable), {
|
|
131
|
-
access: { openToAll:
|
|
131
|
+
access: { openToAll: { reason: "test handler callable by any signed-in test user" } },
|
|
132
132
|
});
|
|
133
133
|
|
|
134
134
|
r.job("record", { trigger: { manual: true }, retries: 0 }, async (payload, ctx) => {
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AUDIT_FEATURE,
|
|
3
|
+
createEscapeHatchAuditSink,
|
|
4
|
+
} from "@cosmicdrift/kumiko-bundled-features/audit";
|
|
1
5
|
import { makeAuthPaths } from "@cosmicdrift/kumiko-bundled-features/auth-email-password";
|
|
2
6
|
import { resolveSessionStore } from "@cosmicdrift/kumiko-bundled-features/auth-foundation";
|
|
3
7
|
import {
|
|
@@ -30,6 +34,7 @@ import type { KmsAdapter } from "@cosmicdrift/kumiko-framework/crypto";
|
|
|
30
34
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
31
35
|
import type {
|
|
32
36
|
ConfigResolver,
|
|
37
|
+
EscapeHatchAuditSink,
|
|
33
38
|
FeatureDefinition,
|
|
34
39
|
NotifyFactory,
|
|
35
40
|
Registry,
|
|
@@ -85,17 +90,27 @@ function buildDeliveryNotifyFactory(opts: {
|
|
|
85
90
|
readonly db: DbConnection;
|
|
86
91
|
readonly registry: Registry;
|
|
87
92
|
readonly sseBroker?: SseBroker;
|
|
93
|
+
readonly escapeHatchAuditSink?: EscapeHatchAuditSink;
|
|
88
94
|
}): NotifyFactory {
|
|
89
95
|
const deliveryService = createDeliveryService({
|
|
90
96
|
db: opts.db,
|
|
91
97
|
registry: opts.registry,
|
|
92
98
|
channels: collectChannels(opts.registry),
|
|
93
99
|
...(opts.sseBroker && { sseBroker: opts.sseBroker }),
|
|
100
|
+
...(opts.escapeHatchAuditSink && { escapeHatchAuditSink: opts.escapeHatchAuditSink }),
|
|
94
101
|
});
|
|
95
102
|
return (user, tenantId) => (notificationType, options) =>
|
|
96
103
|
deliveryService.notify(notificationType, options, user, tenantId);
|
|
97
104
|
}
|
|
98
105
|
|
|
106
|
+
function resolveEscapeHatchAuditSink(
|
|
107
|
+
features: readonly FeatureDefinition[],
|
|
108
|
+
db: DbConnection,
|
|
109
|
+
): EscapeHatchAuditSink | undefined {
|
|
110
|
+
const hasAuditFeature = features.some((f) => f.name === AUDIT_FEATURE);
|
|
111
|
+
return hasAuditFeature ? createEscapeHatchAuditSink({ db }) : undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
99
114
|
export function buildBootExtraContext(opts: {
|
|
100
115
|
readonly db: DbConnection;
|
|
101
116
|
readonly features: readonly FeatureDefinition[];
|
|
@@ -114,14 +129,17 @@ export function buildBootExtraContext(opts: {
|
|
|
114
129
|
const hasSecretsFeature = opts.features.some((f) => f.name === SECRETS_FEATURE_NAME);
|
|
115
130
|
const wireSecrets = hasSecretsFeature && crypto.masterKeyProvider !== undefined;
|
|
116
131
|
const hasDeliveryFeature = opts.features.some((f) => f.name === DELIVERY_FEATURE);
|
|
132
|
+
const escapeHatchAuditSink = resolveEscapeHatchAuditSink(opts.features, opts.db);
|
|
117
133
|
return {
|
|
118
134
|
templateResolver: createTemplateResolverApi(opts.db),
|
|
119
135
|
...(opts.kms && { kms: opts.kms }),
|
|
136
|
+
...(escapeHatchAuditSink && { _escapeHatchAuditSink: escapeHatchAuditSink }),
|
|
120
137
|
...(hasDeliveryFeature && {
|
|
121
138
|
_notifyFactory: buildDeliveryNotifyFactory({
|
|
122
139
|
db: opts.db,
|
|
123
140
|
registry: opts.registry,
|
|
124
141
|
...(opts.sseBroker && { sseBroker: opts.sseBroker }),
|
|
142
|
+
...(escapeHatchAuditSink && { escapeHatchAuditSink }),
|
|
125
143
|
}),
|
|
126
144
|
}),
|
|
127
145
|
// Top-level provider so feature jobs (secrets rotate, config reencrypt)
|