@chanx-js/codegen 0.1.1 → 0.1.2

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/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as generate, t as loadSchema } from "./loader-DtCKhsCU.mjs";
2
+ import { n as generate, t as loadSchema } from "./loader-CQXUAlXv.mjs";
3
3
  import { cac } from "cac";
4
4
  //#region src/cli.ts
5
5
  const cli = cac("chanx-codegen");
package/dist/index.d.mts CHANGED
@@ -89,8 +89,9 @@ interface ConnectionInfo extends ChannelInfo {
89
89
  * Split channels into connections and the topics riding on them.
90
90
  *
91
91
  * A topic channel shares its connection's address, which is what groups the two;
92
- * chanx's own Python generator uses the same rule. A topic channel with no plain
93
- * channel at its address owns its connection, so it is emitted as both.
92
+ * chanx's own Python generator uses the same rule. With no plain channel at its
93
+ * address, a hosted topic gets a connection named after its host, carrying no messages
94
+ * itself; a topic served on its own route is emitted as both.
94
95
  */
95
96
  export declare function analyze(document: AsyncAPIDocument): ConnectionInfo[];
96
97
  //#endregion
@@ -159,6 +160,12 @@ interface ReuseResolution {
159
160
  */
160
161
  export declare function resolveReuse(wanted: ReadonlySet<string>, outDir: string, options: ReuseOptions): Promise<ReuseResolution>;
161
162
  export declare function renderImports(imports: Map<string, Set<string>>): string;
163
+ /**
164
+ * Re-export reused types, so every schema name is available from the output (channels
165
+ * import messages from it) and an import nothing generated references still counts as
166
+ * used under `noUnusedLocals`.
167
+ */
168
+ export declare function renderReexports(imports: Map<string, Set<string>>): string;
162
169
  //#endregion
163
170
  //#region src/generate.d.ts
164
171
  interface GenerateOptions extends ReuseOptions {
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as emitZod, c as emitSchemas, d as emitChannelsDeclaration, f as camelCase, i as resolveReuse, l as tsType, m as analyze, n as generate, o as emitZodDeclaration, p as pascalCase, r as renderImports, s as declareType, t as loadSchema, u as emitChannels } from "./loader-DtCKhsCU.mjs";
2
- export { analyze, camelCase, declareType, emitChannels, emitChannelsDeclaration, emitSchemas, emitZod, emitZodDeclaration, generate, loadSchema, pascalCase, renderImports, resolveReuse, tsType };
1
+ import { a as resolveReuse, c as declareType, d as emitChannels, f as emitChannelsDeclaration, h as analyze, i as renderReexports, l as emitSchemas, m as pascalCase, n as generate, o as emitZod, p as camelCase, r as renderImports, s as emitZodDeclaration, t as loadSchema, u as tsType } from "./loader-CQXUAlXv.mjs";
2
+ export { analyze, camelCase, declareType, emitChannels, emitChannelsDeclaration, emitSchemas, emitZod, emitZodDeclaration, generate, loadSchema, pascalCase, renderImports, renderReexports, resolveReuse, tsType };
@@ -56,11 +56,21 @@ function describe(document, key, channel, buckets) {
56
56
  return info;
57
57
  }
58
58
  /**
59
+ * The consumer hosting a topic channel, from chanx's `<host>_<topic>` naming, when the
60
+ * host declares no messages of its own and so has no plain channel.
61
+ */
62
+ function hostName(topic) {
63
+ const suffix = `_${topic.topic?.name ?? ""}`;
64
+ if (!topic.topic?.name || !topic.name.endsWith(suffix)) return null;
65
+ return topic.name.slice(0, -suffix.length) || null;
66
+ }
67
+ /**
59
68
  * Split channels into connections and the topics riding on them.
60
69
  *
61
70
  * A topic channel shares its connection's address, which is what groups the two;
62
- * chanx's own Python generator uses the same rule. A topic channel with no plain
63
- * channel at its address owns its connection, so it is emitted as both.
71
+ * chanx's own Python generator uses the same rule. With no plain channel at its
72
+ * address, a hosted topic gets a connection named after its host, carrying no messages
73
+ * itself; a topic served on its own route is emitted as both.
64
74
  */
65
75
  function analyze(document) {
66
76
  const buckets = directions(document);
@@ -82,7 +92,16 @@ function analyze(document) {
82
92
  parent.topics.push(topic);
83
93
  continue;
84
94
  }
85
- const standalone = {
95
+ const host = hostName(topic);
96
+ const standalone = host ? {
97
+ key: topic.key,
98
+ name: host,
99
+ address: topic.address,
100
+ toServer: [],
101
+ toClient: [],
102
+ heartbeat: false,
103
+ topics: [topic]
104
+ } : {
86
105
  ...topic,
87
106
  topics: [topic]
88
107
  };
@@ -471,6 +490,15 @@ function renderImports(imports) {
471
490
  return `import type { ${[...names].sort().join(", ")} } from '${specifier}';`;
472
491
  }).join("\n")}\n\n`;
473
492
  }
493
+ /**
494
+ * Re-export reused types, so every schema name is available from the output (channels
495
+ * import messages from it) and an import nothing generated references still counts as
496
+ * used under `noUnusedLocals`.
497
+ */
498
+ function renderReexports(imports) {
499
+ const names = [...imports.values()].flatMap((set) => [...set]).sort();
500
+ return names.length ? `export type { ${names.join(", ")} };\n\n` : "";
501
+ }
474
502
  //#endregion
475
503
  //#region src/generate.ts
476
504
  const HEADER = `// Generated by @chanx-js/codegen. Do not edit.\n// Regenerate with: npx @chanx-js/codegen\n\n`;
@@ -548,7 +576,7 @@ async function generate(document, options) {
548
576
  files.push(filePath);
549
577
  };
550
578
  const isJs = target === "js";
551
- await write(isJs ? "schemas.d.ts" : "schemas.ts", HEADER + renderImports(reuse.imports) + emitSchemas(schemas, reuse.skip));
579
+ await write(isJs ? "schemas.d.ts" : "schemas.ts", HEADER + renderImports(reuse.imports) + renderReexports(reuse.imports) + emitSchemas(schemas, reuse.skip));
552
580
  const messageNames = [...new Set(connections.flatMap((connection) => [connection, ...connection.topics].flatMap((channel) => [...channel.toServer, ...channel.toClient])))];
553
581
  const channelOptions = {
554
582
  withZod,
@@ -600,4 +628,4 @@ async function loadSchema(input) {
600
628
  return document;
601
629
  }
602
630
  //#endregion
603
- export { emitZod as a, emitSchemas as c, emitChannelsDeclaration as d, camelCase as f, resolveReuse as i, tsType as l, analyze as m, generate as n, emitZodDeclaration as o, pascalCase as p, renderImports as r, declareType as s, loadSchema as t, emitChannels as u };
631
+ export { resolveReuse as a, declareType as c, emitChannels as d, emitChannelsDeclaration as f, analyze as h, renderReexports as i, emitSchemas as l, pascalCase as m, generate as n, emitZod as o, camelCase as p, renderImports as r, emitZodDeclaration as s, loadSchema as t, tsType as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chanx-js/codegen",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Generate TypeScript channel descriptors and message types from a chanx AsyncAPI 3 schema.",
5
5
  "license": "MIT",
6
6
  "author": "Huy Nguyen",