@cosmicdrift/kumiko-framework 0.307.0 → 0.309.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 +5 -5
- package/src/__tests__/anonymous-access.integration.test.ts +1 -1
- package/src/__tests__/error-contract.integration.test.ts +1 -1
- package/src/__tests__/field-access.integration.test.ts +1 -1
- package/src/__tests__/fixtures/migrate-open-to-all/manual-only.expected.ts +1 -1
- package/src/__tests__/fixtures/migrate-open-to-all/manual-only.input.ts +1 -1
- package/src/__tests__/fixtures/migrate-open-to-all/test-simple.expected.ts +1 -1
- package/src/__tests__/fixtures/migrate-open-to-all/test-simple.input.ts +1 -1
- package/src/__tests__/full-stack.integration.test.ts +1 -1
- package/src/__tests__/transition-guard.integration.test.ts +1 -1
- package/src/api/__tests__/api.test.ts +1 -1
- package/src/api/__tests__/batch.integration.test.ts +1 -1
- package/src/api/__tests__/body-limit.test.ts +1 -1
- package/src/api/__tests__/dispatcher-live.integration.test.ts +1 -1
- package/src/api/__tests__/extra-routes.integration.test.ts +1 -1
- package/src/api/__tests__/http-route-rate-limit.integration.test.ts +1 -1
- package/src/api/__tests__/nested-write-ownership.integration.test.ts +1 -1
- package/src/api/__tests__/nested-write.integration.test.ts +1 -1
- package/src/api/__tests__/pii-leak-guard.integration.test.ts +1 -1
- package/src/api/__tests__/redis-sse-broker.integration.test.ts +73 -6
- package/src/api/__tests__/request-locale.integration.test.ts +1 -1
- package/src/api/__tests__/server-boot-guards.test.ts +1 -1
- package/src/api/__tests__/server-error-logging.test.ts +1 -1
- package/src/api/__tests__/sse-broker.test.ts +107 -13
- package/src/api/__tests__/stream-escape-hatch.integration.test.ts +1 -1
- package/src/api/auth-routes.ts +1 -1
- package/src/api/redis-sse-broker.ts +51 -11
- package/src/api/server.ts +11 -0
- package/src/api/sse-broker.ts +61 -22
- package/src/bun-db/__tests__/postgres-closed-socket-write.integration.test.ts +87 -0
- package/src/bun-db/connection.ts +2 -0
- package/src/changes.json +61 -0
- package/src/compliance/override-schema.ts +1 -1
- package/src/crypto/__tests__/event-pii.test.ts +1 -1
- package/src/crypto/kms-adapter.ts +1 -1
- package/src/db/__tests__/feature-table-sources.test.ts +2 -2
- package/src/db/__tests__/tenant-db-where-merge.integration.test.ts +1 -1
- package/src/db/collect-table-metas.ts +3 -6
- package/src/db/feature-table-sources.ts +3 -4
- package/src/db/queries/event-consumer.ts +98 -6
- package/src/derivatives/__tests__/derivatives-context.integration.test.ts +1 -1
- package/src/derivatives/delete-stored-file.ts +86 -0
- package/src/derivatives/index.ts +2 -0
- package/src/engine/__tests__/boot-validator-action-wiring.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-dashboard.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-nav-area.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-pii-retention.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-projection-list.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-query-output-schema.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-query-refs.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-ref-entity.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-s0-integration.test.ts +1 -1
- package/src/engine/__tests__/boot-validator.test.ts +35 -1
- package/src/engine/__tests__/build-app-schema.test.ts +1 -1
- package/src/engine/__tests__/build-config-feature-schema-secrets.test.ts +1 -1
- package/src/engine/__tests__/define-feature-entity-mapping.test.ts +1 -1
- package/src/engine/__tests__/engine.test.ts +1 -1
- package/src/engine/__tests__/event-helpers.test.ts +1 -1
- package/src/engine/__tests__/event-migration-declarative.test.ts +1 -1
- package/src/engine/__tests__/extend-entity-projection.test.ts +1 -1
- package/src/engine/__tests__/extends-registrar.test.ts +1 -1
- package/src/engine/__tests__/hook-phases.test.ts +1 -1
- package/src/engine/__tests__/lifecycle-hooks.test.ts +1 -1
- package/src/engine/__tests__/pipeline-engine.test.ts +1 -1
- package/src/engine/__tests__/pipeline-handler.integration.test.ts +1 -1
- package/src/engine/__tests__/pipeline-observability.integration.test.ts +1 -1
- package/src/engine/__tests__/pipeline-performance.integration.test.ts +1 -1
- package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +1 -1
- package/src/engine/__tests__/post-query-hook.test.ts +1 -1
- package/src/engine/__tests__/projection-detail-actions.test.ts +1 -1
- package/src/engine/__tests__/projection-detail-singleton.test.ts +1 -1
- package/src/engine/__tests__/projection-detail-tabs.test.ts +1 -1
- package/src/engine/__tests__/read-steps-tenant-filter.integration.test.ts +1 -1
- package/src/engine/__tests__/registry.test.ts +1 -1
- package/src/engine/__tests__/screen.test.ts +1 -1
- package/src/engine/__tests__/validate-projection-allowlist.test.ts +1 -1
- package/src/engine/boot-validator/__tests__/access-declarations.test.ts +1 -1
- package/src/engine/boot-validator/__tests__/action-icon.test.ts +81 -0
- package/src/engine/boot-validator/__tests__/anonymous-rate-limit-required.test.ts +1 -1
- package/src/engine/boot-validator/__tests__/no-all-role-in-handler-access.test.ts +1 -1
- package/src/engine/boot-validator/__tests__/parent-ref.test.ts +1 -1
- package/src/engine/boot-validator/__tests__/rate-limit-disabled-reason.test.ts +1 -1
- package/src/engine/boot-validator/screens.ts +83 -0
- package/src/engine/define-handler.ts +2 -1
- package/src/engine/entity-handlers.ts +2 -1
- package/src/engine/feature-ast/__tests__/pattern-change-schema.test.ts +1 -1
- package/src/engine/feature-ast/pattern-change-schema.ts +1 -1
- package/src/engine/feature-builder-state.ts +2 -1
- package/src/engine/feature-config-events-jobs.ts +2 -1
- package/src/engine/feature-entity-handlers.ts +2 -1
- package/src/engine/schema-builder.ts +1 -1
- package/src/entrypoint/__tests__/entrypoint-attach-dispatcher.integration.test.ts +1 -1
- package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.test.ts +1 -1
- package/src/entrypoint/__tests__/split-deploy.integration.test.ts +1 -1
- package/src/env/__tests__/compose-env-schema.test.ts +1 -1
- package/src/env/__tests__/dry-run.test.ts +1 -1
- package/src/env/__tests__/parse-env-dry-run.test.ts +1 -1
- package/src/env/_zod-introspect.ts +1 -1
- package/src/env/dry-run.ts +1 -1
- package/src/env/index.ts +1 -1
- package/src/errors/__tests__/classes.test.ts +1 -1
- package/src/es-ops/__tests__/runner.integration.test.ts +1 -1
- package/src/event-store/__tests__/backfill-pii.integration.test.ts +1 -1
- package/src/event-store/__tests__/event-attribution.integration.test.ts +1 -1
- package/src/event-store/__tests__/upcaster.integration.test.ts +1 -1
- package/src/jobs/__tests__/job-backoff.integration.test.ts +1 -1
- package/src/jobs/__tests__/job-event-trigger.integration.test.ts +1 -1
- package/src/jobs/__tests__/job-multi-trigger.integration.test.ts +1 -1
- package/src/jobs/__tests__/job-public-intake-origin.integration.test.ts +1 -1
- package/src/jobs/__tests__/job-retention.integration.test.ts +1 -1
- package/src/jobs/__tests__/job-write-as.integration.test.ts +1 -1
- package/src/jobs/__tests__/jobs.integration.test.ts +1 -1
- package/src/observability/__tests__/metrics-wiring.test.ts +1 -1
- package/src/observability/__tests__/observability.integration.test.ts +1 -1
- package/src/observability/metrics-wiring.ts +1 -1
- package/src/pipeline/__tests__/archive-stream.integration.test.ts +1 -1
- package/src/pipeline/__tests__/causation-chain.integration.test.ts +1 -1
- package/src/pipeline/__tests__/ctx-bridge.integration.test.ts +1 -1
- package/src/pipeline/__tests__/ctx-systemdb.integration.test.ts +1 -1
- package/src/pipeline/__tests__/dispatcher.test.ts +1 -1
- package/src/pipeline/__tests__/domain-events-projections.integration.test.ts +1 -1
- package/src/pipeline/__tests__/escape-hatch-audit.integration.test.ts +1 -1
- package/src/pipeline/__tests__/escape-hatch.integration.test.ts +1 -1
- package/src/pipeline/__tests__/event-dedup.integration.test.ts +1 -1
- package/src/pipeline/__tests__/event-define-event-strict.integration.test.ts +1 -1
- package/src/pipeline/__tests__/event-dispatcher-batch-delivery.test.ts +178 -0
- package/src/pipeline/__tests__/event-dispatcher-batch-handler.integration.test.ts +143 -0
- package/src/pipeline/__tests__/event-dispatcher-db-outage.integration.test.ts +192 -0
- package/src/pipeline/__tests__/event-dispatcher-idle.integration.test.ts +94 -0
- package/src/pipeline/__tests__/event-dispatcher-start-from.integration.test.ts +103 -3
- package/src/pipeline/__tests__/fetch-for-writing.integration.test.ts +1 -1
- package/src/pipeline/__tests__/idempotency-transient-failure.integration.test.ts +1 -1
- package/src/pipeline/__tests__/job-trigger-consumer.integration.test.ts +1 -1
- package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +1 -1
- package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +1 -1
- package/src/pipeline/__tests__/msp-multi-hop.integration.test.ts +1 -1
- package/src/pipeline/__tests__/msp-rebuild.integration.test.ts +116 -1
- package/src/pipeline/__tests__/multi-stream-projection.integration.test.ts +1 -1
- package/src/pipeline/__tests__/pending-gap-ranges.test.ts +94 -0
- package/src/pipeline/__tests__/post-query-hook.integration.test.ts +1 -1
- package/src/pipeline/__tests__/public-intake-runtime-gate.integration.test.ts +1 -1
- package/src/pipeline/__tests__/query-projection.integration.test.ts +1 -1
- package/src/pipeline/__tests__/rate-limit-default.integration.test.ts +1 -1
- package/src/pipeline/__tests__/rebuild-poison-quarantine.integration.test.ts +1 -1
- package/src/pipeline/__tests__/search-consumer-named-events.integration.test.ts +1 -1
- package/src/pipeline/__tests__/system-identity-switch.integration.test.ts +1 -1
- package/src/pipeline/__tests__/try-append-event.integration.test.ts +1 -1
- package/src/pipeline/__tests__/unsafe-raw-escape-hatch.integration.test.ts +1 -1
- package/src/pipeline/dispatch-stream.ts +6 -1
- package/src/pipeline/event-dispatcher-delivery.ts +132 -37
- package/src/pipeline/event-dispatcher.ts +121 -17
- package/src/pipeline/index.ts +1 -0
- package/src/pipeline/msp-rebuild.ts +39 -1
- package/src/pipeline/pending-gap-ranges.ts +48 -0
- package/src/pipeline/system-hooks.ts +223 -68
- package/src/pipeline/write-origin.ts +1 -1
- package/src/rate-limit/__tests__/dispatcher-l3.integration.test.ts +1 -1
- package/src/search/__tests__/derive-search-adapter-config.test.ts +65 -0
- package/src/search/__tests__/meilisearch-adapter.integration.test.ts +91 -0
- package/src/search/__tests__/search-consumer-batch.integration.test.ts +306 -0
- package/src/search/derive-search-adapter-config.ts +27 -0
- package/src/search/index.ts +1 -0
- package/src/search/meilisearch-adapter.ts +96 -14
- package/src/secrets/__tests__/contains-secret.test.ts +1 -1
- package/src/stack/__tests__/request-helper.integration.test.ts +1 -1
- package/src/stack/__tests__/setup-test-stack-entity-tables.integration.test.ts +65 -0
- package/src/stack/__tests__/setup-test-stack-jobs.integration.test.ts +1 -1
- package/src/stack/__tests__/setup-test-stack-metrics.integration.test.ts +1 -1
- package/src/stack/test-stack.ts +61 -54
- package/src/testing/__tests__/e2e-generator.test.ts +1 -1
- package/src/testing/__tests__/real-providers.test.ts +9 -1
- package/src/testing/e2e-generator.ts +1 -1
- package/src/testing/index.ts +1 -1
- package/src/testing/real-providers.ts +12 -4
package/src/stack/test-stack.ts
CHANGED
|
@@ -4,7 +4,6 @@ import type { JwtHelper } from "../api/jwt";
|
|
|
4
4
|
import { buildServer } from "../api/server";
|
|
5
5
|
import { createSseBroker, type SseBroker } from "../api/sse-broker";
|
|
6
6
|
import type { PgClient } from "../db/connection";
|
|
7
|
-
import { extractTableInfo } from "../db/query";
|
|
8
7
|
import { validateOwnershipBoot } from "../engine/boot-validator/ownership";
|
|
9
8
|
import { createRegistry } from "../engine/registry";
|
|
10
9
|
import type { AppContext, FeatureDefinition, JobRunIn, Registry, TenantId } from "../engine/types";
|
|
@@ -181,6 +180,10 @@ export type TestStackOptions = {
|
|
|
181
180
|
* out (e.g. 60_000) so the polling timer can't land inside the
|
|
182
181
|
* assertion window and mask a dead subscription — see E.4 (#2042). */
|
|
183
182
|
eventDispatcherPollIntervalMs?: number;
|
|
183
|
+
/** Opt out of auto-created r.entity() tables for callers that create/migrate
|
|
184
|
+
* them themselves. Default true — false pushes only projection/MSP/
|
|
185
|
+
* storeTable sources, same as before fw#3102. */
|
|
186
|
+
entityTables?: boolean;
|
|
184
187
|
};
|
|
185
188
|
|
|
186
189
|
const DEFAULT_JWT_SECRET = "test-stack-secret-minimum-32-characters!!";
|
|
@@ -215,68 +218,72 @@ export async function setupTestStack(options: TestStackOptions): Promise<TestSta
|
|
|
215
218
|
createTestRedis(),
|
|
216
219
|
]);
|
|
217
220
|
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
221
|
+
// Any throw in this DDL region must still drop the just-created ephemeral
|
|
222
|
+
// DB/Redis — the caller never gets the stack object back to call
|
|
223
|
+
// cleanup() itself (same "leaked ephemeral DB" failure class as the later
|
|
224
|
+
// try/catch below, but for setup that runs before that try starts).
|
|
225
|
+
try {
|
|
226
|
+
// Every ES-entity writes events via createEventStoreExecutor in the
|
|
227
|
+
// feature's write handlers. Auto-create the events table so every
|
|
228
|
+
// setupTestStack call is ready for writes without needing a manual
|
|
229
|
+
// createEventsTable().
|
|
230
|
+
await createEventsTable(testDb.db);
|
|
231
|
+
// Archive-stream metadata — needed by ctx.appendEvent's archive guard and
|
|
232
|
+
// loadAggregate's default-skip. Idempotent, so production boot running
|
|
233
|
+
// the same call is fine.
|
|
234
|
+
await createArchivedStreamsTable(testDb.db);
|
|
227
235
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
236
|
+
// Framework state for projection rebuild/status + event-consumer cursors.
|
|
237
|
+
// Idempotent — production boot flows run the same calls.
|
|
238
|
+
const { createProjectionStateTable, createEventConsumerStateTable } = await import(
|
|
239
|
+
"../pipeline"
|
|
240
|
+
);
|
|
241
|
+
await createProjectionStateTable(testDb.db);
|
|
242
|
+
await createEventConsumerStateTable(testDb.db);
|
|
233
243
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Projection-/MSP-/raw-tables: the executor (or async dispatcher) writes
|
|
243
|
-
// into them as soon as the first matching event flows, so the DDL must
|
|
244
|
-
// exist before setupTestStack returns. The source list is shared with
|
|
245
|
-
// collectTableMetas (`kumiko schema generate`) — divergence between the
|
|
246
|
-
// two was exactly the #255 prod-crash. Two registrations backed by the
|
|
247
|
-
// same physical table (e.g. an alternative apply-shape for the same
|
|
248
|
-
// read-model in a test feature) are deduped by table reference so we
|
|
249
|
-
// emit only one CREATE TABLE per physical table.
|
|
250
|
-
const { enumerateFeatureTableSources } = await import("../db/feature-table-sources");
|
|
251
|
-
const projectionTables: Record<string, unknown> = {};
|
|
252
|
-
// Dedup by NAME, matching collectTableMetas — by-reference alone let two
|
|
253
|
-
// distinct table objects with the same name slip through as a double
|
|
254
|
-
// CREATE TABLE while schema-generate emitted only one meta (silent
|
|
255
|
-
// test-vs-schema divergence).
|
|
256
|
-
const seenTableNames = new Set<string>();
|
|
257
|
-
for (const feature of options.features) {
|
|
258
|
-
for (const { table, origin } of enumerateFeatureTableSources(feature)) {
|
|
259
|
-
const name = extractTableInfo(table).name;
|
|
260
|
-
if (seenTableNames.has(name)) continue;
|
|
261
|
-
seenTableNames.add(name);
|
|
262
|
-
projectionTables[origin] = table;
|
|
244
|
+
// Files support: when a provider is registered, the fileRefs table must
|
|
245
|
+
// exist before the first upload. Skipped when no provider — the table
|
|
246
|
+
// stays off tenant test DBs that never touch files.
|
|
247
|
+
if (options.files) {
|
|
248
|
+
const { fileRefsTable } = await import("../files");
|
|
249
|
+
await unsafePushTables(testDb.db, { fileRefsTable });
|
|
263
250
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
//
|
|
267
|
-
|
|
268
|
-
// were created during a previous run. Filter out the ones that already
|
|
269
|
-
// exist so the re-boot doesn't fail on duplicate CREATE TABLE.
|
|
251
|
+
|
|
252
|
+
// Same table list as `kumiko schema generate` (collectTableMetas) — divergence
|
|
253
|
+
// was the #255 prod-crash and the #3102 missing r.entity() tables.
|
|
254
|
+
const { collectTableMetas } = await import("../db/collect-table-metas");
|
|
270
255
|
const { tableExists } = await import("../db/schema-inspection");
|
|
256
|
+
let metas = collectTableMetas(options.features);
|
|
257
|
+
if (options.entityTables === false) {
|
|
258
|
+
const { enumerateFeatureTableSources } = await import("../db/feature-table-sources");
|
|
259
|
+
const { extractTableInfo } = await import("../db/query");
|
|
260
|
+
const nonEntityNames = new Set(
|
|
261
|
+
options.features.flatMap((f) =>
|
|
262
|
+
enumerateFeatureTableSources(f).map((s) => extractTableInfo(s.table).name),
|
|
263
|
+
),
|
|
264
|
+
);
|
|
265
|
+
metas = metas.filter((m) => nonEntityNames.has(m.tableName));
|
|
266
|
+
}
|
|
271
267
|
const missing: Record<string, unknown> = {};
|
|
272
|
-
for (const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
missing[key] = tbl;
|
|
268
|
+
for (const meta of metas) {
|
|
269
|
+
if (await tableExists(testDb.db, `public.${meta.tableName}`)) continue;
|
|
270
|
+
missing[meta.tableName] = meta;
|
|
276
271
|
}
|
|
277
272
|
if (Object.keys(missing).length > 0) {
|
|
278
273
|
await unsafePushTables(testDb.db, missing);
|
|
279
274
|
}
|
|
275
|
+
} catch (error) {
|
|
276
|
+
try {
|
|
277
|
+
await testDb.cleanup();
|
|
278
|
+
} catch {
|
|
279
|
+
// ignore — `error` is the one that matters
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
await testRedis.cleanup();
|
|
283
|
+
} catch {
|
|
284
|
+
// ignore — `error` is the one that matters
|
|
285
|
+
}
|
|
286
|
+
throw error;
|
|
280
287
|
}
|
|
281
288
|
|
|
282
289
|
const searchAdapter = createInMemorySearchAdapter();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
-
import { requireRealProviders } from "../real-providers";
|
|
2
|
+
import { isRealProviderRun, REAL_PROVIDERS_ENV, requireRealProviders } from "../real-providers";
|
|
3
3
|
|
|
4
4
|
const CI = "CI";
|
|
5
5
|
const FLAG = "KUMIKO_REAL_PROVIDERS";
|
|
@@ -52,3 +52,11 @@ describe("requireRealProviders", () => {
|
|
|
52
52
|
expect(() => requireRealProviders()).not.toThrow();
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
|
+
|
|
56
|
+
describe("isRealProviderRun", () => {
|
|
57
|
+
test("reads the exported flag name from an explicit env map, defaulting to process.env", () => {
|
|
58
|
+
expect(isRealProviderRun({ [REAL_PROVIDERS_ENV]: "1" })).toBe(true);
|
|
59
|
+
expect(isRealProviderRun({ [REAL_PROVIDERS_ENV]: "true" })).toBe(false);
|
|
60
|
+
expect(isRealProviderRun({})).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
// "not supported yet" — wir füllen nach, wenn ein echter Caller es braucht.
|
|
25
25
|
// Fake-komplexe-Werte würden nur False-Green-Tests produzieren.
|
|
26
26
|
|
|
27
|
-
import type
|
|
27
|
+
import type * as z from "zod";
|
|
28
28
|
import {
|
|
29
29
|
type EntityDefinition,
|
|
30
30
|
type EntityEditScreenDefinition,
|
package/src/testing/index.ts
CHANGED
|
@@ -45,7 +45,7 @@ export {
|
|
|
45
45
|
createRecordingProvider,
|
|
46
46
|
type RecordingProvider,
|
|
47
47
|
} from "./observability-recorder";
|
|
48
|
-
export { requireRealProviders } from "./real-providers";
|
|
48
|
+
export { isRealProviderRun, REAL_PROVIDERS_ENV, requireRealProviders } from "./real-providers";
|
|
49
49
|
export { deleteRows, seedRow, seedRows, updateRows } from "./seed";
|
|
50
50
|
export {
|
|
51
51
|
sharedItemEntity,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
export const REAL_PROVIDERS_ENV = "KUMIKO_REAL_PROVIDERS";
|
|
2
2
|
const CI_FLAG = "CI";
|
|
3
3
|
|
|
4
4
|
function isCi(): boolean {
|
|
@@ -6,15 +6,23 @@ function isCi(): boolean {
|
|
|
6
6
|
return ci !== undefined && ci !== "" && ci !== "0" && ci.toLowerCase() !== "false";
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
// Apps and the e2e/bunfig templates gate real-provider runs on this same
|
|
10
|
+
// check instead of re-reading KUMIKO_REAL_PROVIDERS themselves.
|
|
11
|
+
export function isRealProviderRun(
|
|
12
|
+
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
13
|
+
): boolean {
|
|
14
|
+
return env[REAL_PROVIDERS_ENV] === "1";
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
export function requireRealProviders(): void {
|
|
10
18
|
if (isCi()) {
|
|
11
19
|
throw new Error(
|
|
12
|
-
`Real-provider tests never run in CI (CI is set). Run them locally with ${
|
|
20
|
+
`Real-provider tests never run in CI (CI is set). Run them locally with ${REAL_PROVIDERS_ENV}=1 via the test:real / e2e:real script.`,
|
|
13
21
|
);
|
|
14
22
|
}
|
|
15
|
-
if (
|
|
23
|
+
if (!isRealProviderRun()) {
|
|
16
24
|
throw new Error(
|
|
17
|
-
`Real-provider test needs ${
|
|
25
|
+
`Real-provider test needs ${REAL_PROVIDERS_ENV}=1 (an API key alone never enables it). Run it via the test:real / e2e:real script.`,
|
|
18
26
|
);
|
|
19
27
|
}
|
|
20
28
|
}
|