@classytic/mongokit 3.28.0 → 3.30.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/LICENSE +1 -1
- package/README.md +54 -1
- package/TRADEMARK.md +22 -0
- package/dist/{create-repository-D4ZU94b3.d.mts → Repository-BXHkUtLk.d.mts} +30 -57
- package/dist/{Repository-BFBTAMlA.mjs → Repository-X7U2d0kU.mjs} +417 -47
- package/dist/actions/index.mjs +1 -1
- package/dist/adapter/index.mjs +1 -1
- package/dist/{adapter-CLvUHiTW.mjs → adapter-BitHg-CN.mjs} +1 -1
- package/dist/ai/index.d.mts +1 -1
- package/dist/better-auth/index.d.mts +13 -0
- package/dist/better-auth/index.mjs +76 -6
- package/dist/create-repository-CvD4wzuN.d.mts +54 -0
- package/dist/{create-repository-2DMwkYVz.mjs → create-repository-DYe5YEie.mjs} +3 -2
- package/dist/index.d.mts +275 -41
- package/dist/index.mjs +80 -7
- package/dist/kernel-conformance/index.d.mts +217 -0
- package/dist/kernel-conformance/index.mjs +603 -0
- package/dist/method-registry.plugin-DblM7V6j.mjs +112 -0
- package/dist/model-registry-ClKtWiHa.mjs +67 -0
- package/dist/{mongooseToJsonSchema-CByt1VhQ.mjs → mongooseToJsonSchema-DKbnKduN.mjs} +14 -3
- package/dist/{multi-tenant.plugin-DVyVGREb.d.mts → multi-tenant.plugin-2VtSSm1Y.d.mts} +1 -1
- package/dist/outbox/index.d.mts +63 -0
- package/dist/outbox/index.mjs +239 -0
- package/dist/{plugin-options-vFufQZMZ.d.mts → plugin-options-BsFH0sTi.d.mts} +1 -1
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +3 -2
- package/dist/{repository-DCHRWRXw.d.mts → repository-Q16ErTu8.d.mts} +19 -1
- package/dist/testkit/index.d.mts +8 -1
- package/dist/testkit/index.mjs +1 -1
- package/dist/{timestamp.plugin-ennbatTW.mjs → timestamp.plugin-ChFRcLRJ.mjs} +32 -143
- package/dist/{to-plain-DkF5px0R.d.mts → to-plain-BuX1RUZV.d.mts} +12 -4
- package/dist/{update-1Lq9OMD2.mjs → update-DHdXdOk_.mjs} +43 -30
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/index.mjs +1 -1
- package/dist/{validation-chain.plugin-Cm0Ttnd8.d.mts → validation-chain.plugin-BSshLJTA.d.mts} +44 -44
- package/dist/{validation-chain.plugin-k9joH2qw.mjs → validation-chain.plugin-BxTl_dYR.mjs} +139 -138
- package/package.json +28 -15
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { n as idVariants } from "./id-resolution-BqDrk0S2.mjs";
|
|
2
|
-
import { a as supportsTransactions, c as ALL_OPERATIONS, d as READ_OPERATIONS, f as operationsByPolicyKey, i as isTransactionUnsupported, l as MUTATING_OPERATIONS, m as
|
|
3
|
-
import { b as LookupBuilder, x as compileFilterToMongo } from "./update-
|
|
2
|
+
import { _ as resetCapabilityProbeCache, a as supportsTransactions, b as transactionResolutionOf, c as ALL_OPERATIONS, d as READ_OPERATIONS, f as operationsByPolicyKey, g as probeMongoCapabilities, h as classifyHelloReply, i as isTransactionUnsupported, l as MUTATING_OPERATIONS, m as capabilitiesForSupport, n as Repository, o as withTransaction, p as MONGOKIT_CAPABILITIES, r as batchTransaction, s as AggregationBuilder, t as HOOK_PRIORITY, u as OP_REGISTRY, v as resolveMongoCapabilities, x as createMongoPurgePort, y as resolveTransactionSupport } from "./Repository-X7U2d0kU.mjs";
|
|
3
|
+
import { b as LookupBuilder, x as compileFilterToMongo } from "./update-DHdXdOk_.mjs";
|
|
4
4
|
import { n as warn, t as configureLogger } from "./logger-K7dPmu2U.mjs";
|
|
5
5
|
import { n as isDuplicateKeyError, r as parseDuplicateKeyError, t as createError } from "./error-BuByZwKU.mjs";
|
|
6
6
|
import { t as actions_exports } from "./actions/index.mjs";
|
|
7
|
-
import { a as
|
|
7
|
+
import { a as customIdPlugin, c as prefixedId, d as AuditTrailQuery, f as auditTrailPlugin, i as multiTenantPlugin, l as sequentialId, m as auditLogPlugin, n as softDeletePlugin, o as dateSequentialId, p as ensureAuditTrailReady, r as adminBypass, s as getNextSequence, t as timestampPlugin, u as cachePlugin } from "./timestamp.plugin-ChFRcLRJ.mjs";
|
|
8
|
+
import { n as batchOperationsPlugin, t as methodRegistryPlugin } from "./method-registry.plugin-DblM7V6j.mjs";
|
|
8
9
|
import { t as PaginationEngine } from "./PaginationEngine-CczbvCAq.mjs";
|
|
9
10
|
import { isGeoOperator, parseGeoFilter } from "./query/primitives/geo.mjs";
|
|
10
|
-
import { t as createRepository } from "./create-repository-
|
|
11
|
-
import {
|
|
11
|
+
import { t as createRepository } from "./create-repository-DYe5YEie.mjs";
|
|
12
|
+
import { n as defineModel, r as isModelRegistered, t as ModelCollisionError } from "./model-registry-ClKtWiHa.mjs";
|
|
13
|
+
import { _ as cascadePlugin, a as uniqueField, c as subdocumentPlugin, d as mongoOperationsPlugin, f as leasePlugin, g as elasticSearchPlugin, h as fieldFilterPlugin, i as requireField, l as observabilityPlugin, m as idempotencyStorePlugin, n as blockIf, o as validationChainPlugin, p as immutableStatesPlugin, r as immutableField, s as createTenantContext, t as autoInject, u as MONGOKIT_PLUGIN_NAMES, v as appendOnlyPlugin, y as aggregateHelpersPlugin } from "./validation-chain.plugin-BxTl_dYR.mjs";
|
|
12
14
|
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-FSQFLpsU.mjs";
|
|
13
15
|
import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
|
|
14
16
|
import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
|
|
15
17
|
import { n as createMemoryCache, t as toPlain } from "./to-plain-vksRrLtc.mjs";
|
|
16
|
-
import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-
|
|
18
|
+
import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-DKbnKduN.mjs";
|
|
17
19
|
import { runChunkedPurge } from "@classytic/repo-core/repository";
|
|
18
20
|
import { isControlParam } from "@classytic/repo-core/query-parser";
|
|
19
21
|
//#region src/actions/cascade-references.ts
|
|
@@ -145,6 +147,77 @@ async function cascadePurgeReferences(options) {
|
|
|
145
147
|
return out;
|
|
146
148
|
}
|
|
147
149
|
//#endregion
|
|
150
|
+
//#region src/model-blueprint.ts
|
|
151
|
+
function isProductionRuntime() {
|
|
152
|
+
return process.env.NODE_ENV === "production";
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Describe a set of models as a connection-free blueprint. Duplicate spec names are rejected
|
|
156
|
+
* here, at describe time, before any connection is involved.
|
|
157
|
+
*/
|
|
158
|
+
function defineModels(spec) {
|
|
159
|
+
const { models, assemble } = spec;
|
|
160
|
+
const names = [];
|
|
161
|
+
const seen = /* @__PURE__ */ new Set();
|
|
162
|
+
for (const m of models) {
|
|
163
|
+
if (seen.has(m.name)) throw new Error(`[mongokit] defineModels: duplicate model spec name '${m.name}'. Each model must be described exactly once.`);
|
|
164
|
+
seen.add(m.name);
|
|
165
|
+
names.push(m.name);
|
|
166
|
+
}
|
|
167
|
+
const modelNames = Object.freeze([...names]);
|
|
168
|
+
return {
|
|
169
|
+
modelNames,
|
|
170
|
+
bind(connection) {
|
|
171
|
+
const map = /* @__PURE__ */ new Map();
|
|
172
|
+
const created = [];
|
|
173
|
+
const replaced = [];
|
|
174
|
+
try {
|
|
175
|
+
for (const s of models) {
|
|
176
|
+
const preExisting = isModelRegistered(s.name, connection);
|
|
177
|
+
if (s.existing.mode === "replace") {
|
|
178
|
+
if (isProductionRuntime()) throw new Error(`[mongokit] model '${s.name}' declares existing policy 'replace', which is forbidden when NODE_ENV=production. Use a separate connection for a second engine; do not clobber a live production model.`);
|
|
179
|
+
if (preExisting) {
|
|
180
|
+
const original = connection.models[s.name];
|
|
181
|
+
replaced.push({
|
|
182
|
+
name: s.name,
|
|
183
|
+
schema: original.schema,
|
|
184
|
+
collection: original.collection.name
|
|
185
|
+
});
|
|
186
|
+
connection.deleteModel(s.name);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const onExisting = s.existing.mode === "reuse" ? "reuse" : "throw";
|
|
190
|
+
const throwHint = s.existing.mode === "throw" && s.existing.hint ? s.existing.hint : `Registering model set [${modelNames.join(", ")}]; already bound this call: [${created.join(", ") || "none"}]${s.collection ? ` (collection '${s.collection}')` : ""}.`;
|
|
191
|
+
const model = defineModel(s.name, s.schema, {
|
|
192
|
+
onExisting,
|
|
193
|
+
connection,
|
|
194
|
+
throwHint,
|
|
195
|
+
...s.collection !== void 0 ? { collection: s.collection } : {}
|
|
196
|
+
});
|
|
197
|
+
if (!preExisting) created.push(s.name);
|
|
198
|
+
map.set(s.name, model);
|
|
199
|
+
}
|
|
200
|
+
return assemble(map);
|
|
201
|
+
} catch (err) {
|
|
202
|
+
const rollbackErrors = [];
|
|
203
|
+
for (const name of created) try {
|
|
204
|
+
connection.deleteModel(name);
|
|
205
|
+
} catch (e) {
|
|
206
|
+
rollbackErrors.push(e);
|
|
207
|
+
}
|
|
208
|
+
for (const r of replaced) try {
|
|
209
|
+
if (connection.models[r.name]) connection.deleteModel(r.name);
|
|
210
|
+
connection.model(r.name, r.schema, r.collection);
|
|
211
|
+
} catch (e) {
|
|
212
|
+
rollbackErrors.push(e);
|
|
213
|
+
}
|
|
214
|
+
if (rollbackErrors.length > 0) throw new AggregateError([err, ...rollbackErrors], `[mongokit] defineModels.bind failed AND ${rollbackErrors.length} rollback operation(s) failed — the connection model registry may be inconsistent.`);
|
|
215
|
+
throw err;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
148
221
|
//#region src/query/parser/pipeline-sanitizer.ts
|
|
149
222
|
/**
|
|
150
223
|
* Sanitize $match configuration to prevent dangerous operators.
|
|
@@ -1611,4 +1684,4 @@ function systemContext(extra) {
|
|
|
1611
1684
|
*/
|
|
1612
1685
|
var src_default = Repository;
|
|
1613
1686
|
//#endregion
|
|
1614
|
-
export { ALL_OPERATIONS, AggregationBuilder, AuditTrailQuery, HOOK_PRIORITY, LookupBuilder, MONGOKIT_CAPABILITIES, MONGOKIT_PLUGIN_NAMES, MUTATING_OPERATIONS, OP_REGISTRY, PaginationEngine, QueryParser, READ_OPERATIONS, Repository, actions_exports as actions, adminBypass, aggregateHelpersPlugin, appendOnlyPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, batchTransaction, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, cascadePurgeReferences, compileFilterToMongo, configureLogger, createError, createFieldPreset, createMemoryCache, createOptionsExtractor, createRepository, createTenantContext, customIdPlugin, dateSequentialId, src_default as default, elasticSearchPlugin, ensureAuditTrailReady, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, getNextSequence, idVariants, idempotencyStorePlugin, immutableField, immutableStatesPlugin, isDuplicateKeyError, isTransactionUnsupported, leasePlugin, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, repoOptionsFromCtx, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, supportsTransactions, systemContext, timestampPlugin, toPlain, uniqueField, validationChainPlugin, withTransaction };
|
|
1687
|
+
export { ALL_OPERATIONS, AggregationBuilder, AuditTrailQuery, HOOK_PRIORITY, LookupBuilder, MONGOKIT_CAPABILITIES, MONGOKIT_PLUGIN_NAMES, MUTATING_OPERATIONS, ModelCollisionError, OP_REGISTRY, PaginationEngine, QueryParser, READ_OPERATIONS, Repository, actions_exports as actions, adminBypass, aggregateHelpersPlugin, appendOnlyPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, batchTransaction, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, capabilitiesForSupport, cascadePlugin, cascadePurgeReferences, classifyHelloReply, compileFilterToMongo, configureLogger, createError, createFieldPreset, createMemoryCache, createOptionsExtractor, createRepository, createTenantContext, customIdPlugin, dateSequentialId, src_default as default, defineModel, defineModels, elasticSearchPlugin, ensureAuditTrailReady, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, getNextSequence, idVariants, idempotencyStorePlugin, immutableField, immutableStatesPlugin, isDuplicateKeyError, isModelRegistered, isTransactionUnsupported, leasePlugin, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, probeMongoCapabilities, repoOptionsFromCtx, requireField, resetCapabilityProbeCache, resolveMongoCapabilities, resolveTransactionSupport, sequentialId, softDeletePlugin, subdocumentPlugin, supportsTransactions, systemContext, timestampPlugin, toPlain, transactionResolutionOf, uniqueField, validationChainPlugin, withTransaction };
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { Connection } from "mongoose";
|
|
2
|
+
//#region src/kernel-conformance/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Every check the suite can run, in execution order. The ids are STABLE — `skip` is typed
|
|
5
|
+
* against this tuple, so a typo is a compile error rather than a silently-ineffective skip
|
|
6
|
+
* (a skip that skips nothing is the same silent-permissiveness bug class the suite exists
|
|
7
|
+
* to catch).
|
|
8
|
+
*/
|
|
9
|
+
declare const KERNEL_CONFORMANCE_CHECKS: readonly ["describe-purity", "blueprint-model-names", "bind-registers-declared-models", "bind-connection-scoped", "bind-no-index-io", "no-autoindex-on-bind", "fresh-schema-per-connection", "double-bind-collision", "transport-not-closed-when-supplied", "owned-transport-closed", "close-idempotent", "no-legacy-surface", "maintenance-fails-loud", "bind-verifies-requirements", "outbox-requires-transactional-save", "optional-modules-register-no-models"];
|
|
10
|
+
type ConformanceCheck = (typeof KERNEL_CONFORMANCE_CHECKS)[number];
|
|
11
|
+
/**
|
|
12
|
+
* Checks that only run when the kernel supplies the input they need. When the input is
|
|
13
|
+
* absent they are reported as NOT EXERCISED — a visible marker test plus a report entry,
|
|
14
|
+
* never a silent pass.
|
|
15
|
+
*/
|
|
16
|
+
declare const CONDITIONAL_CHECKS: readonly ["bind-verifies-requirements", "outbox-requires-transactional-save", "optional-modules-register-no-models"];
|
|
17
|
+
/**
|
|
18
|
+
* The two runner functions the suite needs, INJECTED by the consumer.
|
|
19
|
+
*
|
|
20
|
+
* mongokit deliberately does not import `vitest` (not even as an optional peer): the suite
|
|
21
|
+
* would then only work under one runner and would put a test framework in the dependency
|
|
22
|
+
* graph of a package every kernel installs in production. Injection costs the consumer one
|
|
23
|
+
* line — `runner: { describe, it }` — and in exchange the suite runs unmodified under
|
|
24
|
+
* vitest, jest, mocha or `node:test`. Assertions are internal (precise `Error` messages),
|
|
25
|
+
* so no `expect` implementation is required either.
|
|
26
|
+
*/
|
|
27
|
+
interface ConformanceRunner {
|
|
28
|
+
describe(name: string, fn: () => void): unknown;
|
|
29
|
+
it(name: string, fn: () => void | Promise<void>): unknown;
|
|
30
|
+
}
|
|
31
|
+
/** The minimum a `defineX(shape)` result must expose to be conformance-testable. */
|
|
32
|
+
interface KernelBlueprintLike {
|
|
33
|
+
readonly id?: string;
|
|
34
|
+
readonly modelNames: readonly string[];
|
|
35
|
+
}
|
|
36
|
+
/** A domain-event-shaped envelope. Structural — the suite never imports primitives. */
|
|
37
|
+
interface ConformanceEvent {
|
|
38
|
+
readonly type: string;
|
|
39
|
+
readonly payload?: unknown;
|
|
40
|
+
readonly meta?: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Structurally compatible with `@classytic/primitives`' `EventTransport` and arc's
|
|
44
|
+
* `MemoryEventTransport`. Declared here so mongokit stays dependency-free.
|
|
45
|
+
*/
|
|
46
|
+
interface EventTransportLike {
|
|
47
|
+
readonly name?: string;
|
|
48
|
+
publish(event: ConformanceEvent): Promise<void> | void;
|
|
49
|
+
publishMany?(events: readonly ConformanceEvent[]): Promise<unknown>;
|
|
50
|
+
subscribe?(pattern: string, handler: (event: ConformanceEvent) => unknown): Promise<() => void> | (() => void);
|
|
51
|
+
close?(): Promise<void> | void;
|
|
52
|
+
}
|
|
53
|
+
/** Collaborators the suite hands to `bind`. The kernel maps them onto its own runtime. */
|
|
54
|
+
interface KernelBindContext {
|
|
55
|
+
/**
|
|
56
|
+
* Present ONLY for the supplied-transport ownership check. When absent the kernel must
|
|
57
|
+
* create (and therefore own) its internal bus.
|
|
58
|
+
*/
|
|
59
|
+
readonly transport?: EventTransportLike;
|
|
60
|
+
}
|
|
61
|
+
/** A connection plus its teardown. Return this from `connect` when cleanup is needed. */
|
|
62
|
+
interface ConformanceConnectionHandle {
|
|
63
|
+
readonly connection: Connection;
|
|
64
|
+
teardown?(): Promise<void> | void;
|
|
65
|
+
}
|
|
66
|
+
type ConformanceConnect = () => Promise<Connection | ConformanceConnectionHandle>;
|
|
67
|
+
/**
|
|
68
|
+
* An explicit, REASONED opt-out. The reason is required: an unexplained skip is
|
|
69
|
+
* indistinguishable from an oversight, and this suite exists because oversights were
|
|
70
|
+
* invisible.
|
|
71
|
+
*/
|
|
72
|
+
interface ConformanceSkip {
|
|
73
|
+
readonly check: ConformanceCheck;
|
|
74
|
+
readonly reason: string;
|
|
75
|
+
}
|
|
76
|
+
type ConformanceCheckOutcome = 'run' | 'skipped' | 'not-exercised';
|
|
77
|
+
interface ConformanceCheckStatus {
|
|
78
|
+
readonly check: ConformanceCheck;
|
|
79
|
+
readonly outcome: ConformanceCheckOutcome;
|
|
80
|
+
/** Why it was skipped, or which option would exercise a conditional check. */
|
|
81
|
+
readonly reason?: string;
|
|
82
|
+
}
|
|
83
|
+
/** Emitted once per suite, before any test runs. */
|
|
84
|
+
interface KernelConformanceReport {
|
|
85
|
+
readonly kernel: string;
|
|
86
|
+
readonly checks: readonly ConformanceCheckStatus[];
|
|
87
|
+
readonly skipped: readonly ConformanceCheckStatus[];
|
|
88
|
+
readonly notExercised: readonly ConformanceCheckStatus[];
|
|
89
|
+
}
|
|
90
|
+
interface KernelConformanceOptions<TBlueprint extends KernelBlueprintLike, TEngine> {
|
|
91
|
+
/** Kernel name, e.g. `'party'`. Used in test titles and to derive legacy export names. */
|
|
92
|
+
readonly name: string;
|
|
93
|
+
/** `describe`/`it` from the consumer's own test runner. See {@link ConformanceRunner}. */
|
|
94
|
+
readonly runner: ConformanceRunner;
|
|
95
|
+
/**
|
|
96
|
+
* A FACTORY, not a value — `() => defineParty({ ... })`.
|
|
97
|
+
*
|
|
98
|
+
* Purity (§11.1) is only observable if the suite can call `defineX` itself while watching
|
|
99
|
+
* the model registries; a pre-built blueprint has already done whatever it was going to do.
|
|
100
|
+
* The factory also gives every check a pristine blueprint, so one check's bind can never
|
|
101
|
+
* poison another's.
|
|
102
|
+
*
|
|
103
|
+
* Describe the conformance blueprint WITHOUT `forceRecreate` (the collision check needs a
|
|
104
|
+
* real collision) and, when the kernel offers it, with `autoIndex: false`.
|
|
105
|
+
*/
|
|
106
|
+
readonly blueprint: () => TBlueprint;
|
|
107
|
+
/**
|
|
108
|
+
* A live or registry-only connection. `async () => mongoose.createConnection()` (never
|
|
109
|
+
* connected) is enough for every check and needs no server — model registration and the
|
|
110
|
+
* index-call spies are registry-level. Return a {@link ConformanceConnectionHandle} when
|
|
111
|
+
* teardown is needed. Called once per check that binds.
|
|
112
|
+
*/
|
|
113
|
+
readonly connect: ConformanceConnect;
|
|
114
|
+
/** Bind the blueprint the suite handed you. Map `ctx.transport` onto the kernel runtime. */
|
|
115
|
+
readonly bind: (blueprint: TBlueprint, connection: Connection, ctx: KernelBindContext) => TEngine | Promise<TEngine>;
|
|
116
|
+
/**
|
|
117
|
+
* Build the transport used by `transport-not-closed-when-supplied`. Defaults to the
|
|
118
|
+
* suite's own in-process transport, which satisfies the `EventTransport` contract.
|
|
119
|
+
*/
|
|
120
|
+
readonly makeTransport?: () => EventTransportLike;
|
|
121
|
+
/**
|
|
122
|
+
* The exact model set the blueprint must declare. Supplied ⇒ an exact match is REQUIRED;
|
|
123
|
+
* a drift in either direction fails.
|
|
124
|
+
*/
|
|
125
|
+
readonly expectedModelNames?: readonly string[];
|
|
126
|
+
/**
|
|
127
|
+
* The kernel's public module namespace (`import * as kernel from '../../src/index.js'`)
|
|
128
|
+
* or a list of its exported names. Required by `no-legacy-surface`.
|
|
129
|
+
*/
|
|
130
|
+
readonly moduleExports?: Readonly<Record<string, unknown>> | readonly string[];
|
|
131
|
+
/** Extra export names that must NOT exist (legacy factories this kernel used to ship). */
|
|
132
|
+
readonly forbiddenExportNames?: readonly string[];
|
|
133
|
+
/** The sole construction export. Defaults to `define<Pascal(name)>`, e.g. `defineParty`. */
|
|
134
|
+
readonly constructionExportName?: string;
|
|
135
|
+
/**
|
|
136
|
+
* Find the engine's INTERNAL transport for the owned-transport check. Defaults to the
|
|
137
|
+
* first transport-shaped value among `events`, `transport`, `eventTransport`, `bus`.
|
|
138
|
+
*/
|
|
139
|
+
readonly resolveInternalTransport?: (engine: TEngine) => EventTransportLike | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* Direct probe for "was the internally-created bus closed?". Overrides the default
|
|
142
|
+
* subscribe-publish-close-publish observation when a kernel's bus is not reachable.
|
|
143
|
+
*/
|
|
144
|
+
readonly internalTransportClosed?: (engine: TEngine) => boolean | Promise<boolean>;
|
|
145
|
+
/**
|
|
146
|
+
* Bind with a deliberately UNMET runtime requirement. Must reject/throw (§11.5).
|
|
147
|
+
* Enables `bind-verifies-requirements`.
|
|
148
|
+
*/
|
|
149
|
+
readonly bindWithUnmetRequirement?: (connection: Connection) => unknown | Promise<unknown>;
|
|
150
|
+
/**
|
|
151
|
+
* Bind with an injected `OutboxStore` whose `transactionalSave` is ABSENT or `false` — the
|
|
152
|
+
* exact shape of a hand-rolled host store. The bind must reject/throw, and the error must
|
|
153
|
+
* NAME `transactionalSave`. Enables `outbox-requires-transactional-save`.
|
|
154
|
+
*
|
|
155
|
+
* ```ts
|
|
156
|
+
* bindWithNonTransactionalOutbox: (connection) =>
|
|
157
|
+
* defineX({ … }).bind(connection, { outbox: { save: async () => undefined } as never }),
|
|
158
|
+
* ```
|
|
159
|
+
*
|
|
160
|
+
* ## When to supply it — and when a reasoned `skip` is the RIGHT answer
|
|
161
|
+
*
|
|
162
|
+
* The rule is **"this kernel persists outbox rows that must commit atomically with the state
|
|
163
|
+
* change they describe"**, NOT "this kernel's runtime happens to accept an `outbox`". Of the
|
|
164
|
+
* 32 kernels that thread an outbox through their runtime, only three verified the flag; but
|
|
165
|
+
* the remedy for the other 29 is a JUDGEMENT per kernel, not a sweep.
|
|
166
|
+
*
|
|
167
|
+
* Supply it when a rolled-back write could still emit its event and a downstream consumer
|
|
168
|
+
* would ACT on the ghost — a sale that never committed paying a commission, an access grant
|
|
169
|
+
* that never committed syncing a credential. That is the case `@classytic/access` and
|
|
170
|
+
* `@classytic/referral` gate at boot.
|
|
171
|
+
*
|
|
172
|
+
* SKIP it, with the reason stating so, when the kernel's outbox use is genuinely best-effort:
|
|
173
|
+
* the events are notifications/telemetry that a later reconciliation would correct, or nothing
|
|
174
|
+
* downstream takes an irreversible action on them. Inventing a requirement no code path needs
|
|
175
|
+
* is decoration of the opposite kind — a recorded remedy for `referral` demanded `transactions`
|
|
176
|
+
* on the belief that `convert()` wrote a row AND bumped a counter, when `attributeSale` is one
|
|
177
|
+
* read plus one atomic `getOrCreate`. Read the write paths before deciding.
|
|
178
|
+
*
|
|
179
|
+
* A kernel whose runtime accepts no outbox at all skips with that as the reason.
|
|
180
|
+
*/
|
|
181
|
+
readonly bindWithNonTransactionalOutbox?: (connection: Connection) => unknown | Promise<unknown>;
|
|
182
|
+
/**
|
|
183
|
+
* A blueprint describing the kernel with its OPTIONAL modules disabled. Enables
|
|
184
|
+
* `optional-modules-register-no-models` (§11.10).
|
|
185
|
+
*/
|
|
186
|
+
readonly minimalBlueprint?: () => TBlueprint;
|
|
187
|
+
/**
|
|
188
|
+
* Explicit, reasoned opt-outs. Unknown or duplicate ids throw at call time. Every skip is
|
|
189
|
+
* printed and registered as a visible marker test.
|
|
190
|
+
*/
|
|
191
|
+
readonly skip?: readonly ConformanceSkip[];
|
|
192
|
+
/** Receives the manifest before any test runs. Defaults to a `console` summary. */
|
|
193
|
+
readonly onReport?: (report: KernelConformanceReport) => void;
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/kernel-conformance/suite.d.ts
|
|
197
|
+
declare function describeKernelConformance<TBlueprint extends KernelBlueprintLike, TEngine>(opts: KernelConformanceOptions<TBlueprint, TEngine>): void;
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region src/kernel-conformance/transport.d.ts
|
|
200
|
+
/** A minimal, valid domain-event envelope (`type` + `meta.id` is all any bus reads). */
|
|
201
|
+
declare function conformanceEvent(type: string): ConformanceEvent;
|
|
202
|
+
/** An in-process transport good enough to stand in for a host-owned shared bus. */
|
|
203
|
+
declare function createConformanceTransport(name?: string): EventTransportLike;
|
|
204
|
+
interface InstrumentedTransport {
|
|
205
|
+
/** Hand THIS to the kernel. */
|
|
206
|
+
readonly transport: EventTransportLike;
|
|
207
|
+
/** How many times the kernel called `close()` on it. Must stay 0. */
|
|
208
|
+
closeCalls(): number;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Wrap a transport so `close()` calls are counted. The wrapper forwards everything else, so
|
|
212
|
+
* the kernel cannot tell the difference — which is the point: ownership must be decided by
|
|
213
|
+
* "did I create this?", never by inspecting the object.
|
|
214
|
+
*/
|
|
215
|
+
declare function instrumentTransport(inner: EventTransportLike): InstrumentedTransport;
|
|
216
|
+
//#endregion
|
|
217
|
+
export { CONDITIONAL_CHECKS, type ConformanceCheck, type ConformanceCheckOutcome, type ConformanceCheckStatus, type ConformanceConnect, type ConformanceConnectionHandle, type ConformanceEvent, type ConformanceRunner, type ConformanceSkip, type EventTransportLike, type InstrumentedTransport, KERNEL_CONFORMANCE_CHECKS, type KernelBindContext, type KernelBlueprintLike, type KernelConformanceOptions, type KernelConformanceReport, conformanceEvent, createConformanceTransport, describeKernelConformance, instrumentTransport };
|