@cosmicdrift/kumiko-framework 0.367.0 → 0.369.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/AGENTS.md +1 -7
- package/README.md +1 -1
- package/agents/examples/access-control.md +2 -2
- package/agents/examples/anonymous-access-multitenant.md +2 -2
- package/agents/examples/anonymous-access.md +3 -3
- package/agents/examples/apex-landing.md +1 -1
- package/agents/examples/apex-surface-auth.md +6 -7
- package/agents/examples/api-worker-split.md +7 -8
- package/agents/examples/auth-claims.md +2 -1
- package/agents/examples/auth-foundation-providers.md +3 -3
- package/agents/examples/auth-mfa.md +3 -4
- package/agents/examples/basic-entity.md +3 -4
- package/agents/examples/chat-channels.md +4 -4
- package/agents/examples/compliance-profiles-demo.md +2 -3
- package/agents/examples/cross-feature-events.md +4 -4
- package/agents/examples/crypto-shredding-hr.md +14 -9
- package/agents/examples/currencies-global.md +3 -4
- package/agents/examples/currencies-per-tenant.md +3 -4
- package/agents/examples/custom-fields-basic.md +2 -3
- package/agents/examples/custom-handlers.md +3 -5
- package/agents/examples/dashboard-stats.md +2 -3
- package/agents/examples/delivery-notifications.md +5 -6
- package/agents/examples/e2e-generator.md +1 -1
- package/agents/examples/embedded-entity-form.md +2 -3
- package/agents/examples/embedded.md +2 -3
- package/agents/examples/encrypted-tenant-config.md +5 -6
- package/agents/examples/error-contract.md +3 -4
- package/agents/examples/event-sourcing.md +19 -23
- package/agents/examples/feature-toggles.md +4 -4
- package/agents/examples/field-access.md +3 -4
- package/agents/examples/files-post-processing.md +12 -13
- package/agents/examples/golden-path.md +208 -0
- package/agents/examples/idempotency.md +2 -2
- package/agents/examples/inbound-mail-triage.md +7 -7
- package/agents/examples/lane-routing.md +3 -3
- package/agents/examples/ledger-banking.md +2 -3
- package/agents/examples/ledger-invoicing.md +2 -3
- package/agents/examples/legal-pages.md +1 -1
- package/agents/examples/lifecycle-hooks.md +3 -3
- package/agents/examples/managed-config.md +3 -4
- package/agents/examples/managed-pages.md +2 -2
- package/agents/examples/notes-history-basic.md +4 -5
- package/agents/examples/ownership.md +3 -5
- package/agents/examples/pdf-audit-export.md +2 -3
- package/agents/examples/pipeline-basics.md +2 -2
- package/agents/examples/public-share-token.md +3 -3
- package/agents/examples/rate-limiting.md +2 -1
- package/agents/examples/realtime-sse.md +2 -3
- package/agents/examples/record-detail-layout.md +1 -1
- package/agents/examples/reference-data.md +3 -3
- package/agents/examples/relations.md +2 -2
- package/agents/examples/screens-nav.md +1 -1
- package/agents/examples/search.md +2 -2
- package/agents/examples/secrets-demo.md +8 -8
- package/agents/examples/security-baseline.md +2 -2
- package/agents/examples/session-revocation.md +7 -8
- package/agents/examples/state-machine.md +181 -165
- package/agents/examples/tags-basic.md +2 -3
- package/agents/examples/tenant-isolation.md +2 -3
- package/agents/examples/tenant-settings.md +2 -2
- package/agents/examples/tier-admin.md +3 -4
- package/agents/examples/timezones.md +3 -3
- package/agents/examples/user-data-rights.md +12 -8
- package/agents/examples/user-profile.md +3 -3
- package/agents/examples/webhook-step.md +2 -3
- package/agents/examples/wizard-form.md +4 -5
- package/agents/examples/workflow-engine.md +7 -3
- package/agents/examples/writeform-section.md +1 -1
- package/agents/examples.md +1 -0
- package/agents/features.md +4 -4
- package/dist/consumer-cli.js +2 -3
- package/dist/crypto/index.d.ts +1 -1
- package/dist/crypto/index.js +1 -1
- package/dist/crypto/owner-transition-rekey.js +2 -0
- package/dist/crypto/pg-kms-adapter.js +1 -1
- package/dist/crypto/subject-resolver.d.ts +2 -0
- package/dist/crypto/subject-resolver.js +30 -15
- package/dist/db/bun-db-deprecated.d.ts +10 -0
- package/dist/{bun-db/index.js → db/bun-db-deprecated.js} +4 -3
- package/dist/db/config-seed.js +1 -1
- package/dist/db/connection.d.ts +23 -5
- package/dist/db/connection.js +10 -5
- package/dist/db/dialect.js +1 -1
- package/dist/db/entity-field-encryption.d.ts +5 -0
- package/dist/db/entity-field-encryption.js +29 -0
- package/dist/db/entity-table-meta.js +6 -5
- package/dist/db/event-store-executor-read.js +26 -5
- package/dist/db/index.d.ts +4 -4
- package/dist/db/index.js +1 -1
- package/dist/db/migrate-runner.js +1 -1
- package/dist/db/queries/backfill-pii.js +16 -9
- package/dist/db/queries/ddl.js +1 -1
- package/dist/db/queries/event-store.d.ts +2 -0
- package/dist/db/queries/event-store.js +26 -0
- package/dist/db/queries/test-stack.js +1 -1
- package/dist/db/query.d.ts +105 -1
- package/dist/db/query.js +1450 -3
- package/dist/{stack/table-helpers.d.ts → db/table-push.d.ts} +5 -15
- package/dist/{stack/table-helpers.js → db/table-push.js} +6 -46
- package/dist/db/tenant-db.d.ts +11 -0
- package/dist/db/tenant-db.js +51 -12
- package/dist/derivatives/derivatives-context.d.ts +1 -1
- package/dist/derivatives/derivatives-context.js +1 -1
- package/dist/engine/boot-validator/gdpr-storage.js +3 -3
- package/dist/engine/boot-validator/pii-retention.js +3 -3
- package/dist/engine/boot-validator/record-owned.js +3 -3
- package/dist/engine/boot-validator/screens.js +37 -1
- package/dist/engine/bridge-stub.d.ts +4 -0
- package/dist/engine/bridge-stub.js +62 -0
- package/dist/engine/build-config-feature-schema.js +197 -65
- package/dist/engine/event-helpers.d.ts +2 -1
- package/dist/engine/event-helpers.js +1 -0
- package/dist/engine/extension-selector-plugins.d.ts +3 -0
- package/dist/engine/extension-selector-plugins.js +14 -0
- package/dist/engine/feature-config-events-jobs.d.ts +2 -0
- package/dist/engine/feature-config-events-jobs.js +3 -2
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/index.js +1 -0
- package/dist/es-ops/operations-schema.js +1 -1
- package/dist/event-store/admin-api.js +1 -1
- package/dist/event-store/archive.js +1 -1
- package/dist/event-store/errors.d.ts +2 -1
- package/dist/event-store/errors.js +6 -2
- package/dist/event-store/event-store.js +17 -9
- package/dist/event-store/events-schema.js +1 -1
- package/dist/event-store/rebuild-dead-letter.js +3 -3
- package/dist/event-store/snapshot.js +1 -1
- package/dist/event-store/upcaster-dead-letter.js +3 -3
- package/dist/files/create-file-ref-from-bytes.js +1 -1
- package/dist/files/file-routes.js +1 -1
- package/dist/i18n/settings-hub-keys.js +1 -2
- package/dist/internal/stack-support.d.ts +12 -0
- package/dist/internal/stack-support.js +12 -0
- package/dist/internal/testing.d.ts +4 -0
- package/dist/internal/testing.js +5 -0
- package/dist/jobs/job-runner.js +23 -11
- package/dist/migrations/pending-rebuilds.js +1 -1
- package/dist/migrations/pii-event-backfill.js +2 -2
- package/dist/pipeline/dispatch-shared.js +43 -23
- package/dist/pipeline/dispatch-write.js +6 -2
- package/dist/pipeline/dispatcher-utils.js +6 -2
- package/dist/pipeline/event-consumer-state.js +1 -1
- package/dist/pipeline/projection-rebuild.d.ts +1 -0
- package/dist/pipeline/projection-rebuild.js +1 -1
- package/dist/pipeline/projection-state.js +1 -1
- package/dist/pipeline/system-hooks.js +1 -1
- package/dist/schema-cli.js +3 -3
- package/dist/search/purge-subject.js +20 -10
- package/dist/seeding/index.d.ts +1 -0
- package/dist/seeding/index.js +1 -0
- package/dist/stack/index.d.ts +10 -9
- package/dist/stack/index.js +11 -19
- package/dist/testing/e2e-generator.d.ts +5 -49
- package/dist/testing/e2e-generator.js +5 -382
- package/dist/testing/handler-context.d.ts +5 -4
- package/dist/testing/handler-context.js +5 -69
- package/dist/testing/index.d.ts +10 -26
- package/dist/testing/index.js +10 -34
- package/dist/testing/real-providers.d.ts +5 -3
- package/dist/testing/real-providers.js +5 -21
- package/dist/upgrade-cli.js +6 -4
- package/package.json +37 -9
- package/src/changes.json +64 -0
- package/src/scripts/codemod/README.md +43 -0
- package/src/scripts/codemod/codemod-support.ts +276 -0
- package/src/scripts/codemod/db-factory.ts +810 -0
- package/src/scripts/codemod/feature-factory.ts +429 -0
- package/src/scripts/codemod/s3-imports.ts +274 -0
- package/src/scripts/codemod/tenant-db-options.ts +454 -0
- package/src/scripts/codemod/testing-move-targets.ts +161 -0
- package/src/scripts/codemod/testing-move.ts +520 -0
- package/dist/bun-db/connection.d.ts +0 -17
- package/dist/bun-db/connection.js +0 -40
- package/dist/bun-db/index.d.ts +0 -4
- package/dist/bun-db/query.d.ts +0 -106
- package/dist/bun-db/query.js +0 -1457
- package/dist/db/api.d.ts +0 -19
- package/dist/db/api.js +0 -23
- package/dist/db/bun-provider.d.ts +0 -2
- package/dist/db/bun-provider.js +0 -28
- package/dist/db/postgres-provider.d.ts +0 -2
- package/dist/db/postgres-provider.js +0 -21
- package/dist/db/query-api.d.ts +0 -2
- package/dist/db/query-api.js +0 -6
- package/dist/stack/db.d.ts +0 -22
- package/dist/stack/db.js +0 -67
- package/dist/stack/drain-event-consumers.d.ts +0 -4
- package/dist/stack/drain-event-consumers.js +0 -51
- package/dist/stack/drain-jobs.d.ts +0 -22
- package/dist/stack/drain-jobs.js +0 -141
- package/dist/stack/event-collector.d.ts +0 -9
- package/dist/stack/event-collector.js +0 -12
- package/dist/stack/push-entity-projection-tables.d.ts +0 -24
- package/dist/stack/push-entity-projection-tables.js +0 -74
- package/dist/stack/redis.d.ts +0 -17
- package/dist/stack/redis.js +0 -52
- package/dist/stack/request-helper.d.ts +0 -35
- package/dist/stack/request-helper.js +0 -144
- package/dist/stack/test-stack.d.ts +0 -192
- package/dist/stack/test-stack.js +0 -429
- package/dist/testing/access-assertions.d.ts +0 -2
- package/dist/testing/access-assertions.js +0 -13
- package/dist/testing/assertions.d.ts +0 -10
- package/dist/testing/assertions.js +0 -22
- package/dist/testing/boot-validator-fixture.d.ts +0 -3
- package/dist/testing/boot-validator-fixture.js +0 -101
- package/dist/testing/closed-connection-error.d.ts +0 -7
- package/dist/testing/closed-connection-error.js +0 -46
- package/dist/testing/db-cleanup.d.ts +0 -9
- package/dist/testing/db-cleanup.js +0 -31
- package/dist/testing/expect-error.d.ts +0 -2
- package/dist/testing/expect-error.js +0 -22
- package/dist/testing/file-provider-contract.d.ts +0 -2
- package/dist/testing/file-provider-contract.js +0 -102
- package/dist/testing/http-cookies.d.ts +0 -7
- package/dist/testing/http-cookies.js +0 -47
- package/dist/testing/late-bound.d.ts +0 -9
- package/dist/testing/late-bound.js +0 -31
- package/dist/testing/manual-clock.d.ts +0 -14
- package/dist/testing/manual-clock.js +0 -12
- package/dist/testing/multipart-helper.d.ts +0 -22
- package/dist/testing/multipart-helper.js +0 -77
- package/dist/testing/mutable-master-key-provider.d.ts +0 -7
- package/dist/testing/mutable-master-key-provider.js +0 -35
- package/dist/testing/observability-recorder.d.ts +0 -9
- package/dist/testing/observability-recorder.js +0 -29
- package/dist/testing/seed.d.ts +0 -9
- package/dist/testing/seed.js +0 -21
- package/dist/testing/shared-entities.d.ts +0 -286
- package/dist/testing/shared-entities.js +0 -56
- package/dist/testing/utils.d.ts +0 -1
- package/dist/testing/utils.js +0 -1
- package/dist/testing/wait-for.d.ts +0 -20
- package/dist/testing/wait-for.js +0 -47
- package/dist/testing/without-ambient-temporal.d.ts +0 -5
- package/dist/testing/without-ambient-temporal.js +0 -17
- package/dist/testing/zip-fixture.d.ts +0 -1
- package/dist/testing/zip-fixture.js +0 -33
- /package/dist/{stack/test-users.d.ts → seeding/seed-users.d.ts} +0 -0
- /package/dist/{stack/test-users.js → seeding/seed-users.js} +0 -0
|
@@ -1,49 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly title: string;
|
|
7
|
-
readonly urlPath: string;
|
|
8
|
-
} | {
|
|
9
|
-
readonly kind: "list-has-fixture-row";
|
|
10
|
-
readonly screenQn: string;
|
|
11
|
-
readonly title: string;
|
|
12
|
-
readonly urlPath: string;
|
|
13
|
-
readonly writeHandlerQn: string;
|
|
14
|
-
readonly fixture: Readonly<Record<string, unknown>>;
|
|
15
|
-
readonly identifyingValue: string;
|
|
16
|
-
} | {
|
|
17
|
-
readonly kind: "edit-validates-required";
|
|
18
|
-
readonly screenQn: string;
|
|
19
|
-
readonly title: string;
|
|
20
|
-
readonly urlPath: string;
|
|
21
|
-
readonly requiredFields: readonly string[];
|
|
22
|
-
} | {
|
|
23
|
-
readonly kind: "edit-save-persists";
|
|
24
|
-
readonly screenQn: string;
|
|
25
|
-
readonly title: string;
|
|
26
|
-
readonly urlPath: string;
|
|
27
|
-
readonly listUrlPath?: string;
|
|
28
|
-
readonly fills: readonly EditFillOp[];
|
|
29
|
-
readonly identifyingValue: string;
|
|
30
|
-
readonly identifyingField: string;
|
|
31
|
-
};
|
|
32
|
-
export type EditFillOp = {
|
|
33
|
-
readonly kind: "fill";
|
|
34
|
-
readonly field: string;
|
|
35
|
-
readonly value: string;
|
|
36
|
-
} | {
|
|
37
|
-
readonly kind: "check";
|
|
38
|
-
readonly field: string;
|
|
39
|
-
readonly value: boolean;
|
|
40
|
-
} | {
|
|
41
|
-
readonly kind: "select";
|
|
42
|
-
readonly field: string;
|
|
43
|
-
readonly value: string;
|
|
44
|
-
};
|
|
45
|
-
export type E2EGeneratorOptions = {
|
|
46
|
-
readonly tenantPlaceholder?: string;
|
|
47
|
-
};
|
|
48
|
-
export declare function generateE2ESpec(registry: Registry, options?: E2EGeneratorOptions): readonly E2ETestSpec[];
|
|
49
|
-
export declare function generateZodFixture(schema: z.ZodTypeAny): unknown;
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-testing/helpers/e2e-generator`. Run
|
|
3
|
+
* `bun kumiko-upgrade --apply` to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export * from "@cosmicdrift/kumiko-testing/helpers/e2e-generator";
|
|
@@ -1,382 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// iteriert getAllScreens() und baut pro Screen einen Satz TestSpecs (vier
|
|
7
|
-
// Kinds, einer pro "was muss mindestens funktionieren"). Die Specs sind
|
|
8
|
-
// JSON-serialisierbar — Consumer (Sample/Package-e2e) schreiben sie via
|
|
9
|
-
// bun-Script als JSON auf Platte, und ein Playwright-globalSetup triggert
|
|
10
|
-
// das vor jedem Run. Der eigentliche Playwright-Runner liest die JSON und
|
|
11
|
-
// iteriert mit kind-spezifischen Handlern gegen den echten Renderer.
|
|
12
|
-
//
|
|
13
|
-
// Vorteil des 2-Prozess-Modells: die framework-runtime (Registry, drizzle,
|
|
14
|
-
// ioredis-types etc.) lädt NIE im Playwright-Worker. Würde sie das, kollidierte
|
|
15
|
-
// sie mit Playwrights Object.prototype-Symbolen ($$jest-matchers-object) und
|
|
16
|
-
// der Worker würde beim spec-import crashen.
|
|
17
|
-
//
|
|
18
|
-
// Zwei Stufen, jede einzeln testbar:
|
|
19
|
-
// 1. generateE2ESpec(registry) — Registry → TestSpec[]
|
|
20
|
-
// 2. generateZodFixture(schema) — ZodType → plausibler Value
|
|
21
|
-
//
|
|
22
|
-
// Stufe 2 ist intentionally minimal (Strategy a aus dem Plan): string/number/
|
|
23
|
-
// boolean/date/enum/uuid + ZodOptional/ZodDefault-Unwrap. Alles andere wirft
|
|
24
|
-
// "not supported yet" — wir füllen nach, wenn ein echter Caller es braucht.
|
|
25
|
-
// Fake-komplexe-Werte würden nur False-Green-Tests produzieren.
|
|
26
|
-
import { isFieldsEditSection, normalizeEditField, normalizeListColumn, parseQn, qn, sectionFieldSpecs, toKebab, } from "../engine/index.js";
|
|
27
|
-
// --- Stufe 1: Spec-Ableitung aus der Registry ---
|
|
28
|
-
export function generateE2ESpec(registry, options = {}) {
|
|
29
|
-
const tenant = options.tenantPlaceholder ?? "{tenant}";
|
|
30
|
-
const specs = [];
|
|
31
|
-
for (const [screenQn, screen] of registry.getAllScreens()) {
|
|
32
|
-
if (screen.type === "custom")
|
|
33
|
-
continue; // keine generische Annahme möglich
|
|
34
|
-
// actionForm: kein generischer E2E-Spec — Author-defined Handler
|
|
35
|
-
// braucht Author-defined Test-Daten, die der Generator nicht kennt.
|
|
36
|
-
if (screen.type === "actionForm")
|
|
37
|
-
continue;
|
|
38
|
-
// secretMint: same reasoning — author-defined write handler, no generic spec.
|
|
39
|
-
if (screen.type === "secretMint")
|
|
40
|
-
continue;
|
|
41
|
-
// configEdit: dito — die Werte werden über config:write:set
|
|
42
|
-
// pro Field geschrieben, ohne CRUD-Zustand zu generieren wäre der
|
|
43
|
-
// Spec wertlos. Branding/SMTP/etc. sind Author-spezifisch.
|
|
44
|
-
if (screen.type === "configEdit")
|
|
45
|
-
continue;
|
|
46
|
-
// secretsEdit: dito — writes go through secrets:write:set with
|
|
47
|
-
// plaintext values the generator has no author-defined test data for.
|
|
48
|
-
if (screen.type === "secretsEdit")
|
|
49
|
-
continue;
|
|
50
|
-
// projectionList: query-getrieben, Author-spezifische Projection —
|
|
51
|
-
// kein generischer CRUD-Spec ableitbar (wie actionForm/configEdit).
|
|
52
|
-
if (screen.type === "projectionList")
|
|
53
|
-
continue;
|
|
54
|
-
// projectionDetail: dito — read-only single-row inspector, kein CRUD-Zustand.
|
|
55
|
-
if (screen.type === "projectionDetail")
|
|
56
|
-
continue;
|
|
57
|
-
// dashboard: panel-getrieben (Stat/Chart/List-Queries) — dito, keine
|
|
58
|
-
// generische CRUD-Annahme möglich.
|
|
59
|
-
if (screen.type === "dashboard")
|
|
60
|
-
continue;
|
|
61
|
-
const { scope: feature, name: short } = parseQn(screenQn);
|
|
62
|
-
const urlPath = `/t/${tenant}/${feature}/${short}`;
|
|
63
|
-
const title = `${feature}/${short}`;
|
|
64
|
-
if (screen.type === "entityList") {
|
|
65
|
-
specs.push(...buildListSpecs(screen, screenQn, title, urlPath, registry));
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
specs.push(...buildEditSpecs(screen, screenQn, title, urlPath, registry, tenant));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return specs;
|
|
72
|
-
}
|
|
73
|
-
function buildListSpecs(screen, screenQn, title, urlPath, registry) {
|
|
74
|
-
const out = [{ kind: "list-renders", screenQn, title, urlPath }];
|
|
75
|
-
const entity = registry.getEntity(screen.entity);
|
|
76
|
-
if (!entity)
|
|
77
|
-
return out;
|
|
78
|
-
const writeHandlerQn = findCreateHandlerQn(registry, screen.entity);
|
|
79
|
-
if (!writeHandlerQn)
|
|
80
|
-
return out;
|
|
81
|
-
const fixture = buildEntityFixture(entity);
|
|
82
|
-
const identifyingValue = pickIdentifyingValue(fixture, screen, entity);
|
|
83
|
-
if (identifyingValue === undefined)
|
|
84
|
-
return out;
|
|
85
|
-
out.push({
|
|
86
|
-
kind: "list-has-fixture-row",
|
|
87
|
-
screenQn,
|
|
88
|
-
title,
|
|
89
|
-
urlPath,
|
|
90
|
-
writeHandlerQn,
|
|
91
|
-
fixture,
|
|
92
|
-
identifyingValue,
|
|
93
|
-
});
|
|
94
|
-
return out;
|
|
95
|
-
}
|
|
96
|
-
function buildEditSpecs(screen, screenQn, title, urlPath, registry, tenant) {
|
|
97
|
-
const out = [];
|
|
98
|
-
const entity = registry.getEntity(screen.entity);
|
|
99
|
-
if (!entity)
|
|
100
|
-
return out;
|
|
101
|
-
const requiredFields = collectRequiredEditFields(screen, entity);
|
|
102
|
-
if (requiredFields.length > 0) {
|
|
103
|
-
out.push({ kind: "edit-validates-required", screenQn, title, urlPath, requiredFields });
|
|
104
|
-
}
|
|
105
|
-
const fixture = buildEntityFixture(entity);
|
|
106
|
-
const listScreen = findListScreenForEntity(registry, screen.entity);
|
|
107
|
-
const listUrlPath = listScreen ? buildScreenUrlPath(listScreen.qn, tenant) : undefined;
|
|
108
|
-
const identifying = pickIdentifyingForEdit(fixture, screen, entity, listScreen?.def);
|
|
109
|
-
if (identifying) {
|
|
110
|
-
const fills = buildEditFillOps(screen, entity, fixture);
|
|
111
|
-
out.push({
|
|
112
|
-
kind: "edit-save-persists",
|
|
113
|
-
screenQn,
|
|
114
|
-
title,
|
|
115
|
-
urlPath,
|
|
116
|
-
listUrlPath,
|
|
117
|
-
fills,
|
|
118
|
-
identifyingValue: identifying.value,
|
|
119
|
-
identifyingField: identifying.field,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
return out;
|
|
123
|
-
}
|
|
124
|
-
function buildScreenUrlPath(qn, tenant) {
|
|
125
|
-
const { scope, name } = parseQn(qn);
|
|
126
|
-
return `/t/${tenant}/${scope}/${name}`;
|
|
127
|
-
}
|
|
128
|
-
function findCreateHandlerQn(registry, entityName) {
|
|
129
|
-
// feature.writeHandlers ist mit Short-Names gekeyt ("task:create"), der
|
|
130
|
-
// Registry-Lookup braucht die qualified Form ("tasks:write:task:create").
|
|
131
|
-
// Wir qualifizieren via qn() + toKebab wie die Registry selbst — das ist
|
|
132
|
-
// der Vertrag aus qualified-name.ts.
|
|
133
|
-
for (const feature of registry.features.values()) {
|
|
134
|
-
for (const shortName of Object.keys(feature.writeHandlers ?? {})) {
|
|
135
|
-
if (!shortName.endsWith(":create"))
|
|
136
|
-
continue;
|
|
137
|
-
const qualified = qn(toKebab(feature.name), "write", toKebab(shortName));
|
|
138
|
-
if (registry.getHandlerEntity(qualified) === entityName)
|
|
139
|
-
return qualified;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|
|
144
|
-
function findListScreenForEntity(registry, entityName) {
|
|
145
|
-
for (const [qn, screen] of registry.getAllScreens()) {
|
|
146
|
-
if (screen.type === "entityList" && screen.entity === entityName) {
|
|
147
|
-
return { qn, def: screen };
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return undefined;
|
|
151
|
-
}
|
|
152
|
-
function collectRequiredEditFields(screen, entity) {
|
|
153
|
-
const out = [];
|
|
154
|
-
for (const section of screen.layout.sections) {
|
|
155
|
-
if (!isFieldsEditSection(section))
|
|
156
|
-
continue;
|
|
157
|
-
for (const rawField of sectionFieldSpecs(section)) {
|
|
158
|
-
const { field } = normalizeEditField(rawField);
|
|
159
|
-
const def = entity.fields[field];
|
|
160
|
-
if (def && "required" in def && def.required === true) {
|
|
161
|
-
out.push(field);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return out;
|
|
166
|
-
}
|
|
167
|
-
function pickIdentifyingValue(fixture, screen, entity) {
|
|
168
|
-
// Erste Text-Spalte mit Fixture-Wert — das ist die visuell zuverlässigste
|
|
169
|
-
// Identifikation in einer generischen Tabelle.
|
|
170
|
-
for (const raw of screen.columns) {
|
|
171
|
-
const { field } = normalizeListColumn(raw);
|
|
172
|
-
if (entity.fields[field]?.type !== "text")
|
|
173
|
-
continue;
|
|
174
|
-
const v = fixture[field];
|
|
175
|
-
if (typeof v === "string" && v.length > 0)
|
|
176
|
-
return v;
|
|
177
|
-
}
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
|
-
function buildEditFillOps(screen, entity, fixture) {
|
|
181
|
-
// Laufe die Layout-Reihenfolge — das Resultat spiegelt, was ein User
|
|
182
|
-
// tatsächlich ausfüllt. Per Field-Typ entscheiden wir die Interaktions-
|
|
183
|
-
// form; Felder ohne Fixture-Wert (file/image/…) werden übersprungen.
|
|
184
|
-
const ops = [];
|
|
185
|
-
for (const section of screen.layout.sections) {
|
|
186
|
-
if (!isFieldsEditSection(section))
|
|
187
|
-
continue;
|
|
188
|
-
for (const raw of sectionFieldSpecs(section)) {
|
|
189
|
-
const { field } = normalizeEditField(raw);
|
|
190
|
-
const def = entity.fields[field];
|
|
191
|
-
if (!def)
|
|
192
|
-
continue;
|
|
193
|
-
const v = fixture[field];
|
|
194
|
-
if (v === undefined)
|
|
195
|
-
continue;
|
|
196
|
-
switch (def.type) {
|
|
197
|
-
case "boolean":
|
|
198
|
-
if (typeof v === "boolean")
|
|
199
|
-
ops.push({ kind: "check", field, value: v });
|
|
200
|
-
break;
|
|
201
|
-
case "select":
|
|
202
|
-
if (typeof v === "string")
|
|
203
|
-
ops.push({ kind: "select", field, value: v });
|
|
204
|
-
break;
|
|
205
|
-
case "text":
|
|
206
|
-
case "longText":
|
|
207
|
-
case "number":
|
|
208
|
-
case "date":
|
|
209
|
-
case "tz":
|
|
210
|
-
// date: ein Text-Input, akzeptiert getippte ISO-Werte direkt.
|
|
211
|
-
ops.push({ kind: "fill", field, value: String(v) });
|
|
212
|
-
break;
|
|
213
|
-
// embedded/money/timestamp/locatedTimestamp/file/image/files/images:
|
|
214
|
-
// keine generische Interaktion. timestamp rendert seit #369 zwei
|
|
215
|
-
// Inputs (Datum + Uhrzeit), die ein einzelnes .fill() nicht bedienen
|
|
216
|
-
// kann — der Test-Autor liefert einen Hand-Override oder überspringt.
|
|
217
|
-
default:
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return ops;
|
|
223
|
-
}
|
|
224
|
-
function pickIdentifyingForEdit(fixture, editScreen, entity, listScreen) {
|
|
225
|
-
// Bevorzugt ein Feld das im List-Screen als Column auftaucht — sonst ist
|
|
226
|
-
// die "taucht in Liste auf"-Assertion nicht durchführbar.
|
|
227
|
-
const columns = listScreen
|
|
228
|
-
? new Set(listScreen.columns.map((c) => normalizeListColumn(c).field))
|
|
229
|
-
: undefined;
|
|
230
|
-
for (const section of editScreen.layout.sections) {
|
|
231
|
-
if (!isFieldsEditSection(section))
|
|
232
|
-
continue;
|
|
233
|
-
for (const rawField of sectionFieldSpecs(section)) {
|
|
234
|
-
const { field } = normalizeEditField(rawField);
|
|
235
|
-
if (entity.fields[field]?.type !== "text")
|
|
236
|
-
continue;
|
|
237
|
-
if (columns && !columns.has(field))
|
|
238
|
-
continue;
|
|
239
|
-
const v = fixture[field];
|
|
240
|
-
if (typeof v === "string" && v.length > 0)
|
|
241
|
-
return { field, value: v };
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return undefined;
|
|
245
|
-
}
|
|
246
|
-
function readZodInternals(schema) {
|
|
247
|
-
return schema._def;
|
|
248
|
-
}
|
|
249
|
-
export function generateZodFixture(schema) {
|
|
250
|
-
const def = readZodInternals(schema);
|
|
251
|
-
const typeName = def?.type;
|
|
252
|
-
switch (typeName) {
|
|
253
|
-
case "optional":
|
|
254
|
-
case "nullable":
|
|
255
|
-
case "default": {
|
|
256
|
-
if (!def?.innerType)
|
|
257
|
-
throw new Error(`zod ${typeName} without innerType`);
|
|
258
|
-
return generateZodFixture(def.innerType);
|
|
259
|
-
}
|
|
260
|
-
case "string":
|
|
261
|
-
return fixtureString(def?.format);
|
|
262
|
-
case "number":
|
|
263
|
-
return 1;
|
|
264
|
-
case "boolean":
|
|
265
|
-
return true;
|
|
266
|
-
case "enum": {
|
|
267
|
-
const first = def?.entries ? Object.values(def.entries)[0] : undefined;
|
|
268
|
-
return first ?? "";
|
|
269
|
-
}
|
|
270
|
-
case "date":
|
|
271
|
-
return new Date("2026-01-01T00:00:00Z");
|
|
272
|
-
case "pipe": {
|
|
273
|
-
if (!def?.out)
|
|
274
|
-
throw new Error("zod pipe without out");
|
|
275
|
-
return generateZodFixture(def.out);
|
|
276
|
-
}
|
|
277
|
-
default:
|
|
278
|
-
throw new Error(`generateZodFixture: not supported yet: ${typeName ?? "<unknown>"}`);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
function fixtureString(format) {
|
|
282
|
-
if (format === "email")
|
|
283
|
-
return "e2e@example.com";
|
|
284
|
-
if (format === "url")
|
|
285
|
-
return "https://example.com";
|
|
286
|
-
if (format === "uuid" || format === "guid")
|
|
287
|
-
return "00000000-0000-4000-8000-000000000000";
|
|
288
|
-
if (format === "datetime" || format === "date")
|
|
289
|
-
return "2026-01-01T00:00:00Z";
|
|
290
|
-
return "e2e-fixture";
|
|
291
|
-
}
|
|
292
|
-
// --- Fixture aus FieldDefinition (für Stufe 1 statt Zod-Schema) ---
|
|
293
|
-
//
|
|
294
|
-
// Bewusstes Duplicate zu generateZodFixture. Die beiden haben unterschiedliche
|
|
295
|
-
// Aufgaben:
|
|
296
|
-
// generateZodFixture — public, generisch, weiß nur Zod-Primitives
|
|
297
|
-
// buildEntityFixture — intern, Kumiko-Domain, weiß über file-skip,
|
|
298
|
-
// embedded-Shape, money/tz-Objekte und nutzt den
|
|
299
|
-
// Feldnamen für lesbare Prefixes ("e2e-email@...")
|
|
300
|
-
//
|
|
301
|
-
// Ein Zusammenziehen über buildInsertSchema + generateZodFixture würde entweder
|
|
302
|
-
// den Feldnamen-Hint verlieren (alle email-Fixtures bekämen denselben Wert —
|
|
303
|
-
// Unique-Constraints wären inkonsistent) oder einen hint-Parameter in die
|
|
304
|
-
// public API von generateZodFixture drücken, den externe Caller nie brauchen.
|
|
305
|
-
function buildEntityFixture(entity) {
|
|
306
|
-
const out = {};
|
|
307
|
-
for (const [name, field] of Object.entries(entity.fields)) {
|
|
308
|
-
const value = fieldToFixture(name, field);
|
|
309
|
-
if (value !== undefined)
|
|
310
|
-
out[name] = value;
|
|
311
|
-
}
|
|
312
|
-
return out;
|
|
313
|
-
}
|
|
314
|
-
function fieldToFixture(name, field) {
|
|
315
|
-
switch (field.type) {
|
|
316
|
-
case "text": {
|
|
317
|
-
if (field.format === "email")
|
|
318
|
-
return `e2e-${name}@example.com`;
|
|
319
|
-
if (field.format === "url")
|
|
320
|
-
return "https://example.com";
|
|
321
|
-
return `e2e ${name}`;
|
|
322
|
-
}
|
|
323
|
-
case "longText":
|
|
324
|
-
// longText hat keine format-Optionen — generic placeholder reicht.
|
|
325
|
-
return `e2e ${name} (long-form content)`;
|
|
326
|
-
case "boolean":
|
|
327
|
-
return true;
|
|
328
|
-
case "select": {
|
|
329
|
-
const conditional = new Set(field.conditionalOptions?.flatMap((rule) => rule.options));
|
|
330
|
-
return (field.default ??
|
|
331
|
-
field.options.find((option) => !conditional.has(option)) ??
|
|
332
|
-
field.options[0] ??
|
|
333
|
-
"");
|
|
334
|
-
}
|
|
335
|
-
case "multiSelect": {
|
|
336
|
-
const first = field.options[0];
|
|
337
|
-
return first ? [first] : [];
|
|
338
|
-
}
|
|
339
|
-
case "number":
|
|
340
|
-
return 1;
|
|
341
|
-
case "money":
|
|
342
|
-
return { amount: 1, currency: "EUR" };
|
|
343
|
-
case "date":
|
|
344
|
-
return "2026-01-01";
|
|
345
|
-
case "timestamp":
|
|
346
|
-
return field.locatedBy !== undefined ? "2026-01-01T00:00:00" : "2026-01-01T00:00:00Z";
|
|
347
|
-
case "tz":
|
|
348
|
-
return "Europe/Berlin";
|
|
349
|
-
case "locatedTimestamp":
|
|
350
|
-
return { at: "2026-01-01T00:00:00", tz: "Europe/Berlin" };
|
|
351
|
-
case "embedded": {
|
|
352
|
-
const sub = {};
|
|
353
|
-
for (const [subName, subDef] of Object.entries(field.schema)) {
|
|
354
|
-
sub[subName] =
|
|
355
|
-
subDef.type === "text"
|
|
356
|
-
? `e2e ${subName}`
|
|
357
|
-
: subDef.type === "number" || subDef.type === "decimal"
|
|
358
|
-
? 1
|
|
359
|
-
: subDef.type === "money"
|
|
360
|
-
? 100
|
|
361
|
-
: subDef.type === "boolean"
|
|
362
|
-
? true
|
|
363
|
-
: "2026-01-01";
|
|
364
|
-
}
|
|
365
|
-
return field.multiple === true ? [sub] : sub;
|
|
366
|
-
}
|
|
367
|
-
case "jsonb":
|
|
368
|
-
// Free-form jsonb — e2e-generator returns empty-object.
|
|
369
|
-
return {};
|
|
370
|
-
case "file":
|
|
371
|
-
case "image":
|
|
372
|
-
case "files":
|
|
373
|
-
case "images":
|
|
374
|
-
// File-Upload-Fixture ist noch nicht generisch: Playwright müsste
|
|
375
|
-
// Dateiinhalte mitliefern, und die Write-API verlangt bereits ge-
|
|
376
|
-
// uploadete fileRef-UUIDs. Lässt sich nachziehen, sobald Sample die
|
|
377
|
-
// Pfade klärt (M4).
|
|
378
|
-
return undefined;
|
|
379
|
-
default:
|
|
380
|
-
return undefined;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-testing/helpers/e2e-generator`. Run
|
|
3
|
+
* `bun kumiko-upgrade --apply` to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export * from "@cosmicdrift/kumiko-testing/helpers/e2e-generator";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-framework/engine`. Run `bun kumiko-upgrade --apply`
|
|
3
|
+
* to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export { bridgeStub } from "../engine/bridge-stub.js";
|
|
@@ -1,69 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// calls without a real dispatcher). Hence the runtime classification despite
|
|
7
|
-
// living under `testing/` — no vitest imports, no test side-effects.
|
|
8
|
-
import { createAnonymousUser } from "../engine/system-user.js";
|
|
9
|
-
import { DEFAULT_LOCALE } from "../i18n/request-locale.js";
|
|
10
|
-
import { createNoopMetricsHandle, getFallbackTracer } from "../observability/index.js";
|
|
11
|
-
import { createTzContext } from "../time/index.js";
|
|
12
|
-
// Test/service helper: cross-feature bridge methods that throw on use.
|
|
13
|
-
//
|
|
14
|
-
// Production code always receives a full HandlerContext from the Dispatcher's
|
|
15
|
-
// buildHandlerContext (with real query/write closures). Some internal services
|
|
16
|
-
// and tests construct a mini-context manually (typically just `{ db, registry }`)
|
|
17
|
-
// to invoke a single handler. Those call sites don't use ctx.query/write —
|
|
18
|
-
// the stubs make the TypeScript shape match while still failing loudly if
|
|
19
|
-
// anything downstream accidentally reaches for them.
|
|
20
|
-
//
|
|
21
|
-
// Use: `{ db, registry, ...bridgeStub() }`
|
|
22
|
-
const notAvailable = (what) => async () => {
|
|
23
|
-
throw new Error(`ctx.${what} not available in this context — use the dispatcher, not a stubbed handler context`);
|
|
24
|
-
};
|
|
25
|
-
// Noop observability — hand back the shared fallback tracer so ctx.tracer has
|
|
26
|
-
// a valid Tracer shape. No allocations per call.
|
|
27
|
-
const noopTracer = getFallbackTracer();
|
|
28
|
-
export function bridgeStub(opts) {
|
|
29
|
-
// ctx.user is a convenience alias for event.user (see HandlerContext
|
|
30
|
-
// docs). Caller code expects the field; bridgeStub hands back a stub with
|
|
31
|
-
// anonymous default values when no user is passed explicitly. Test code
|
|
32
|
-
// that cares about identity passes its own SessionUser here and gets it
|
|
33
|
-
// back on ctx.
|
|
34
|
-
const stubUser = opts?.user ??
|
|
35
|
-
createAnonymousUser("00000000-0000-0000-0000-000000000000"); // @cast-boundary engine-bridge
|
|
36
|
-
return {
|
|
37
|
-
user: stubUser,
|
|
38
|
-
query: notAvailable("query"), // @cast-boundary engine-bridge
|
|
39
|
-
queryAs: notAvailable("queryAs"),
|
|
40
|
-
write: notAvailable("write"),
|
|
41
|
-
writeAs: notAvailable("writeAs"),
|
|
42
|
-
appendEvent: notAvailable("appendEvent"),
|
|
43
|
-
unsafeAppendEvent: notAvailable("unsafeAppendEvent"),
|
|
44
|
-
tryAppendEvent: notAvailable("tryAppendEvent"),
|
|
45
|
-
fetchForWriting: notAvailable("fetchForWriting"),
|
|
46
|
-
loadAggregate: notAvailable("loadAggregate"),
|
|
47
|
-
archiveStream: notAvailable("archiveStream"),
|
|
48
|
-
restoreStream: notAvailable("restoreStream"),
|
|
49
|
-
isStreamArchived: notAvailable("isStreamArchived"),
|
|
50
|
-
snapshotAggregate: notAvailable("snapshotAggregate"),
|
|
51
|
-
loadAggregateWithSnapshot: notAvailable("loadAggregateWithSnapshot"),
|
|
52
|
-
queryProjection: notAvailable("queryProjection"),
|
|
53
|
-
resolveAuthClaims: notAvailable("resolveAuthClaims"),
|
|
54
|
-
resolveActiveMembership: notAvailable("resolveActiveMembership"),
|
|
55
|
-
queryAsMember: notAvailable("queryAsMember"),
|
|
56
|
-
// Stub defaults to always-enabled — matches the dispatcher's behaviour
|
|
57
|
-
// when no effectiveFeatures resolver is wired (tests without toggles).
|
|
58
|
-
hasFeature: async () => true,
|
|
59
|
-
metrics: createNoopMetricsHandle(),
|
|
60
|
-
metricsFor: () => createNoopMetricsHandle(),
|
|
61
|
-
tracer: noopTracer,
|
|
62
|
-
// Real TzContext, not notAvailable — test code uses ctx.tz routinely,
|
|
63
|
-
// it isn't a "bridge" concept. Defaults to UTC.
|
|
64
|
-
tz: createTzContext(),
|
|
65
|
-
// Same reasoning as tz above — ctx.locale is always-present, not a
|
|
66
|
-
// bridge method. Defaults to DEFAULT_LOCALE.
|
|
67
|
-
locale: DEFAULT_LOCALE,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-framework/engine`. Run `bun kumiko-upgrade --apply`
|
|
3
|
+
* to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export { bridgeStub } from "../engine/bridge-stub.js";
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,26 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
export { expectErrorIncludes } from "./expect-error.js";
|
|
12
|
-
export { describeFileProviderContract } from "./file-provider-contract.js";
|
|
13
|
-
export { bridgeStub } from "./handler-context.js";
|
|
14
|
-
export { getSetCookieRaw, getSetCookies, getSetCookieValue, type ParsedSetCookie, } from "./http-cookies.js";
|
|
15
|
-
export { createLateBoundHolder, type LateBoundHolder } from "./late-bound.js";
|
|
16
|
-
export { createManualClock, type ManualClock } from "./manual-clock.js";
|
|
17
|
-
export { buildMultipartBody, patchFileInstanceofForBunTest } from "./multipart-helper.js";
|
|
18
|
-
export { createMutableMasterKeyProvider, createTestEnvelopeCipher, createTestMasterKeyProvider, type MutableMasterKeyProvider, } from "./mutable-master-key-provider.js";
|
|
19
|
-
export { createRecordingProvider, type RecordingProvider, } from "./observability-recorder.js";
|
|
20
|
-
export { isRealProviderRun, REAL_PROVIDERS_ENV, requireRealProviders } from "./real-providers.js";
|
|
21
|
-
export { deleteRows, seedRow, seedRows, updateRows } from "./seed.js";
|
|
22
|
-
export { sharedItemEntity, sharedItemTable, sharedUserEntity, sharedUserTable, sharedWidgetEntity, sharedWidgetTable, } from "./shared-entities.js";
|
|
23
|
-
export { sleep } from "./utils.js";
|
|
24
|
-
export { waitFor } from "./wait-for.js";
|
|
25
|
-
export { withoutAmbientTemporal } from "./without-ambient-temporal.js";
|
|
26
|
-
export { zipWithEntries } from "./zip-fixture.js";
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-testing/helpers`. Run `bun kumiko-upgrade --apply`
|
|
3
|
+
* to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export * from "@cosmicdrift/kumiko-testing/helpers";
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-framework/engine`. Run `bun kumiko-upgrade --apply`
|
|
8
|
+
* to rewrite imports. Removed in the first release after 2026-10-29.
|
|
9
|
+
*/
|
|
10
|
+
export { bridgeStub } from "../engine/bridge-stub.js";
|
package/dist/testing/index.js
CHANGED
|
@@ -1,34 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
export { resetPiiSubjectKmsForTests } from "../crypto/pii-field-encryption.js";
|
|
12
|
-
export { resetEntityFieldEncryptionCacheForTests } from "../db/entity-field-encryption.js";
|
|
13
|
-
export { rolesOf } from "./access-assertions.js";
|
|
14
|
-
export { expectError, expectSuccess } from "./assertions.js";
|
|
15
|
-
export { withBootValidatorFixture } from "./boot-validator-fixture.js";
|
|
16
|
-
export { captureClosedConnectionError } from "./closed-connection-error.js";
|
|
17
|
-
export { clearTables, resetTestTables } from "./db-cleanup.js";
|
|
18
|
-
export { generateE2ESpec, generateZodFixture, } from "./e2e-generator.js";
|
|
19
|
-
export { expectErrorIncludes } from "./expect-error.js";
|
|
20
|
-
export { describeFileProviderContract } from "./file-provider-contract.js";
|
|
21
|
-
export { bridgeStub } from "./handler-context.js";
|
|
22
|
-
export { getSetCookieRaw, getSetCookies, getSetCookieValue, } from "./http-cookies.js";
|
|
23
|
-
export { createLateBoundHolder } from "./late-bound.js";
|
|
24
|
-
export { createManualClock } from "./manual-clock.js";
|
|
25
|
-
export { buildMultipartBody, patchFileInstanceofForBunTest } from "./multipart-helper.js";
|
|
26
|
-
export { createMutableMasterKeyProvider, createTestEnvelopeCipher, createTestMasterKeyProvider, } from "./mutable-master-key-provider.js";
|
|
27
|
-
export { createRecordingProvider, } from "./observability-recorder.js";
|
|
28
|
-
export { isRealProviderRun, REAL_PROVIDERS_ENV, requireRealProviders } from "./real-providers.js";
|
|
29
|
-
export { deleteRows, seedRow, seedRows, updateRows } from "./seed.js";
|
|
30
|
-
export { sharedItemEntity, sharedItemTable, sharedUserEntity, sharedUserTable, sharedWidgetEntity, sharedWidgetTable, } from "./shared-entities.js";
|
|
31
|
-
export { sleep } from "./utils.js";
|
|
32
|
-
export { waitFor } from "./wait-for.js";
|
|
33
|
-
export { withoutAmbientTemporal } from "./without-ambient-temporal.js";
|
|
34
|
-
export { zipWithEntries } from "./zip-fixture.js";
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-testing/helpers`. Run `bun kumiko-upgrade --apply`
|
|
3
|
+
* to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export * from "@cosmicdrift/kumiko-testing/helpers";
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-framework/engine`. Run `bun kumiko-upgrade --apply`
|
|
8
|
+
* to rewrite imports. Removed in the first release after 2026-10-29.
|
|
9
|
+
*/
|
|
10
|
+
export { bridgeStub } from "../engine/bridge-stub.js";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-testing/helpers/real-providers`. Run
|
|
3
|
+
* `bun kumiko-upgrade --apply` to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export * from "@cosmicdrift/kumiko-testing/helpers/real-providers";
|
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const ci = process.env[CI_FLAG];
|
|
7
|
-
return ci !== undefined && ci !== "" && ci !== "0" && ci.toLowerCase() !== "false";
|
|
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(env = process.env) {
|
|
12
|
-
return env[REAL_PROVIDERS_ENV] === "1";
|
|
13
|
-
}
|
|
14
|
-
export function requireRealProviders() {
|
|
15
|
-
if (isCi()) {
|
|
16
|
-
throw new Error(`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.`);
|
|
17
|
-
}
|
|
18
|
-
if (!isRealProviderRun()) {
|
|
19
|
-
throw new Error(`Real-provider test needs ${REAL_PROVIDERS_ENV}=1 (an API key alone never enables it). Run it via the test:real / e2e:real script.`);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Moved to `@cosmicdrift/kumiko-testing/helpers/real-providers`. Run
|
|
3
|
+
* `bun kumiko-upgrade --apply` to rewrite imports. Removed in the first release after 2026-10-29.
|
|
4
|
+
*/
|
|
5
|
+
export * from "@cosmicdrift/kumiko-testing/helpers/real-providers";
|