@ishibashi0112/webview2-bridge-gen 0.2.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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +60 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/define.d.ts +19 -0
  8. package/dist/define.d.ts.map +1 -0
  9. package/dist/define.js +8 -0
  10. package/dist/define.js.map +1 -0
  11. package/dist/emit-ts.d.ts +15 -0
  12. package/dist/emit-ts.d.ts.map +1 -0
  13. package/dist/emit-ts.js +113 -0
  14. package/dist/emit-ts.js.map +1 -0
  15. package/dist/emit-vb.d.ts +22 -0
  16. package/dist/emit-vb.d.ts.map +1 -0
  17. package/dist/emit-vb.js +467 -0
  18. package/dist/emit-vb.js.map +1 -0
  19. package/dist/emitted.d.ts +6 -0
  20. package/dist/emitted.d.ts.map +1 -0
  21. package/dist/emitted.js +2 -0
  22. package/dist/emitted.js.map +1 -0
  23. package/dist/generate.d.ts +47 -0
  24. package/dist/generate.d.ts.map +1 -0
  25. package/dist/generate.js +103 -0
  26. package/dist/generate.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +8 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/naming.d.ts +8 -0
  32. package/dist/naming.d.ts.map +1 -0
  33. package/dist/naming.js +42 -0
  34. package/dist/naming.js.map +1 -0
  35. package/dist/schema.d.ts +45 -0
  36. package/dist/schema.d.ts.map +1 -0
  37. package/dist/schema.js +21 -0
  38. package/dist/schema.js.map +1 -0
  39. package/dist/to-schema.d.ts +10 -0
  40. package/dist/to-schema.d.ts.map +1 -0
  41. package/dist/to-schema.js +75 -0
  42. package/dist/to-schema.js.map +1 -0
  43. package/dist/vb-runtime.d.ts +12 -0
  44. package/dist/vb-runtime.d.ts.map +1 -0
  45. package/dist/vb-runtime.js +50 -0
  46. package/dist/vb-runtime.js.map +1 -0
  47. package/package.json +73 -0
  48. package/vb-runtime/README.md +10 -0
  49. package/vb-runtime/runtime/Dispatcher.vb +145 -0
  50. package/vb-runtime/runtime/IBridgeEmitter.vb +16 -0
  51. package/vb-runtime/runtime/JsonRpc.vb +124 -0
  52. package/vb-runtime/winforms/WebViewBridge.vb +100 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ishibashi0112
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # @ishibashi0112/webview2-bridge-gen
2
+
3
+ Code generator for [webview2-bridge](https://github.com/ishibashi0112/webview2-bridge):
4
+ write the contract between a Vite/React UI and a VB.NET WinForms (.NET Framework 4.8) host **once**, in [zod](https://zod.dev),
5
+ and generate both sides.
6
+
7
+ ```
8
+ contract.ts (zod) ──> contract.schema.json ──> contract-types.ts (TypeScript, for the UI)
9
+ └─> Dto.vb / Interfaces.vb / Dispatcher.Generated.vb / Events.vb (VB.NET)
10
+ ```
11
+
12
+ The front-end runtime is [`@ishibashi0112/webview2-bridge-client`](https://www.npmjs.com/package/@ishibashi0112/webview2-bridge-client);
13
+ the VB.NET runtime is the NuGet package `WebView2Bridge.Runtime` (plus `WebView2Bridge.WinForms` for the host).
14
+
15
+ ## Install
16
+
17
+ ```sh
18
+ pnpm add -D @ishibashi0112/webview2-bridge-gen zod
19
+ ```
20
+
21
+ Requires Node.js 20.19+ and zod 4.
22
+
23
+ ## Define the contract
24
+
25
+ ```ts
26
+ // contract/contract.ts
27
+ import { z } from "zod";
28
+ import { defineContract } from "@ishibashi0112/webview2-bridge-gen";
29
+
30
+ // Give shared objects / enums a name with .meta({ id }) — it becomes the VB class name and the TS type name
31
+ const Part = z
32
+ .object({ partNo: z.string(), name: z.string(), qty: z.number().int(), updatedAt: z.string() })
33
+ .meta({ id: "Part" });
34
+
35
+ export const contract = defineContract({
36
+ methods: {
37
+ parts: {
38
+ search: {
39
+ input: z.object({ keyword: z.string().min(1), limit: z.number().int().optional() }),
40
+ output: z.object({ items: z.array(Part) }),
41
+ },
42
+ },
43
+ },
44
+ events: {
45
+ progress: z.object({ percent: z.number(), message: z.string().optional() }),
46
+ },
47
+ });
48
+ export type Contract = typeof contract;
49
+ ```
50
+
51
+ ## Configure and run
52
+
53
+ ```jsonc
54
+ // webview2-bridge.gen.json (repository root)
55
+ {
56
+ "contract": "contract/contract.ts",
57
+ "schemaOut": "contract/contract.schema.json",
58
+ "ts": { "outDir": "apps/web/src/generated", "contractImport": "@webview2-bridge/contract" },
59
+ "vb": { "outDir": "dotnet/MyApp.Contract/Generated", "namespace": "MyApp.Contract" }
60
+ }
61
+ ```
62
+
63
+ ```sh
64
+ webview2-bridge-gen # generate (uses ./webview2-bridge.gen.json)
65
+ webview2-bridge-gen --check # CI: exit 1 if the generated files are out of date
66
+ webview2-bridge-gen --config path/to/config.json
67
+ ```
68
+
69
+ Generated files start with an `<auto-generated>` header; the generator only overwrites / removes files carrying that header.
70
+ Commit the generated files.
71
+
72
+ ## What is generated
73
+
74
+ **TypeScript** (`contract-types.ts`): `PartsSearchInput` / `PartsSearchOutput`, `ProgressEvent`, named types (`Part`),
75
+ `MethodMap` / `EventMap`, `methodNames` / `eventNames`. Types are derived from the zod contract with `z.input` / `z.output`.
76
+
77
+ **VB.NET** (into `Namespace Global.<namespace>`, referencing the `WebView2Bridge.Runtime` NuGet package):
78
+
79
+ | File | Content |
80
+ |---|---|
81
+ | `Dto.vb` | one `Public Class` per object with `<JsonProperty("camelCase")>`; string enums as `NotInheritable Class` with `Public Const` |
82
+ | `Interfaces.vb` | `Public Interface IPartsApi` with `Function Search(req As PartsSearchRequest) As Task(Of PartsSearchResponse)` |
83
+ | `Dispatcher.Generated.vb` | `DispatcherExtensions.Register(dispatcher, api)` extension methods wiring `"parts.search"` to `IPartsApi.Search` |
84
+ | `Events.vb` | `BridgeEvents` with `Sub Progress(payload As ProgressEvent)` emitting `"event.progress"` |
85
+
86
+ Type mapping: `string`→`String`, `number`→`Double`, `int`→`Integer` (`.meta({ format: "int64" })`→`Long`), `boolean`→`Boolean`,
87
+ `array`→`List(Of T)`, `record`→`Dictionary(Of String, T)`, `unknown`→`JToken`, `X | null`→nullable, optional value types→`Nullable(Of T)`.
88
+ Optional properties get `NullValueHandling.Ignore` so `Nothing` is omitted from JSON (zod `.optional()` rejects `null`).
89
+ Unions, intersections, dates and bigints are rejected with a clear error.
90
+
91
+ Naming: `.meta({ id })` wins; otherwise `<Namespace><Method>Request` / `Response`, `<Event>Event`,
92
+ nested objects `<Owner><Prop>`, array items singularized (`items` → `Item`).
93
+
94
+ ## VB runtime without NuGet
95
+
96
+ The VB.NET runtime (`Dispatcher`, `JsonRpc`, `IBridgeEmitter`) and the WinForms glue (`WebViewBridge`) are bundled
97
+ in this package. Point `vb.runtime.outDir` / `vb.winforms.outDir` at your projects and the generator writes them as
98
+ auto-generated files, so **no custom NuGet package is needed** — your Contract project only references `Newtonsoft.Json`
99
+ and your Host only `Microsoft.Web.WebView2`.
100
+
101
+ ```jsonc
102
+ "vb": {
103
+ "outDir": "dotnet/MyApp.Contract/Generated",
104
+ "namespace": "MyApp.Contract",
105
+ "runtime": { "outDir": "dotnet/MyApp.Contract/Runtime" },
106
+ "winforms": { "outDir": "dotnet/MyApp.Host/Bridge" }
107
+ }
108
+ ```
109
+
110
+ The files keep the namespaces `WebView2Bridge.Runtime` / `WebView2Bridge.WinForms`, so the code you write is identical
111
+ whether the runtime comes from these files or from the NuGet packages of the same name. Upgrading the runtime = upgrading
112
+ this npm package and running the generator again (`--check` reports outdated copies).
113
+
114
+ ## Options (`vb`)
115
+
116
+ | Option | Default | Meaning |
117
+ |---|---|---|
118
+ | `namespace` | required | namespace of the generated code |
119
+ | `runtimeNamespace` | `WebView2Bridge.Runtime` | namespace of `Dispatcher` / `IBridgeEmitter` (NuGet `WebView2Bridge.Runtime`) |
120
+ | `dispatcherClass` | `Dispatcher` | runtime dispatcher class name |
121
+ | `eventsClass` | `BridgeEvents` | generated events helper class name |
122
+ | `emitterInterface` | `IBridgeEmitter` | runtime emitter interface name |
123
+ | `runtime.outDir` | — | write the bundled VB runtime (3 files) here; omit when using the NuGet package or a ProjectReference |
124
+ | `winforms.outDir` | — | write the bundled `WebViewBridge.vb` here; omit when using the NuGet package or a ProjectReference |
125
+
126
+ ## Programmatic use
127
+
128
+ ```ts
129
+ import { defineContract, toSchema, emitTs, emitVb } from "@ishibashi0112/webview2-bridge-gen";
130
+ import { generate, emitVbRuntime } from "@ishibashi0112/webview2-bridge-gen/generate"; // Node only (fs)
131
+ ```
132
+
133
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { generate } from "./generate.js";
5
+ import { GenerateError } from "./schema.js";
6
+ const DEFAULT_CONFIG = "webview2-bridge.gen.json";
7
+ function usage() {
8
+ console.error(`Usage: webview2-bridge-gen [--config <file>] [--cwd <dir>] [--check]
9
+
10
+ --config 設定ファイル(既定: ./${DEFAULT_CONFIG})
11
+ --cwd 設定ファイル内の相対パスの基準(既定: 設定ファイルのあるディレクトリ)
12
+ --check 書き込まず、生成物が最新かだけを確認する(差分があれば exit 1)`);
13
+ process.exit(2);
14
+ }
15
+ async function main(argv) {
16
+ let configPath = DEFAULT_CONFIG;
17
+ let cwd;
18
+ let check = false;
19
+ for (let i = 0; i < argv.length; i++) {
20
+ const a = argv[i];
21
+ if (a === "--config")
22
+ configPath = argv[++i] ?? usage();
23
+ else if (a === "--cwd")
24
+ cwd = argv[++i] ?? usage();
25
+ else if (a === "--check")
26
+ check = true;
27
+ else if (a === "-h" || a === "--help")
28
+ usage();
29
+ else {
30
+ console.error(`Unknown argument: ${a}`);
31
+ usage();
32
+ }
33
+ }
34
+ const absConfig = path.resolve(configPath);
35
+ const config = JSON.parse(await readFile(absConfig, "utf8"));
36
+ const base = cwd ? path.resolve(cwd) : path.dirname(absConfig);
37
+ const result = await generate(config, { cwd: base, check });
38
+ const rel = (p) => path.relative(base, p);
39
+ if (check) {
40
+ if (result.stale.length > 0) {
41
+ console.error("Generated files are out of date:\n" + result.stale.map((f) => ` ${rel(f)}`).join("\n"));
42
+ console.error("Run `pnpm gen`.");
43
+ return 1;
44
+ }
45
+ console.log(`Up to date (${result.files.length} files).`);
46
+ return 0;
47
+ }
48
+ console.log(result.files.map((f) => `wrote ${rel(f)}`).join("\n"));
49
+ return 0;
50
+ }
51
+ main(process.argv.slice(2)).then((code) => process.exit(code), (err) => {
52
+ if (err instanceof GenerateError) {
53
+ console.error(`webview2-bridge-gen: ${err.message}`);
54
+ }
55
+ else {
56
+ console.error(err);
57
+ }
58
+ process.exit(1);
59
+ });
60
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { z } from "zod";
2
+ /** 1 メソッド: 入力と出力の zod スキーマ */
3
+ export interface MethodDef {
4
+ input: z.ZodType;
5
+ output: z.ZodType;
6
+ }
7
+ /** namespace → method 名 → MethodDef */
8
+ export type NamespaceDef = Record<string, MethodDef>;
9
+ /** 契約全体の形。`methods.<namespace>.<name>` と `events.<name>` */
10
+ export interface ContractDef {
11
+ methods: Record<string, NamespaceDef>;
12
+ events: Record<string, z.ZodType>;
13
+ }
14
+ /**
15
+ * 契約を定義する。型を保持して返すだけの identity 関数。
16
+ * 実行時の検証・変換は行わない(ジェネレータと client が型パラメータとして受ける)。
17
+ */
18
+ export declare function defineContract<const C extends ContractDef>(contract: C): C;
19
+ //# sourceMappingURL=define.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,8BAA8B;AAC9B,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;CACnB;AAED,uCAAuC;AACvC,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAErD,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAE1E"}
package/dist/define.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 契約を定義する。型を保持して返すだけの identity 関数。
3
+ * 実行時の検証・変換は行わない(ジェネレータと client が型パラメータとして受ける)。
4
+ */
5
+ export function defineContract(contract) {
6
+ return contract;
7
+ }
8
+ //# sourceMappingURL=define.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAA8B,QAAW;IACrE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type ContractSchema } from "./schema.js";
2
+ import type { EmittedFile } from "./emitted.js";
3
+ export interface EmitTsOptions {
4
+ /** 契約モジュールの import 指定子(例: "@webview2-bridge/contract") */
5
+ contractImport: string;
6
+ /** 契約モジュールが export している名前 */
7
+ contractExport?: string;
8
+ }
9
+ /**
10
+ * contract.schema.json → contract-types.ts
11
+ * 型は zod 契約から `z.input` / `z.output` で引く(JSON Schema から型を再構築しない)。
12
+ * JSON Schema は「どのメソッド・イベント・$defs があるか」と、$defs へ到達する経路の決定に使う。
13
+ */
14
+ export declare function emitTs(schema: ContractSchema, options: EmitTsOptions): EmittedFile[];
15
+ //# sourceMappingURL=emit-ts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-ts.d.ts","sourceRoot":"","sources":["../src/emit-ts.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,cAAc,EAAmB,MAAM,aAAa,CAAC;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,6BAA6B;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,GAAG,WAAW,EAAE,CAqEpF"}
@@ -0,0 +1,113 @@
1
+ import { isTsReserved, pascalCase } from "./naming.js";
2
+ import { GenerateError, refName } from "./schema.js";
3
+ /**
4
+ * contract.schema.json → contract-types.ts
5
+ * 型は zod 契約から `z.input` / `z.output` で引く(JSON Schema から型を再構築しない)。
6
+ * JSON Schema は「どのメソッド・イベント・$defs があるか」と、$defs へ到達する経路の決定に使う。
7
+ */
8
+ export function emitTs(schema, options) {
9
+ const exportName = options.contractExport ?? "contract";
10
+ const out = [];
11
+ out.push("// <auto-generated>");
12
+ out.push("// This code was generated by @ishibashi0112/webview2-bridge-gen from contract.schema.json.");
13
+ out.push("// DO NOT EDIT. Changes will be lost when `pnpm gen` runs.");
14
+ out.push("// </auto-generated>");
15
+ out.push('import type { z } from "zod";');
16
+ out.push(`import type { ${exportName} } from ${JSON.stringify(options.contractImport)};`);
17
+ out.push("");
18
+ out.push(`type C = typeof ${exportName};`);
19
+ out.push("");
20
+ const methodEntries = [];
21
+ const defPaths = new Map();
22
+ out.push("// ---- methods");
23
+ for (const [ns, methods] of Object.entries(schema.methods)) {
24
+ for (const [name, m] of Object.entries(methods)) {
25
+ const base = `${pascalCase(ns)}${pascalCase(name)}`;
26
+ const access = `C["methods"][${JSON.stringify(ns)}][${JSON.stringify(name)}]`;
27
+ const inputName = `${base}Input`;
28
+ const outputName = `${base}Output`;
29
+ out.push(`/** \`${ns}.${name}\` の入力 */`);
30
+ out.push(`export type ${inputName} = z.input<${access}["input"]>;`);
31
+ out.push(`/** \`${ns}.${name}\` の出力 */`);
32
+ out.push(`export type ${outputName} = z.output<${access}["output"]>;`);
33
+ methodEntries.push({ rpcName: `${ns}.${name}`, input: inputName, output: outputName });
34
+ collectDefPaths(m.input, inputName, `methods.${ns}.${name}.input`, defPaths, schema.$defs);
35
+ collectDefPaths(m.output, outputName, `methods.${ns}.${name}.output`, defPaths, schema.$defs);
36
+ }
37
+ }
38
+ out.push("");
39
+ out.push("// ---- events");
40
+ const eventEntries = [];
41
+ for (const [name, e] of Object.entries(schema.events)) {
42
+ const typeName = `${pascalCase(name)}Event`;
43
+ out.push(`/** \`event.${name}\` のペイロード */`);
44
+ out.push(`export type ${typeName} = z.output<C["events"][${JSON.stringify(name)}]>;`);
45
+ eventEntries.push({ name, type: typeName });
46
+ collectDefPaths(e, typeName, `events.${name}`, defPaths, schema.$defs);
47
+ }
48
+ out.push("");
49
+ out.push("// ---- named types (.meta({ id }))");
50
+ for (const id of Object.keys(schema.$defs)) {
51
+ const p = defPaths.get(id);
52
+ if (!p) {
53
+ throw new GenerateError(`$defs "${id}" is not referenced from any method or event`, `$defs.${id}`);
54
+ }
55
+ if (isTsReserved(id))
56
+ throw new GenerateError(`meta id "${id}" is a reserved word in TypeScript`, `$defs.${id}`);
57
+ out.push(`export type ${id} = ${p};`);
58
+ }
59
+ out.push("");
60
+ out.push("// ---- maps");
61
+ out.push("export interface MethodMap {");
62
+ for (const m of methodEntries) {
63
+ out.push(` ${JSON.stringify(m.rpcName)}: { input: ${m.input}; output: ${m.output} };`);
64
+ }
65
+ out.push("}");
66
+ out.push("export interface EventMap {");
67
+ for (const e of eventEntries) {
68
+ out.push(` ${JSON.stringify(e.name)}: ${e.type};`);
69
+ }
70
+ out.push("}");
71
+ out.push("export type MethodName = keyof MethodMap;");
72
+ out.push("export type EventName = keyof EventMap;");
73
+ out.push(`export const methodNames = [${methodEntries.map((m) => JSON.stringify(m.rpcName)).join(", ")}] as const;`);
74
+ out.push(`export const eventNames = [${eventEntries.map((e) => JSON.stringify(e.name)).join(", ")}] as const;`);
75
+ return [{ path: "contract-types.ts", content: out.join("\n") + "\n" }];
76
+ }
77
+ /**
78
+ * `$ref` に最初に到達した経路を TS の indexed access 型として記録する。
79
+ * 例: PartsSearchOutput["items"][number]
80
+ */
81
+ function collectDefPaths(s, rootExpr, path, acc, defs) {
82
+ const visit = (node, expr, viaOptional, p) => {
83
+ if (node.$ref) {
84
+ const id = refName(node.$ref);
85
+ if (acc.has(id))
86
+ return;
87
+ acc.set(id, viaOptional ? `NonNullable<${expr}>` : expr);
88
+ // $defs の中で参照される $defs は、その名前付き型を起点に辿る(例: Address = NonNullable<Customer["address"]>)
89
+ const def = defs[id];
90
+ if (def)
91
+ visit(def, id, false, `$defs.${id}`);
92
+ return;
93
+ }
94
+ const nullable = (Array.isArray(node.type) && node.type.includes("null")) ||
95
+ Boolean((node.anyOf ?? node.oneOf)?.some((u) => u.type === "null"));
96
+ const union = (node.anyOf ?? node.oneOf)?.filter((u) => u.type !== "null");
97
+ if (union && union.length === 1) {
98
+ visit(union[0], expr, viaOptional || nullable, p);
99
+ return;
100
+ }
101
+ const required = new Set(node.required ?? []);
102
+ for (const [name, child] of Object.entries(node.properties ?? {})) {
103
+ visit(child, `${expr}[${JSON.stringify(name)}]`, viaOptional || nullable || !required.has(name), `${p}.${name}`);
104
+ }
105
+ if (node.items)
106
+ visit(node.items, `${expr}[number]`, viaOptional || nullable, `${p}[]`);
107
+ if (typeof node.additionalProperties === "object") {
108
+ visit(node.additionalProperties, `${expr}[string]`, viaOptional || nullable, `${p}.*`);
109
+ }
110
+ };
111
+ visit(s, rootExpr, false, path);
112
+ }
113
+ //# sourceMappingURL=emit-ts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-ts.js","sourceRoot":"","sources":["../src/emit-ts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type ContractSchema } from "./schema.js";
2
+ import type { EmittedFile } from "./emitted.js";
3
+ export interface EmitVbOptions {
4
+ /** 生成物を置く名前空間(`Namespace Global.<namespace>`)。RootNamespace とは独立 */
5
+ namespace: string;
6
+ /** 手書き側と Partial で結合する Dispatcher クラス名 */
7
+ dispatcherClass?: string;
8
+ /** 型付きイベント発行ヘルパのクラス名 */
9
+ eventsClass?: string;
10
+ /** IBridgeEmitter の名前(手書きランタイム側の Interface) */
11
+ emitterInterface?: string;
12
+ /**
13
+ * ランタイム(Dispatcher / IBridgeEmitter)の名前空間。NuGet パッケージ WebView2Bridge.Runtime の既定は
14
+ * `WebView2Bridge.Runtime`。生成される Dispatcher 拡張と Events はこれを Imports する
15
+ */
16
+ runtimeNamespace?: string;
17
+ }
18
+ /**
19
+ * contract.schema.json → VB.NET ソース(Dto.vb / Interfaces.vb / Dispatcher.Generated.vb / Events.vb)
20
+ */
21
+ export declare function emitVb(schema: ContractSchema, options: EmitVbOptions): EmittedFile[];
22
+ //# sourceMappingURL=emit-vb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-vb.d.ts","sourceRoot":"","sources":["../src/emit-vb.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,KAAK,cAAc,EAAmB,MAAM,aAAa,CAAC;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAyDD;;GAEG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,GAAG,WAAW,EAAE,CASpF"}