{"id":13629067,"url":"https://github.com/siteforge-io/surreal-codegen","last_synced_at":"2025-04-17T04:32:58.836Z","repository":{"id":239223502,"uuid":"798692451","full_name":"siteforge-io/surreal-codegen","owner":"siteforge-io","description":"SurrealDB code generation library inspired by GraphQL codegen tooling","archived":false,"fork":false,"pushed_at":"2025-02-24T05:27:16.000Z","size":571,"stargazers_count":23,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-24T06:32:09.787Z","etag":null,"topics":["codegen","codegenerator","rust","surrealdb","typescript"],"latest_commit_sha":null,"homepage":"https://siteforge.io","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/siteforge-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-10T09:40:23.000Z","updated_at":"2025-02-24T05:27:19.000Z","dependencies_parsed_at":"2025-01-12T13:19:54.982Z","dependency_job_id":"1c58a475-f5f9-4141-b386-afce71c1bf83","html_url":"https://github.com/siteforge-io/surreal-codegen","commit_stats":null,"previous_names":["siteforge-io/surreal-codegen"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siteforge-io%2Fsurreal-codegen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siteforge-io%2Fsurreal-codegen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siteforge-io%2Fsurreal-codegen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siteforge-io%2Fsurreal-codegen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/siteforge-io","download_url":"https://codeload.github.com/siteforge-io/surreal-codegen/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249316040,"owners_count":21249880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codegen","codegenerator","rust","surrealdb","typescript"],"created_at":"2024-08-01T22:01:02.183Z","updated_at":"2025-04-17T04:32:58.828Z","avatar_url":"https://github.com/siteforge-io.png","language":"Rust","readme":"# `surreal-codegen`\n\u003e [!WARNING]\n\u003e This is a WIP, but we are currently using it in production at [Siteforge](https://siteforge.io) to help ensure type safety in our SurrealDB queries.\n\u003e See the [Features Supported](#features-supported) section for a list of features we currently support.\n\n# Installation\n\u003e [!WARNING]\n\u003e We haven't currently setup a build automation system, so you must build via the manual installation instructions below.\n\n\n## Manual Installation\nYou must have the rust toolchain installed, then run:\n\n```sh\ncargo install --git https://github.com/siteforge-io/surreal-codegen.git\n```\nOr, if you have cloned the repo:\n```sh\ncargo install --path surreal-codegen\n```\n\n## Running `surreal-codegen`\n```sh\nsurreal-codegen --help\n```\n\n```\nUsage: surreal-codegen [OPTIONS] --dir \u003cDIR\u003e --schema \u003cSCHEMA\u003e\n\nOptions:\n  -d, --dir \u003cDIR\u003e        The directory containing the Surql files\n  -s, --schema \u003cSCHEMA\u003e\n  -o, --output \u003cOUTPUT\u003e  The name of the output file default of `types.ts` [default: ./types.ts]\n      --header \u003cHEADER\u003e  Header to add to the top of the output file If you specify this, you must import in RecordId type and a Surreal class that has a .query(query: string, variables?: Record\u003cstring, unknown\u003e) method [default: \"import { type RecordId, Surreal } from 'surrealdb'\"]\n  -h, --help             Print help\n```\n\n# Usage\n\n## Schema Example\n\n`./schema.surql`\n```ts\nDEFINE TABLE user SCHEMAFULL;\nDEFINE FIELD id ON user TYPE string;\nDEFINE FIELD email ON user TYPE string\n  VALUE string::lowercase($value)\n  ASSERT string::is::email($value);\nDEFINE FIELD password ON user TYPE string\n  VALUE crypto::bcrypt::generate($value);\nDEFINE FIELD name ON user TYPE string\n  VALUE string::trim($value);\nDEFINE FIELD created_at ON user TYPE datetime\n  VALUE time::now()\n  READONLY;\n```\n\n## Query Example\n\n`./queries/create_user.surql`\n```ts\nCREATE user CONTENT $user;\n```\n\n\n## Codegen\nThis wil generate a `types.ts` file in the current directory, which includes all your queries, as well as some prototype and type overrides for the SurrealDB database to allow you to use the generated types in your TypeScript code.\n```sh\nsurreal-codegen \\\n  --schema ./schema.surql \\\n  --dir ./queries \\\n  --output ./queries.ts\n```\n\n## TypeScript usage\n```ts\nimport { TypedSurreal, CreateUserQuery } from \"./queries\"\n\nconst db = new TypedSurreal()\n\nawait db.connect(...)\n/*\n  Result is typed as CreateUserResult from the generated types.ts file\n*/\nconst [created_users] = await db.typed(CreateUserQuery, {\n  user: {\n    name: \"John Doe\",\n    email: \"john@doe.com\",\n    password: \"123456\",\n  } // can also be an array of users\n})\n```\n\n## Typing parameters\n\nWe exploit the SurrealDB casting system to infer the types of parameters, for places where they cannot be inferred from the query itself.\n\nAll you must do is add a casting annotation with the parameter name, eg:\n\n```sql\n-- Casting syntax in SurrealDB.\n\u003cstring\u003e $email;\n```\n\nThis will allow the codegen to infer the type of `$email` variable as a `string`.\n\n### Example:\n\n`./queries/reset_password.surql`\n```sql\n\u003crecord\u003cuser\u003e\u003e $user;\n\u003cstring\u003e $password;\n\nUPDATE ONLY $user\n  SET password = $password\n```\n\n### Global parameters\nYou can also define global parameters in a `global.surql` file, which will be available to all queries in the directory, this is useful things like typing the $auth parameters available in SurrealDB across all queries.\n\n`./queries/globals.surql`\n```sql\n\u003crecord\u003cuser\u003e\u003e $auth;\n```\n\n## Overriding the default file header\nYou can override the default imported classes by specifying the `--header` option. You must include a RecordID type import, and a Surreal class that contains\na `.query(query: string, variables?: Record\u003cstring, unknown\u003e)` method.\n\nYou can also use this to specify a comment to be added to the top of the generated file, such as ESLint ignore comments.\nOr alternatively, you can ignore the generated file by including the file in your eslint ignore list.\n\n### Example\n```sh\nsurreal-codegen \\\n  --schema ./schema.surql \\\n  --dir ./queries \\\n  --output ./queries.ts \\\n  --header \"import { RecordId, Surreal } from 'my-custom-surreal-class'\"\n```\n\n\n\n# Features Supported\n\n### Notes\n- We only currently support `SCHEMAFULL` tables so far, but we are working on supporting other table types.\n\n### General Type Support and Handling\n- [x] `never`\n- [x] `unknown`\n- [x] `string`\n- [x] `int`\n- [x] `float`\n- [x] `datetime`\n- [x] `duration`\n- [x] `decimal`\n- [x] `bool`\n- [x] `record\u003ctable\u003e`\n- [x] `option\u003ctype\u003e`\n- [x] `array\u003ctype\u003e`\n- [x] `object`\n- [x] `number`\n- [x] `NULL`\n- [x] `NONE` (for `Option`)\n- [x] `any`\n- [x] `foo | bar` Unions (mixed return type unions)\n- [x] Surreal 2.0 typed literals (eg: `\"foo\"`, `123`, `1d`, `{ foo: 123 }`, `array\u003c1|2\u003e`)\n- [ ] GEOJson types (eg: `point`, `line`, `polygon`)\n- [x] Typed `id` record ID values for tables, eg: `DEFINE FIELD id ON user TYPE string`\n\n## Objects\n- [x] `RETURN { foo: 1, bar: 2 }`\n\n## Automatic Parameter Inference\n\n### General\n- [ ] `WHERE foo = $bar` parameter inference\n- [ ] `fn::foo($bar)` function calling parameter inference\n\n### `SELECT` statements\n- [x] `*` all fields\n- [x] `foo.bar` field access\n- [x] `foo as bar` field alias\n- [ ] `foo.{bar, baz}` destructuring access.\n- [x] `FROM` targets\n- [x] `VALUE`\n- [x] `GROUP BY`\n- [x] `GROUP ALL`\n- [ ] `SPLIT` fields\n- [ ] `FETCH` fields\n\n### `DELETE` statements\n- [x] `FROM` targets\n- [x] `RETURN BEFORE`\n- [x] `RETURN AFTER`\n- [ ] `RETURN DIFF`\n- [x] `RETRUN @statement_param` with `$before` field access\n\n### `INSERT` statements\n- [x] `INSERT INTO baz $foo` parameter inference\n- [ ] `INSERT INTO baz { foo: $bar }` parameter inference\n- [ ] `INSERT INTO baz ... ON DUPLICATE KEY UPDATE foo = $bar` parameter inference\n\n### `RELATE` statements\n- [ ] TODO\n\n### `DEFINE TABLE .. AS` precomputed tables\n- [X] `DEFINE TABLE foo AS SELECT ... FROM bar`\n- [X] `DEFINE TABLE foo AS SELECT ... FROM bar GROUP BY ...`\n- [X] `DEFINE TABLE foo AS SELECT ... FROM bar GROUP ALL`\n\n\n### `UPDATE` statements\n- [x] `RETURN BEFORE`\n- [x] `RETURN AFTER`\n- [ ] `RETURN DIFF`\n- [x] `RETRUN @statement_param` with `$before` and `$after` field access\n- [ ] `CONTENT $foo` parameter inference\n- [ ] `CONTENT { foo: $bar }` parameter inference\n- [ ] `SET foo = $bar` parameter inference\n- [ ] `MERGE $bar` parameter inference\n- [ ] `MERGE { foo: $bar }` parameter inference\n- [ ] `PATCH ...` parameter inference\n\n\n### `CREATE` statements\n- [ ] `CREATE baz SET foo = $bar` parameter inference\n- [ ] `CREATE baz CONTENT { foo: $bar }` parameter inference\n- [x] `CREATE baz CONTENT $foo` parameter inference\n- [x] `RETURN BEFORE`\n- [x] `RETURN AFTER`\n- [ ] `RETURN DIFF`\n- [x] `RETRUN @statement_param` with `$after` field access\n\n### `UPSERT` statements\n- [X] `RETURN BEFORE`\n- [X] `RETURN AFTER`\n- [X] `RETURN DIFF`\n- [X] `RETRUN @statement_param` with `$after` field access\n- [x] `CONTENT $foo` parameter inference\n- [ ] `SET foo = $bar` parameter inference\n- [ ] `MERGE { foo: $bar }` parameter inference\n- [ ] `CONTENT { foo: $bar }` parameter inference\n- [X] `MERGE $foo` parameter inference\n- [ ] `PATCH ...` parameter inference\n\n\n### Value expressions\n#### Idiom/path expressions\n- [x] `foo.bar`\n- [x] `foo.*` for arrays\n- [x] `foo.*` for objects\n- [ ] `foo[0]`\n- [ ] edge traversal eg: `foo-\u003ebar\u003c-baz`\n\n#### Literal/constant expressions\n- [x] `true`\n- [x] `false`\n- [x] `null`\n- [x] `\"string\"`\n- [x] `123`\n- [x] `123.456`\n- [x] `[1, 2, 3]`\n- [x] `{\"foo\": \"bar\"}`\n\n#### Comparison expressions\n- [x] `foo == \"bar\"`\n- [x] `foo != \"bar\"`\n- [x] `foo \u003c \"bar\"`\n- [x] `foo \u003c= \"bar\"`\n- [x] `foo \u003e \"bar\"`\n- [x] `foo \u003e= \"bar\"`\n\n#### Subquery expressions\n- [x] `SELECT` statements\n- [x] `DELETE` statements\n- [X] `INSERT` statements\n- [x] `UPDATE` statements\n- [x] `CREATE` statements\n- [ ] `RELATE` statements\n- [ ] `UPSERT` statements\n\n### Parameter expressions\n- [x] Custom global `$param` definitions in a `global.surql` file\n  - [x] `$auth`\n  - [x] `$session`\n  - [x] `$scope`\n  - [x] `$input`\n  - [x] `$token`\n- [ ] built-in parameters\n  - [x] `$this`\n  - [x] `$parent`\n  - [x] `$after`\n  - [x] `$before`\n- [ ] Automatic parameter inference in some cases\n\n### Other Statements\n- [ ] `IF ELSE`\n- [ ] `FOR`\n- [ ] `CONTINUE`\n- [ ] `BREAK`\n- [x] `RETURN`\n- [X] `BEGIN`\n- [X] `COMMIT`\n- [ ] `LET`\n- [ ] `ABORT`\n- [ ] `THROW`\n\n### `LET` statement\n- [x] `LET` statement\n```surql\n-- If we can't infer the type of the `LET` statement\n-- you can use a type annotation\nLET $id: record\u003cfoo\u003e = $foo.id;\n\nUPSERT ONLY $id CONTENT $foo;\n```\n\n\n## Contributing\n\nWe welcome contributions to this project, please see our [Contributing Guide](CONTRIBUTING.md) for more information.\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE.md).\n","funding_links":[],"categories":["Development tools"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiteforge-io%2Fsurreal-codegen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsiteforge-io%2Fsurreal-codegen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiteforge-io%2Fsurreal-codegen/lists"}