@lunora/codegen 1.0.0-alpha.32 → 1.0.0-alpha.320

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 (125) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +1 -1
  3. package/dist/index.d.mts +4230 -2183
  4. package/dist/index.d.ts +4230 -2183
  5. package/dist/index.mjs +1 -35
  6. package/dist/packem_shared/AGENTS_FILENAME-B6-kjzM3.mjs +1 -0
  7. package/dist/packem_shared/CAPABILITY_PROBES-brcmKenl.mjs +25 -0
  8. package/dist/packem_shared/CONTAINERS_FILENAME-dFRtAyIe.mjs +1 -0
  9. package/dist/packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs +1 -0
  10. package/dist/packem_shared/DEFAULT_TARGET-B0FkdiZq.mjs +1 -0
  11. package/dist/packem_shared/FLAGS_FILENAME-Bf0MSlHH.mjs +1 -0
  12. package/dist/packem_shared/GENERATED_HEADER-Ck_WOHzE.mjs +1 -0
  13. package/dist/packem_shared/LUNORA_ERROR_CODES-C2s0xWQD.mjs +1 -0
  14. package/dist/packem_shared/MUTATORS_FILENAME-Jkk8Zgkb.mjs +1 -0
  15. package/dist/packem_shared/NOTIFY_FILENAME-bAt7J3cs.mjs +1 -0
  16. package/dist/packem_shared/OPENRPC_VERSION-CCY7xqSL.mjs +3 -0
  17. package/dist/packem_shared/PROJECT_CONFIG_FILENAMES-DzOu-lSc.mjs +1 -0
  18. package/dist/packem_shared/QUEUES_FILENAME-CsRy4VTF.mjs +1 -0
  19. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-Bo67h-3B.mjs +11 -0
  20. package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs +2 -0
  21. package/dist/packem_shared/SHAPES_FILENAME-DkBUN9dK.mjs +1 -0
  22. package/dist/packem_shared/SchemaSnapshotParseError-BRJT7c2k.mjs +18 -0
  23. package/dist/packem_shared/WORKFLOWS_FILENAME-CdeS224T.mjs +1 -0
  24. package/dist/packem_shared/attribution-hVBriwzy.mjs +1 -0
  25. package/dist/packem_shared/buildOpenApiDocument-DFv-RYZU.mjs +3 -0
  26. package/dist/packem_shared/capabilitiesUsedBy-QgSZyE0T.mjs +1 -0
  27. package/dist/packem_shared/chain-Cm6BMT8g.mjs +1 -0
  28. package/dist/packem_shared/classify-procedure-call-DVxdUhZt.mjs +1 -0
  29. package/dist/packem_shared/context-property-calls-Cn3upNgZ.mjs +1 -0
  30. package/dist/packem_shared/context-root-BdxINX-T.mjs +1 -0
  31. package/dist/packem_shared/createCodegenProject-V51_yBw3.mjs +1 -0
  32. package/dist/packem_shared/database-calls-BKozZUEW.mjs +1 -0
  33. package/dist/packem_shared/declared-output-Iaar469J.mjs +1 -0
  34. package/dist/packem_shared/describeErrorLevelFindings-vzaGS9KL.mjs +1 -0
  35. package/dist/packem_shared/discoverAuthApiCalls-xs0ONfI-.mjs +1 -0
  36. package/dist/packem_shared/discoverCrons-DBnCama4.mjs +1 -0
  37. package/dist/packem_shared/discoverFunctions-CZgLhsMn.mjs +1 -0
  38. package/dist/packem_shared/discoverHttpRoutes-WBAqBcfK.mjs +1 -0
  39. package/dist/packem_shared/discoverHyperdriveCalls-DV4IglLE.mjs +1 -0
  40. package/dist/packem_shared/discoverInserts-BjxXCACZ.mjs +1 -0
  41. package/dist/packem_shared/discoverMaskProcedures-DE-8CDen.mjs +1 -0
  42. package/dist/packem_shared/discoverMigrations-C9mLIhGZ.mjs +1 -0
  43. package/dist/packem_shared/discoverNondeterministicCalls-DvhyKM-f.mjs +1 -0
  44. package/dist/packem_shared/discoverQueries-C8E7TeRT.mjs +1 -0
  45. package/dist/packem_shared/discoverR2sqlCalls-DVcfMO6-.mjs +1 -0
  46. package/dist/packem_shared/discoverRlsMetadata-QRsWRQbM.mjs +1 -0
  47. package/dist/packem_shared/discoverRlsProcedures-Du7ITNTQ.mjs +1 -0
  48. package/dist/packem_shared/discoverSandboxUsage-w6Q3RvxZ.mjs +1 -0
  49. package/dist/packem_shared/discoverSchema-BtsX-CN9.mjs +1 -0
  50. package/dist/packem_shared/discoverStorageRulesMetadata-ClzKLdCV.mjs +1 -0
  51. package/dist/packem_shared/dispatch-namespace-DwTjD7BU.mjs +1 -0
  52. package/dist/packem_shared/emitAgents-CR2_X_ov.mjs +1 -0
  53. package/dist/packem_shared/emitApi-CDgIPAG2.mjs +147 -0
  54. package/dist/packem_shared/emitApp-BEe4wd3R.mjs +985 -0
  55. package/dist/packem_shared/emitCrons-BQW2lviZ.mjs +96 -0
  56. package/dist/packem_shared/emitDataModel-BskFt9Wv.mjs +114 -0
  57. package/dist/packem_shared/emitDrizzleSchema-DitcRZ1a.mjs +15 -0
  58. package/dist/packem_shared/emitFunctions-rjyb7h7k.mjs +422 -0
  59. package/dist/packem_shared/emitServer-D1vA5_X1.mjs +1 -0
  60. package/dist/packem_shared/emitShard-D3Po46nf.mjs +1 -0
  61. package/dist/packem_shared/exported-procedure-chains-BNBUkXui.mjs +1 -0
  62. package/dist/packem_shared/fingerprintSchemaSources-eVG9aVt0.mjs +1 -0
  63. package/dist/packem_shared/formatAdvisories-BCVASH7N.mjs +2 -0
  64. package/dist/packem_shared/handler-reference-vIeqkhV_.mjs +1 -0
  65. package/dist/packem_shared/index-JnqBWRYO.mjs +1 -0
  66. package/dist/packem_shared/isD1GlobalTable-udvHAAzD.mjs +1 -0
  67. package/dist/packem_shared/isTestPath-B81lOULB.mjs +1 -0
  68. package/dist/packem_shared/isTypedSchema-CKzc3ioR.mjs +4 -0
  69. package/dist/packem_shared/json-data-Chfs2Cz5.mjs +1 -0
  70. package/dist/packem_shared/loadProjectConfig-NO0dVJSl.mjs +1 -0
  71. package/dist/packem_shared/module-specifiers-WF8iAydP.mjs +1 -0
  72. package/dist/packem_shared/modules-CjOcuQnK.mjs +1 -0
  73. package/dist/packem_shared/parse-validator-IDBKIT7M.mjs +1 -0
  74. package/dist/packem_shared/platform-8oj7iXQy.mjs +1 -0
  75. package/dist/packem_shared/project-config-file-BV7RR-l6.mjs +1 -0
  76. package/dist/packem_shared/qualifiers-DEdXn5wP.mjs +1 -0
  77. package/dist/packem_shared/readPackageDependencies-RHhGiz0k.mjs +1 -0
  78. package/dist/packem_shared/readServiceBindings-DvqIThzd.mjs +1 -0
  79. package/dist/packem_shared/redact-Cy14LEnc.mjs +1 -0
  80. package/dist/packem_shared/reserved-words-CW1QFbTd.mjs +1 -0
  81. package/dist/packem_shared/schema-BgM8A3XV.mjs +1 -0
  82. package/dist/packem_shared/schemaFromIr-BWFnvCVg.mjs +1 -0
  83. package/dist/packem_shared/server-DAvi_bv_.mjs +368 -0
  84. package/dist/packem_shared/shard-CsOnD3Na.mjs +1601 -0
  85. package/dist/packem_shared/shard-runtime-BpoCV-aM.mjs +331 -0
  86. package/dist/packem_shared/shared-DnCokNcE.mjs +13 -0
  87. package/dist/packem_shared/unwrap-handler-return-CeaOifqX.mjs +1 -0
  88. package/dist/sdk/index.d.mts +288 -0
  89. package/dist/sdk/index.d.ts +288 -0
  90. package/dist/sdk/index.mjs +372 -0
  91. package/package.json +21 -8
  92. package/dist/packem_shared/CONTAINERS_FILENAME-DjpXMqhp.mjs +0 -224
  93. package/dist/packem_shared/CodegenDiagnosticError-DyQ5FwkM.mjs +0 -24
  94. package/dist/packem_shared/FLAGS_FILENAME-BjpS5w08.mjs +0 -139
  95. package/dist/packem_shared/GENERATED_HEADER-CLwPlCQe.mjs +0 -3
  96. package/dist/packem_shared/LUNORA_ERROR_CODES-CySpQPD3.mjs +0 -61
  97. package/dist/packem_shared/MUTATORS_FILENAME-BZOfUhlY.mjs +0 -81
  98. package/dist/packem_shared/OPENRPC_VERSION-4YIeMkOI.mjs +0 -60
  99. package/dist/packem_shared/QUEUES_FILENAME-BF0iUmx7.mjs +0 -119
  100. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-OBXQBJV0.mjs +0 -3520
  101. package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-D0ARY6rL.mjs +0 -249
  102. package/dist/packem_shared/SHAPES_FILENAME-DOhPGi-6.mjs +0 -94
  103. package/dist/packem_shared/WORKFLOWS_FILENAME-CCC_42o3.mjs +0 -124
  104. package/dist/packem_shared/buildOpenApiDocument-bp1pYSV6.mjs +0 -183
  105. package/dist/packem_shared/discover-ast-CT6BgBr4.mjs +0 -13
  106. package/dist/packem_shared/discoverAuthApiCalls-URDoTADN.mjs +0 -62
  107. package/dist/packem_shared/discoverCrons-DdZOeroL.mjs +0 -257
  108. package/dist/packem_shared/discoverFunctions-BJdF7lRs.mjs +0 -514
  109. package/dist/packem_shared/discoverHttpRoutes-CcwP-Rkr.mjs +0 -131
  110. package/dist/packem_shared/discoverInserts-BpFhM32L.mjs +0 -61
  111. package/dist/packem_shared/discoverMaskProcedures-DT-v8wvj.mjs +0 -273
  112. package/dist/packem_shared/discoverMigrations-cG1idBVM.mjs +0 -97
  113. package/dist/packem_shared/discoverNondeterministicCalls-CEOjmfk4.mjs +0 -122
  114. package/dist/packem_shared/discoverQueries-DeVBQVAG.mjs +0 -62
  115. package/dist/packem_shared/discoverR2sqlCalls-CWCAU-xJ.mjs +0 -80
  116. package/dist/packem_shared/discoverRlsMetadata-BL0oukaK.mjs +0 -280
  117. package/dist/packem_shared/discoverSchema-CeXJWVKV.mjs +0 -874
  118. package/dist/packem_shared/discoverStorageRulesMetadata-CFHByjIl.mjs +0 -97
  119. package/dist/packem_shared/emit-CBwEvCXQ.mjs +0 -3451
  120. package/dist/packem_shared/emitApp-nQ2oC-8G.mjs +0 -668
  121. package/dist/packem_shared/formatAdvisories-C9wNBNvL.mjs +0 -113
  122. package/dist/packem_shared/parse-validator-D6zI2i85.mjs +0 -134
  123. package/dist/packem_shared/paths-BRd6JHuF.mjs +0 -11
  124. package/dist/packem_shared/redact-oTmsol5A.mjs +0 -33
  125. package/dist/packem_shared/schemaFromIr-DTYsLBaA.mjs +0 -57
