Code generator: a folder of .xsql → committed Clojure source.
Connects to a running Synthigy backend ONCE (op:describe = the XSQL compiler) and emits one namespace per XSQL @namespace, with a named, documented function per operation. The generated code carries NO parser and needs NO backend at runtime — it embeds each op's compiled XSQL source string and sends it via synthigy.client. Connection is a BUILD-time dependency, like Prisma/sqlc/genqlient; commit the output and it runs offline forever after.
clj -X:gen :dir '"synthigy"' :out '"src"'
:ns-prefix myapp.ops :endpoint '"http://localhost:7887"'
Auth for the pull: THE APP'S OWN client credentials (:client-id/:client-secret
or SYNTHIGY_CLIENT_ID/SYNTHIGY_CLIENT_SECRET) — /schema + describe are
IAM-filtered per principal, so generating as the app makes the generated
contract exactly what the app can do at runtime (a personal/dev identity
would generate a surface the app can't honor). Grant the client schema:read
(or the broader dataset:load). :token / SYNTHIGY_TOKEN and authless remain
for bare dev servers. Regenerate any time you edit an .xsql — the diff shows
exactly what changed.
Code generator: a folder of .xsql → committed Clojure source.
Connects to a running Synthigy backend ONCE (op:describe = the XSQL
compiler) and emits one namespace per XSQL @namespace, with a named,
documented function per operation. The generated code carries NO parser and
needs NO backend at runtime — it embeds each op's compiled XSQL source string
and sends it via synthigy.client. Connection is a BUILD-time dependency, like
Prisma/sqlc/genqlient; commit the output and it runs offline forever after.
clj -X:gen :dir '"synthigy"' :out '"src"' \
:ns-prefix myapp.ops :endpoint '"http://localhost:7887"'
Auth for the pull: THE APP'S OWN client credentials (:client-id/:client-secret
or SYNTHIGY_CLIENT_ID/SYNTHIGY_CLIENT_SECRET) — /schema + describe are
IAM-filtered per principal, so generating as the app makes the generated
contract exactly what the app can do at runtime (a personal/dev identity
would generate a surface the app can't honor). Grant the client `schema:read`
(or the broader `dataset:load`). :token / SYNTHIGY_TOKEN and authless remain
for bare dev servers. Regenerate any time you edit an .xsql — the diff shows
exactly what changed.(check opts)CI gate: pull IR and verify the committed files under out match what
generate would write. Prints each missing/drifted/stale file and throws
(non-zero exit under -X) when anything is out of sync.
clj -X:gen-check :dir '"synthigy"' :out '"src"' :ns-prefix myapp.ops
CI gate: pull IR and verify the committed files under `out` match what `generate` would write. Prints each missing/drifted/stale file and throws (non-zero exit under -X) when anything is out of sync. clj -X:gen-check :dir '"synthigy"' :out '"src"' :ns-prefix myapp.ops
(check*
operations
{:keys [out ns-prefix] :or {out "src" ns-prefix "synthigy.ops"} :as opts})The offline half of check: diff emit-files output for operations
against what's on disk. Returns {:missing [..] :drifted [..] :stale [..]}
(all empty = in sync). :stale = .clj files under the ns-prefix subtree of
out that the IR no longer produces (deleted ops leaving orphans).
The offline half of `check`: diff `emit-files` output for `operations`
against what's on disk. Returns `{:missing [..] :drifted [..] :stale [..]}`
(all empty = in sync). `:stale` = .clj files under the ns-prefix subtree of
`out` that the IR no longer produces (deleted ops leaving orphans).(emit-all operations opts)Emit generated namespaces from IR operations into out under ns-prefix.
No network (drives the proof against a committed ops.ir.json too).
Returns the seq of written paths.
Emit generated namespaces from IR `operations` into `out` under `ns-prefix`. No network (drives the proof against a committed ops.ir.json too). Returns the seq of written paths.
(emit-files operations
{:keys [out ns-prefix] :or {out "src" ns-prefix "synthigy.ops"}})Pure half of the generator: IR operations →
{:files {path {:content s :ops n :batches n}} :skipped [op …]}.
No I/O, no printing — emit-all writes it, check diffs it against disk.
Pure half of the generator: IR `operations` →
`{:files {path {:content s :ops n :batches n}} :skipped [op …]}`.
No I/O, no printing — `emit-all` writes it, `check` diffs it against disk.(generate opts)Pull IR from the backend (op:describe over dir's .xsql) and emit source.
Also refreshes <dir>/schema.json for editor tooling.
Returns the seq of written paths.
Pull IR from the backend (op:describe over `dir`'s .xsql) and emit source. Also refreshes `<dir>/schema.json` for editor tooling. Returns the seq of written paths.
(pull-schema! {:keys [dir] :or {dir "synthigy"}})GET /schema → <dir>/schema.json. Nothing at runtime reads this file; it is
the snapshot XSQL editor tooling lints and completes against (xsql-lint,
and the LSP when it lands) — see docs/plans/PLAN-XSQL-TOOLING.md. Same filename and
same indentation the JS and Go generators write, so a polyglot repo gets one
artifact rather than one per language. Requires score/*client* bound: the
snapshot must describe the same principal the IR did.
GET /schema → `<dir>/schema.json`. Nothing at runtime reads this file; it is the snapshot XSQL editor tooling lints and completes against (`xsql-lint`, and the LSP when it lands) — see docs/plans/PLAN-XSQL-TOOLING.md. Same filename and same indentation the JS and Go generators write, so a polyglot repo gets one artifact rather than one per language. Requires `score/*client*` bound: the snapshot must describe the same principal the IR did.
Cheshire printer tuned to JSON.stringify(x, null, 2) — byte-identical to
what the JS and Go generators write, so a polyglot repo keeps one artifact.
Cheshire's defaults differ: : between key and value, and inline arrays.
Cheshire printer tuned to `JSON.stringify(x, null, 2)` — byte-identical to what the JS and Go generators write, so a polyglot repo keeps one artifact. Cheshire's defaults differ: ` : ` between key and value, and inline arrays.
(watch! {:keys [interval-ms] :or {interval-ms 500} :as opts})Dev loop for user.clj: poll dir for .xsql content changes (also fires once
on start); on change re-describe against the backend, rewrite out, and
load-file every written file so the running REPL picks the new fns up
immediately. Backend errors don't kill the loop — it reports once per
distinct error and retries each poll until the regen succeeds. Returns a
0-arg stop fn.
(defonce stop-gen (gen/watch! {:dir "synthigy" :out "src" :ns-prefix "myapp.ops"}))
Dev loop for user.clj: poll `dir` for .xsql content changes (also fires once
on start); on change re-describe against the backend, rewrite `out`, and
`load-file` every written file so the running REPL picks the new fns up
immediately. Backend errors don't kill the loop — it reports once per
distinct error and retries each poll until the regen succeeds. Returns a
0-arg stop fn.
(defonce stop-gen
(gen/watch! {:dir "synthigy" :out "src" :ns-prefix "myapp.ops"}))cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |