@lunora/codegen 1.0.0-alpha.229 → 1.0.0-alpha.230
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/index.mjs +1 -1
- package/dist/packem_shared/{GENERATED_HEADER-Dxg5tOEa.mjs → GENERATED_HEADER-Cfw75xC4.mjs} +1 -1
- package/dist/packem_shared/{OPENRPC_VERSION-DAxS0CaZ.mjs → OPENRPC_VERSION-DDd0VJyT.mjs} +1 -1
- package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-BveaOaFr.mjs → SCHEMA_SNAPSHOT_FILENAME-Cssrg7G6.mjs} +1 -1
- package/dist/packem_shared/SDK_LANGUAGES-Df_CnJx5.mjs +372 -0
- package/dist/packem_shared/{buildOpenApiDocument-D1dd4rBh.mjs → buildOpenApiDocument-D6SBl-tk.mjs} +1 -1
- package/dist/packem_shared/{emit-6YJU3YbV.mjs → emit-D_prE7y6.mjs} +12 -2
- package/dist/packem_shared/{emitApp-BiATunRA.mjs → emitApp-rCWsXXGd.mjs} +14 -11
- package/dist/packem_shared/isTypedSchema-CKzc3ioR.mjs +4 -0
- package/package.json +1 -1
- package/dist/packem_shared/SDK_LANGUAGES-Cmn8nq91.mjs +0 -371
- package/dist/packem_shared/isTypedSchema-B_qlBbE-.mjs +0 -2
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
import{modelSources as ce,toPascalCase as o,referencedModels as N,generatedHeaderLines as f,commentText as l,argsChoice as p,stringLiteral as $,kotlinLiteral as v,allMethods as P,toSnakeCase as B,parseSpec as ke,assertGeneratable as Oe,withDeclaredModels as Ne,unrepresentableFunctions as Ce,undeclaredModels as Le}from"./isTypedSchema-B_qlBbE-.mjs";import{isTypedSchema as br}from"./isTypedSchema-B_qlBbE-.mjs";const We=async(e,n)=>{if(n.quicktype===void 0)return"";const r=ce(e);if(r.length===0)return"";const{InputData:t,JSONSchemaInput:a,JSONSchemaStore:i,quicktype:s}=await import("quicktype-core");class u extends i{fetch(){return Promise.resolve(void 0)}}const m=new a(new u);for(const g of r)await m.addSource({name:g.name,schema:JSON.stringify(g.schema)});const d=new t;d.addInput(m);const{lines:c}=await s({inputData:d,lang:n.quicktype.lang,rendererOptions:n.quicktype.rendererOptions??{}});return c.join(`
|
|
2
|
-
`)},L=`${f("dart").map(e=>`// ${e}`).join(`
|
|
3
|
-
`)}
|
|
4
|
-
|
|
5
|
-
`,Me=`# GENERATED by \`lunora sdk generate --lang dart\` — do not edit.
|
|
6
|
-
#
|
|
7
|
-
# The transport is vendored under lib/, so this package has no dependencies and
|
|
8
|
-
# nothing to fetch. Add it to a consuming app as a path dependency — pub takes a
|
|
9
|
-
# path dependency's identity from the "name" below, NOT from the directory, so
|
|
10
|
-
# this is the name you write no matter where you generated into:
|
|
11
|
-
#
|
|
12
|
-
# dependencies:
|
|
13
|
-
# lunora_sdk:
|
|
14
|
-
# path: sdk/dart
|
|
15
|
-
#
|
|
16
|
-
# import 'package:lunora_sdk/lunora_api.dart';
|
|
17
|
-
name: lunora_sdk
|
|
18
|
-
description: Generated Lunora SDK, transport included.
|
|
19
|
-
version: 0.0.0
|
|
20
|
-
publish_to: none
|
|
21
|
-
|
|
22
|
-
environment:
|
|
23
|
-
sdk: ^3.6.0
|
|
24
|
-
`,Re=new Set(["assert","break","case","catch","class","const","continue","default","do","else","enum","extends","false","final","finally","for","if","in","is","new","null","rethrow","return","super","switch","this","throw","true","try","var","void","while","with"]),E=e=>{const n=o(e),r=n.charAt(0).toLowerCase()+n.slice(1);return Re.has(r)?`${r}_`:r},pe=e=>$(e).replaceAll("$",String.raw`\$`),De=e=>e.replaceAll(" == null ? [] : List<"," == null ? null : List<").replaceAll(/Map\.from\((?<source>[^()]*?)!\)/gu,"$<source> == null ? null : Map.from($<source>!)"),z=" ".repeat(8),Pe=/^class (\w+) \{/u,Ve=/^class \w+ \{\n[\s\S]*?\n\}$/gmu,Ke=/^ {4}\w+\(\{\n([\s\S]*?)^ {4}\}\);$/mu,Ie=/^ {8}(?:required )?this\.\w+,$/gmu,Fe=/^ {4}Map<String, dynamic> toJson\(\) => \{\n([\s\S]*?)^ {4}\};$/mu,xe=/^ {8}"(?:[^\\"]|\\.)*": .*,$/gmu,qe=e=>e.replaceAll(Ve,n=>{const[,r]=Ke.exec(n)??[],[,t]=Fe.exec(n)??[];if(r===void 0||t===void 0)return n;const a=[...r.matchAll(Ie)].map(m=>{const d=m[0].trim();return{field:d.slice(d.indexOf("this.")+5,-1),optional:!d.startsWith("required ")}}),i=[...t.matchAll(xe)],s=a.filter(m=>m.optional);if(a.length!==i.length){if(s.length===0)return n;throw new Error(`dart models: cannot place the optional-field guards in ${Pe.exec(n)?.[1]??"a generated class"} — ${String(a.length)} constructor parameter(s) against ${String(i.length)} toJson entr(ies). quicktype's Dart output has changed shape; \`guardOptionalFields\` in targets/dart.ts must be updated to match.`)}let u=t;for(const[m,d]of i.entries()){const c=a[m];if(!c?.optional)continue;const g=d[0],Te=g.slice(z.length).replace(`${c.field} == null ? null : `,"");u=u.replace(g,`${z}if (${c.field} != null) ${Te}`)}return n.replace(t,u)}),de=e=>p(e,{none:"null",typed:()=>"LunoraClient.wireValue(args)",untyped:"args"}),$e={declaration:"LunoraOptimistic? optimistic, LunoraOptimisticUpdate? optimisticUpdate, bool Function()? precondition",forward:"optimistic: optimistic, optimisticUpdate: optimisticUpdate, precondition: precondition"},Z=e=>{const n=e.verb==="mutation"?`{String? shardKey, ${$e.declaration}}`:"{String? shardKey}";return p(e,{none:n,typed:r=>`${r} args, ${n}`,untyped:`Object? args, ${n}`})},me=(e,n)=>`${e}.fromJson(${n} as Map<String, dynamic>)`,X=e=>{const n=e.verb==="mutation"?`, ${$e.forward}`:"",r=`_client.${e.verb}("${pe(e.functionPath)}", args: ${de(e)}, shardKey: shardKey${n})`;return e.resultType===void 0?[` /// ${l(e.summary)}`,` Future<Object?> ${E(e.functionName)}(${Z(e)}) => ${r};`].join(`
|
|
25
|
-
`):[` /// ${l(e.summary)}`,` Future<${e.resultType}> ${E(e.functionName)}(${Z(e)}) async =>`,` ${me(e.resultType,`await ${r}`)};`].join(`
|
|
26
|
-
`)},Ue=e=>{const n=p(e,{none:"",typed:s=>`${s} args`,untyped:"Object? args"}),r=n===""?"":`${n}, `,t=de(e),a=`"${pe(e.functionPath)}"`,i=`_client.watch(${a}, args: ${t})`;return[` /// live ${l(e.summary)} — re-runs on every write to the tables it reads.`,` LunoraUnsubscribe subscribe${o(e.functionName)}(`,` ${r}{LunoraDataCallback? onData, LunoraErrorCallback? onError}`,` ) => _client.subscribe(${a}, args: ${t}, onData: onData, onError: onError);`,"",` /// live ${l(e.summary)}, as a Stream — bind it with StreamBuilder.`,e.resultType===void 0?` Stream<Object?> watch${o(e.functionName)}(${n}) => ${i};`:[` Stream<${e.resultType}> watch${o(e.functionName)}(${n}) =>`,` ${i}.map((raw) => ${me(e.resultType,"raw")});`].join(`
|
|
27
|
-
`)].join(`
|
|
28
|
-
`)},He=e=>{const n=`${o(e.name)}Api`,r=e.methods.map(t=>t.verb==="query"?`${X(t)}
|
|
29
|
-
|
|
30
|
-
${Ue(t)}`:X(t)).join(`
|
|
31
|
-
|
|
32
|
-
`);return[`/// Functions declared in \`${l(e.name)}\`.`,`class ${n} {`,` const ${n}(this._client);`,""," final LunoraClient _client;","",r,"}"].join(`
|
|
33
|
-
`)},Ge=({models:e,namespaces:n})=>{const r=n.map(s=>` final ${o(s.name)}Api ${E(s.name)};`).join(`
|
|
34
|
-
`),t=n.map(s=>` ${E(s.name)} = ${o(s.name)}Api(client)`).join(`,
|
|
35
|
-
`),a=N(n).length>0?`import 'models.dart';
|
|
36
|
-
`:"";return{"lib/lunora_api.dart":[L,`/// The generated Lunora surface. Re-exports the vendored transport, so one
|
|
37
|
-
`,`/// import gives a consumer the client, the wire types and the models.
|
|
38
|
-
`,`library;
|
|
39
|
-
`,`
|
|
40
|
-
`,`export 'lunora.dart';
|
|
41
|
-
`,`export 'models.dart';
|
|
42
|
-
`,`
|
|
43
|
-
`,`import 'lunora.dart';
|
|
44
|
-
`,a,`
|
|
45
|
-
`,n.map(s=>He(s)).join(`
|
|
46
|
-
|
|
47
|
-
`),n.length>0?`
|
|
48
|
-
|
|
49
|
-
`:"","/// Typed entry point: `Api(client).<namespace>.<function>(args)`.\n",`class Api {
|
|
50
|
-
`,n.length>0?` Api(LunoraClient client)
|
|
51
|
-
: ${t.trimStart()};
|
|
52
|
-
|
|
53
|
-
${r}
|
|
54
|
-
`:` const Api(LunoraClient client);
|
|
55
|
-
`,`}
|
|
56
|
-
`].join(""),"lib/models.dart":e.length>0?`${L}${qe(De(e))}
|
|
57
|
-
`:`${L}// No typed argument or result schemas in this deployment.
|
|
58
|
-
`,"pubspec.yaml":Me}},Be={id:"dart",quicktype:{lang:"dart"},render:Ge,requires:[],vendor:[{from:"lib",to:"lib"}]},W=`${f("go").map(e=>`// ${e}`).join(`
|
|
59
|
-
`)}
|
|
60
|
-
|
|
61
|
-
`,b="lunoraapi",_="lunorasdk",Je=`${_}/lunora`,Ye="1.22",V=e=>o(e),Q=(e,n)=>{const r=p(n,{none:"",typed:u=>`args ${u}, `,untyped:"args any, "}),t=p(n,{none:"nil",typed:()=>"args",untyped:"args"}),a=n.resultType??"any",i=`lunora.Verb${n.verb.charAt(0).toUpperCase()}${n.verb.slice(1)}`,s=`lunora.Call[${a}](a.client, ${i}, "${$(n.functionPath)}", ${t}, shardKey)`;return[`// ${V(n.functionName)} invokes ${l(n.summary)}.`,`func (a *${e}) ${V(n.functionName)}(${r}shardKey string) (${a}, error) {`,` return ${s}`,"}"].join(`
|
|
62
|
-
`)},ze=(e,n)=>{const r=p(n,{none:"",typed:i=>`args ${i}, `,untyped:"args any, "}),t=p(n,{none:"nil",typed:()=>"args",untyped:"args"}),a=`Subscribe${V(n.functionName)}`;return[`// ${a} opens a live ${l(n.functionPath)}; it re-runs on every write to the tables it reads.`,`func (a *${e}) ${a}(${r}onData lunora.DataHandler, onError lunora.ErrorHandler, shardKey string) lunora.Unsubscribe {`,` return a.client.Subscribe("${$(n.functionPath)}", ${t}, onData, onError, shardKey)`,"}"].join(`
|
|
63
|
-
`)},Ze=e=>{const n=`${o(e.name)}API`,r=e.methods.map(t=>t.verb==="query"?`${Q(n,t)}
|
|
64
|
-
|
|
65
|
-
${ze(n,t)}`:Q(n,t)).join(`
|
|
66
|
-
|
|
67
|
-
`);return[`// ${n} groups the functions declared in ${l(e.name)}.`,`type ${n} struct{ client *lunora.Client }`,"",r].join(`
|
|
68
|
-
`)},Xe=({models:e,namespaces:n})=>{const r=n.map(s=>` ${o(s.name)} *${o(s.name)}API`).join(`
|
|
69
|
-
`),t=n.map(s=>` ${o(s.name)}: &${o(s.name)}API{client: client},`).join(`
|
|
70
|
-
`),a=[W,`package ${b}
|
|
71
|
-
`,`
|
|
72
|
-
`,`import "${Je}"
|
|
73
|
-
`,`
|
|
74
|
-
`,`// API is the typed entry point: api.<Namespace>.<Function>(args, shardKey).
|
|
75
|
-
`,`type API struct {
|
|
76
|
-
`,`${r}
|
|
77
|
-
`,`}
|
|
78
|
-
`,`
|
|
79
|
-
`,`// NewAPI binds the generated surface to a client.
|
|
80
|
-
`,`func NewAPI(client *lunora.Client) *API {
|
|
81
|
-
`,` return &API{
|
|
82
|
-
`,`${t}
|
|
83
|
-
`,` }
|
|
84
|
-
`,`}
|
|
85
|
-
`,`
|
|
86
|
-
`,n.map(s=>Ze(s)).join(`
|
|
87
|
-
|
|
88
|
-
`),`
|
|
89
|
-
`].join(""),i=e.length>0?`${W}package ${b}
|
|
90
|
-
|
|
91
|
-
${e}
|
|
92
|
-
`:`${W}package ${b}
|
|
93
|
-
|
|
94
|
-
// No typed argument or result schemas in this deployment.
|
|
95
|
-
`;return{[`${b}/api.go`]:a,[`${b}/models.go`]:i,"go.mod":[`// The generated Lunora Go SDK, with the transport vendored under ./lunora.
|
|
96
|
-
`,`//
|
|
97
|
-
`,`// A consuming module wires it in without a network fetch:
|
|
98
|
-
`,`//
|
|
99
|
-
`,`// require ${_} v0.0.0
|
|
100
|
-
`,`// replace ${_} => ./path/to/this/directory
|
|
101
|
-
`,`module ${_}
|
|
102
|
-
`,`
|
|
103
|
-
`,`go ${Ye}
|
|
104
|
-
`].join("")}},Qe={id:"go",quicktype:{lang:"go",rendererOptions:{"just-types":"true",package:b}},render:Xe,requires:[],vendor:[{from:"lunora",to:"lunora"}]},w="lunoraapi.models",K="lunoraapi/models",en=24,nn=new Set(["abstract","as","assert","boolean","break","byte","case","catch","char","class","const","continue","default","do","double","else","enum","extends","false","final","finally","float","for","fromWire","fun","goto","if","implements","import","in","instanceof","int","interface","is","long","native","new","null","object","package","private","protected","public","return","short","static","strictfp","super","switch","synchronized","this","throw","throws","toWire","transient","true","try","typealias","typeof","val","var","void","volatile","when","while","wireValue"]),rn=/[^A-Za-z0-9]+/gu,tn=/([a-z0-9])([A-Z])/gu,an=/^[A-Za-z]/u,sn=/^[A-Z]/u;class ye extends Error{}const y=e=>e!==null&&typeof e=="object"&&!Array.isArray(e)?e:void 0,on=e=>{const n=e.anyOf??e.oneOf;if(!Array.isArray(n)||n.length===0)return;const r=n.map(t=>y(t)?.const);if(r.every(t=>typeof t=="string"))return[...new Set(r)].toSorted((t,a)=>t.localeCompare(a))},fe=e=>{const n=e.anyOf??e.oneOf;if(!Array.isArray(n)||n.length!==2)return e;const r=n.filter(t=>y(t)?.type!=="null");return r.length===1?y(r[0])??e:e},ln=e=>{const n=o(e),r=n.charAt(0).toLowerCase()+n.slice(1),t=an.test(r)?r:`value${n}`;return nn.has(t)?`${t}_`:t},un=e=>{const n=e.replaceAll(tn,"$1_$2").replaceAll(rn,"_").toUpperCase().split("_").filter(r=>r.length>0).join("_");return sn.test(n)?n:`VALUE_${n}`},ge=(e,n)=>{if(!n.has(e))return n.add(e),e;let r=2;for(;n.has(`${e}${String(r)}`);)r+=1;return n.add(`${e}${String(r)}`),`${e}${String(r)}`},ee=(e,n)=>{if(e.has(n.name))throw new ye(`sdk: two schemas both produce the JVM model "${n.name}"`);e.set(n.name,n)},cn=(e,n,r,t,a)=>{const i=new Set(Array.isArray(n)?n.filter(u=>typeof u=="string"):[]),s=new Set;return Object.entries(e).map(([u,m])=>{const d=y(m)??{},c=!i.has(u);return{name:ge(ln(u),s),nullable:!c&&fe(d)!==d,optional:c,type:j(d,`${r}${o(u)}`,t+1,a),wireKey:u}})},j=(e,n,r,t)=>{if(r>=en)return{kind:"unknown"};const a=on(e);if(a!==void 0){const d=new Set;return ee(t,{constants:a.map(c=>({name:ge(un(c),d),wireValue:c})),kind:"enum",name:n}),{kind:"enum",name:n}}const i=fe(e);if(i!==e)return j(i,n,r+1,t);const s=y(e.properties);if(s!==void 0)return ee(t,{fields:cn(s,e.required,n,r,t),kind:"class",name:n}),{kind:"class",name:n};const u=y(e.additionalProperties);if(u!==void 0)return{kind:"record",value:j(u,`${n}Value`,r+1,t)};const m=y(e.items);if(m!==void 0)return{item:j(m,`${n}Item`,r+1,t),kind:"list"};switch(e.type){case"boolean":return{kind:"boolean"};case"integer":case"number":return{kind:"number"};case"string":return{kind:"string"};default:return{kind:"unknown"}}},be=e=>{const n=new Map;for(const r of ce(e)){if(y(r.schema.properties)===void 0)continue;const t=new Map;try{j(r.schema,r.name,0,t)}catch(a){if(a instanceof ye)continue;throw a}if(![...t.keys()].some(a=>n.has(a)))for(const[a,i]of t)n.set(a,i)}return[...n.values()].toSorted((r,t)=>r.name.localeCompare(t.name))},C=e=>[`// GENERATED by \`lunora sdk generate --lang ${e}\` — do not edit.`,"// Run the command again to regenerate."],T=e=>{switch(e.kind){case"boolean":return"Boolean";case"class":case"enum":return e.name;case"list":return`java.util.List<${T(e.item)}>`;case"number":return"Double";case"record":return`java.util.Map<String, ${T(e.value)}>`;case"string":return"String";default:return"Object"}},I=e=>{switch(e.kind){case"class":case"enum":return!0;case"list":return I(e.item);case"record":return I(e.value);default:return!1}},F=(e,n,r)=>{if(!I(e))return n;const t=`item${String(r)}`;switch(e.kind){case"class":return`${n} == null ? null : ${n}.toWire()`;case"enum":return`${n} == null ? null : ${n}.toValue()`;case"list":return`ModelWire.writeList(${n}, ${t} -> ${F(e.item,t,r+1)})`;case"record":return`ModelWire.writeRecord(${n}, ${t} -> ${F(e.value,t,r+1)})`;default:return n}},x=(e,n,r)=>{const t=`item${String(r)}`;switch(e.kind){case"boolean":return`ModelWire.flag(${n})`;case"class":return`ModelWire.readObject(${n}, ${e.name}::fromWire)`;case"enum":return`ModelWire.readEnum(${n}, ${e.name}::forValue)`;case"list":return`ModelWire.readList(${n}, ${t} -> ${x(e.item,t,r+1)})`;case"number":return`ModelWire.number(${n})`;case"record":return`ModelWire.readRecord(${n}, ${t} -> ${x(e.value,t,r+1)})`;case"string":return`ModelWire.text(${n})`;default:return n}},pn=e=>{const n=l(e.wireKey);return e.optional?[" /**",` * Wire key {@code ${n}} — OPTIONAL: null omits the key entirely, because`," * `v.optional` accepts the value or `undefined` and rejects an explicit null."," */"]:[` /** Wire key {@code ${n}}.${e.nullable?" Nullable: null is sent as an explicit null.":""} */`]},dn=100,$n=e=>{const n=e.fields.map(t=>`${T(t.type)} ${t.name}`),r=` public ${e.name}(${n.join(", ")}) {`;return r.length<=dn?[r]:[` public ${e.name}(`,...n.map((t,a)=>` ${t}${a===n.length-1?") {":","}`)]},mn=e=>{const n=e.fields.flatMap(t=>{const a=`wire.put("${$(t.wireKey)}", ${F(t.type,`this.${t.name}`,0)});`;return t.optional?[` if (this.${t.name} != null) {`,` ${a}`," }"]:[` ${a}`]}),r=e.fields.map(t=>` ${x(t.type,`wire.get("${$(t.wireKey)}")`,0)}`);return[...C("java"),"",`package ${w};`,"","/**",` * The \`${e.name}\` model.`," *"," * <p>Field names are local; the keys {@link #toWire()} and {@link #fromWire(Object)} use are"," * the schema's own, emitted verbatim, so a renamed field cannot reach the wire."," */",`public final class ${e.name} {`,...e.fields.flatMap(t=>[...pn(t),` public final ${T(t.type)} ${t.name};`,""]),...$n(e),...e.fields.map(t=>` this.${t.name} = ${t.name};`)," }",""," /** This model as the wire-shaped map the transport encodes. */"," public java.util.Map<String, Object> toWire() {"," java.util.Map<String, Object> wire = new java.util.LinkedHashMap<>();",...n,""," return wire;"," }",""," /** Rebuild from a decoded wire value. */",` public static ${e.name} fromWire(Object value) {`," java.util.Map<String, Object> wire = ModelWire.object(value);","",...r.length===0?[` return new ${e.name}();`]:[` return new ${e.name}(`,`${r.join(`,
|
|
105
|
-
`)});`]," }","}",""].join(`
|
|
106
|
-
`)},yn=e=>[...C("java"),"",`package ${w};`,"",`/** The \`${e.name}\` union. Each constant keeps the wire string it encodes to. */`,`public enum ${e.name} {`,...e.constants.map((n,r)=>` ${n.name}("${$(n.wireValue)}")${r===e.constants.length-1?";":","}`),""," private final String value;","",` ${e.name}(String value) {`," this.value = value;"," }",""," /** The wire string this constant encodes to. */"," public String toValue() {"," return this.value;"," }",""," /** The constant a wire string decodes to. */",` public static ${e.name} forValue(String value) {`,` for (${e.name} candidate : values()) {`," if (candidate.value.equals(value)) {"," return candidate;"," }"," }","",` throw new IllegalArgumentException("${e.name}: unknown wire value " + value);`," }","}",""].join(`
|
|
107
|
-
`),fn=[{lines:[' @SuppressWarnings("unchecked")'," static java.util.Map<String, Object> object(Object value) {"," return value instanceof java.util.Map"," ? (java.util.Map<String, Object>) value"," : new java.util.LinkedHashMap<String, Object>();"," }"],name:"object"},{lines:[" static String text(Object value) {"," return value instanceof String ? (String) value : null;"," }"],name:"text"},{lines:[" static Double number(Object value) {"," return value instanceof Number ? ((Number) value).doubleValue() : null;"," }"],name:"number"},{lines:[" static Boolean flag(Object value) {"," return value instanceof Boolean ? (Boolean) value : null;"," }"],name:"flag"},{lines:[" /** A nested model, or null when the payload carried no object there. */"," static <T> T readObject(Object value, java.util.function.Function<Object, T> read) {"," return value instanceof java.util.Map ? read.apply(value) : null;"," }"],name:"readObject"},{lines:[" /** An enum constant, or null when the payload carried no string there. */"," static <T> T readEnum(Object value, java.util.function.Function<String, T> read) {"," return value instanceof String ? read.apply((String) value) : null;"," }"],name:"readEnum"},{lines:[" static <T> java.util.List<T> readList("," Object value, java.util.function.Function<Object, T> read) {"," if (!(value instanceof java.util.List)) {"," return null;"," }",""," java.util.List<T> items = new java.util.ArrayList<T>();",""," for (Object item : (java.util.List<?>) value) {"," items.add(read.apply(item));"," }",""," return items;"," }"],name:"readList"},{lines:[" static <T> java.util.Map<String, T> readRecord("," Object value, java.util.function.Function<Object, T> read) {"," if (!(value instanceof java.util.Map)) {"," return null;"," }",""," java.util.Map<String, T> entries = new java.util.LinkedHashMap<String, T>();",""," for (java.util.Map.Entry<?, ?> entry : ((java.util.Map<?, ?>) value).entrySet()) {"," entries.put(String.valueOf(entry.getKey()), read.apply(entry.getValue()));"," }",""," return entries;"," }"],name:"readRecord"},{lines:[" static <T> java.util.List<Object> writeList("," java.util.List<T> items, java.util.function.Function<T, Object> write) {"," if (items == null) {"," return null;"," }",""," java.util.List<Object> encoded = new java.util.ArrayList<Object>(items.size());",""," for (T item : items) {"," encoded.add(write.apply(item));"," }",""," return encoded;"," }"],name:"writeList"},{lines:[" static <T> java.util.Map<String, Object> writeRecord("," java.util.Map<String, T> entries, java.util.function.Function<T, Object> write) {"," if (entries == null) {"," return null;"," }",""," java.util.Map<String, Object> encoded = new java.util.LinkedHashMap<String, Object>();",""," for (java.util.Map.Entry<String, T> entry : entries.entrySet()) {"," encoded.put(entry.getKey(), write.apply(entry.getValue()));"," }",""," return encoded;"," }"],name:"writeRecord"}],gn=e=>{const n=fn.filter(r=>e.includes(`ModelWire.${r.name}(`));return[...C("java"),"",`package ${w};`,"","/** Wire readers and writers shared by the generated models. */","final class ModelWire {"," private ModelWire() {}",...n.flatMap(r=>["",...r.lines]),"}",""].join(`
|
|
108
|
-
`)},bn=e=>{const n=be(e);if(n.length===0)return{};const r={};for(const t of n)r[`${K}/${t.name}.java`]=t.kind==="enum"?yn(t):mn(t);return{[`${K}/ModelWire.java`]:gn(Object.values(r).join(`
|
|
109
|
-
`)),...r}},q=e=>{switch(e.kind){case"boolean":return"Boolean";case"class":case"enum":return e.name;case"list":return`List<${q(e.item)}>`;case"number":return"Double";case"record":return`Map<String, ${q(e.value)}>`;case"string":return"String";default:return"WireValue"}},h=(e,n,r)=>{const t=`item${String(r)}`,a=`entry${String(r)}`;switch(e.kind){case"boolean":return`WireValue.Bool(${n})`;case"class":return`${n}.toWire()`;case"enum":return`WireValue.Text(${n}.wireValue)`;case"list":return`WireValue.Arr(${n}.map { ${t} -> ${h(e.item,t,r+1)} })`;case"number":return`WireValue.Num(${n})`;case"record":return`WireValue.Obj(${n}.map { ${a} -> ${a}.key to ${h(e.value,`${a}.value`,r+1)} })`;case"string":return`WireValue.Text(${n})`;default:return n}},U=(e,n,r,t)=>`wireNeed(${ve(e,n,r,t)}, "${v(t)}")`,ve=(e,n,r,t)=>{const a=`item${String(r)}`,i=`entry${String(r)}`;switch(e.kind){case"boolean":return`wireBool(${n})`;case"class":return`wireObj(${n})?.let { ${a} -> ${e.name}.fromWire(${a}) }`;case"enum":return`wireText(${n})?.let { ${a} -> ${e.name}.forValue(${a}) }`;case"list":return`wireArr(${n})?.items?.map { ${a} -> ${U(e.item,a,r+1,`${t}[]`)} }`;case"number":return`wireNum(${n})`;case"record":return`wireObj(${n})?.fields?.associate { ${i} -> ${i}.first to ${U(e.value,`${i}.second`,r+1,`${t}{}`)} }`;case"string":return`wireText(${n})`;default:return n}},vn=e=>{const n=e.fields.map(a=>{const i=l(a.wireKey);return[...a.optional?[" /**",` * Wire key \`${i}\` — OPTIONAL: null omits the key entirely, because`," * `v.optional` accepts the value or `undefined` and rejects an explicit null."," */"]:[` /** Wire key \`${i}\`.${a.nullable?" Nullable: null is sent as an explicit null.":""} */`],` val ${a.name}: ${q(a.type)}${a.optional||a.nullable?"?":""}${a.optional?" = null":""},`]}),r=e.fields.map(a=>{const i=v(a.wireKey);return a.optional?` ${a.name}?.let { add("${i}" to ${h(a.type,"it",0)}) }`:a.nullable?` add("${i}" to (${a.name}?.let { ${h(a.type,"it",0)} } ?: WireValue.Null))`:` add("${i}" to ${h(a.type,a.name,0)})`}),t=e.fields.map(a=>{const i=`wireField(value, "${v(a.wireKey)}")`,s=a.optional||a.nullable?ve(a.type,i,0,a.wireKey):U(a.type,i,0,a.wireKey);return` ${a.name} = ${s},`});return["/**",` * The \`${e.name}\` model.`," *"," * Property names are local; the keys [toWire] and [fromWire] use are the schema's own,"," * emitted verbatim, so a renamed property cannot reach the wire."," */",`class ${e.name}(`,...n.flat(),") {"," /** This model as the wire-shaped object the transport encodes. */"," fun toWire(): WireValue ="," WireValue.Obj("," buildList {",...r," },"," )",""," companion object {"," /** Rebuild from a decoded wire value. */",` fun fromWire(value: WireValue): ${e.name} =`,` ${e.name}(`,...t," )"," }","}"]},wn=e=>[`/** The \`${e.name}\` union. Each entry keeps the wire string it encodes to. */`,`enum class ${e.name}(val wireValue: String) {`,...e.constants.map(n=>` ${n.name}("${v(n.wireValue)}"),`)," ;",""," companion object {"," /** The entry a wire string decodes to. */",` fun forValue(value: String): ${e.name} =`," entries.firstOrNull { it.wireValue == value }",` ?: throw IllegalArgumentException("${e.name}: unknown wire value " + value)`," }","}"],jn=[{lines:["private fun wireField(value: WireValue, key: String): WireValue? ="," (value as? WireValue.Obj)?.fields?.firstOrNull { it.first == key }?.second"],name:"wireField"},{lines:["private fun wireText(value: WireValue?): String? = (value as? WireValue.Text)?.value"],name:"wireText"},{lines:["private fun wireNum(value: WireValue?): Double? = (value as? WireValue.Num)?.value"],name:"wireNum"},{lines:["private fun wireBool(value: WireValue?): Boolean? = (value as? WireValue.Bool)?.value"],name:"wireBool"},{lines:["private fun wireArr(value: WireValue?): WireValue.Arr? = value as? WireValue.Arr"],name:"wireArr"},{lines:["private fun wireObj(value: WireValue?): WireValue.Obj? = value as? WireValue.Obj"],name:"wireObj"},{lines:["/** A required field the payload omitted or mistyped is a contract violation, not a null. */","private fun <T> wireNeed(read: T?, label: String): T =",' read ?: throw WireFormatException("lunora: the wire payload is missing or mistyped " + label)'],name:"wireNeed"}],hn=e=>{const n=be(e);if(n.length===0)return{};const r=n.flatMap(s=>[...s.kind==="enum"?wn(s):vn(s),""]),t=jn.filter(s=>r.some(u=>u.includes(`${s.name}(`))),a=t.flatMap((s,u)=>u===0?[...s.lines]:["",...s.lines]),i=[...C("kotlin"),"",`package ${w}`,"",...t.some(s=>s.name==="wireNeed")?["import dev.lunora.WireFormatException"]:[],"import dev.lunora.WireValue","",...r,...a,""].join(`
|
|
110
|
-
`);return{[`${K}/Models.kt`]:i}},An=`${f("java").map(e=>`// ${e}`).join(`
|
|
111
|
-
`)}
|
|
112
|
-
|
|
113
|
-
`,ne="lunoraapi",_n=new Set(["abstract","assert","boolean","break","byte","case","catch","char","class","const","continue","default","do","double","else","enum","extends","final","finally","float","for","goto","if","implements","import","instanceof","int","interface","long","native","new","package","private","protected","public","return","short","static","strictfp","super","switch","synchronized","this","throw","throws","transient","try","void","volatile","while"]),H=e=>{const n=o(e),r=n.charAt(0).toLowerCase()+n.slice(1);return _n.has(r)?`${r}_`:r},Sn=e=>`Client.Verb.${e.toUpperCase()}`,we=e=>e.argsType===void 0?{payload:"args",type:"java.util.Map<String, Object>"}:{payload:"args == null ? null : args.toWire()",type:e.argsType},re=e=>{const n=we(e),r=`client.call(
|
|
114
|
-
${Sn(e.verb)}, "${$(e.functionPath)}", ${n.payload}, shardKey)`;return[` /** ${l(e.summary)} */`,` public ${e.resultType??"Object"} ${H(e.functionName)}(${n.type} args, String shardKey) {`,` return ${e.resultType===void 0?r:`${e.resultType}.fromWire(${r})`};`," }"].join(`
|
|
115
|
-
`)},En=e=>{const n=we(e);return[` /** live ${l(e.summary)} — re-runs on every write to the tables it reads. */`,` public Runnable subscribe${o(e.functionName)}(`,` ${n.type} args,`," java.util.function.Consumer<Object> onData,"," java.util.function.Consumer<Client.SubscriptionError> onError,"," String shardKey) {"," return client.subscribe(",` "${$(e.functionPath)}", ${n.payload}, onData, onError, shardKey);`," }"].join(`
|
|
116
|
-
`)},Tn=e=>{const n=`${o(e.name)}Api`,r=e.methods.map(t=>t.verb==="query"?`${re(t)}
|
|
117
|
-
|
|
118
|
-
${En(t)}`:re(t)).join(`
|
|
119
|
-
|
|
120
|
-
`);return[` /** Functions declared in \`${l(e.name)}\`. */`,` public static final class ${n} {`," private final Client client;","",` ${n}(Client client) {`," this.client = client;"," }","",r.replaceAll(/^ {4}/gmu," ")," }"].join(`
|
|
121
|
-
`)},kn=({namespaces:e})=>{const n=e.map(i=>` public final ${o(i.name)}Api ${H(i.name)};`).join(`
|
|
122
|
-
`),r=e.map(i=>` this.${H(i.name)} = new ${o(i.name)}Api(client);`).join(`
|
|
123
|
-
`),t=N(e).map(i=>`import ${w}.${i};
|
|
124
|
-
`),a=[An,`package ${ne};
|
|
125
|
-
`,`
|
|
126
|
-
`,`import dev.lunora.Client;
|
|
127
|
-
`,...t,`
|
|
128
|
-
`,"/** Typed entry point: `new Api(client).<namespace>.<function>(args, shardKey)`. */\n",`public final class Api {
|
|
129
|
-
`,n.length>0?`${n}
|
|
130
|
-
|
|
131
|
-
`:"",` public Api(Client client) {
|
|
132
|
-
`,r.length>0?`${r}
|
|
133
|
-
`:` // No functions in this deployment.
|
|
134
|
-
`,` }
|
|
135
|
-
`,`
|
|
136
|
-
`,e.map(i=>Tn(i)).join(`
|
|
137
|
-
|
|
138
|
-
`),`
|
|
139
|
-
}
|
|
140
|
-
`].join("");return{[`${ne}/Api.java`]:a}},On={id:"java",render:kn,renderModels:bn,requires:[],vendor:[{from:"src/dev/lunora",to:"dev/lunora"}]},Nn=`${f("kotlin").map(e=>`// ${e}`).join(`
|
|
141
|
-
`)}
|
|
142
|
-
|
|
143
|
-
`,te="lunoraapi",Cn=new Set(["as","break","class","continue","do","else","false","for","fun","if","in","interface","is","null","object","package","return","super","this","throw","true","try","typealias","typeof","val","var","when","while"]),je=e=>{const n=o(e),r=n.charAt(0).toLowerCase()+n.slice(1);return Cn.has(r)?`\`${r}\``:r},Ln=e=>`Verb.${e.toUpperCase()}`,he=e=>e.argsType===void 0?{declaration:"args: WireValue? = null",payload:"args"}:{declaration:`args: ${e.argsType}`,payload:"args.toWire()"},ae=e=>{const n=he(e),r=`client.call(${Ln(e.verb)}, "${v(e.functionPath)}", ${n.payload}, shardKey)`;return[` /** ${l(e.summary)} */`,` fun ${je(e.functionName)}(${n.declaration}, shardKey: String? = null): ${e.resultType??"WireValue"} =`,` ${e.resultType===void 0?r:`${e.resultType}.fromWire(${r})`}`].join(`
|
|
144
|
-
`)},Wn=e=>{const n=he(e);return[` /** live ${l(e.summary)} — re-runs on every write to the tables it reads. */`,` fun subscribe${o(e.functionName)}(`,` ${n.declaration},`," onData: ((WireValue) -> Unit)?,"," onError: ((SubscriptionError) -> Unit)? = null,"," shardKey: String? = null,"," ): () -> Unit =",` client.subscribe("${v(e.functionPath)}", ${n.payload}, onData, onError, shardKey)`].join(`
|
|
145
|
-
`)},Mn=e=>{const n=`${o(e.name)}Api`,r=e.methods.map(t=>t.verb==="query"?`${ae(t)}
|
|
146
|
-
|
|
147
|
-
${Wn(t)}`:ae(t)).join(`
|
|
148
|
-
|
|
149
|
-
`);return[`/** Functions declared in \`${l(e.name)}\`. */`,`class ${n}(private val client: Client) {`,r,"}"].join(`
|
|
150
|
-
`)},Rn=({namespaces:e})=>{const n=e.map(i=>` val ${je(i.name)}: ${o(i.name)}Api = ${o(i.name)}Api(client)`).join(`
|
|
151
|
-
`),r=e.flatMap(i=>i.methods),t=[`import dev.lunora.Client
|
|
152
|
-
`,...r.some(i=>i.verb==="query")?[`import dev.lunora.SubscriptionError
|
|
153
|
-
`]:[],`import dev.lunora.Verb
|
|
154
|
-
`,...r.some(i=>i.argsType===void 0||i.resultType===void 0)?[`import dev.lunora.WireValue
|
|
155
|
-
`]:[],...N(e).map(i=>`import ${w}.${i}
|
|
156
|
-
`)],a=[Nn,`package ${te}
|
|
157
|
-
`,`
|
|
158
|
-
`,...t,`
|
|
159
|
-
`,e.map(i=>Mn(i)).join(`
|
|
160
|
-
|
|
161
|
-
`),`
|
|
162
|
-
|
|
163
|
-
`,"/** Typed entry point: `Api(client).<namespace>.<function>(args)`. */\n",`class Api(client: Client) {
|
|
164
|
-
`,n.length>0?`${n}
|
|
165
|
-
`:` init { require(true) { client } }
|
|
166
|
-
`,`}
|
|
167
|
-
`].join("");return{[`${te}/Api.kt`]:a}},Dn={id:"kotlin",render:Rn,renderModels:hn,requires:[],vendor:[{from:"src",to:"dev/lunora"}]},Pn=new Set(["and","as","assert","async","await","break","class","continue","def","del","elif","else","except","False","finally","for","from","global","if","import","in","is","lambda","None","nonlocal","not","or","pass","raise","return","True","try","while","with","yield"]),A=`"""${f("python").join(`
|
|
168
|
-
|
|
169
|
-
`)}
|
|
170
|
-
"""
|
|
171
|
-
|
|
172
|
-
`,M="lunora_api",J=e=>{const n=B(e);return Pn.has(n)?`${n}_`:n},Ae=e=>p(e,{none:"{}",typed:()=>"args.to_dict()",untyped:"args"}),Vn=(e,n,r,t)=>p(e,{none:n,typed:r,untyped:t}),ie=e=>{const n=e.resultType??"Any",r=Vn(e,"self",i=>`self, args: ${i}`,"self, args: Any"),t=Ae(e),a=`await self._client.${e.verb}("${$(e.functionPath)}", ${t}, shard_key)`;return[` async def ${J(e.functionName)}(${r}, *, shard_key: Optional[str] = None) -> ${n}:`,` """${l(e.summary)}"""`,` ${e.resultType===void 0?`return ${a}`:`return ${e.resultType}.from_dict(${a})`}`].join(`
|
|
173
|
-
`)},Kn=e=>{const n=Ae(e),r=["self",...p(e,{none:[],typed:t=>[`args: ${t}`],untyped:["args: Any"]}),"on_data: Callback","on_error: Optional[ErrorCallback] = None","*","shard_key: Optional[str] = None"];return[` def subscribe_${J(e.functionName)}(`,...r.map(t=>` ${t},`)," ) -> Unsubscribe:",` """live ${l(e.summary)} — re-runs on every write to the tables it reads."""`,` return self._client.subscribe("${$(e.functionPath)}", ${n}, on_data, on_error, shard_key)`].join(`
|
|
174
|
-
`)},In=e=>{const n=e.methods.map(r=>r.verb==="query"?`${ie(r)}
|
|
175
|
-
|
|
176
|
-
${Kn(r)}`:ie(r)).join(`
|
|
177
|
-
|
|
178
|
-
`);return[`class ${o(e.name)}Api:`,` """Functions declared in \`${l(e.name)}\`."""`,""," def __init__(self, client: LunoraClient) -> None:"," self._client = client","",n].join(`
|
|
179
|
-
`)},Fn=e=>e.replaceAll(/^([ \t]*)except:$/gmu,"$1except Exception:"),xn=({models:e,namespaces:n})=>{const r=N(n),t=r.length>0?`from .models import ${r.join(", ")}
|
|
180
|
-
`:"",i=P(n).some(c=>c.verb==="query")?"Callback, ErrorCallback, LunoraClient, Unsubscribe":"LunoraClient",s=P(n).some(c=>c.resultType===void 0),u=n.map(c=>` self.${J(c.name)} = ${o(c.name)}Api(client)`).join(`
|
|
181
|
-
`),m=[A,`from typing import ${s?"Any, Optional":"Optional"}
|
|
182
|
-
`,`
|
|
183
|
-
`,`from lunora.client import ${i}
|
|
184
|
-
`,t,`
|
|
185
|
-
|
|
186
|
-
`,n.map(c=>In(c)).join(`
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
`),`
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
`,`class Api:
|
|
193
|
-
`,' """Typed entry point: `Api(client).<namespace>.<function>(args)`."""\n',`
|
|
194
|
-
`,` def __init__(self, client: LunoraClient) -> None:
|
|
195
|
-
`,u.length>0?`${u}
|
|
196
|
-
`:` pass
|
|
197
|
-
`].join(""),d=["Api",...n.map(c=>`${o(c.name)}Api`)];return{[`${M}/__init__.py`]:[A,`from .api import ${d.join(", ")}
|
|
198
|
-
`,`
|
|
199
|
-
`,`__all__ = [${d.map(c=>`"${c}"`).join(", ")}]
|
|
200
|
-
`].join(""),[`${M}/api.py`]:m,[`${M}/models.py`]:e.length>0?`${A}${Fn(e)}
|
|
201
|
-
`:`${A}# No typed argument or result schemas in this deployment.
|
|
202
|
-
`}},qn={id:"python",quicktype:{lang:"python",rendererOptions:{"python-version":"3.7"}},render:xn,requires:[],vendor:[{from:"lunora",to:"lunora"}]},R=`${f("ruby").map(e=>`# ${e}`).join(`
|
|
203
|
-
`)}
|
|
204
|
-
|
|
205
|
-
`,Un=new Set(["alias","and","begin","break","case","class","def","defined?","do","else","elsif","end","ensure","false","for","if","in","module","next","nil","not","or","redo","rescue","retry","return","self","super","then","true","undef","unless","until","when","while","yield"]),Y=e=>$(e).replaceAll("#","\\#"),k=e=>{const n=B(e);return Un.has(n)?`${n}_`:n},Hn=` # Delegates to the transport, which owns the projection and its tests — see
|
|
206
|
-
# \`Lunora.wire_args\`. The path list is generated per model because only the
|
|
207
|
-
# schema knows which nils may be dropped.
|
|
208
|
-
def self.wire_args(model, optional_paths = [])
|
|
209
|
-
Lunora.wire_args(model, optional_paths)
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
`,Gn=e=>`[${e.map(n=>`[${n.map(r=>`"${Y(r)}"`).join(", ")}]`).join(", ")}]`,_e=e=>p(e,{none:"{}",typed:()=>`LunoraApi.wire_args(args, ${Gn(e.argsNullPaths.optional)})`,untyped:"args"}),se=e=>{const n=e.argsType===void 0&&!e.takesArgs?"shard_key: nil":"args, shard_key: nil",r=_e(e),t=`@client.${e.verb}("${Y(e.functionPath)}", ${r}, shard_key)`,a=e.resultType===void 0?t:`${e.resultType}.from_dynamic!(${t})`;return[` # ${l(e.summary)}`,` def ${k(e.functionName)}(${n})`,` ${a}`," end"].join(`
|
|
213
|
-
`)},Bn=e=>{const n=e.argsType===void 0&&!e.takesArgs?"on_data, on_error = nil, shard_key: nil":"args, on_data, on_error = nil, shard_key: nil",r=_e(e);return[` # live ${l(e.summary)} — re-runs on every write to the tables it reads.`,` def subscribe_${k(e.functionName)}(${n})`,` @client.subscribe("${Y(e.functionPath)}", ${r}, on_data, on_error, shard_key)`," end"].join(`
|
|
214
|
-
`)},Jn=e=>{const n=e.methods.map(r=>r.verb==="query"?`${se(r)}
|
|
215
|
-
|
|
216
|
-
${Bn(r)}`:se(r)).join(`
|
|
217
|
-
|
|
218
|
-
`);return[` # Functions declared in \`${l(e.name)}\`.`,` class ${o(e.name)}Api`," def initialize(client)"," @client = client"," end","",n," end"].join(`
|
|
219
|
-
`)},Yn=({models:e,namespaces:n})=>{const r=n.map(i=>`:${k(i.name)}`).join(", "),t=n.map(i=>` @${k(i.name)} = ${o(i.name)}Api.new(client)`).join(`
|
|
220
|
-
`);return{"api.rb":[`# frozen_string_literal: true
|
|
221
|
-
|
|
222
|
-
`,R,`require_relative "models"
|
|
223
|
-
`,`
|
|
224
|
-
`,`module LunoraApi
|
|
225
|
-
`,P(n).some(i=>i.argsType!==void 0)?Hn:"",n.map(i=>Jn(i)).join(`
|
|
226
|
-
|
|
227
|
-
`),`
|
|
228
|
-
|
|
229
|
-
`," # Typed entry point: `Api.new(client).<namespace>.<function>(args)`.\n",` class Api
|
|
230
|
-
`,r.length>0?` attr_reader ${r}
|
|
231
|
-
|
|
232
|
-
`:"",` def initialize(client)
|
|
233
|
-
`,t.length>0?`${t}
|
|
234
|
-
`:` @client = client
|
|
235
|
-
`,` end
|
|
236
|
-
`,` end
|
|
237
|
-
`,`end
|
|
238
|
-
`].join(""),"models.rb":e.length>0?`# frozen_string_literal: true
|
|
239
|
-
|
|
240
|
-
${R}${e}
|
|
241
|
-
`:`# frozen_string_literal: true
|
|
242
|
-
|
|
243
|
-
${R}# No typed argument or result schemas in this deployment.
|
|
244
|
-
`}},zn={id:"ruby",quicktype:{lang:"ruby",rendererOptions:{}},render:Yn,requires:["dry-struct + dry-types (gems, required by the generated models)"],vendor:[{from:"lib/lunora.rb",to:"lunora.rb"},{from:"lib/lunora",to:"lunora"}]},S=`${f("rust").map(e=>`// ${e}`).join(`
|
|
245
|
-
`)}
|
|
246
|
-
|
|
247
|
-
`,Zn=`${S}pub mod api;
|
|
248
|
-
pub mod models;
|
|
249
|
-
`,Xn=`# The generated Lunora Rust SDK, with the transport vendored under ./lunora.
|
|
250
|
-
#
|
|
251
|
-
# Add to a consuming crate:
|
|
252
|
-
#
|
|
253
|
-
# lunora-api = { path = "sdk/rust" }
|
|
254
|
-
|
|
255
|
-
[package]
|
|
256
|
-
name = "lunora-api"
|
|
257
|
-
version = "0.1.0"
|
|
258
|
-
edition = "2021"
|
|
259
|
-
publish = false
|
|
260
|
-
|
|
261
|
-
# Its own workspace root, so a consumer whose project IS a workspace does not
|
|
262
|
-
# adopt this directory as a member (which then fails to build on its own).
|
|
263
|
-
[workspace]
|
|
264
|
-
|
|
265
|
-
[dependencies]
|
|
266
|
-
lunora = { path = "lunora" }
|
|
267
|
-
serde = { version = "1", features = ["derive"] }
|
|
268
|
-
serde_json = "1"
|
|
269
|
-
`,Qn=new Set(["abstract","as","async","await","become","box","break","const","continue","crate","do","dyn","else","enum","extern","false","final","fn","for","if","impl","in","let","loop","macro","match","mod","move","mut","override","priv","pub","ref","return","self","static","struct","super","trait","true","try","type","typeof","unsafe","unsized","use","virtual","where","while","yield"]),O=e=>{const n=B(e);return Qn.has(n)?`r#${n}`:n},er=e=>`Verb::${o(e)}`,Se=e=>e.length===0?"&[]":`&[${e.map(n=>`&["${n.map(r=>$(r)).join('", "')}"][..]`).join(", ")}]`,oe=e=>{const n=p(e,{none:"&self, shard_key: Option<&str>",typed:a=>`&self, args: &${a}, shard_key: Option<&str>`,untyped:"&self, args: &WireValue, shard_key: Option<&str>"}),r=p(e,{none:"&WireValue::Object(Vec::new())",typed:()=>`&from_model_json(&serde_json::to_value(args).map_err(|error| ClientError::Transport(error.to_string()))?, ${Se(e.argsNullPaths.optional)})`,untyped:"args"}),t=`self.client.call(${er(e.verb)}, "${$(e.functionPath)}", ${r}, shard_key)`;return e.resultType===void 0?[` /// ${l(e.summary)}`,` pub fn ${O(e.functionName)}(${n}) -> Result<WireValue, ClientError> {`,` ${t}`," }"].join(`
|
|
270
|
-
`):[` /// ${l(e.summary)}`,` pub fn ${O(e.functionName)}(${n}) -> Result<${e.resultType}, ClientError> {`,` let raw = ${t}?;`," let json = encode_wire(&raw).map_err(ClientError::Wire)?;"," serde_json::from_value(json).map_err(|error| ClientError::Transport(error.to_string()))"," }"].join(`
|
|
271
|
-
`)},nr=e=>{const n=p(e,{none:"",typed:t=>`args: &${t}, `,untyped:"args: &WireValue, "}),r=p(e,{none:"WireValue::Object(Vec::new())",typed:()=>`from_model_json(&serde_json::to_value(args).map_err(|error| ClientError::Transport(error.to_string()))?, ${Se(e.argsNullPaths.optional)})`,untyped:"args.clone()"});return[` /// live ${l(e.summary)} — re-runs on every write to the tables it reads.`,` pub fn subscribe_${O(e.functionName)}(`," &mut self,",` ${n}on_data: DataHandler,`," on_error: ErrorHandler,"," shard_key: Option<&str>,"," ) -> Result<String, ClientError> {",` Ok(self.client.subscribe_on_shard("${$(e.functionPath)}", ${r}, on_data, on_error, shard_key))`," }"].join(`
|
|
272
|
-
`)},rr=e=>{const n=`${o(e.name)}Api`,r=e.methods.map(t=>t.verb==="query"?`${oe(t)}
|
|
273
|
-
|
|
274
|
-
${nr(t)}`:oe(t)).join(`
|
|
275
|
-
|
|
276
|
-
`);return[`/// Functions declared in \`${l(e.name)}\`.`,`pub struct ${n}<'client> {`," client: &'client mut Client,","}","",`impl<'client> ${n}<'client> {`,r,"}"].join(`
|
|
277
|
-
`)},tr=({models:e,namespaces:n})=>{const r=n.map(a=>[` /// Functions declared in \`${l(a.name)}\`.`,` pub fn ${O(a.name)}(&mut self) -> ${o(a.name)}Api<'_> {`,` ${o(a.name)}Api { client: self.client }`," }"].join(`
|
|
278
|
-
`)).join(`
|
|
279
|
-
|
|
280
|
-
`),t=[S,`#![allow(dead_code, unused_imports)]
|
|
281
|
-
`,`
|
|
282
|
-
`,`use lunora::client::{Client, ClientError, DataHandler, ErrorHandler, Verb};
|
|
283
|
-
`,`use lunora::wire::{encode_wire, from_model_json, WireValue};
|
|
284
|
-
`,`
|
|
285
|
-
`,`use crate::models::*;
|
|
286
|
-
`,`
|
|
287
|
-
`,n.map(a=>rr(a)).join(`
|
|
288
|
-
|
|
289
|
-
`),`
|
|
290
|
-
|
|
291
|
-
`,"/// Typed entry point: `Api::new(&client).<namespace>().<function>(args)`.\n",`pub struct Api<'client> {
|
|
292
|
-
`,` client: &'client mut Client,
|
|
293
|
-
`,`}
|
|
294
|
-
`,`
|
|
295
|
-
`,`impl<'client> Api<'client> {
|
|
296
|
-
`,` pub fn new(client: &'client mut Client) -> Self {
|
|
297
|
-
`,` Self { client }
|
|
298
|
-
`,` }
|
|
299
|
-
`,r.length>0?`
|
|
300
|
-
${r}
|
|
301
|
-
`:"",`}
|
|
302
|
-
`].join("");return{"Cargo.toml":Xn,"src/api.rs":t,"src/lib.rs":Zn,"src/models.rs":e.length>0?`${S}#![allow(dead_code)]
|
|
303
|
-
|
|
304
|
-
${e}
|
|
305
|
-
`:`${S}#![allow(dead_code)]
|
|
306
|
-
|
|
307
|
-
// No typed argument or result schemas in this deployment.
|
|
308
|
-
`}},ar={id:"rust",quicktype:{lang:"rust",rendererOptions:{"just-types":"true"}},render:tr,requires:["serde (derive) + serde_json — declared in the emitted Cargo.toml, fetched by cargo"],vendor:[{from:"Cargo.toml",to:"lunora/Cargo.toml"},{from:"src",to:"lunora/src"}]},D=`${f("swift").map(e=>`// ${e}`).join(`
|
|
309
|
-
`)}
|
|
310
|
-
|
|
311
|
-
`,le="Sources/LunoraApi",ir=`// swift-tools-version:5.9
|
|
312
|
-
|
|
313
|
-
import PackageDescription
|
|
314
|
-
|
|
315
|
-
// The generated Lunora Swift SDK, with the transport vendored under
|
|
316
|
-
// Sources/Lunora. Add to a consuming package — where "swift" below is the NAME OF
|
|
317
|
-
// THE DIRECTORY THIS FILE IS IN, which is how SwiftPM identifies a local path
|
|
318
|
-
// dependency. It ignores the "name:" field for that, and a bare product name in a
|
|
319
|
-
// target's dependencies does not resolve at all, so the directory name is the one
|
|
320
|
-
// spelling that works:
|
|
321
|
-
//
|
|
322
|
-
// dependencies: [.package(path: "sdk/swift")],
|
|
323
|
-
// targets: [
|
|
324
|
-
// .target(
|
|
325
|
-
// name: "YourTarget",
|
|
326
|
-
// dependencies: [.product(name: "LunoraApi", package: "swift")]
|
|
327
|
-
// )
|
|
328
|
-
// ]
|
|
329
|
-
let package = Package(
|
|
330
|
-
name: "LunoraSdk",
|
|
331
|
-
platforms: [.macOS(.v12), .iOS(.v15)],
|
|
332
|
-
products: [
|
|
333
|
-
.library(name: "LunoraApi", targets: ["LunoraApi"]),
|
|
334
|
-
.library(name: "Lunora", targets: ["Lunora"]),
|
|
335
|
-
],
|
|
336
|
-
targets: [
|
|
337
|
-
.target(name: "Lunora"),
|
|
338
|
-
.target(name: "LunoraApi", dependencies: ["Lunora"]),
|
|
339
|
-
]
|
|
340
|
-
)
|
|
341
|
-
`,sr=new Set(["as","associatedtype","borrowing","break","case","catch","class","consuming","continue","default","defer","deinit","do","else","enum","extension","fallthrough","false","fileprivate","for","func","guard","if","import","in","init","inout","internal","is","let","nil","nonisolated","open","operator","precedencegroup","private","protocol","public","repeat","rethrows","return","self","static","struct","subscript","super","switch","throw","throws","true","try","typealias","var","where","while"]),G=e=>{const n=o(e),r=n.charAt(0).toLowerCase()+n.slice(1);return sr.has(r)?`\`${r}\``:r},or=e=>`[${e.map(n=>`["${n.map(r=>$(r)).join('", "')}"]`).join(", ")}]`,Ee=e=>p(e,{none:"nil",typed:()=>{const{nullable:n}=e.argsNullPaths;return n.length===0?"try LunoraClient.wireValue(args)":`try LunoraClient.wireValue(args, nullablePaths: ${or(n)})`},untyped:"args"}),ue=e=>{const n=p(e,{none:"shardKey: String? = nil",typed:s=>`_ args: ${s}, shardKey: String? = nil`,untyped:"_ args: Any, shardKey: String? = nil"}),r=Ee(e),t=e.resultType??"Any",a=`try client.${e.verb}("${$(e.functionPath)}", args: ${r}, shardKey: shardKey)`,i=e.resultType===void 0?`return ${a}`:[`let raw = ${a}`," let data = Data(Wire.stableStringify(raw).utf8)",` return try JSONDecoder().decode(${e.resultType}.self, from: data)`].join(`
|
|
342
|
-
`);return[` /// ${l(e.summary)}`,` public func ${G(e.functionName)}(${n}) throws -> ${t} {`,` ${i}`," }"].join(`
|
|
343
|
-
`)},lr=e=>{const n=p(e,{none:"",typed:t=>`_ args: ${t}, `,untyped:"_ args: Any, "}),r=Ee(e);return[` /// live ${l(e.summary)} — re-runs on every write to the tables it reads.`," @discardableResult",` public func subscribe${o(e.functionName)}(`,` ${n}onData: ((Any) -> Void)?,`," onError: ((LunoraSubscriptionError) -> Void)? = nil,"," shardKey: String? = nil"," ) throws -> LunoraUnsubscribe {",` client.subscribe("${$(e.functionPath)}", args: ${r}, onData: onData, onError: onError, shardKey: shardKey)`," }"].join(`
|
|
344
|
-
`)},ur=e=>{const n=`${o(e.name)}API`,r=e.methods.map(t=>t.verb==="query"?`${ue(t)}
|
|
345
|
-
|
|
346
|
-
${lr(t)}`:ue(t)).join(`
|
|
347
|
-
|
|
348
|
-
`);return[`/// Functions declared in \`${l(e.name)}\`.`,`public struct ${n} {`," let client: LunoraClient","",r,"}"].join(`
|
|
349
|
-
`)},cr=({models:e,namespaces:n})=>{const r=n.map(i=>` public let ${G(i.name)}: ${o(i.name)}API`).join(`
|
|
350
|
-
`),t=n.map(i=>` ${G(i.name)} = ${o(i.name)}API(client: client)`).join(`
|
|
351
|
-
`),a=[D,`import Foundation
|
|
352
|
-
`,`import Lunora
|
|
353
|
-
`,`
|
|
354
|
-
`,n.map(i=>ur(i)).join(`
|
|
355
|
-
|
|
356
|
-
`),`
|
|
357
|
-
|
|
358
|
-
`,"/// Typed entry point: `API(client:).<namespace>.<function>(args)`.\n",`public struct API {
|
|
359
|
-
`,r.length>0?`${r}
|
|
360
|
-
|
|
361
|
-
`:"",` public init(client: LunoraClient) {
|
|
362
|
-
`,t.length>0?`${t}
|
|
363
|
-
`:` _ = client
|
|
364
|
-
`,` }
|
|
365
|
-
`,`}
|
|
366
|
-
`].join("");return{"Package.swift":ir,[`${le}/Api.swift`]:a,[`${le}/Models.swift`]:e.length>0?`${D}${e}
|
|
367
|
-
`:`${D}import Foundation
|
|
368
|
-
|
|
369
|
-
// No typed argument or result schemas in this deployment.
|
|
370
|
-
`}},pr={id:"swift",quicktype:{lang:"swift",rendererOptions:{"access-level":"public"}},render:cr,requires:[],vendor:[{from:"Sources/Lunora",to:"Sources/Lunora"}]},dr={dart:Be,go:Qe,java:On,kotlin:Dn,python:qn,ruby:zn,rust:ar,swift:pr},mr=Object.keys(dr).toSorted((e,n)=>e.localeCompare(n)),yr=async(e,n)=>{const r=ke(e);Oe(r);const t=n.renderModels?.(e),a=t===void 0?await We(e,n):Object.values(t).join(`
|
|
371
|
-
`),i=Ne(r,a);return{files:{...t,...n.render({models:a,namespaces:i})},undeclared:Le(r,a),unrepresentable:Ce(e)}};export{mr as SDK_LANGUAGES,dr as SDK_TARGETS,yr as generateSdk,br as isTypedSchema};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const b=/[^a-zA-Z0-9]+/gu,M=/([a-z0-9])([A-Z])/gu,p=t=>t.split(b).filter(e=>e.length>0).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(""),L=t=>t.replaceAll(M,"$1_$2").replaceAll(b,"_").toLowerCase(),d=t=>t===void 0?!1:["$ref","allOf","anyOf","enum","items","oneOf","properties","type"].some(e=>e in t),O=t=>t==="query"?"query":t==="action"?"action":"mutation",i=(t,e=0)=>{if(e>32||t===null||typeof t!="object")return!1;if(Array.isArray(t))return t.some(o=>i(o,e+1));const r=t;if(r.type==="integer"&&r.format==="int64"||r.type==="string"&&r.contentEncoding==="base64")return!0;const{properties:n}=r;return n!==null&&typeof n=="object"&&Object.values(n).some(o=>i(o,e+1))?!0:["additionalProperties","allOf","anyOf","items","oneOf"].some(o=>i(r[o],e+1))},R=t=>t.replaceAll(/[\n\r\u2028\u2029]+/gu," ").replaceAll("*/","* /").replaceAll('"""','" ""'),T=t=>t.replaceAll("\\","\\\\").replaceAll('"','\\"').replaceAll(`
|
|
2
|
-
`,"\\n").replaceAll("\r","\\r"),j=["$","{","'","$","'","}"].join(""),D=t=>T(t).split("$").join(j),_=(t,e)=>t.argsType!==void 0?e.typed(t.argsType):t.takesArgs?e.untyped:e.none,f=32,h=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return!1;const r=t;return r.type==="null"||Array.isArray(r.type)&&r.type.includes("null")?!0:["anyOf","oneOf"].some(n=>{const o=r[n];return Array.isArray(o)&&o.some(s=>h(s,e+1))})},E=(t,e,r)=>e.length===0?r===0?[]:[t]:e.map(n=>({properties:{...t.properties,...n.properties},required:new Set([...t.required,...n.required])})),C=t=>{const{properties:e}=t;if(e===null||typeof e!="object")return[];const r=t.required;return[{properties:e,required:new Set(Array.isArray(r)?r.filter(n=>typeof n=="string"):[])}]},m=(t,e,r)=>{const n=t[e];return Array.isArray(n)?n.flatMap(o=>A(o,r+1)):[]},A=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return[];const r=t,n=[...C(r),...m(r,"allOf",e)],o={properties:Object.assign({},...n.map(a=>a.properties)),required:new Set(n.flatMap(a=>[...a.required]))},s=[...m(r,"anyOf",e),...m(r,"oneOf",e)];return E(o,s,n.length)},S=(t,e=0)=>{if(e>f||t===null||typeof t!="object")return[];const r=t,n=[r];for(const o of["anyOf","oneOf","allOf"]){const s=r[o];if(Array.isArray(s))for(const a of s)n.push(...S(a,e+1))}return n},y=(t,e,r,n=0)=>{if(n>f||t===null||typeof t!="object")return;const o=A(t),s=[...new Set(o.flatMap(a=>Object.keys(a.properties)))].toSorted((a,l)=>a.localeCompare(l));for(const a of s){const l=[...e,a],u=o.every(c=>c.required.has(a)),g=o.map(c=>c.properties[a]).filter(c=>c!==void 0);u?g.some(c=>h(c))&&r.nullable.push(l):r.optional.push(l);for(const c of g)y(c,l,r,n+1)}for(const a of S(t))for(const l of["additionalProperties","items"]){const u=a[l];u!==null&&typeof u=="object"&&y(u,[...e,"*"],r,n+1)}},N=(t,e)=>t.join("\0").localeCompare(e.join("\0")),k=t=>{const e={nullable:[],optional:[]};y(t,[],e);const r=n=>[...new Map(n.map(o=>[o.join("\0"),o])).values()].toSorted(N);return{nullable:r(e.nullable),optional:r(e.optional)}},w=t=>{const[e="",r=""]=t.name.split(":"),n=`${p(e)}${p(r)}`,o=t.params?.[0]?.schema,s=t.result?.schema;return{argsNullPaths:k(o),argsType:d(o)&&!i(o)?`${n}Args`:void 0,takesArgs:d(o),functionName:r,functionPath:t.name,namespace:e,resultType:d(s)&&!i(s)?`${n}Result`:void 0,summary:t.summary??t.name,verb:O(t["x-lunora-function-kind"])}},x=t=>{const e=new Map;for(const r of t.methods){const n=w(r),o=e.get(n.namespace);o===void 0?e.set(n.namespace,[n]):o.push(n)}return[...e.entries()].toSorted(([r],[n])=>r.localeCompare(n)).map(([r,n])=>({methods:n.toSorted((o,s)=>o.functionName.localeCompare(s.functionName)),name:r}))},I=t=>t.methods.flatMap(e=>{const r=w(e);return[{name:r.argsType,schema:e.params?.[0]?.schema},{name:r.resultType,schema:e.result?.schema}]}).filter(e=>e.name!==void 0&&e.schema!==void 0).toSorted((e,r)=>e.name.localeCompare(r.name)),P=/^[A-Za-z][A-Za-z0-9]*$/u,$=t=>P.test(t),q=t=>{const e=new Map;for(const r of t.methods){const n=p(r.functionName);if(!$(n))throw new Error(`sdk: function "${r.functionPath}" produces the invalid identifier "${n}" — rename the export so it starts with a letter.`);const o=r.verb==="query"?[n,`Subscribe${n}`,`Watch${n}`]:[n];for(const s of o){const a=e.get(s);if(a!==void 0){const l=s.startsWith("Watch")?' (the Dart target emits a "watch" Stream member for every query)':"";throw new Error(`sdk: functions "${a}" and "${r.functionPath}" both generate "${s}"${l} — rename one so the generated methods stay distinct.`)}e.set(s,r.functionPath)}}},z=t=>{const e=new Map;for(const r of t){const n=p(r.name);if(!$(n))throw new Error(`sdk: namespace "${r.name}" produces the invalid identifier "${n}" — rename the file so it starts with a letter.`);const o=e.get(n);if(o!==void 0)throw new Error(`sdk: namespaces "${o}" and "${r.name}" both generate "${n}" — rename one so the generated types stay distinct.`);e.set(n,r.name),q(r)}},v=t=>t.flatMap(e=>e.methods),H=t=>[`GENERATED by \`lunora sdk generate --lang ${t}\` — do not edit.`,"Run the command again to regenerate."],U=(t,e)=>{const r=n=>n!==void 0&&new RegExp(String.raw`\b${n}\b`,"u").test(e)?n:void 0;return t.map(n=>({methods:n.methods.map(o=>({...o,argsType:r(o.argsType),resultType:r(o.resultType)})),name:n.name}))},W=t=>t.methods.filter(e=>i(e.params?.[0]?.schema)||i(e.result?.schema)).map(e=>e.name).toSorted((e,r)=>e.localeCompare(r)),Z=(t,e)=>[...new Set(v(t).flatMap(r=>[r.argsType,r.resultType]).filter(r=>r!==void 0&&!new RegExp(String.raw`\b${r}\b`,"u").test(e)))].toSorted((r,n)=>r.localeCompare(n)),F=t=>[...new Set(v(t).flatMap(e=>[e.argsType,e.resultType]).filter(e=>e!==void 0))].toSorted((e,r)=>e.localeCompare(r));export{v as allMethods,_ as argsChoice,z as assertGeneratable,R as commentText,H as generatedHeaderLines,i as hasUnrepresentableWireType,d as isTypedSchema,D as kotlinLiteral,I as modelSources,k as nullPathsOf,w as parseMethod,x as parseSpec,F as referencedModels,T as stringLiteral,p as toPascalCase,L as toSnakeCase,Z as undeclaredModels,W as unrepresentableFunctions,O as verbForKind,U as withDeclaredModels};
|