@@ -0,0 +1,288 @@
1
+ import { LanguageName } from 'quicktype-core';
2
+ /**
3
+ * Language-agnostic half of SDK generation: turn an OpenRPC document
4
+ * (`_generated/openrpc.json`, see {@link file://../openrpc.ts}) into the parsed
5
+ * shape every per-language target renders from.
6
+ *
7
+ * Nothing here knows about a target language. A target supplies its own member
8
+ * naming and templates (see {@link file://./targets}); everything that would
9
+ * otherwise be re-derived per language — how a `functionPath` splits, which
10
+ * runtime verb a kind maps to, whether a schema is real or the untyped
11
+ * placeholder, how namespaces group and sort — lives here exactly once.
12
+ *
13
+ * That single-source rule is not stylistic. `paths.ts` documents the same
14
+ * discipline for namespaces ("if these ever disagree, runtime dispatch silently
15
+ * misses functions"), and the failure mode here is the same in a new costume: a
16
+ * target that re-derives a model name renders an import pointing at a class
17
+ * quicktype never emitted.
18
+ *
19
+ * Deriving names in one place is necessary but NOT sufficient, because only
20
+ * half the decision is ours: quicktype chooses whether a predicted name becomes
21
+ * a declared type, and different backends answer differently for the same
22
+ * schema. {@link withDeclaredModels} reconciles the two halves before a target
23
+ * renders anything.
24
+ */
25
+ /** One OpenRPC method as {@link file://../openrpc.ts} emits it. */
26
+ interface OpenRpcMethod {
27
+ name: string;
28
+ params?: ReadonlyArray<{
29
+ name: string;
30
+ schema?: Record<string, unknown>;
31
+ }>;
32
+ result?: {
33
+ name: string;
34
+ schema?: Record<string, unknown>;
35
+ };
36
+ summary?: string;
37
+ "x-lunora-function-kind"?: string;
38
+ }
39
+ /** The `_generated/openrpc.json` document. */
40
+ interface OpenRpcDocument {
41
+ info?: {
42
+ title?: string;
43
+ version?: string;
44
+ };
45
+ methods: ReadonlyArray<OpenRpcMethod>;
46
+ }
47
+ /** The runtime verbs a generated SDK can call. Mirrors the client transports. */
48
+ type RuntimeVerb = "action" | "mutation" | "query";
49
+ /** One RPC function, parsed and language-neutral. */
50
+ interface SdkMethod {
51
+ /**
52
+ * Where this function's ARGUMENT nulls mean "unset" and where they mean
53
+ * "null" — see {@link ModelNullPaths}.
54
+ *
55
+ * On the method rather than on a shared render input because it is a
56
+ * per-method fact and the parser already holds the schema it comes from. Read
57
+ * by the three targets whose rendered models cannot tell the two apart
58
+ * (ruby, rust, swift); the other five have a marker of their own and ignore
59
+ * it.
60
+ */
61
+ argsNullPaths: ModelNullPaths;
62
+ /**
63
+ * Generated args model name, or `undefined` when NO model could be named for
64
+ * this function's arguments.
65
+ *
66
+ * `undefined` does NOT mean "takes no arguments" — see {@link SdkMethod.takesArgs}.
67
+ * A schema carrying a `v.bigint()` or `v.bytes()` gets no model deliberately
68
+ * (`hasUnrepresentableWireType`), and a backend that cannot name a shape leaves
69
+ * it undeclared. Both still take arguments, just untyped ones.
70
+ */
71
+ argsType: string | undefined;
72
+ /** Raw exported function name (`"list"`), before any naming convention. */
73
+ functionName: string;
74
+ /** The wire identifier (`"messages:list"`), emitted verbatim into calls. */
75
+ functionPath: string;
76
+ /** Raw file namespace (`"messages"`), before any naming convention. */
77
+ namespace: string;
78
+ /** Generated result model name, or `undefined` while the result is untyped. */
79
+ resultType: string | undefined;
80
+ /** Human summary for the doc comment. */
81
+ summary: string;
82
+ /**
83
+ * Whether this function declares arguments at all, independent of whether a
84
+ * model could be named for them.
85
+ *
86
+ * A target emits three shapes from this: a TYPED parameter when `argsType` is
87
+ * set, an UNTYPED wire-shaped parameter when it is not but this is true, and no
88
+ * parameter at all when this is false. Collapsing the middle case into the last
89
+ * is what made `v.bigint()` functions uncallable with arguments.
90
+ */
91
+ takesArgs: boolean;
92
+ /** Which runtime verb this dispatches to. */
93
+ verb: RuntimeVerb;
94
+ }
95
+ /** One namespace's functions, sorted. */
96
+ interface SdkNamespace {
97
+ methods: ReadonlyArray<SdkMethod>;
98
+ /** Raw namespace (`"messages"`); a target applies its own casing. */
99
+ name: string;
100
+ }
101
+ /**
102
+ * True when a schema actually describes a shape.
103
+ *
104
+ * `openrpc.ts` emits a description-only placeholder for any function without a
105
+ * declared `.output()` (the return type is TS-inferred and absent from the IR).
106
+ * A placeholder must never become a generated model: quicktype would render an
107
+ * empty type, and the surface would decode every response into it — silently
108
+ * discarding the real payload rather than leaving it untyped.
109
+ */
110
+ declare const isTypedSchema: (schema: Record<string, unknown> | undefined) => boolean;
111
+ /**
112
+ * A path from a model's root to one property. `*` stands for every element of an
113
+ * array or every value of a record, neither of which has named positions.
114
+ */
115
+ type SchemaPath = ReadonlyArray<string>;
116
+ /**
117
+ * Where a model's nulls mean different things — the one fact a generated model
118
+ * flattens away, and the reason three ports could not send a `v.nullable()`
119
+ * argument at all.
120
+ *
121
+ * An unset `v.optional()` and a `v.nullable()` set to null are the SAME value in
122
+ * every generated model (a nil field), and opposite things on the wire: the
123
+ * validator rejects an explicit null for the first and requires the key present
124
+ * for the second. Neither Ruby, Rust nor Swift renders a marker telling them
125
+ * apart, so the distinction is computed here, from the schema, where `required`
126
+ * still exists — and handed to the targets that need it.
127
+ *
128
+ * Two lists rather than one because the ports need opposite operations. Ruby and
129
+ * Rust project a whole value tree and prune nulls, so they prune at
130
+ * {@link ModelNullPaths.optional} and nowhere else — which also stops them
131
+ * dropping a legitimate null inside a record or an array, as a blanket prune
132
+ * does. Swift's `JSONEncoder` has already dropped every struct-property nil
133
+ * before the transport sees a tree, so it restores nulls at
134
+ * {@link ModelNullPaths.nullable} instead: an absent key at a required path can
135
+ * only have been a nil, so putting the null back is exact.
136
+ *
137
+ * A `$ref` is NOT resolved. `openrpc.ts` inlines everything it emits, so this
138
+ * never comes up for a generated document — but `--spec` accepts a hand-written
139
+ * one, and there a `$ref`'d sub-object contributes no paths at all: the ports
140
+ * that prune would send its unset optionals as null, and Swift would not restore
141
+ * its nullables. Inline the schema, or teach this to follow the pointer.
142
+ *
143
+ * Both lists name PROPERTIES only. A record's values and an array's elements can
144
+ * be null too, but no port drops one: the pruning ports prune at `optional`
145
+ * paths, which a `*` position can never be, and `JSONEncoder` drops a nil only
146
+ * from a struct property — a nil inside a dictionary or array encodes as null.
147
+ * Listing a `*` leaf would also make Swift's restore INVENT record keys that
148
+ * were never there, which is why the walk records the path it descends through
149
+ * but never the `*` position itself.
150
+ */
151
+ interface ModelNullPaths {
152
+ /** Required properties that permit null — a null there is a VALUE and must survive. */
153
+ nullable: ReadonlyArray<SchemaPath>;
154
+ /** Properties absent from their object's `required` — a null there means UNSET. */
155
+ optional: ReadonlyArray<SchemaPath>;
156
+ }
157
+ /** What a target renders from. */
158
+ interface SdkRenderInput {
159
+ /**
160
+ * The rendered model source, to be written as the target's model file.
161
+ *
162
+ * Empty for a target that emits its own model FILES via
163
+ * {@link SdkTarget.renderModels} — those are already written, and this string
164
+ * exists only so the declared-model reconciliation reads one shape.
165
+ */
166
+ models: string;
167
+ /** Namespaces and their functions, already sorted. */
168
+ namespaces: ReadonlyArray<SdkNamespace>;
169
+ }
170
+ /**
171
+ * One directory or file of the hand-written transport, and where it lands in the
172
+ * output.
173
+ *
174
+ * `from` is relative to `sdks/<target id>/` and `to` is relative to `--out`. The
175
+ * two differ because a repo layout and a consumable layout are not the same
176
+ * shape: the Ruby transport lives under `lib/` so `ruby -Ilib` works in the
177
+ * repo, while a vendored copy has no `lib` to point at, and the Rust transport
178
+ * is the repo's root crate but a nested one in the output.
179
+ *
180
+ * Only the runtime is listed. A transport's own conformance suite and its
181
+ * `generated_check/` sample are deliberately absent — they assert against
182
+ * `protocol/fixtures/`, which is not copied, so vendoring them would ship a user
183
+ * a test suite that cannot run.
184
+ */
185
+ interface SdkVendorEntry {
186
+ /** Path under `sdks/<id>/`. A directory is copied recursively. */
187
+ from: string;
188
+ /** Destination path under `--out`. */
189
+ to: string;
190
+ }
191
+ /** A language target. One per `--lang` value. */
192
+ interface SdkTarget {
193
+ /** The `--lang` value (`"python"`, `"go"`, …). */
194
+ id: string;
195
+ /**
196
+ * The quicktype backend + renderer options that produce this target's
197
+ * models, or absent when the target emits its own (see
198
+ * {@link SdkTarget.renderModels}) or none at all.
199
+ *
200
+ * `LanguageName` is quicktype's own union, so a target naming a backend
201
+ * quicktype does not ship fails to compile rather than at run time.
202
+ */
203
+ quicktype?: {
204
+ lang: LanguageName;
205
+ rendererOptions?: Record<string, string>;
206
+ };
207
+ /**
208
+ * Render the SDK. Returns file contents keyed by path relative to the
209
+ * output directory (nested paths are created as needed).
210
+ *
211
+ * This includes the BUILD MANIFEST the layout needs — `go.mod`, `Cargo.toml`,
212
+ * `Package.swift`, a crate root — because those name the vendored transport
213
+ * and are therefore part of "how this language resolves the copy", not
214
+ * something a consumer should have to write. Languages that resolve by
215
+ * directory (Python, Ruby, Java, Kotlin) emit no manifest.
216
+ */
217
+ render: (input: SdkRenderInput) => Record<string, string>;
218
+ /**
219
+ * Emit this target's models from the schema directly, INSTEAD of quicktype,
220
+ * as file contents keyed by path relative to the output directory.
221
+ *
222
+ * Present only for the two JVM targets, and the exception is earned rather
223
+ * than a preference: quicktype's Java and Kotlin backends rename properties
224
+ * and, under `just-types`, emit no mapping metadata, so a model they render
225
+ * cannot be projected back onto the wire — and the only complete mapping
226
+ * they offer requires a Jackson / Klaxon / kotlinx dependency, which is the
227
+ * one thing these JDK-only transports are defined not to have.
228
+ * `targets/java.ts` records every option that was measured.
229
+ *
230
+ * A MAP rather than the single string quicktype returns, because Java takes
231
+ * one file per class: its single-file render is not compilable Java at all.
232
+ * The values are still joined for {@link SdkRenderInput.models}, so the
233
+ * declared-model reconciliation is the same code for every target.
234
+ */
235
+ renderModels?: (document: OpenRpcDocument) => Record<string, string>;
236
+ /**
237
+ * THIRD-PARTY packages a consuming project must still install, reported by
238
+ * the CLI. Empty for six of the eight — the transport is vendored and those
239
+ * six reach the wire with only their standard library.
240
+ *
241
+ * A list, and not derivable from the transport, because a target's MODELS can
242
+ * carry a dependency the transport does not: quicktype's Ruby backend emits
243
+ * `Dry::Struct` types with no renderer option to avoid them, so a Ruby SDK
244
+ * needs the gems even though `sdks/ruby` itself is dependency-free.
245
+ */
246
+ requires: ReadonlyArray<string>;
247
+ /**
248
+ * Which parts of `sdks/<id>/` are the transport, and where they land under
249
+ * `--out`. See {@link SdkVendorEntry}.
250
+ */
251
+ vendor: ReadonlyArray<SdkVendorEntry>;
252
+ }
253
+ /** Every language `lunora sdk generate --lang` accepts, keyed by id. */
254
+ declare const SDK_TARGETS: Readonly<Record<string, SdkTarget>>;
255
+ /** The accepted `--lang` values, sorted — for help text and error messages. */
256
+ declare const SDK_LANGUAGES: ReadonlyArray<string>;
257
+ /** The files a generation run writes, keyed by path relative to the output directory. */
258
+ type SdkFiles = Record<string, string>;
259
+ /** What a generation run produced, plus what it had to weaken and why. */
260
+ interface SdkResult {
261
+ files: SdkFiles;
262
+ /**
263
+ * Model names predicted from the schema that the chosen backend did not
264
+ * declare, so their call sites fell back to an untyped return. Surfaced
265
+ * rather than swallowed — silently weaker types are how an SDK looks
266
+ * finished while returning `Any` everywhere.
267
+ */
268
+ undeclared: ReadonlyArray<string>;
269
+ /**
270
+ * Functions whose args or result carry a `v.bigint()` or `v.bytes()`. No
271
+ * typed model can represent those — the wire needs a tagged value that no
272
+ * generated field produces — so their parameters stay untyped and the
273
+ * caller passes wire values directly.
274
+ */
275
+ unrepresentable: ReadonlyArray<string>;
276
+ }
277
+ /**
278
+ * Generate the SDK for `document` in `target`'s language.
279
+ *
280
+ * Async only because the model layer is: quicktype's renderer is promise-based.
281
+ * The surface itself is pure, so a target's `render` stays synchronous and
282
+ * unit-testable without touching quicktype.
283
+ *
284
+ * Models are rendered BEFORE the surface because the surface's model references
285
+ * depend on what the backend actually declared — see {@link withDeclaredModels}.
286
+ */
287
+ declare const generateSdk: (document: OpenRpcDocument, target: SdkTarget) => Promise<SdkResult>;
288
+ export { type OpenRpcDocument, type OpenRpcMethod, type RuntimeVerb, SDK_LANGUAGES, SDK_TARGETS, type SdkFiles, type SdkMethod, type SdkNamespace, type SdkRenderInput, type SdkResult, type SdkTarget, generateSdk, isTypedSchema };
@@ -0,0 +1,288 @@
1
+ import { LanguageName } from 'quicktype-core';
2
+ /**
3
+ * Language-agnostic half of SDK generation: turn an OpenRPC document
4
+ * (`_generated/openrpc.json`, see {@link file://../openrpc.ts}) into the parsed
5
+ * shape every per-language target renders from.
6
+ *
7
+ * Nothing here knows about a target language. A target supplies its own member
8
+ * naming and templates (see {@link file://./targets}); everything that would
9
+ * otherwise be re-derived per language — how a `functionPath` splits, which
10
+ * runtime verb a kind maps to, whether a schema is real or the untyped
11
+ * placeholder, how namespaces group and sort — lives here exactly once.
12
+ *
13
+ * That single-source rule is not stylistic. `paths.ts` documents the same
14
+ * discipline for namespaces ("if these ever disagree, runtime dispatch silently
15
+ * misses functions"), and the failure mode here is the same in a new costume: a
16
+ * target that re-derives a model name renders an import pointing at a class
17
+ * quicktype never emitted.
18
+ *
19
+ * Deriving names in one place is necessary but NOT sufficient, because only
20
+ * half the decision is ours: quicktype chooses whether a predicted name becomes
21
+ * a declared type, and different backends answer differently for the same
22
+ * schema. {@link withDeclaredModels} reconciles the two halves before a target
23
+ * renders anything.
24
+ */
25
+ /** One OpenRPC method as {@link file://../openrpc.ts} emits it. */
26
+ interface OpenRpcMethod {
27
+ name: string;
28
+ params?: ReadonlyArray<{
29
+ name: string;
30
+ schema?: Record<string, unknown>;
31
+ }>;
32
+ result?: {
33
+ name: string;
34
+ schema?: Record<string, unknown>;
35
+ };
36
+ summary?: string;
37
+ "x-lunora-function-kind"?: string;
38
+ }
39
+ /** The `_generated/openrpc.json` document. */
40
+ interface OpenRpcDocument {
41
+ info?: {
42
+ title?: string;
43
+ version?: string;
44
+ };
45
+ methods: ReadonlyArray<OpenRpcMethod>;
46
+ }
47
+ /** The runtime verbs a generated SDK can call. Mirrors the client transports. */
48
+ type RuntimeVerb = "action" | "mutation" | "query";
49
+ /** One RPC function, parsed and language-neutral. */
50
+ interface SdkMethod {
51
+ /**
52
+ * Where this function's ARGUMENT nulls mean "unset" and where they mean
53
+ * "null" — see {@link ModelNullPaths}.
54
+ *
55
+ * On the method rather than on a shared render input because it is a
56
+ * per-method fact and the parser already holds the schema it comes from. Read
57
+ * by the three targets whose rendered models cannot tell the two apart
58
+ * (ruby, rust, swift); the other five have a marker of their own and ignore
59
+ * it.
60
+ */
61
+ argsNullPaths: ModelNullPaths;
62
+ /**
63
+ * Generated args model name, or `undefined` when NO model could be named for
64
+ * this function's arguments.
65
+ *
66
+ * `undefined` does NOT mean "takes no arguments" — see {@link SdkMethod.takesArgs}.
67
+ * A schema carrying a `v.bigint()` or `v.bytes()` gets no model deliberately
68
+ * (`hasUnrepresentableWireType`), and a backend that cannot name a shape leaves
69
+ * it undeclared. Both still take arguments, just untyped ones.
70
+ */
71
+ argsType: string | undefined;
72
+ /** Raw exported function name (`"list"`), before any naming convention. */
73
+ functionName: string;
74
+ /** The wire identifier (`"messages:list"`), emitted verbatim into calls. */
75
+ functionPath: string;
76
+ /** Raw file namespace (`"messages"`), before any naming convention. */
77
+ namespace: string;
78
+ /** Generated result model name, or `undefined` while the result is untyped. */
79
+ resultType: string | undefined;
80
+ /** Human summary for the doc comment. */
81
+ summary: string;
82
+ /**
83
+ * Whether this function declares arguments at all, independent of whether a
84
+ * model could be named for them.
85
+ *
86
+ * A target emits three shapes from this: a TYPED parameter when `argsType` is
87
+ * set, an UNTYPED wire-shaped parameter when it is not but this is true, and no
88
+ * parameter at all when this is false. Collapsing the middle case into the last
89
+ * is what made `v.bigint()` functions uncallable with arguments.
90
+ */
91
+ takesArgs: boolean;
92
+ /** Which runtime verb this dispatches to. */
93
+ verb: RuntimeVerb;
94
+ }
95
+ /** One namespace's functions, sorted. */
96
+ interface SdkNamespace {
97
+ methods: ReadonlyArray<SdkMethod>;
98
+ /** Raw namespace (`"messages"`); a target applies its own casing. */
99
+ name: string;
100
+ }
101
+ /**
102
+ * True when a schema actually describes a shape.
103
+ *
104
+ * `openrpc.ts` emits a description-only placeholder for any function without a
105
+ * declared `.output()` (the return type is TS-inferred and absent from the IR).
106
+ * A placeholder must never become a generated model: quicktype would render an
107
+ * empty type, and the surface would decode every response into it — silently
108
+ * discarding the real payload rather than leaving it untyped.
109
+ */
110
+ declare const isTypedSchema: (schema: Record<string, unknown> | undefined) => boolean;
111
+ /**
112
+ * A path from a model's root to one property. `*` stands for every element of an
113
+ * array or every value of a record, neither of which has named positions.
114
+ */
115
+ type SchemaPath = ReadonlyArray<string>;
116
+ /**
117
+ * Where a model's nulls mean different things — the one fact a generated model
118
+ * flattens away, and the reason three ports could not send a `v.nullable()`
119
+ * argument at all.
120
+ *
121
+ * An unset `v.optional()` and a `v.nullable()` set to null are the SAME value in
122
+ * every generated model (a nil field), and opposite things on the wire: the
123
+ * validator rejects an explicit null for the first and requires the key present
124
+ * for the second. Neither Ruby, Rust nor Swift renders a marker telling them
125
+ * apart, so the distinction is computed here, from the schema, where `required`
126
+ * still exists — and handed to the targets that need it.
127
+ *
128
+ * Two lists rather than one because the ports need opposite operations. Ruby and
129
+ * Rust project a whole value tree and prune nulls, so they prune at
130
+ * {@link ModelNullPaths.optional} and nowhere else — which also stops them
131
+ * dropping a legitimate null inside a record or an array, as a blanket prune
132
+ * does. Swift's `JSONEncoder` has already dropped every struct-property nil
133
+ * before the transport sees a tree, so it restores nulls at
134
+ * {@link ModelNullPaths.nullable} instead: an absent key at a required path can
135
+ * only have been a nil, so putting the null back is exact.
136
+ *
137
+ * A `$ref` is NOT resolved. `openrpc.ts` inlines everything it emits, so this
138
+ * never comes up for a generated document — but `--spec` accepts a hand-written
139
+ * one, and there a `$ref`'d sub-object contributes no paths at all: the ports
140
+ * that prune would send its unset optionals as null, and Swift would not restore
141
+ * its nullables. Inline the schema, or teach this to follow the pointer.
142
+ *
143
+ * Both lists name PROPERTIES only. A record's values and an array's elements can
144
+ * be null too, but no port drops one: the pruning ports prune at `optional`
145
+ * paths, which a `*` position can never be, and `JSONEncoder` drops a nil only
146
+ * from a struct property — a nil inside a dictionary or array encodes as null.
147
+ * Listing a `*` leaf would also make Swift's restore INVENT record keys that
148
+ * were never there, which is why the walk records the path it descends through
149
+ * but never the `*` position itself.
150
+ */
151
+ interface ModelNullPaths {
152
+ /** Required properties that permit null — a null there is a VALUE and must survive. */
153
+ nullable: ReadonlyArray<SchemaPath>;
154
+ /** Properties absent from their object's `required` — a null there means UNSET. */
155
+ optional: ReadonlyArray<SchemaPath>;
156
+ }
157
+ /** What a target renders from. */
158
+ interface SdkRenderInput {
159
+ /**
160
+ * The rendered model source, to be written as the target's model file.
161
+ *
162
+ * Empty for a target that emits its own model FILES via
163
+ * {@link SdkTarget.renderModels} — those are already written, and this string
164
+ * exists only so the declared-model reconciliation reads one shape.
165
+ */
166
+ models: string;
167
+ /** Namespaces and their functions, already sorted. */
168
+ namespaces: ReadonlyArray<SdkNamespace>;
169
+ }
170
+ /**
171
+ * One directory or file of the hand-written transport, and where it lands in the
172
+ * output.
173
+ *
174
+ * `from` is relative to `sdks/<target id>/` and `to` is relative to `--out`. The
175
+ * two differ because a repo layout and a consumable layout are not the same
176
+ * shape: the Ruby transport lives under `lib/` so `ruby -Ilib` works in the
177
+ * repo, while a vendored copy has no `lib` to point at, and the Rust transport
178
+ * is the repo's root crate but a nested one in the output.
179
+ *
180
+ * Only the runtime is listed. A transport's own conformance suite and its
181
+ * `generated_check/` sample are deliberately absent — they assert against
182
+ * `protocol/fixtures/`, which is not copied, so vendoring them would ship a user
183
+ * a test suite that cannot run.
184
+ */
185
+ interface SdkVendorEntry {
186
+ /** Path under `sdks/<id>/`. A directory is copied recursively. */
187
+ from: string;
188
+ /** Destination path under `--out`. */
189
+ to: string;
190
+ }
191
+ /** A language target. One per `--lang` value. */
192
+ interface SdkTarget {
193
+ /** The `--lang` value (`"python"`, `"go"`, …). */
194
+ id: string;
195
+ /**
196
+ * The quicktype backend + renderer options that produce this target's
197
+ * models, or absent when the target emits its own (see
198
+ * {@link SdkTarget.renderModels}) or none at all.
199
+ *
200
+ * `LanguageName` is quicktype's own union, so a target naming a backend
201
+ * quicktype does not ship fails to compile rather than at run time.
202
+ */
203
+ quicktype?: {
204
+ lang: LanguageName;
205
+ rendererOptions?: Record<string, string>;
206
+ };
207
+ /**
208
+ * Render the SDK. Returns file contents keyed by path relative to the
209
+ * output directory (nested paths are created as needed).
210
+ *
211
+ * This includes the BUILD MANIFEST the layout needs — `go.mod`, `Cargo.toml`,
212
+ * `Package.swift`, a crate root — because those name the vendored transport
213
+ * and are therefore part of "how this language resolves the copy", not
214
+ * something a consumer should have to write. Languages that resolve by
215
+ * directory (Python, Ruby, Java, Kotlin) emit no manifest.
216
+ */
217
+ render: (input: SdkRenderInput) => Record<string, string>;
218
+ /**
219
+ * Emit this target's models from the schema directly, INSTEAD of quicktype,
220
+ * as file contents keyed by path relative to the output directory.
221
+ *
222
+ * Present only for the two JVM targets, and the exception is earned rather
223
+ * than a preference: quicktype's Java and Kotlin backends rename properties
224
+ * and, under `just-types`, emit no mapping metadata, so a model they render
225
+ * cannot be projected back onto the wire — and the only complete mapping
226
+ * they offer requires a Jackson / Klaxon / kotlinx dependency, which is the
227
+ * one thing these JDK-only transports are defined not to have.
228
+ * `targets/java.ts` records every option that was measured.
229
+ *
230
+ * A MAP rather than the single string quicktype returns, because Java takes
231
+ * one file per class: its single-file render is not compilable Java at all.
232
+ * The values are still joined for {@link SdkRenderInput.models}, so the
233
+ * declared-model reconciliation is the same code for every target.
234
+ */
235
+ renderModels?: (document: OpenRpcDocument) => Record<string, string>;
236
+ /**
237
+ * THIRD-PARTY packages a consuming project must still install, reported by
238
+ * the CLI. Empty for six of the eight — the transport is vendored and those
239
+ * six reach the wire with only their standard library.
240
+ *
241
+ * A list, and not derivable from the transport, because a target's MODELS can
242
+ * carry a dependency the transport does not: quicktype's Ruby backend emits
243
+ * `Dry::Struct` types with no renderer option to avoid them, so a Ruby SDK
244
+ * needs the gems even though `sdks/ruby` itself is dependency-free.
245
+ */
246
+ requires: ReadonlyArray<string>;
247
+ /**
248
+ * Which parts of `sdks/<id>/` are the transport, and where they land under
249
+ * `--out`. See {@link SdkVendorEntry}.
250
+ */
251
+ vendor: ReadonlyArray<SdkVendorEntry>;
252
+ }
253
+ /** Every language `lunora sdk generate --lang` accepts, keyed by id. */
254
+ declare const SDK_TARGETS: Readonly<Record<string, SdkTarget>>;
255
+ /** The accepted `--lang` values, sorted — for help text and error messages. */
256
+ declare const SDK_LANGUAGES: ReadonlyArray<string>;
257
+ /** The files a generation run writes, keyed by path relative to the output directory. */
258
+ type SdkFiles = Record<string, string>;
259
+ /** What a generation run produced, plus what it had to weaken and why. */
260
+ interface SdkResult {
261
+ files: SdkFiles;
262
+ /**
263
+ * Model names predicted from the schema that the chosen backend did not
264
+ * declare, so their call sites fell back to an untyped return. Surfaced
265
+ * rather than swallowed — silently weaker types are how an SDK looks
266
+ * finished while returning `Any` everywhere.
267
+ */
268
+ undeclared: ReadonlyArray<string>;
269
+ /**
270
+ * Functions whose args or result carry a `v.bigint()` or `v.bytes()`. No
271
+ * typed model can represent those — the wire needs a tagged value that no
272
+ * generated field produces — so their parameters stay untyped and the
273
+ * caller passes wire values directly.
274
+ */
275
+ unrepresentable: ReadonlyArray<string>;
276
+ }
277
+ /**
278
+ * Generate the SDK for `document` in `target`'s language.
279
+ *
280
+ * Async only because the model layer is: quicktype's renderer is promise-based.
281
+ * The surface itself is pure, so a target's `render` stays synchronous and
282
+ * unit-testable without touching quicktype.
283
+ *
284
+ * Models are rendered BEFORE the surface because the surface's model references
285
+ * depend on what the backend actually declared — see {@link withDeclaredModels}.
286
+ */
287
+ declare const generateSdk: (document: OpenRpcDocument, target: SdkTarget) => Promise<SdkResult>;
288
+ export { type OpenRpcDocument, type OpenRpcMethod, type RuntimeVerb, SDK_LANGUAGES, SDK_TARGETS, type SdkFiles, type SdkMethod, type SdkNamespace, type SdkRenderInput, type SdkResult, type SdkTarget, generateSdk, isTypedSchema };