@gonvex/cli 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/dist/function-catalog.d.ts +19 -0
- package/dist/function-catalog.js +107 -0
- package/dist/function-catalog.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +47 -3
- package/dist/index.js.map +1 -1
- package/dist/manifest-types.d.ts +13 -0
- package/dist/module-artifact.d.ts +1 -1
- package/dist/module-artifact.js +65 -4
- package/dist/module-artifact.js.map +1 -1
- package/dist/templates/vite-react/agent-api.d.ts +77 -0
- package/dist/templates/vite-react/agent-api.ndjson +4 -0
- package/dist/templates/vite-react/gonvex/_build/module.js +172 -7
- package/dist/templates/vite-react/gonvex/_generated/api.ts +109 -2
- package/dist/templates/vite-react/gonvex/_generated/manifest.json +285 -11
- package/dist/templates/vite-react/gonvex/_generated/module.json +147 -8
- package/dist/templates/vite-react/gonvex/_generated/react.ts +1 -1
- package/dist/templates/vite-react/gonvex/index.ts +1 -1
- package/dist/templates/vite-react/gonvex/messages.ts +59 -6
- package/dist/templates/vite-react/migrations/0002_message_timestamp_default.sql +3 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The Gonvex CLI for app-local development with the Gonvex runtime.
|
|
4
4
|
|
|
5
|
-
Gonvex
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Gonvex provides TypeScript backend functions, generated TypeScript bindings,
|
|
6
|
+
React hooks, transaction-ordered realtime delivery, and a persistent Local
|
|
7
|
+
Replica backed by Postgres.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -88,6 +88,21 @@ Run a one-shot sync for CI or Docker builds:
|
|
|
88
88
|
npx gonvex dev --once
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
Emit or verify the deterministic interactive-function catalog used by agent
|
|
92
|
+
orchestration:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx gonvex functions emit --format ndjson --output agent-api.ndjson
|
|
96
|
+
npx gonvex functions emit --format typescript --output agent-api.d.ts
|
|
97
|
+
npx gonvex functions check
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Both files are derived from the compiled module artifact, sorted by public
|
|
101
|
+
function path, and contain the artifact hash. The NDJSON format stores one
|
|
102
|
+
complete function contract per line. The TypeScript declaration renders the
|
|
103
|
+
same schemas, classification, offline policy, optimistic transaction,
|
|
104
|
+
description, tags, and confirmation requirement as literal types.
|
|
105
|
+
|
|
91
106
|
By default, `gonvex dev` streams only runtime warnings and errors to the
|
|
92
107
|
terminal. To tail every Query, Reducer, and Action:
|
|
93
108
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { JsonValue, ModuleArtifact, ModuleFunction, ModuleSchema } from "./manifest-types.js";
|
|
2
|
+
export type FunctionCatalogFormat = "ndjson" | "typescript";
|
|
3
|
+
export type FunctionCatalogEntry = {
|
|
4
|
+
path: string;
|
|
5
|
+
kind: ModuleFunction["kind"];
|
|
6
|
+
artifactHash: string;
|
|
7
|
+
args: ModuleSchema;
|
|
8
|
+
result: ModuleSchema;
|
|
9
|
+
classification: "interactive";
|
|
10
|
+
interactive: true;
|
|
11
|
+
offline: JsonValue | null;
|
|
12
|
+
optimistic: JsonValue | null;
|
|
13
|
+
description: string;
|
|
14
|
+
tags: string[];
|
|
15
|
+
confirmation: "none" | "required" | "destructive";
|
|
16
|
+
};
|
|
17
|
+
export declare function functionCatalogEntries(artifact: ModuleArtifact): FunctionCatalogEntry[];
|
|
18
|
+
export declare function renderFunctionCatalog(artifact: ModuleArtifact, format: FunctionCatalogFormat): string;
|
|
19
|
+
export declare function renderPortableSchema(schema: ModuleSchema, indent?: number): string;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
2
|
+
export function functionCatalogEntries(artifact) {
|
|
3
|
+
return Object.entries(artifact.functions)
|
|
4
|
+
.filter(([, definition]) => !definition.internal && (definition.classification === "interactive" || (definition.classification === undefined
|
|
5
|
+
&& (definition.interactive === true || (definition.interactive === undefined && definition.kind !== "action")))))
|
|
6
|
+
.sort(([left], [right]) => compareText(left, right))
|
|
7
|
+
.map(([path, definition]) => ({
|
|
8
|
+
path,
|
|
9
|
+
kind: definition.kind,
|
|
10
|
+
artifactHash: artifact.hash,
|
|
11
|
+
args: definition.args ?? { kind: "object", fields: {} },
|
|
12
|
+
result: definition.result ?? { kind: "any" },
|
|
13
|
+
classification: "interactive",
|
|
14
|
+
interactive: true,
|
|
15
|
+
offline: definition.offline ?? null,
|
|
16
|
+
optimistic: definition.optimistic ?? null,
|
|
17
|
+
description: definition.description ?? "",
|
|
18
|
+
tags: [...(definition.agent?.tags ?? [])].sort(),
|
|
19
|
+
confirmation: definition.agent?.confirmation ?? "none",
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
export function renderFunctionCatalog(artifact, format) {
|
|
23
|
+
const entries = functionCatalogEntries(artifact);
|
|
24
|
+
if (format === "ndjson") {
|
|
25
|
+
return entries.map((entry) => JSON.stringify(entry)).join("\n") + (entries.length > 0 ? "\n" : "");
|
|
26
|
+
}
|
|
27
|
+
const lines = [
|
|
28
|
+
"// Generated by Gonvex. Do not edit.",
|
|
29
|
+
`export declare const artifactHash: ${JSON.stringify(artifact.hash)};`,
|
|
30
|
+
"export type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue };",
|
|
31
|
+
"export type Id<Entity extends string> = string & { readonly __gonvexEntity: Entity };",
|
|
32
|
+
"export interface GonvexAgentAPI {",
|
|
33
|
+
];
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
lines.push(` ${JSON.stringify(entry.path)}: {`);
|
|
36
|
+
lines.push(` kind: ${JSON.stringify(entry.kind)};`);
|
|
37
|
+
lines.push(' classification: "interactive";');
|
|
38
|
+
lines.push(" interactive: true;");
|
|
39
|
+
lines.push(` args: ${renderPortableSchema(entry.args, 4)};`);
|
|
40
|
+
lines.push(` result: ${renderPortableSchema(entry.result, 4)};`);
|
|
41
|
+
lines.push(` offline: ${renderJsonLiteralType(entry.offline)};`);
|
|
42
|
+
lines.push(` optimistic: ${renderJsonLiteralType(entry.optimistic)};`);
|
|
43
|
+
lines.push(` description: ${JSON.stringify(entry.description)};`);
|
|
44
|
+
lines.push(` tags: readonly [${entry.tags.map((tag) => JSON.stringify(tag)).join(", ")}];`);
|
|
45
|
+
lines.push(` confirmation: ${JSON.stringify(entry.confirmation)};`);
|
|
46
|
+
lines.push(" };");
|
|
47
|
+
}
|
|
48
|
+
lines.push("}", "");
|
|
49
|
+
return lines.join("\n");
|
|
50
|
+
}
|
|
51
|
+
export function renderPortableSchema(schema, indent = 0) {
|
|
52
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema))
|
|
53
|
+
return "unknown";
|
|
54
|
+
const value = schema;
|
|
55
|
+
switch (value.kind) {
|
|
56
|
+
case "string": return "string";
|
|
57
|
+
case "number": return "number";
|
|
58
|
+
case "boolean": return "boolean";
|
|
59
|
+
case "null": return "null";
|
|
60
|
+
case "any": return "JsonValue";
|
|
61
|
+
case "id": return `Id<${JSON.stringify(String(value.entity ?? ""))}>`;
|
|
62
|
+
case "literal": return renderLiteral(value.value);
|
|
63
|
+
case "array": return `Array<${renderPortableSchema(value.items, indent)}>`;
|
|
64
|
+
case "record": return `Record<string, ${renderPortableSchema(value.values, indent)}>`;
|
|
65
|
+
case "optional": return `${renderPortableSchema(value.value, indent)} | undefined`;
|
|
66
|
+
case "object": {
|
|
67
|
+
const fields = value.fields && typeof value.fields === "object" && !Array.isArray(value.fields)
|
|
68
|
+
? Object.entries(value.fields).sort(([left], [right]) => compareText(left, right))
|
|
69
|
+
: [];
|
|
70
|
+
if (fields.length === 0)
|
|
71
|
+
return "Record<string, never>";
|
|
72
|
+
const padding = " ".repeat(indent);
|
|
73
|
+
const childPadding = " ".repeat(indent + 2);
|
|
74
|
+
const rendered = fields.map(([name, field]) => {
|
|
75
|
+
const optional = field?.kind === "optional";
|
|
76
|
+
const actual = field.kind === "optional" ? field.value : field;
|
|
77
|
+
return `${childPadding}${renderProperty(name)}${optional ? "?" : ""}: ${renderPortableSchema(actual, indent + 2)};`;
|
|
78
|
+
});
|
|
79
|
+
if (value.allowUnknown === true)
|
|
80
|
+
rendered.push(`${childPadding}[key: string]: JsonValue;`);
|
|
81
|
+
return `{\n${rendered.join("\n")}\n${padding}}`;
|
|
82
|
+
}
|
|
83
|
+
default: return "unknown";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function renderProperty(value) {
|
|
87
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value) ? value : JSON.stringify(value);
|
|
88
|
+
}
|
|
89
|
+
function renderLiteral(value) {
|
|
90
|
+
if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
91
|
+
return JSON.stringify(value);
|
|
92
|
+
}
|
|
93
|
+
return "JsonValue";
|
|
94
|
+
}
|
|
95
|
+
function renderJsonLiteralType(value) {
|
|
96
|
+
if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
97
|
+
return JSON.stringify(value);
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
return `readonly [${value.map(renderJsonLiteralType).join(", ")}]`;
|
|
101
|
+
}
|
|
102
|
+
const fields = Object.entries(value)
|
|
103
|
+
.sort(([left], [right]) => compareText(left, right))
|
|
104
|
+
.map(([name, field]) => `readonly ${renderProperty(name)}: ${renderJsonLiteralType(field)};`);
|
|
105
|
+
return `{ ${fields.join(" ")} }`;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=function-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-catalog.js","sourceRoot":"","sources":["../src/function-catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
export type * from "./manifest-types.js";
|
|
3
3
|
export type { ProjectLanguage } from "./module-artifact.js";
|
|
4
|
+
export * from "./function-catalog.js";
|
|
4
5
|
export declare function main(argv?: string[]): Promise<void>;
|
|
5
6
|
export declare function runCreate(argv: string[]): Promise<void>;
|
|
6
7
|
export declare function runAuth(argv: string[]): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ import { dirname, join, relative, resolve } from "node:path";
|
|
|
9
9
|
import { Writable } from "node:stream";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
11
|
import { buildModuleArtifact, detectProjectLanguage, moduleManifestFunctions, moduleSourceFiles, isModuleSchema, } from "./module-artifact.js";
|
|
12
|
+
import { renderFunctionCatalog } from "./function-catalog.js";
|
|
13
|
+
export * from "./function-catalog.js";
|
|
12
14
|
const defaultRuntimeURL = "http://localhost:8080";
|
|
13
15
|
const runtimeSyncRetryMs = 5000;
|
|
14
16
|
const runtimeStateCheckMs = 2500;
|
|
@@ -57,6 +59,10 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
57
59
|
await runCodegen(argv.slice(1));
|
|
58
60
|
return;
|
|
59
61
|
}
|
|
62
|
+
if (command === "functions") {
|
|
63
|
+
await runFunctions(argv.slice(1));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
60
66
|
if (command === "init") {
|
|
61
67
|
await runInit(argv.slice(1));
|
|
62
68
|
return;
|
|
@@ -96,6 +102,42 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
96
102
|
printHelp();
|
|
97
103
|
throw new Error(`unknown command ${command}`);
|
|
98
104
|
}
|
|
105
|
+
async function runFunctions(argv) {
|
|
106
|
+
const action = argv[0];
|
|
107
|
+
if (!action || !["emit", "check"].includes(action)) {
|
|
108
|
+
throw new Error("usage: gonvex functions <emit|check> [--format ndjson|typescript] [--output FILE] [--project PATH]");
|
|
109
|
+
}
|
|
110
|
+
const root = resolve(valueFor(argv, "--project") ?? ".");
|
|
111
|
+
const sources = await collectBackendSources(root);
|
|
112
|
+
const settings = await loadSettings(root, {});
|
|
113
|
+
const manifest = await buildManifest(root, sources, settings.projectID);
|
|
114
|
+
const targets = action === "check"
|
|
115
|
+
? [
|
|
116
|
+
{ format: "ndjson", output: resolve(root, "agent-api.ndjson") },
|
|
117
|
+
{ format: "typescript", output: resolve(root, "agent-api.d.ts") },
|
|
118
|
+
]
|
|
119
|
+
: [{
|
|
120
|
+
format: normalizeCatalogFormat(valueFor(argv, "--format") ?? "ndjson"),
|
|
121
|
+
output: resolve(root, valueFor(argv, "--output") ?? (valueFor(argv, "--format") === "typescript" ? "agent-api.d.ts" : "agent-api.ndjson")),
|
|
122
|
+
}];
|
|
123
|
+
for (const target of targets) {
|
|
124
|
+
const expected = renderFunctionCatalog(manifest.module, target.format);
|
|
125
|
+
if (action === "check") {
|
|
126
|
+
const actual = await readFile(target.output, "utf8").catch(() => "");
|
|
127
|
+
if (actual !== expected)
|
|
128
|
+
throw new Error(`${relative(root, target.output)} is stale; run gonvex functions emit --format ${target.format} --output ${relative(root, target.output)}`);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
await mkdir(dirname(target.output), { recursive: true });
|
|
132
|
+
await writeFile(target.output, expected);
|
|
133
|
+
console.log(`[gonvex] wrote ${relative(root, target.output)} for artifact ${manifest.module.hash}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function normalizeCatalogFormat(value) {
|
|
137
|
+
if (value === "ndjson" || value === "typescript")
|
|
138
|
+
return value;
|
|
139
|
+
throw new Error("--format must be ndjson or typescript");
|
|
140
|
+
}
|
|
99
141
|
export async function runCreate(argv) {
|
|
100
142
|
const optionNames = ["--template", "--runtime-url", "--runtime", "--database-mode", "--origin", "--callback-path", "--signup-mode", "--owner"];
|
|
101
143
|
const target = positionalArgs(argv, optionNames)[0] ?? "my-gonvex-app";
|
|
@@ -1186,7 +1228,7 @@ function renderAPI(manifest) {
|
|
|
1186
1228
|
const internalRoot = {};
|
|
1187
1229
|
const optimisticTransactions = {};
|
|
1188
1230
|
const functionTypes = [];
|
|
1189
|
-
for (const [path, entry] of Object.entries(manifest.functions).sort(([a], [b]) => a
|
|
1231
|
+
for (const [path, entry] of Object.entries(manifest.functions).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
1190
1232
|
const parts = path.split(".").filter(Boolean);
|
|
1191
1233
|
if (parts.length === 0)
|
|
1192
1234
|
continue;
|
|
@@ -1417,7 +1459,7 @@ function renderSchemaObject(scope, tables, depth) {
|
|
|
1417
1459
|
function renderObject(value, depth) {
|
|
1418
1460
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1419
1461
|
return JSON.stringify(value);
|
|
1420
|
-
const entries = Object.entries(value).sort(([a], [b]) => a
|
|
1462
|
+
const entries = Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
1421
1463
|
if (isFunctionRef(value)) {
|
|
1422
1464
|
const visible = Object.fromEntries(entries.filter(([key]) => !key.startsWith("__")));
|
|
1423
1465
|
return `${renderObject(visible, depth)} as unknown as FunctionReference<${JSON.stringify(value.kind)}, ${value.__argsType}, ${value.__resultType}>`;
|
|
@@ -2177,9 +2219,11 @@ function sleep(ms, signal) {
|
|
|
2177
2219
|
});
|
|
2178
2220
|
}
|
|
2179
2221
|
function printHelp() {
|
|
2180
|
-
console.log("Usage: gonvex <dev|codegen|init|create|env|auth|login|logout|whoami|project|token> [options]");
|
|
2222
|
+
console.log("Usage: gonvex <dev|codegen|functions|init|create|env|auth|login|logout|whoami|project|token> [options]");
|
|
2181
2223
|
console.log(" gonvex dev [--project <path>] [--runtime-url <url>] [--project-id <id>] [--key <key>] [--once] [--verbose-logs] [-- <command>]");
|
|
2182
2224
|
console.log(" gonvex codegen [--project <path>] [--project-id <id>]");
|
|
2225
|
+
console.log(" gonvex functions emit --format ndjson|typescript [--output FILE] [--project <path>]");
|
|
2226
|
+
console.log(" gonvex functions check [--project <path>]");
|
|
2183
2227
|
console.log(" gonvex init [--template vite-react] [--project <id>] [--runtime <url>]");
|
|
2184
2228
|
console.log(" gonvex create <app-name> [--runtime-url <url>] [--provision] [--database-mode single|multiTenant] [--google-auth] [--origin <url>]... [--signup-mode personal|inviteOnly] [--owner <email>]");
|
|
2185
2229
|
console.log(" gonvex env <list|get|set|push|remove> [--project <path>] [--runtime-url <url>] [--project-id <id>] [--key <key>]");
|