@spooky-sync/cli 0.0.0-canary.1

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 ADDED
@@ -0,0 +1,105 @@
1
+ # Spooky CLI
2
+
3
+ Generate TypeScript and Dart types from SurrealDB schema files.
4
+
5
+ ## Overview
6
+
7
+ This package wraps a Rust-based code generator that parses SurrealDB `.surql` schema files and generates type definitions. The core logic is implemented in Rust for performance, with a TypeScript/Node.js wrapper for easy integration into JavaScript/TypeScript projects.
8
+
9
+ ## Prerequisites
10
+
11
+ - Rust toolchain (for building from source)
12
+ - Node.js 18+
13
+ - npx (for quicktype code generation)
14
+
15
+ ## Usage
16
+
17
+ ### CLI
18
+
19
+ ```bash
20
+ # Generate TypeScript types
21
+ spooky --input schema.surql --output types.ts
22
+
23
+ # Generate Dart types
24
+ spooky --input schema.surql --output types.dart
25
+
26
+ # Generate JSON Schema
27
+ spooky --input schema.surql --output schema.json
28
+
29
+ # Generate all formats at once
30
+ spooky --input schema.surql --output output --all
31
+
32
+ # Specify format explicitly
33
+ spooky --input schema.surql --output output.ts --format typescript
34
+ ```
35
+
36
+ ### Programmatic API
37
+
38
+ ```typescript
39
+ import { runSpooky } from 'spooky-cli';
40
+
41
+ // Generate types
42
+ const output = await runSpooky({
43
+ input: 'path/to/schema.surql',
44
+ output: 'path/to/output.ts',
45
+ format: 'typescript', // or 'dart', 'json'
46
+ pretty: true,
47
+ all: false,
48
+ });
49
+
50
+ console.log(output);
51
+ ```
52
+
53
+ ## Options
54
+
55
+ - `--input, -i`: Path to the input `.surql` schema file (required)
56
+ - `--output, -o`: Path to the output file (required)
57
+ - `--format, -f`: Output format: `json`, `typescript`, `dart` (optional, inferred from extension)
58
+ - `--pretty, -p`: Pretty print JSON output (default: true)
59
+ - `--all, -a`: Generate all formats (TypeScript, Dart, and JSON Schema)
60
+
61
+ ## Development
62
+
63
+ ### Build
64
+
65
+ ```bash
66
+ # Install dependencies
67
+ npm install
68
+
69
+ # Build Rust binary and TypeScript wrapper
70
+ npm run build
71
+
72
+ # Build only Rust
73
+ npm run build:rust
74
+
75
+ # Build only TypeScript
76
+ npm run build:vite
77
+ ```
78
+
79
+ ### Project Structure
80
+
81
+ ```
82
+ cli/
83
+ ├── src/
84
+ │ ├── main.rs # Rust CLI entry point
85
+ │ ├── parser.rs # SurrealDB schema parser
86
+ │ ├── json_schema.rs # JSON Schema generator
87
+ │ ├── codegen.rs # Code generation logic
88
+ │ ├── index.ts # TypeScript wrapper
89
+ │ └── cli.ts # TypeScript CLI wrapper
90
+ ├── Cargo.toml # Rust dependencies
91
+ ├── package.json # npm package config
92
+ ├── vite.config.ts # Vite build config
93
+ └── tsconfig.json # TypeScript config
94
+ ```
95
+
96
+ ## How It Works
97
+
98
+ 1. The Rust binary (`spooky`) parses SurrealDB schema files and generates JSON Schema
99
+ 2. For TypeScript/Dart output, it uses `quicktype` to convert JSON Schema to the target language
100
+ 3. The TypeScript wrapper (`src/index.ts`) spawns the Rust binary as a child process
101
+ 4. Vite bundles the TypeScript wrapper for distribution
102
+
103
+ ## License
104
+
105
+ MIT
package/dist/cli.cjs ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ "use strict";const n=require("commander"),r=require("./syncgen.cjs"),o=new n.Command;o.name("syncgen").description("Generate types from SurrealDB schema files").version("0.1.0");o.option("-i, --input <path>","Path to the input .surql schema file").option("-o, --output <path>","Path to the output file (extension determines format: .json, .ts, .dart)").option("-f, --format <format>","Output format (json, typescript, dart, surql)").option("-p, --pretty","Pretty print the JSON output (only for JSON format)",!0).option("-a, --all","Generate all formats (TypeScript and Dart) in addition to JSON Schema",!1).option("--no-header","Disable the generated file comment header (enabled by default)",!1).option("--append <path>","Path to another .surql file to append to the input").option("--modules-dir <path>","Directory containing Surrealism modules to compile and bundle").option("--mode <mode>",'Generation mode: "singlenode" (HTTP to single SSP), "cluster" (HTTP to scheduler), or "surrealism" (embedded WASM)',"singlenode").option("--endpoint <url>","SSP/Scheduler Endpoint URL").option("--secret <secret>","SSP/Scheduler Auth Secret").option("--config <path>","Path to spooky.yml configuration file").parse(process.argv);const e=o.opts();async function i(){(!e.input||!e.output)&&(console.error("Error: --input and --output are required"),o.help(),process.exit(1));try{const t=await r.runSyncgen({input:e.input,output:e.output,format:e.format,pretty:e.pretty,all:e.all,noHeader:e.noHeader,append:e.append,modulesDir:e.modulesDir,mode:e.mode,endpoint:e.endpoint,secret:e.secret,config:e.config});console.log(t)}catch(t){console.error("Error:",t instanceof Error?t.message:String(t)),process.exit(1)}}i();
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ import { Command as n } from "commander";
3
+ import { runSyncgen as r } from "./syncgen.js";
4
+ const o = new n();
5
+ o.name("syncgen").description("Generate types from SurrealDB schema files").version("0.1.0");
6
+ o.option("-i, --input <path>", "Path to the input .surql schema file").option(
7
+ "-o, --output <path>",
8
+ "Path to the output file (extension determines format: .json, .ts, .dart)"
9
+ ).option("-f, --format <format>", "Output format (json, typescript, dart, surql)").option("-p, --pretty", "Pretty print the JSON output (only for JSON format)", !0).option(
10
+ "-a, --all",
11
+ "Generate all formats (TypeScript and Dart) in addition to JSON Schema",
12
+ !1
13
+ ).option("--no-header", "Disable the generated file comment header (enabled by default)", !1).option("--append <path>", "Path to another .surql file to append to the input").option("--modules-dir <path>", "Directory containing Surrealism modules to compile and bundle").option(
14
+ "--mode <mode>",
15
+ 'Generation mode: "singlenode" (HTTP to single SSP), "cluster" (HTTP to scheduler), or "surrealism" (embedded WASM)',
16
+ "singlenode"
17
+ ).option("--endpoint <url>", "SSP/Scheduler Endpoint URL").option("--secret <secret>", "SSP/Scheduler Auth Secret").option("--config <path>", "Path to spooky.yml configuration file").parse(process.argv);
18
+ const e = o.opts();
19
+ async function i() {
20
+ (!e.input || !e.output) && (console.error("Error: --input and --output are required"), o.help(), process.exit(1));
21
+ try {
22
+ const t = await r({
23
+ input: e.input,
24
+ output: e.output,
25
+ format: e.format,
26
+ pretty: e.pretty,
27
+ all: e.all,
28
+ noHeader: e.noHeader,
29
+ append: e.append,
30
+ modulesDir: e.modulesDir,
31
+ mode: e.mode,
32
+ endpoint: e.endpoint,
33
+ secret: e.secret,
34
+ config: e.config
35
+ });
36
+ console.log(t);
37
+ } catch (t) {
38
+ console.error("Error:", t instanceof Error ? t.message : String(t)), process.exit(1);
39
+ }
40
+ }
41
+ i();
@@ -0,0 +1,16 @@
1
+ export interface SyncgenOptions {
2
+ input: string;
3
+ output: string;
4
+ format?: 'json' | 'typescript' | 'dart' | 'surql';
5
+ pretty?: boolean;
6
+ all?: boolean;
7
+ noHeader?: boolean;
8
+ append?: string;
9
+ modulesDir?: string;
10
+ mode?: string;
11
+ endpoint?: string;
12
+ secret?: string;
13
+ config?: string;
14
+ }
15
+ export declare function runSyncgen(options: SyncgenOptions): Promise<string>;
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA0BD,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA0DzE"}
@@ -0,0 +1,4 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("child_process"),o=require("util"),t=require("path"),d=require("fs"),f=require("os"),l=require("url");var c=typeof document<"u"?document.currentScript:null;const p=o.promisify(a.execFile),h=l.fileURLToPath(typeof document>"u"?require("url").pathToFileURL(__filename).href:c&&c.tagName.toUpperCase()==="SCRIPT"&&c.src||new URL("syncgen.cjs",document.baseURI).href),i=t.dirname(h);function m(){const e=f.platform()==="win32"?"spooky.exe":"spooky",n=[t.resolve(i,"../target/release",e),t.resolve(i,"..",e),t.resolve(process.cwd(),e)];for(const r of n)if(d.existsSync(r))return r;throw new Error(`Could not find syncgen binary. Checked paths:
2
+ ${n.map(r=>` - ${r}`).join(`
3
+ `)}
4
+ Please ensure it is built or installed.`)}async function y(e){const n=m(),r=[];r.push("--input",e.input),r.push("--output",e.output),e.format&&r.push("--format",e.format),e.pretty&&r.push("--pretty"),e.all&&r.push("--all"),e.noHeader&&r.push("--no-header"),e.append&&r.push("--append",e.append),e.modulesDir&&r.push("--modules-dir",e.modulesDir),e.mode&&r.push("--mode",e.mode),e.endpoint&&r.push("--endpoint",e.endpoint),e.secret&&r.push("--secret",e.secret),e.config&&r.push("--config",e.config);try{const{stdout:s,stderr:u}=await p(n,r);return u&&console.error(u),s}catch(s){throw new Error(`Syncgen failed: ${s.message}`)}}exports.runSyncgen=y;
@@ -0,0 +1 @@
1
+ export * from './index'
@@ -0,0 +1,39 @@
1
+ import { execFile as s } from "child_process";
2
+ import { promisify as o } from "util";
3
+ import { dirname as c, resolve as i } from "path";
4
+ import { existsSync as m } from "fs";
5
+ import { platform as u } from "os";
6
+ import { fileURLToPath as d } from "url";
7
+ const p = o(s), l = d(import.meta.url), f = c(l);
8
+ function h() {
9
+ const e = u() === "win32" ? "spooky.exe" : "spooky", t = [
10
+ // Development/Source build location (from dist/index.js -> ../target/release)
11
+ i(f, "../target/release", e),
12
+ // Distributed package location (relative to dist/index.js -> ../bin)
13
+ i(f, "..", e),
14
+ // Installation root
15
+ i(process.cwd(), e)
16
+ ];
17
+ for (const r of t)
18
+ if (m(r))
19
+ return r;
20
+ throw new Error(
21
+ `Could not find syncgen binary. Checked paths:
22
+ ${t.map((r) => ` - ${r}`).join(`
23
+ `)}
24
+ Please ensure it is built or installed.`
25
+ );
26
+ }
27
+ async function _(e) {
28
+ const t = h(), r = [];
29
+ r.push("--input", e.input), r.push("--output", e.output), e.format && r.push("--format", e.format), e.pretty && r.push("--pretty"), e.all && r.push("--all"), e.noHeader && r.push("--no-header"), e.append && r.push("--append", e.append), e.modulesDir && r.push("--modules-dir", e.modulesDir), e.mode && r.push("--mode", e.mode), e.endpoint && r.push("--endpoint", e.endpoint), e.secret && r.push("--secret", e.secret), e.config && r.push("--config", e.config);
30
+ try {
31
+ const { stdout: n, stderr: a } = await p(t, r);
32
+ return a && console.error(a), n;
33
+ } catch (n) {
34
+ throw new Error(`Syncgen failed: ${n.message}`);
35
+ }
36
+ }
37
+ export {
38
+ _ as runSyncgen
39
+ };
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@spooky-sync/cli",
3
+ "version": "0.0.0-canary.1",
4
+ "description": "Generate TypeScript/Dart types from SurrealDB schema files",
5
+ "type": "module",
6
+ "main": "./dist/syncgen.cjs",
7
+ "module": "./dist/syncgen.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "spooky": "./dist/cli.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/syncgen.js",
15
+ "require": "./dist/syncgen.cjs",
16
+ "types": "./dist/index.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "target/release/spooky"
22
+ ],
23
+ "scripts": {
24
+ "dev": "vite",
25
+ "build:rust": "cargo build --release",
26
+ "build:vite": "vite build",
27
+ "build:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist",
28
+ "build": "npm run build:rust && npm run build:vite && npm run build:types",
29
+ "preview": "vite preview",
30
+ "test": "vitest",
31
+ "lint": "eslint src",
32
+ "prepare": "test -f ./dist/cli.js || npm run build"
33
+ },
34
+ "keywords": [
35
+ "surrealdb",
36
+ "code-generation",
37
+ "typescript",
38
+ "dart",
39
+ "schema"
40
+ ],
41
+ "author": "",
42
+ "license": "MIT",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/mono424/spooky.git",
46
+ "directory": "apps/cli"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "dependencies": {
52
+ "commander": "^12.0.0"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^20.0.0",
56
+ "typescript": "^5.3.0",
57
+ "vite": "^5.0.0",
58
+ "vite-plugin-dts": "^3.7.0",
59
+ "vitest": "^1.0.0"
60
+ }
61
+ }
Binary file