bazis 0.97.4 → 0.97.5

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/README.md CHANGED
@@ -15,9 +15,10 @@ executable.
15
15
  (`ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`), and the runtime uses Bun
16
16
  APIs throughout: `Bun.serve`, `Bun.SQL`, the built-in Redis client,
17
17
  `bun:test`, `bun build --compile`.
18
- - TypeScript 5.9 or newer as a peer dependency: the code generator reads
19
- your sources through the TypeScript compiler API. Nothing is compiled to
20
- JavaScript.
18
+ - TypeScript 5.9, 6 or 7 as a peer dependency: the code generator reads
19
+ your sources through the TypeScript compiler API. With TypeScript 7, which
20
+ has no such API, also install `@typescript/typescript6`. Nothing is
21
+ compiled to JavaScript.
21
22
  - PostgreSQL for the ORM.
22
23
  - Qualified platforms: macOS arm64, Linux x64 and arm64.
23
24
 
@@ -40,9 +41,20 @@ bunx bazis dev # GET http://127.0.0.1:3000/health
40
41
 
41
42
  ```sh
42
43
  bun add bazis # or a fixed version: bun add bazis@0.96.2
43
- bun add -d typescript@^6 @types/bun # TypeScript 7 is not supported yet
44
+ bun add -d typescript@^6 @types/bun
44
45
  ```
45
46
 
47
+ TypeScript 7 also works. It ships no compiler API, which the code generator
48
+ needs, so add Microsoft's TypeScript 6 API package next to it:
49
+
50
+ ```sh
51
+ bun add -d typescript@^7 @typescript/typescript6 @types/bun
52
+ ```
53
+
54
+ The project keeps type-checking with TypeScript 7; only codegen reads the
55
+ sources through the TypeScript 6 API. Without `@typescript/typescript6`
56
+ codegen stops with `BAZIS_TYPESCRIPT_API_MISSING` and this install command.
57
+
46
58
  Then take `tsconfig.json`, `bazis.config.json` and `src/index.ts` from a
47
59
  project made by `bazis new` as the starting point, and run `bunx bazis codegen`.
48
60
 
package/cli/codegen.ts CHANGED
@@ -11,7 +11,10 @@ export async function runCodegen(cwd: string, target?: string): Promise<number>
11
11
  const config = await configFile.json();
12
12
  if (target !== "all" && !Object.hasOwn(config.targets ?? {}, target)) throw new Error(`Unknown codegen target: ${target}`);
13
13
  }
14
- const args = [await resolveBun(cwd), resolveGenerator(cwd), ...(target === undefined ? [] : ["--target", target])];
14
+ const generator = resolveGenerator(cwd);
15
+ // TypeScript 7 has no compiler API: the preload switches it to @typescript/typescript6.
16
+ const preload = path.join(path.dirname(generator), "typescriptApiPreload.ts");
17
+ const args = [await resolveBun(cwd), ...(existsSync(preload) ? ["--preload", preload] : []), generator, ...(target === undefined ? [] : ["--target", target])];
15
18
  return await Bun.spawn(args, { cwd, stdout: "inherit", stderr: "inherit" }).exited;
16
19
  }
17
20
 
package/cli/main.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { generateModule, generateModulePack } from "./generateModule";
2
+ import { useTypeScriptCompilerApi } from "../core/scripts/typescriptApi";
3
3
  import { parseCliArgs } from "./parseCli";
4
4
  import { runCodegen } from "./codegen";
5
5
  import { generateProject } from "./generateProject";
@@ -100,6 +100,10 @@ export async function runCli(argv: readonly string[], runtime: CliRuntime = defa
100
100
  name: args.name, modulesRoot: args.modulesRoot, appModulePath: args.appModule,
101
101
  register: args.register, force: args.force, dryRun: args.dryRun,
102
102
  };
103
+ // Module registration parses the host module with the TypeScript API: load it
104
+ // only after switching TypeScript 7 to @typescript/typescript6.
105
+ useTypeScriptCompilerApi(process.cwd());
106
+ const { generateModule, generateModulePack } = await import("./generateModule");
103
107
  const result = args.generator === "pack"
104
108
  ? await generateModulePack({ ...options, parts: args.parts })
105
109
  : await generateModule({ ...options, profile: args.profile });
