bazis 0.100.1 → 0.100.3
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/cli/codegen.ts
CHANGED
|
@@ -86,13 +86,12 @@ export function renderCodegen(ui: CliOutput, report: CodegenReport, cwd: string,
|
|
|
86
86
|
commandFailed(ui.err, t.failure.codegen(report.errors.length), report.errors.map((error) => codegenProblem(error, cwd, ui.err)), 1, footer);
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
|
+
// Files always; the rest only when the project has them.
|
|
89
90
|
const counts = target === undefined ? [] : [
|
|
90
91
|
s.num(target.sources, t.noun("file", target.sources)),
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
s.num(target.listModels, t.noun("list", target.listModels)),
|
|
95
|
-
s.num(target.tools, t.noun("tool", target.tools)),
|
|
92
|
+
...([[target.deps, "dep"], [target.controllers, "controller"], [target.requestModels, "requestModel"], [target.listModels, "list"], [target.tools, "tool"]] as const)
|
|
93
|
+
.filter(([value]) => value > 0)
|
|
94
|
+
.map(([value, noun]) => s.num(value, t.noun(noun, value))),
|
|
96
95
|
];
|
|
97
96
|
s.step("ok", t.step.codegen, counts.join(s.dot), time);
|
|
98
97
|
const directories = new Map<string, string[]>();
|
package/core/http/HttpServer.ts
CHANGED
|
@@ -231,7 +231,8 @@ export class HttpServer implements HostedService {
|
|
|
231
231
|
error: (error) => this.transportError(error),
|
|
232
232
|
}),
|
|
233
233
|
);
|
|
234
|
-
}
|
|
234
|
+
}
|
|
235
|
+
this.reportStarted(routes);
|
|
235
236
|
}
|
|
236
237
|
|
|
237
238
|
/** Routes and the address for the startup screen. */
|
|
@@ -369,7 +370,8 @@ export class HttpServer implements HostedService {
|
|
|
369
370
|
}
|
|
370
371
|
}
|
|
371
372
|
|
|
372
|
-
private async dispatch(
|
|
373
|
+
private async dispatch(incoming: Request, clientIp?: string): Promise<Response> {
|
|
374
|
+
const request = this.withAbsoluteUrl(incoming);
|
|
373
375
|
let response: Response;
|
|
374
376
|
try {
|
|
375
377
|
response = await this.handle(request, clientIp);
|
|
@@ -395,6 +397,18 @@ export class HttpServer implements HostedService {
|
|
|
395
397
|
return response;
|
|
396
398
|
}
|
|
397
399
|
|
|
400
|
+
/**
|
|
401
|
+
* HTTP/1.0 allows a request without `Host`; Bun then gives a path, not a
|
|
402
|
+
* URL. Such a request is addressed to this server, so it gets the server's
|
|
403
|
+
* own origin and the rest of the pipeline sees an ordinary absolute URL.
|
|
404
|
+
*/
|
|
405
|
+
private withAbsoluteUrl(request: Request): Request {
|
|
406
|
+
if (URL.canParse(request.url)) return request;
|
|
407
|
+
const server = this.server;
|
|
408
|
+
const host = server?.hostname === undefined || server.hostname === "0.0.0.0" || server.hostname === "::" ? "localhost" : server.hostname.includes(":") ? `[${server.hostname}]` : server.hostname;
|
|
409
|
+
return new Request(new URL(request.url, `http://${host}:${server?.port ?? 80}`).href, request);
|
|
410
|
+
}
|
|
411
|
+
|
|
398
412
|
private async handle(request: Request, clientIp?: string): Promise<Response> {
|
|
399
413
|
const url = new URL(request.url);
|
|
400
414
|
|
|
@@ -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.100.
|
|
235
|
+
clientInfo: { name: "bazis", title: "Bazis", version: "0.100.3" }, 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");
|
|
@@ -113,7 +113,7 @@ export class StartupScreen {
|
|
|
113
113
|
if (schemas.length > 0) {
|
|
114
114
|
const operations = schemas.flatMap((schema) => [...schema.migrated.map((name) => `migration ${name}`), ...schema.applied]);
|
|
115
115
|
s.section(t.section.schema, s.muted([...new Set(schemas.map((schema) => schema.mode))].join(", ")));
|
|
116
|
-
s.step("ok", t.step.schema, operations.length === 0 ? s.muted(t.schema.none) : [s.num(operations.length, t.noun("operation", operations.length)), s.num(schemas.length, t.noun("
|
|
116
|
+
s.step("ok", t.step.schema, operations.length === 0 ? s.muted(t.schema.none) : [s.num(operations.length, t.noun("operation", operations.length)), s.num(schemas.length, t.noun("context", schemas.length))].join(s.dot), formatDuration(stageMs(kernel, "schema")));
|
|
117
117
|
const shown = operations.slice(0, 12).map((operation) => ({ text: `${s.strong("+", PALETTE.lime)} ${s.text(operation)}` }));
|
|
118
118
|
if (operations.length > 12) shown.push({ text: s.muted(`… ${t.common.plus} ${operations.length - 12}`) });
|
|
119
119
|
s.tree(shown, this.indent);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { inspect } from "node:util";
|
|
2
2
|
import { redactSensitive, redactSensitiveText } from "../../library/redaction";
|
|
3
|
+
import { StartupFailuresError } from "./errors";
|
|
3
4
|
|
|
4
5
|
const MAX_CAUSES = 5;
|
|
5
6
|
/** Properties already printed in the header, the frames or the cause chain. */
|
|
6
|
-
const SHOWN = new Set(["name", "message", "stack", "cause", "code", "errno", "errors"]);
|
|
7
|
+
const SHOWN = new Set(["name", "message", "stack", "cause", "code", "errno", "errors", "failures"]);
|
|
7
8
|
const INSPECT = { depth: null, colors: false, customInspect: false, getters: false, maxArrayLength: null, maxStringLength: null } as const;
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -28,7 +29,9 @@ export function formatStartupFailure(error: unknown): string {
|
|
|
28
29
|
if (current instanceof AggregateError) {
|
|
29
30
|
for (const inner of current.errors) lines.push(` - ${inner instanceof Error ? `${inner.name}: ${inner.message}` : String(inner)}`);
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
+
// Services that failed together: the list above is the report; the
|
|
33
|
+
// aggregate's own frames are the kernel's, not the application's.
|
|
34
|
+
if (!(current instanceof StartupFailuresError)) lines.push(...(current.stack ?? "").split("\n").filter((line) => /^\s+at /.test(line)));
|
|
32
35
|
const details = Object.fromEntries(Object.entries(current).filter(([name]) => !SHOWN.has(name)));
|
|
33
36
|
if (Object.keys(details).length > 0) lines.push(inspect(redactSensitive(details), INSPECT));
|
|
34
37
|
current = current.cause;
|
|
@@ -31,6 +31,7 @@ const NOUNS_EN = {
|
|
|
31
31
|
test: ["test", "tests", "tests"],
|
|
32
32
|
change: ["change", "changes", "changes"],
|
|
33
33
|
part: ["part", "parts", "parts"],
|
|
34
|
+
context: ["database context", "database contexts", "database contexts"],
|
|
34
35
|
} as const satisfies Record<string, Forms>;
|
|
35
36
|
|
|
36
37
|
export type Noun = keyof typeof NOUNS_EN;
|
|
@@ -58,8 +59,19 @@ const NOUNS_RU: Record<Noun, Forms> = {
|
|
|
58
59
|
test: ["тест", "теста", "тестов"],
|
|
59
60
|
change: ["изменение", "изменения", "изменений"],
|
|
60
61
|
part: ["часть", "части", "частей"],
|
|
62
|
+
context: ["контекст базы данных", "контекста базы данных", "контекстов базы данных"],
|
|
61
63
|
};
|
|
62
64
|
|
|
65
|
+
/** Genitive after «из N»: «из 1 подключения», «из 3 подключений», «из 21 подключения». */
|
|
66
|
+
const GENITIVE_RU: Partial<Record<Noun, readonly [one: string, many: string]>> = {
|
|
67
|
+
connection: ["подключения", "подключений"],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
function genitiveRu(count: number, noun: Noun): string {
|
|
71
|
+
const forms = GENITIVE_RU[noun] ?? [NOUNS_RU[noun][1], NOUNS_RU[noun][2]];
|
|
72
|
+
return count % 10 === 1 && count % 100 !== 11 ? forms[0] : forms[1];
|
|
73
|
+
}
|
|
74
|
+
|
|
63
75
|
function formEn(count: number, forms: Forms): string {
|
|
64
76
|
return count === 1 ? forms[0] : forms[1];
|
|
65
77
|
}
|
|
@@ -316,7 +328,7 @@ const ru: Messages = {
|
|
|
316
328
|
},
|
|
317
329
|
failure: {
|
|
318
330
|
config: (count) => `конфигурация с ошибками · ${count} ${formRu(count, NOUNS_RU.problem)}`,
|
|
319
|
-
infra: (down, total) => `инфраструктура недоступна · ${down} из ${total} ${
|
|
331
|
+
infra: (down, total) => `инфраструктура недоступна · ${down} из ${total} ${genitiveRu(total, "connection")}`,
|
|
320
332
|
timeout: (seconds) => `запуск не уложился в ${seconds}`,
|
|
321
333
|
di: "внедрение зависимостей не собрано",
|
|
322
334
|
codegen: (count) => `кодогенерация не удалась · ${count} ${formRu(count, NOUNS_RU.error)}`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bazis",
|
|
3
|
-
"version": "0.100.
|
|
3
|
+
"version": "0.100.3",
|
|
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",
|