bazis 0.98.20 → 0.98.22
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/core/di/errors/NamedDependencyNotFoundError.ts +12 -1
- package/core/di/module/encapsulation.ts +36 -3
- package/core/infra/connectors/codex/CodexAppServerClient.ts +1 -1
- package/core/orm/OrmHostedPlan.validator.ts +1 -1
- package/core/orm/OrmLifecycle.ts +13 -3
- package/core/orm/encapsulationHook.ts +11 -1
- package/core/orm/ormModule.ts +1 -1
- package/library/orm/DatabaseFacade.ts +35 -0
- package/library/orm/Repository/README.md +3 -0
- package/library/orm/Schema/MigrationRunner.ts +21 -0
- package/library/orm/errors.ts +1 -1
- package/library/orm/index.ts +1 -0
- package/package.json +1 -1
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { DiError } from "./DiError";
|
|
2
2
|
|
|
3
|
+
/** Returns a hint for a named dependency nobody registers, or `undefined`. */
|
|
4
|
+
export type NamedDependencyHint = (name: string) => string | undefined;
|
|
5
|
+
|
|
6
|
+
const hints: NamedDependencyHint[] = [];
|
|
7
|
+
|
|
8
|
+
/** Infrastructure extensions (ORM repositories, …) explain their own named dependencies here. */
|
|
9
|
+
export function registerNamedDependencyHint(hint: NamedDependencyHint): void {
|
|
10
|
+
hints.push(hint);
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
export class NamedDependencyNotFoundError extends DiError {
|
|
4
14
|
public constructor(name: string) {
|
|
5
|
-
|
|
15
|
+
const hint = hints.map((item) => item(name)).find((text) => text !== undefined);
|
|
16
|
+
super(`No provider token found for named dependency "${name}".${hint ? ` ${hint}` : ""}`);
|
|
6
17
|
}
|
|
7
18
|
}
|
|
@@ -84,7 +84,9 @@ export function validateModuleEncapsulation(
|
|
|
84
84
|
if (isFamilyExport(ref)) {
|
|
85
85
|
continue;
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
// A closed token of a visible family (`repositoryFor(Product)` next to an
|
|
88
|
+
// `ormBazis` that exports the whole `IRepository` family) may be passed on alone.
|
|
89
|
+
if (record.providedTokens.has(ref) || visible.has(ref) || (typeof ref !== "function" && ref.genericFamilyId !== undefined && allProvidedTokens.has(ref) && visibleFamilies(record).has(ref.genericFamilyId))) {
|
|
88
90
|
result.add(ref);
|
|
89
91
|
} else {
|
|
90
92
|
issues.push(
|
|
@@ -173,6 +175,10 @@ export function validateModuleEncapsulation(
|
|
|
173
175
|
// Why a provided token is not visible: the owner does not export it, or the
|
|
174
176
|
// consumer module does not import the owner. Both used to read "not exported".
|
|
175
177
|
const explainHidden = (token: Token<unknown>, consumer: ModuleGraphRecord): string => {
|
|
178
|
+
if (typeof token !== "function" && token.genericFamilyId !== undefined) {
|
|
179
|
+
const family = explainHiddenFamily(token, token.genericFamilyId, consumer);
|
|
180
|
+
if (family !== undefined) return family;
|
|
181
|
+
}
|
|
176
182
|
// A module the consumer imports already sees the token but does not pass it
|
|
177
183
|
// on. That export is the fix, whatever inner module (an `ormBazis` feature
|
|
178
184
|
// module, say) registered the token.
|
|
@@ -188,6 +194,31 @@ export function validateModuleEncapsulation(
|
|
|
188
194
|
: `which module "${owner.name}" provides but does not export. Add it to the exports of "${owner.name}".`;
|
|
189
195
|
};
|
|
190
196
|
|
|
197
|
+
// A closed token (`IRepository<Product>`) travels with its family export, so
|
|
198
|
+
// the fix is named in family terms and skips unnamed inner modules such as
|
|
199
|
+
// the one `ormBazis` creates.
|
|
200
|
+
const explainHiddenFamily = (token: Token<unknown>, familyId: symbol, consumer: ModuleGraphRecord): string | undefined => {
|
|
201
|
+
const closed = tokenToDebugName(token);
|
|
202
|
+
const family = closed.includes("<") ? closed.slice(0, closed.indexOf("<")) : closed;
|
|
203
|
+
const exportFix = `${family} (or only ${closed})`;
|
|
204
|
+
const sees = (record: ModuleGraphRecord) => visibleFamilies(record).has(familyId) || visibleTokens(record).has(token);
|
|
205
|
+
const passes = (record: ModuleGraphRecord) => exportedFamilies(record).has(familyId) || exportedTokens(record).has(token);
|
|
206
|
+
const named = (record: ModuleGraphRecord) => !/^module#\d+$/.test(record.name);
|
|
207
|
+
const blocking = consumer.imports.find((imported) => named(imported) && sees(imported) && !passes(imported));
|
|
208
|
+
if (blocking !== undefined) {
|
|
209
|
+
return `which its import "${blocking.name}" receives from its own imports but does not export. Add ${exportFix} to the exports of "${blocking.name}".`;
|
|
210
|
+
}
|
|
211
|
+
const exporter = records.find((record) => record !== consumer && named(record) && passes(record));
|
|
212
|
+
if (exporter !== undefined) {
|
|
213
|
+
return `which module "${exporter.name}" exports, but "${consumer.name}" does not list "${exporter.name}" in its imports. Add "${exporter.name}" to the imports of "${consumer.name}".`;
|
|
214
|
+
}
|
|
215
|
+
const host = records.find((record) => record !== consumer && named(record) && sees(record));
|
|
216
|
+
if (host !== undefined) {
|
|
217
|
+
return `which module "${host.name}" receives from its own imports but does not export. Add ${exportFix} to the exports of "${host.name}" and "${host.name}" to the imports of "${consumer.name}".`;
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
};
|
|
221
|
+
|
|
191
222
|
const contexts = new Map<ModuleGraphRecord, DependencyCheckContext>();
|
|
192
223
|
for (let recordIndex = 0; recordIndex < records.length; recordIndex += 1) {
|
|
193
224
|
const record = records[recordIndex] as ModuleGraphRecord;
|
|
@@ -302,7 +333,7 @@ function checkDependency(
|
|
|
302
333
|
!context.familiesVisible.has(token.genericFamilyId)
|
|
303
334
|
) {
|
|
304
335
|
context.issues.push(
|
|
305
|
-
`Module "${record.name}": "${consumer}" depends on
|
|
336
|
+
`Module "${record.name}": "${consumer}" depends on "${tokenToDebugName(token)}", ${context.explainHidden(token, record)}`,
|
|
306
337
|
);
|
|
307
338
|
}
|
|
308
339
|
return;
|
|
@@ -363,6 +394,7 @@ export function computeModuleVisibleTokens(
|
|
|
363
394
|
): Map<ModuleGraphRecord, Set<Token<unknown>>> {
|
|
364
395
|
const exportedMemo = new Map<ModuleGraphRecord, Set<Token<unknown>>>();
|
|
365
396
|
const visiting = new Set<ModuleGraphRecord>();
|
|
397
|
+
const allProvided = new Set<Token<unknown>>(records.flatMap((record) => [...record.providedTokens]));
|
|
366
398
|
|
|
367
399
|
const visibleOf = (record: ModuleGraphRecord): Set<Token<unknown>> => {
|
|
368
400
|
const result = new Set<Token<unknown>>(record.providedTokens);
|
|
@@ -401,7 +433,8 @@ export function computeModuleVisibleTokens(
|
|
|
401
433
|
if (isFamilyExport(ref)) {
|
|
402
434
|
continue;
|
|
403
435
|
}
|
|
404
|
-
|
|
436
|
+
// Validation already admitted closed tokens re-exported from a visible family.
|
|
437
|
+
if (record.providedTokens.has(ref) || visible.has(ref) || (typeof ref !== "function" && ref.genericFamilyId !== undefined && allProvided.has(ref))) {
|
|
405
438
|
result.add(ref);
|
|
406
439
|
}
|
|
407
440
|
}
|
|
@@ -232,7 +232,7 @@ export class CodexAppServerClient implements CodexClient {
|
|
|
232
232
|
if (method === "account/updated") this.modelCache = undefined;
|
|
233
233
|
}, () => { this.clearLogin(); this.modelCache = undefined; });
|
|
234
234
|
const initialized = await client.request("initialize", {
|
|
235
|
-
clientInfo: { name: "bazis", title: "Bazis", version: "0.98.
|
|
235
|
+
clientInfo: { name: "bazis", title: "Bazis", version: "0.98.22" }, capabilities: { experimentalApi: true },
|
|
236
236
|
}, 15_000, signal);
|
|
237
237
|
if (resolve(text(initialized.codexHome, 4096)) !== this.paths.home) throw new CodexError("PROTOCOL_ERROR");
|
|
238
238
|
client.notify("initialized");
|
|
@@ -50,7 +50,7 @@ function validateOrmHostedPlan(services: readonly HostedService[]): void {
|
|
|
50
50
|
const owner = (service as { __bazisSchemaOwner?: { context: string; mode: string } }).__bazisSchemaOwner;
|
|
51
51
|
return owner ? `${owner.context} uses ${owner.mode}` : "a module uses migrateOnStart or migrations";
|
|
52
52
|
};
|
|
53
|
-
throw new SchemaAdmissionError("ORM_SCHEMA_HOSTED_PHASE_CONFLICT", `Schema admission and legacy ORM schema authority cannot be composed together: ${[...strict, ...legacy].map(describe).join(", ")}. Use one schema mode in the application: ensureCreated in every module, or migrateOnStart/migrations in every module.`);
|
|
53
|
+
throw new SchemaAdmissionError("ORM_SCHEMA_HOSTED_PHASE_CONFLICT", `Schema admission and legacy ORM schema authority cannot be composed together: ${[...strict, ...legacy].map(describe).join(", ")}. Use one schema mode in the application: ensureCreated (with or without migrations) in every module, or migrateOnStart/migrations without ensureCreated in every module.`);
|
|
54
54
|
}
|
|
55
55
|
for (const service of services) {
|
|
56
56
|
const framework = isOrmProviderLifecycle(service)
|
package/core/orm/OrmLifecycle.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ormHostedPlanValidator } from "./OrmHostedPlan.validator";
|
|
2
2
|
import type { HostedService } from "../di";
|
|
3
|
-
import { DatabaseFacade, type DbContextOptions, type Migration } from "../../library/orm";
|
|
3
|
+
import { DatabaseFacade, type DbContextOptions, type EnsureCreatedWithMigrationsResult, type Migration } from "../../library/orm";
|
|
4
4
|
import { compileExpectedSchema } from "../../library/orm/Schema/ExpectedSchema";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -29,6 +29,8 @@ export class OrmLifecycle implements HostedService {
|
|
|
29
29
|
};
|
|
30
30
|
/** Internal hosted-plan marker: the context and its startup schema mode, for readable plan errors. */
|
|
31
31
|
readonly __bazisSchemaOwner: { readonly context: string; readonly mode: string };
|
|
32
|
+
/** `ensureCreated` owns the versioned migrations of this context (run or baselined before the check). */
|
|
33
|
+
private readonly withMigrations: boolean;
|
|
32
34
|
private connectionClosed = false;
|
|
33
35
|
private closePromise?: Promise<void>;
|
|
34
36
|
|
|
@@ -48,6 +50,7 @@ export class OrmLifecycle implements HostedService {
|
|
|
48
50
|
contextName = "DbContext",
|
|
49
51
|
) {
|
|
50
52
|
const modes = [ensureCreated && "ensureCreated", migrateOnStart && "migrateOnStart", runMigrationsOnStart && migrations.length > 0 && "migrations"].filter(Boolean);
|
|
53
|
+
this.withMigrations = ensureCreated && runMigrationsOnStart && migrations.length > 0;
|
|
51
54
|
this.__bazisSchemaOwner = Object.freeze({ context: contextName, mode: modes.join(" + ") || "none" });
|
|
52
55
|
this.phase = ensureCreated && options.provider.name === "postgres" ? -105 : -100;
|
|
53
56
|
this.__bazisLegacySchemaAuthority = this.phase === -100 && (ensureCreated || migrateOnStart || (runMigrationsOnStart && migrations.length > 0));
|
|
@@ -72,10 +75,17 @@ export class OrmLifecycle implements HostedService {
|
|
|
72
75
|
const database = new DatabaseFacade(this.options.provider, this.options.model);
|
|
73
76
|
try {
|
|
74
77
|
if (this.ensureCreated) {
|
|
75
|
-
const result = await database.ensureCreated();
|
|
78
|
+
const result: Partial<EnsureCreatedWithMigrationsResult> & Pick<EnsureCreatedWithMigrationsResult, "warnings"> = this.withMigrations ? await database.ensureCreatedWithMigrations(this.migrations) : await database.ensureCreated();
|
|
79
|
+
// Logged in execution order: migrations, schema changes, then the baseline record.
|
|
80
|
+
if (result.migrated && result.migrated.length > 0) {
|
|
81
|
+
console.info(`[orm:migrations] applied: ${result.migrated.join(", ")}`);
|
|
82
|
+
}
|
|
76
83
|
if (result.applied && result.applied.length > 0) {
|
|
77
84
|
console.info(`[orm:schema] applied ${result.applied.length} operation(s): ${result.applied.join(", ")}`);
|
|
78
85
|
}
|
|
86
|
+
if (result.baselined && result.baselined.length > 0) {
|
|
87
|
+
console.info(`[orm:migrations] baseline: the schema was created from the model, recorded as applied without running: ${result.baselined.join(", ")}`);
|
|
88
|
+
}
|
|
79
89
|
for (const warning of result.warnings) {
|
|
80
90
|
console.warn(`[orm:schema] ${warning}`);
|
|
81
91
|
}
|
|
@@ -89,7 +99,7 @@ export class OrmLifecycle implements HostedService {
|
|
|
89
99
|
console.warn(`[orm:migrate] ${warning}`);
|
|
90
100
|
}
|
|
91
101
|
}
|
|
92
|
-
if (this.runMigrationsOnStart && this.migrations.length > 0) {
|
|
102
|
+
if (this.runMigrationsOnStart && this.migrations.length > 0 && !this.withMigrations) {
|
|
93
103
|
const result = await database.migrateVersioned(this.migrations);
|
|
94
104
|
if (result.applied.length > 0) {
|
|
95
105
|
console.info(`[orm:migrations] applied: ${result.applied.join(", ")}`);
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { registerNamedDependencyEncapsulationHook } from "../di/module/encapsulationHooks";
|
|
2
|
+
import { registerNamedDependencyHint } from "../di/errors/NamedDependencyNotFoundError";
|
|
2
3
|
import { IRepository } from "./repository";
|
|
3
4
|
|
|
4
5
|
let registered = false;
|
|
5
6
|
|
|
6
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Allows closed `IRepository<Entity>` named deps when the module exports open
|
|
9
|
+
* generic `IRepository`, and explains a repository nobody registers.
|
|
10
|
+
*/
|
|
7
11
|
export function registerRepositoryEncapsulationHook(): void {
|
|
8
12
|
if (registered) {
|
|
9
13
|
return;
|
|
@@ -16,4 +20,10 @@ export function registerRepositoryEncapsulationHook(): void {
|
|
|
16
20
|
}
|
|
17
21
|
return undefined;
|
|
18
22
|
});
|
|
23
|
+
|
|
24
|
+
registerNamedDependencyHint((name) => {
|
|
25
|
+
const match = /^IRepository<(.+)>$/.exec(name);
|
|
26
|
+
if (!match) return undefined;
|
|
27
|
+
return `Repositories are registered by ormBazis for the entities of its context: add ${match[1]} to the entities of an ormBazis module and keep registerRepositories on (the default), or inject that module's DbContext instead.`;
|
|
28
|
+
});
|
|
19
29
|
}
|
package/core/orm/ormModule.ts
CHANGED
|
@@ -121,7 +121,7 @@ export function ormModule<TContext extends DbContext>(config: OrmModuleConfig<TC
|
|
|
121
121
|
attachOwnedStoreRegistration(module, buildConfig.context, buildConfig.entities ?? [], config.ownedStore);
|
|
122
122
|
return module;
|
|
123
123
|
}
|
|
124
|
-
if (config.ensureCreated &&
|
|
124
|
+
if (config.ensureCreated && config.migrateOnStart) throw new OrmError("ensureCreated and migrateOnStart are mutually exclusive: ensureCreated already adds the safe changes. Put other changes into migrations with runMigrationsOnStart: true.");
|
|
125
125
|
if (config.ensureCreated && config.provider?.name === "postgres" && config.context) throw new OrmError("PostgreSQL ensureCreated requires the shared DATABASE_PROVIDER from @Infra.");
|
|
126
126
|
// "Connection" mode: a provider only, no context.
|
|
127
127
|
if (!config.context) {
|
|
@@ -5,6 +5,15 @@ import { Migrator, type MigrationResult } from "./Schema/Migrator";
|
|
|
5
5
|
import { MigrationRunner, type Migration, type VersionedMigrationResult } from "./Schema/MigrationRunner";
|
|
6
6
|
import { SchemaDiffer } from "./Schema/SchemaDiffer";
|
|
7
7
|
import { SchemaAdmissionEngine, type EnsureCreatedResult } from "./Schema/SchemaAdmission";
|
|
8
|
+
import { entityStorageKey } from "./Schema/tableKey";
|
|
9
|
+
|
|
10
|
+
/** Result of `ensureCreated` together with versioned migrations. */
|
|
11
|
+
export interface EnsureCreatedWithMigrationsResult extends EnsureCreatedResult {
|
|
12
|
+
/** Migrations run before the schema check. */
|
|
13
|
+
readonly migrated: readonly string[];
|
|
14
|
+
/** Migrations recorded as applied without running, because the schema was created from the model. */
|
|
15
|
+
readonly baselined: readonly string[];
|
|
16
|
+
}
|
|
8
17
|
import { SchemaAdmissionError } from "./errors";
|
|
9
18
|
import { physicalColumnTypes } from "./Schema/physicalColumnTypes";
|
|
10
19
|
import { bindResolvedForeignKey } from "./Providers/resolvedForeignKey";
|
|
@@ -47,6 +56,32 @@ export class DatabaseFacade {
|
|
|
47
56
|
return { warnings: [] };
|
|
48
57
|
}
|
|
49
58
|
|
|
59
|
+
/**
|
|
60
|
+
* `ensureCreated` with versioned migrations, under the migration lock so that
|
|
61
|
+
* starting instances do not race:
|
|
62
|
+
*
|
|
63
|
+
* - none of the context tables exist yet: `ensureCreated` creates the current
|
|
64
|
+
* model and the migrations are recorded as applied without running (a
|
|
65
|
+
* baseline: the model already contains their result, so a seed `INSERT` in
|
|
66
|
+
* a migration is skipped here too);
|
|
67
|
+
* - otherwise pending migrations run first (`ALTER`, renames, data moves),
|
|
68
|
+
* then `ensureCreated` adds what is still missing and verifies the result.
|
|
69
|
+
*/
|
|
70
|
+
async ensureCreatedWithMigrations(migrations: readonly Migration[]): Promise<EnsureCreatedWithMigrationsResult> {
|
|
71
|
+
const work = async (): Promise<EnsureCreatedWithMigrationsResult> => {
|
|
72
|
+
const runner = new MigrationRunner(this.provider, migrations);
|
|
73
|
+
const existing = await this.provider.introspect();
|
|
74
|
+
const fresh = this.models.entities.every((model) => !existing.tables.has(entityStorageKey(model)) && !existing.tables.has(model.tableName));
|
|
75
|
+
if (fresh) {
|
|
76
|
+
const created = await this.ensureCreated();
|
|
77
|
+
return { ...created, migrated: [], baselined: await runner.baseline() };
|
|
78
|
+
}
|
|
79
|
+
const { applied } = await runner.migrate();
|
|
80
|
+
return { ...(await this.ensureCreated()), migrated: applied, baselined: [] };
|
|
81
|
+
};
|
|
82
|
+
return this.provider.withMigrationLock ? this.provider.withMigrationLock(work) : work();
|
|
83
|
+
}
|
|
84
|
+
|
|
50
85
|
/**
|
|
51
86
|
* Additive auto-migration of the schema for all context entities (enabled in
|
|
52
87
|
* the module: `ormBazis: { migrateOnStart: true }`): introspects the database,
|
|
@@ -82,6 +82,9 @@ const DataModule = ormModule({
|
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
`ormModule` exports the `IRepository` family token so importing modules can inject `repositoryFor(User)`.
|
|
85
|
+
A feature module that declares `ormBazis` passes repositories on with its own
|
|
86
|
+
`exports`: `exports: [IRepository]` opens the repositories of all its entities,
|
|
87
|
+
`exports: [repositoryFor(User)]` (since 0.98.22) only that one.
|
|
85
88
|
|
|
86
89
|
Turning repositories off:
|
|
87
90
|
|
|
@@ -61,6 +61,27 @@ export class MigrationRunner {
|
|
|
61
61
|
return { applied, rolledBack: [] };
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Records pending migrations as applied without running them. Used when the
|
|
66
|
+
* schema was just created from the current model, which already contains
|
|
67
|
+
* their result.
|
|
68
|
+
*/
|
|
69
|
+
async baseline(): Promise<readonly string[]> {
|
|
70
|
+
return this.withMigrationLock(async () => {
|
|
71
|
+
await this.ensureHistory();
|
|
72
|
+
const appliedSet = await this.loadApplied();
|
|
73
|
+
const recorded: string[] = [];
|
|
74
|
+
for (const migration of this.migrations.filter((item) => !appliedSet.has(item.id))) {
|
|
75
|
+
await this.provider.execute(
|
|
76
|
+
`INSERT INTO ${this.quote(HISTORY_TABLE)} (${this.quote("MigrationId")}, ${this.quote("AppliedAt")}) VALUES (${this.param(0)}, ${this.param(1)})`,
|
|
77
|
+
[migration.id, new Date().toISOString()],
|
|
78
|
+
);
|
|
79
|
+
recorded.push(migration.id);
|
|
80
|
+
}
|
|
81
|
+
return recorded;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
64
85
|
/** Rolls back the last `steps` migrations (requires `down`). */
|
|
65
86
|
async rollback(steps = 1): Promise<VersionedMigrationResult> {
|
|
66
87
|
if (!Number.isSafeInteger(steps) || steps < 0) {
|
package/library/orm/errors.ts
CHANGED
|
@@ -33,7 +33,7 @@ export class SchemaMigrationRequiredError extends SchemaAdmissionError {
|
|
|
33
33
|
|
|
34
34
|
function schemaVerificationMessage(summary: string, verification: SchemaVerificationResult): string {
|
|
35
35
|
return [summary, formatSchemaDifferences(verification),
|
|
36
|
-
"Check the application version and target database. Align the ORM model and database schema; apply an explicit migration if a database change is intended.",
|
|
36
|
+
"Check the application version and target database. Align the ORM model and database schema; apply an explicit migration if a database change is intended (with ensureCreated: add it to the module's migrations with runMigrationsOnStart: true).",
|
|
37
37
|
].filter(Boolean).join("\n");
|
|
38
38
|
}
|
|
39
39
|
|
package/library/orm/index.ts
CHANGED
|
@@ -132,6 +132,7 @@ export type {
|
|
|
132
132
|
} from "./Schema/introspection";
|
|
133
133
|
export type { SchemaDifferenceCode, SafeSchemaDescriptor, SchemaDifference, SchemaVerificationResult } from "./Schema/ExactSchemaVerifier";
|
|
134
134
|
export type { EnsureCreatedResult } from "./Schema/SchemaAdmission";
|
|
135
|
+
export type { EnsureCreatedWithMigrationsResult } from "./DatabaseFacade";
|
|
135
136
|
export { SchemaAdmissionError, SchemaMigrationRequiredError, SchemaVerificationError } from "./errors";
|
|
136
137
|
export type { SchemaAdmissionErrorCode } from "./errors";
|
|
137
138
|
export { compileCheck, renderCheck } from "./Schema/CheckExpression";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bazis",
|
|
3
|
-
"version": "0.98.
|
|
3
|
+
"version": "0.98.22",
|
|
4
4
|
"description": "Modular backend framework for Bun in TypeScript: DI wired by codegen, HTTP, a PostgreSQL ORM, JWT, WebSocket, agents and a CLI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Alexander Alenin",
|