@@ -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.97.4" }, capabilities: { experimentalApi: true },
235
+ clientInfo: { name: "bazis", title: "Bazis", version: "0.97.5" }, 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");
@@ -0,0 +1,61 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { plugin } from "bun";
4
+
5
+ /**
6
+ * bazis codegen uses the TypeScript compiler API (`createProgram`, the type
7
+ * checker). TypeScript 7 no longer ships it: `import ts from "typescript"`
8
+ * gives only the version. Microsoft publishes the TypeScript 6 API as
9
+ * `@typescript/typescript6`. When the `typescript` package seen from `fromDir`
10
+ * is 7 or newer, this makes `import ts from "typescript"` in the current
11
+ * process load that package instead. The project keeps TypeScript 7 as its
12
+ * compiler (`tsc`).
13
+ *
14
+ * Must run before anything imports "typescript": as a `--preload` of the
15
+ * codegen process, or in the CLI before its first dynamic import that needs it.
16
+ * Does nothing when `typescript` cannot be resolved (for example inside the
17
+ * compiled CLI binary, which bundles its own compiler API).
18
+ */
19
+ export function useTypeScriptCompilerApi(fromDir: string): void {
20
+ let entry: string;
21
+ try {
22
+ entry = Bun.resolveSync("typescript", fromDir);
23
+ } catch {
24
+ return;
25
+ }
26
+ const major = Number.parseInt(packageVersion(entry, "typescript")?.split(".")[0] ?? "", 10);
27
+ if (!Number.isFinite(major) || major < 7) return;
28
+
29
+ let api: string;
30
+ try {
31
+ api = Bun.resolveSync("@typescript/typescript6", fromDir);
32
+ } catch {
33
+ throw new Error(
34
+ `BAZIS_TYPESCRIPT_API_MISSING: TypeScript ${major} has no compiler API, and bazis codegen needs one. ` +
35
+ "Install the TypeScript 6 API next to it: bun add -d @typescript/typescript6",
36
+ );
37
+ }
38
+ const exact = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`);
39
+ plugin({
40
+ name: "bazis-typescript6-api",
41
+ setup(build) {
42
+ build.onLoad({ filter: exact }, () => ({
43
+ contents: `import ts from ${JSON.stringify(api)};\nexport default ts;\n`,
44
+ loader: "js",
45
+ }));
46
+ },
47
+ });
48
+ }
49
+
50
+ /** Version from the package.json of the package that contains `file`. */
51
+ function packageVersion(file: string, name: string): string | undefined {
52
+ for (let dir = path.dirname(file); dir !== path.dirname(dir); dir = path.dirname(dir)) {
53
+ try {
54
+ const manifest = JSON.parse(readFileSync(path.join(dir, "package.json"), "utf8")) as { name?: string; version?: string };
55
+ if (manifest.name === name) return manifest.version;
56
+ } catch {
57
+ // No package.json at this level: keep walking up.
58
+ }
59
+ }
60
+ return undefined;
61
+ }
@@ -0,0 +1,9 @@
1
+ // Preloaded into the codegen process (`bun --preload`): see useTypeScriptCompilerApi.
2
+ import { useTypeScriptCompilerApi } from "./typescriptApi";
3
+
4
+ try {
5
+ useTypeScriptCompilerApi(import.meta.dir);
6
+ } catch (error) {
7
+ console.error(`[bazis] ${error instanceof Error ? error.message : String(error)}`);
8
+ process.exit(1);
9
+ }
@@ -653,8 +653,11 @@ export class OwnedStoreCatalogReader {
653
653
  readonly OwnedCatalogArrayTypeV1[]
654
654
  ]> {
655
655
  const relationOids = relations.filter(relation => relation.rowTypeOid !== null).map(relation => relation.oid);
656
- if (!relationOids.length)
657
- return Object.freeze([Object.freeze([]), Object.freeze([])]);
656
+ if (!relationOids.length) {
657
+ // An explicit tuple: TypeScript 7 infers Object.freeze([a, b]) as an array.
658
+ const empty: readonly [readonly OwnedCatalogRowTypeV1[], readonly OwnedCatalogArrayTypeV1[]] = [Object.freeze([]), Object.freeze([])];
659
+ return Object.freeze(empty);
660
+ }
658
661
  const rowTypes: OwnedCatalogRowTypeV1[] = [], arrayTypes: OwnedCatalogArrayTypeV1[] = [];
659
662
  for (let offset = 0; offset < relationOids.length; offset += 1024) {
660
663
  const batch = relationOids.slice(offset, offset + 1024), parameter = this.encodePgOidArrayParameter(batch), issuedLimit = Math.min(batch.length + 1, budget.remaining + 1);
@@ -693,7 +696,8 @@ export class OwnedStoreCatalogReader {
693
696
  this.source.drift();
694
697
  }
695
698
  }
696
- return Object.freeze([Object.freeze(rowTypes), Object.freeze(arrayTypes)]);
699
+ const types: readonly [readonly OwnedCatalogRowTypeV1[], readonly OwnedCatalogArrayTypeV1[]] = [Object.freeze(rowTypes), Object.freeze(arrayTypes)];
700
+ return Object.freeze(types);
697
701
  }
698
702
  private async readColumns(relations: readonly OwnedCatalogRelationV1[], operation: "registry-read" | "catalog-read", budget: {
699
703
  remaining: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bazis",
3
- "version": "0.97.4",
3
+ "version": "0.97.5",
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",
@@ -71,10 +71,16 @@
71
71
  "bun": ">=1.4.0"
72
72
  },
73
73
  "peerDependencies": {
74
- "typescript": "^5.9.3 || ^6.0.0"
74
+ "typescript": "^5.9.3 || ^6.0.0 || ^7.0.0",
75
+ "@typescript/typescript6": "^6.0.0"
75
76
  },
76
77
  "publishConfig": {
77
78
  "access": "public",
78
79
  "provenance": true
80
+ },
81
+ "peerDependenciesMeta": {
82
+ "@typescript/typescript6": {
83
+ "optional": true
84
+ }
79
85
  }
80
86
  }