@cosmicdrift/kumiko-framework 0.294.1 → 0.295.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 +4 -4
- package/src/__tests__/schema-cli-temporal-polyfill.test.ts +1 -1
- package/src/search/__tests__/meilisearch-adapter.integration.test.ts +2 -3
- package/src/stack/db.ts +1 -1
- package/src/testing/__tests__/real-providers.test.ts +54 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/real-providers.ts +20 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.295.0",
|
|
4
4
|
"description": "Framework core — engine, pipeline, API, DB, and every other bit that makes Kumiko go.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -198,8 +198,8 @@
|
|
|
198
198
|
"./package.json": "./package.json"
|
|
199
199
|
},
|
|
200
200
|
"dependencies": {
|
|
201
|
-
"@cosmicdrift/kumiko-http": "0.
|
|
202
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
201
|
+
"@cosmicdrift/kumiko-http": "0.295.0",
|
|
202
|
+
"@cosmicdrift/kumiko-types": "0.295.0",
|
|
203
203
|
"bullmq": "^5.76.7",
|
|
204
204
|
"bun-types": "^1.3.13",
|
|
205
205
|
"hono": "^4.13.1",
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
"zod": "^4.4.3"
|
|
216
216
|
},
|
|
217
217
|
"devDependencies": {
|
|
218
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
218
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.295.0",
|
|
219
219
|
"bun-types": "^1.3.13",
|
|
220
220
|
"pino-pretty": "^13.1.3"
|
|
221
221
|
},
|
|
@@ -28,7 +28,7 @@ describe("runSchemaCli — Temporal polyfill", () => {
|
|
|
28
28
|
// never retried on the next run.
|
|
29
29
|
//
|
|
30
30
|
// Asserting on globalThis.Temporal directly doesn't work here: the test
|
|
31
|
-
// harness's own preload (
|
|
31
|
+
// harness's own preload (@cosmicdrift/kumiko-testing/preload/temporal) already calls
|
|
32
32
|
// ensureTemporalPolyfill() once per process, and its idempotency cache
|
|
33
33
|
// (a module-level flag, not re-derived from globalThis) short-circuits
|
|
34
34
|
// any later call regardless of what a test does to globalThis.Temporal in
|
|
@@ -42,7 +42,7 @@ let indexPrefix: string;
|
|
|
42
42
|
describe.skipIf(!MEILI_UP)("meilisearch adapter (live)", () => {
|
|
43
43
|
beforeAll(async () => {
|
|
44
44
|
client = new Meilisearch({ host: MEILI_URL, apiKey: MEILI_KEY });
|
|
45
|
-
indexPrefix = `test_${uuid()
|
|
45
|
+
indexPrefix = `test_${uuid()}_`;
|
|
46
46
|
adapter = createMeilisearchAdapter({
|
|
47
47
|
url: MEILI_URL,
|
|
48
48
|
apiKey: MEILI_KEY,
|
|
@@ -110,10 +110,9 @@ describe.skipIf(!MEILI_UP)("meilisearch adapter (live)", () => {
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
afterAll(async () => {
|
|
113
|
-
// Clean up all test indices
|
|
114
113
|
const indices = await client.getIndexes();
|
|
115
114
|
for (const idx of indices.results) {
|
|
116
|
-
if (idx.uid.startsWith(
|
|
115
|
+
if (idx.uid.startsWith(indexPrefix)) {
|
|
117
116
|
try {
|
|
118
117
|
await client.index(idx.uid).delete().waitTask();
|
|
119
118
|
} catch {
|
package/src/stack/db.ts
CHANGED
|
@@ -12,7 +12,7 @@ function requireEnv(name: string): string {
|
|
|
12
12
|
const value = process.env[name];
|
|
13
13
|
if (!value) {
|
|
14
14
|
throw new Error(
|
|
15
|
-
`Missing required env var: ${name}. Copy .env.example to .env and fill in values.`,
|
|
15
|
+
`Missing required env var: ${name}. Copy .env.example to .env and fill in values. Tests also need the test services (Postgres, Redis) running, e.g. "docker compose up -d".`,
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
18
|
return value;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { requireRealProviders } from "../real-providers";
|
|
3
|
+
|
|
4
|
+
const CI = "CI";
|
|
5
|
+
const FLAG = "KUMIKO_REAL_PROVIDERS";
|
|
6
|
+
const API_KEY = "ANTHROPIC_API_KEY";
|
|
7
|
+
const TOUCHED_ENV = [CI, FLAG, API_KEY];
|
|
8
|
+
|
|
9
|
+
describe("requireRealProviders", () => {
|
|
10
|
+
const saved = new Map<string, string | undefined>();
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
for (const name of TOUCHED_ENV) {
|
|
14
|
+
saved.set(name, process.env[name]);
|
|
15
|
+
delete process.env[name];
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
for (const [name, value] of saved) {
|
|
21
|
+
if (value === undefined) delete process.env[name];
|
|
22
|
+
else process.env[name] = value;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("throws when the flag is missing, even with an API key set", () => {
|
|
27
|
+
process.env[API_KEY] = "sk-test";
|
|
28
|
+
expect(() => requireRealProviders()).toThrow(/KUMIKO_REAL_PROVIDERS=1/);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("throws when the flag has any value other than 1", () => {
|
|
32
|
+
process.env[FLAG] = "true";
|
|
33
|
+
expect(() => requireRealProviders()).toThrow(/KUMIKO_REAL_PROVIDERS=1/);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("throws in CI even with the flag set", () => {
|
|
37
|
+
process.env[CI] = "true";
|
|
38
|
+
process.env[FLAG] = "1";
|
|
39
|
+
expect(() => requireRealProviders()).toThrow(/never run in CI/);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("does not throw with the flag set outside CI", () => {
|
|
43
|
+
process.env[FLAG] = "1";
|
|
44
|
+
expect(() => requireRealProviders()).not.toThrow();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("treats CI=false and CI=0 as not CI", () => {
|
|
48
|
+
process.env[FLAG] = "1";
|
|
49
|
+
process.env[CI] = "false";
|
|
50
|
+
expect(() => requireRealProviders()).not.toThrow();
|
|
51
|
+
process.env[CI] = "0";
|
|
52
|
+
expect(() => requireRealProviders()).not.toThrow();
|
|
53
|
+
});
|
|
54
|
+
});
|
package/src/testing/index.ts
CHANGED
|
@@ -44,6 +44,7 @@ export {
|
|
|
44
44
|
createRecordingProvider,
|
|
45
45
|
type RecordingProvider,
|
|
46
46
|
} from "./observability-recorder";
|
|
47
|
+
export { requireRealProviders } from "./real-providers";
|
|
47
48
|
export { deleteRows, seedRow, seedRows, updateRows } from "./seed";
|
|
48
49
|
export {
|
|
49
50
|
sharedItemEntity,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const REAL_PROVIDERS_FLAG = "KUMIKO_REAL_PROVIDERS";
|
|
2
|
+
const CI_FLAG = "CI";
|
|
3
|
+
|
|
4
|
+
function isCi(): boolean {
|
|
5
|
+
const ci = process.env[CI_FLAG];
|
|
6
|
+
return ci !== undefined && ci !== "" && ci !== "0" && ci.toLowerCase() !== "false";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function requireRealProviders(): void {
|
|
10
|
+
if (isCi()) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`Real-provider tests never run in CI (CI is set). Run them locally with ${REAL_PROVIDERS_FLAG}=1 via the test:real / e2e:real script.`,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
if (process.env[REAL_PROVIDERS_FLAG] !== "1") {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`Real-provider test needs ${REAL_PROVIDERS_FLAG}=1 (an API key alone never enables it). Run it via the test:real / e2e:real script.`,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|