@cosmicdrift/kumiko-server-runtime 0.154.1 → 0.154.2
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.154.
|
|
3
|
+
"version": "0.154.2",
|
|
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>",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@cosmicdrift/kumiko-bundled-features": "0.154.
|
|
76
|
-
"@cosmicdrift/kumiko-framework": "0.154.
|
|
75
|
+
"@cosmicdrift/kumiko-bundled-features": "0.154.2",
|
|
76
|
+
"@cosmicdrift/kumiko-framework": "0.154.2"
|
|
77
77
|
},
|
|
78
78
|
"publishConfig": {
|
|
79
79
|
"registry": "https://registry.npmjs.org",
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
computeBuildId,
|
|
17
17
|
discoverClientEntries,
|
|
18
18
|
discoverHtmlTemplate,
|
|
19
|
+
formatBuildResult,
|
|
19
20
|
injectAssetTags,
|
|
20
21
|
} from "../build-prod-bundle";
|
|
21
22
|
|
|
@@ -276,3 +277,60 @@ describe("build-prod-bundle/injectAssetTags build-info", () => {
|
|
|
276
277
|
expect(result).not.toContain("__KUMIKO_BUILD__");
|
|
277
278
|
});
|
|
278
279
|
});
|
|
280
|
+
|
|
281
|
+
describe("build-prod-bundle/formatBuildResult", () => {
|
|
282
|
+
test("lists outDir, duration, and every manifest entry", () => {
|
|
283
|
+
const out = formatBuildResult(
|
|
284
|
+
{
|
|
285
|
+
outDir: "dist",
|
|
286
|
+
manifest: {
|
|
287
|
+
"client.js": "/assets/client-abc.js",
|
|
288
|
+
"styles.css": "/assets/styles-xyz.css",
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
42,
|
|
292
|
+
);
|
|
293
|
+
expect(out).toContain("dist");
|
|
294
|
+
expect(out).toContain("42ms");
|
|
295
|
+
expect(out).toContain("client.js");
|
|
296
|
+
expect(out).toContain("/assets/client-abc.js");
|
|
297
|
+
expect(out).toContain("styles.css");
|
|
298
|
+
expect(out).toContain("/assets/styles-xyz.css");
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
test("empty manifest still prints the success line", () => {
|
|
302
|
+
const out = formatBuildResult({ outDir: "dist-server", manifest: {} }, 1);
|
|
303
|
+
expect(out).toContain("dist-server");
|
|
304
|
+
expect(out).toContain("1ms");
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
describe("build-prod-bundle/discovery edges", () => {
|
|
309
|
+
let workDir = "";
|
|
310
|
+
|
|
311
|
+
beforeEach(async () => {
|
|
312
|
+
workDir = await mkdtemp(join(tmpdir(), "kumiko-build-edge-"));
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
afterEach(async () => {
|
|
316
|
+
await rm(workDir, { recursive: true, force: true });
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test("discoverClientEntries accepts src/client.ts (no x)", async () => {
|
|
320
|
+
await mkdir(join(workDir, "src"), { recursive: true });
|
|
321
|
+
await writeFile(join(workDir, "src/client.ts"), "// single ts");
|
|
322
|
+
const entries = discoverClientEntries(workDir);
|
|
323
|
+
expect(entries).toHaveLength(1);
|
|
324
|
+
expect(entries[0]?.name).toBe("client");
|
|
325
|
+
expect(entries[0]?.sourceFile.endsWith("src/client.ts")).toBe(true);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test("discoverClientEntries ignores non-matching client-* names", async () => {
|
|
329
|
+
await mkdir(join(workDir, "src"), { recursive: true });
|
|
330
|
+
// Uppercase / leading digit / underscore violate ^client-([a-z][a-z0-9-]*)\.tsx?$
|
|
331
|
+
await writeFile(join(workDir, "src/client-Admin.tsx"), "// bad");
|
|
332
|
+
await writeFile(join(workDir, "src/client-1bad.tsx"), "// bad");
|
|
333
|
+
await writeFile(join(workDir, "src/client_admin.tsx"), "// bad");
|
|
334
|
+
expect(discoverClientEntries(workDir)).toEqual([]);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
@@ -886,6 +886,25 @@ describe("runProdApp job-lane wiring (runSingleInstance)", () => {
|
|
|
886
886
|
};
|
|
887
887
|
await expect(boot(undefined, { kms: unhealthyKms })).rejects.toThrow(/KMS health check failed/);
|
|
888
888
|
});
|
|
889
|
+
|
|
890
|
+
test("rateLimit flows from runProdApp through entrypoint into the L1/L2 middleware (#1101)", async () => {
|
|
891
|
+
const handle = await boot(undefined, {
|
|
892
|
+
rateLimit: { global: { limit: 1, windowSeconds: 60 } },
|
|
893
|
+
anonymousAccess: { defaultTenantId: TENANT_ID },
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
const fetchOnce = () =>
|
|
897
|
+
handle.entrypoint.app.fetch(
|
|
898
|
+
new Request("http://test/api/query", {
|
|
899
|
+
method: "POST",
|
|
900
|
+
headers: { "content-type": "application/json", "x-forwarded-for": "203.0.113.9" },
|
|
901
|
+
body: JSON.stringify({ type: "prod-probe:query:ping", payload: {} }),
|
|
902
|
+
}),
|
|
903
|
+
);
|
|
904
|
+
|
|
905
|
+
expect((await fetchOnce()).status).toBe(200);
|
|
906
|
+
expect((await fetchOnce()).status).toBe(429);
|
|
907
|
+
});
|
|
889
908
|
});
|
|
890
909
|
|
|
891
910
|
describe("hard PII boot gate (#818 step 2)", () => {
|
package/src/run-prod-app.ts
CHANGED
|
@@ -564,6 +564,11 @@ export type RunProdAppOptions = {
|
|
|
564
564
|
* PrometheusMeter-basierten `observability`-Provider antwortet `/metrics`
|
|
565
565
|
* mit 503 + Misconfiguration-Hinweis statt echter Metriken. */
|
|
566
566
|
readonly metrics?: import("@cosmicdrift/kumiko-framework/api").ServerOptions["metrics"];
|
|
567
|
+
/** L1 (Login-Lockout) + L2 (globaler IP-Limit) Rate-Limit-Middleware —
|
|
568
|
+
* 1:1 durchgereicht an `buildServer`s `ServerOptions.rateLimit`. Ohne
|
|
569
|
+
* dieses Feld wird kein L1/L2 verdrahtet (L3 Handler-`rateLimit:`
|
|
570
|
+
* funktioniert unabhängig davon bereits). */
|
|
571
|
+
readonly rateLimit?: import("@cosmicdrift/kumiko-framework/api").ServerOptions["rateLimit"];
|
|
567
572
|
};
|
|
568
573
|
|
|
569
574
|
export type ProdAppHandle = {
|
|
@@ -893,6 +898,7 @@ export async function runProdApp(options: RunProdAppOptions): Promise<ProdAppHan
|
|
|
893
898
|
...(options.observability && { observability: options.observability }),
|
|
894
899
|
...(options.observabilityOptions && { observabilityOptions: options.observabilityOptions }),
|
|
895
900
|
...(options.metrics && { metrics: options.metrics }),
|
|
901
|
+
...(options.rateLimit && { rateLimit: options.rateLimit }),
|
|
896
902
|
...(effectiveAuth && {
|
|
897
903
|
auth: {
|
|
898
904
|
membershipQuery: TenantQueries.memberships,
|