From beebd51712cf8fd5b26525e4fbf26a2dde946876 Mon Sep 17 00:00:00 2001 From: Teo Stocco Date: Thu, 3 Aug 2023 23:11:56 +0200 Subject: [PATCH] feat: more stable run by fixing little bugs + typegraph upgrade (#384) --- .github/workflows/tests.yml | 3 +- Cargo.lock | 14 +-- dev/lock.yml | 6 +- examples/metatype.yaml | 25 ---- examples/templates/new/compose.yml | 2 +- examples/templates/new/pyproject.toml | 4 +- libs/common/Cargo.toml | 2 +- libs/macros/Cargo.toml | 2 +- libs/typescript/Cargo.toml | 2 +- libs/xtask/Cargo.toml | 2 +- meta-cli/Cargo.toml | 2 +- meta-cli/src/cli/deploy.rs | 11 +- meta-cli/src/cli/serialize.rs | 3 +- poetry.lock | 22 ++-- pyproject.toml | 2 +- typegate/native/Cargo.toml | 2 +- typegate/src/hooks.ts | 114 ------------------ typegate/src/log.ts | 16 ++- typegate/src/main.ts | 18 ++- typegate/src/replicated_map.ts | 45 ++++--- typegate/src/runtimes/mod.ts | 14 +++ typegate/src/services/auth/mod.ts | 2 +- typegate/src/services/auth/protocols/jwt.ts | 2 +- .../src/services/auth/protocols/oauth2.ts | 2 +- .../src/services/auth/protocols/protocol.ts | 2 +- typegate/src/services/graphql_service.ts | 2 +- typegate/src/services/middlewares.ts | 16 ++- typegate/src/services/playground_service.ts | 13 +- typegate/src/services/responses.ts | 14 ++- typegate/src/typegate/mod.ts | 25 +--- typegate/src/typegate/register.ts | 37 ++++-- typegate/src/typegraph.ts | 2 - typegate/src/typegraph/versions.ts | 9 +- .../tests/runtimes/python_wasi/python_wasi.py | 2 +- .../runtimes/python_wasi/python_wasi_test.ts | 1 + .../tests/runtimes/wasmedge/rust/Cargo.toml | 2 +- typegate/tests/utils/mod.ts | 4 + typegate/tests/utils/test.ts | 2 - typegraph/core/Cargo.toml | 2 +- ...core__tests__successful_serialization.snap | 2 +- typegraph/python/pyproject.toml | 2 +- typegraph/python/typegraph/__init__.py | 2 +- typegraph/python_next/pyproject.toml | 2 +- .../python_next/typegraph_next/__init__.py | 2 +- website/docs/reference/changelog.mdx | 23 ++++ website/metatype.yaml | 2 +- whiz.yaml | 2 +- 47 files changed, 230 insertions(+), 257 deletions(-) delete mode 100644 examples/metatype.yaml delete mode 100644 typegate/src/hooks.ts create mode 100644 typegate/src/runtimes/mod.ts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dceea5e39b..692b96862d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -158,7 +158,8 @@ jobs: shared-key: ${{ runner.os }}-rust-${{ hashFiles('**/rust-toolchain.toml') }}-${{ hashFiles('**/Cargo.lock') }} - run: | # test in native rust, not in wasm for a future rust SDK - # cargo test --locked --package typegraph_core + # without --tests, the --doc is causing a link error "syntax error in VERSION script" + cargo test --locked --package typegraph_core --tests test-meta-cli: needs: changes diff --git a/Cargo.lock b/Cargo.lock index 81d09adad3..5157eac950 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -979,7 +979,7 @@ dependencies = [ [[package]] name = "common" -version = "0.1.11" +version = "0.1.12" dependencies = [ "anyhow", "base64 0.21.2", @@ -3170,7 +3170,7 @@ dependencies = [ [[package]] name = "macros" -version = "0.1.11" +version = "0.1.12" dependencies = [ "proc-macro2", "quote", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "meta-cli" -version = "0.1.11" +version = "0.1.12" dependencies = [ "anyhow", "assert_cmd", @@ -3671,7 +3671,7 @@ dependencies = [ [[package]] name = "native" -version = "0.1.11" +version = "0.1.12" dependencies = [ "anyhow", "base64 0.21.2", @@ -7392,7 +7392,7 @@ dependencies = [ [[package]] name = "typegraph_core" -version = "0.1.11" +version = "0.1.12" dependencies = [ "common", "enum_dispatch", @@ -7416,7 +7416,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "typescript" -version = "0.1.11" +version = "0.1.12" dependencies = [ "anyhow", "dprint-plugin-typescript", @@ -8273,7 +8273,7 @@ dependencies = [ [[package]] name = "xtask" -version = "0.1.11" +version = "0.1.12" dependencies = [ "anyhow", "clap", diff --git a/dev/lock.yml b/dev/lock.yml index 7136902179..7acca100d8 100644 --- a/dev/lock.yml +++ b/dev/lock.yml @@ -33,8 +33,8 @@ dev: (ARG DENO_BINDGEN_URL=).*(): DENO_BINDGEN_URL (ARG RUST_VERSION=).*(): RUST_VERSION (ARG WASMEDGE_VERSION=).*(): WASMEDGE_VERSION - typegate/src/typegraph.ts: - (export const typegraphVersion = ").*(";): TYPEGRAPH_VERSION + typegate/src/typegraph/versions.ts: + (const typegraphVersion = ").*(";): TYPEGRAPH_VERSION typegraph/python/typegraph/graph/typegraph.py: (typegraph_version = ").*("): TYPEGRAPH_VERSION typegraph/core/src/typegraph.rs: @@ -71,7 +71,7 @@ dev: WASMTIME_VERSION: 10.0.1 WASMEDGE_VERSION: 0.12.1 TYPEGRAPH_VERSION: 0.0.2 - METATYPE_VERSION: 0.1.12-0+dev + METATYPE_VERSION: 0.1.12 TAGLINE: >- Declarative API development platform. Build serverless backends with zero-trust and less code, no matter where and how your (legacy) systems diff --git a/examples/metatype.yaml b/examples/metatype.yaml deleted file mode 100644 index aea9ef5b73..0000000000 --- a/examples/metatype.yaml +++ /dev/null @@ -1,25 +0,0 @@ -typegates: - dev: - url: "http://localhost:7890" - username: admin - password: password - env: - TG_RETREND_IMGPROXY_SALT: ffb86b4e98bff8c1a44aaf66ca5636c8fd114574e1b277937fa5916837c6ef676459b96cb175e251ef4fb57cfa68740ae24b2b20c5096b64841259fc3cf1711a - TG_RETREND_IMGPROXY_SECRET: 063d3a2c90682394c0487532a7d0d9918fd761efd8d08bfe62c532736a01eadcfa3956ec7768ffa019c95e438dfbb4b3691ba7416505fb6989f9fea664b73d55 - TG_RETREND_ACCESS_KEY: minio - TG_RETREND_SECRET_KEY: password - TG_BISCUICUITS_SENDER: no-reply@metatype.dev - TG_BISCUICUITS_TO: no-reply@metatype.dev - TG_BISCUICUITS_SENDINBLUE_API_KEY: fake - TG_BISCUICUITS_GITHUB_CLIENT_ID: fake - TG_BISCUICUITS_GITHUB_CLIENT_SECRET: fake - TG_ELASTIC_CERT: "-----BEGIN CERTIFICATE-----\nMIIFWTCCA0GgAwIBAgIUZWnGpkvJcphtt0jQKN9yIPw9CKEwDQYJKoZIhvcNAQEL\nBQAwPDE6MDgGA1UEAxMxRWxhc3RpY3NlYXJjaCBzZWN1cml0eSBhdXRvLWNvbmZp\nZ3VyYXRpb24gSFRUUCBDQTAeFw0yMjEwMjUxNDUxMDdaFw0yNTEwMjQxNDUxMDda\nMDwxOjA4BgNVBAMTMUVsYXN0aWNzZWFyY2ggc2VjdXJpdHkgYXV0by1jb25maWd1\ncmF0aW9uIEhUVFAgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDE\nbVsMVOaPntg9R/8gB8idAXNKr4I+lOKyIk4c9eW/RoRpaoaZyFh68pG1IbV3MZLx\nWSSHKf/Q9Dy84OufBJ9PwqWpDix7F+L4ABgfw0GPPKm1xAuAVkFT9jtbT0NsPQsm\nv0hBH83hvLBCFOr0q6fG2/vQbRMkkw2fZKo3k7TOn89YDNKGh0g3/Yu4S7IAEyJw\nQsCJGxjixE700QWAoEcJ/7Ey5h9DQJZ9xQs4JoqfsDC1w40w6Fann3kR2qsWGyJ0\nQKwOmeagv7zc0qADdXfeuAJAy2PSxNdZUUgpomlYL48LjgQxuCp3aRRA5PKnu0pY\nw7GzKyc9Td/FD3jb1mIqb1bNqMmweWH9tPxFeSfNYuGTwQQWtcl7qBqWrDr08MB/\nKFkdbtwjewdTzBVNrSlbxKL7raEMJFubUZYYqM32tE3EfY5jm7TH3TWO+WD1yejh\nOxVf6S9ZarFJtdXi2weJHXXo85yxW+IAQxEKf1ojEx7Ju5hrfh+XoLWxfot3kHk2\n/BNyrlw5QekO6+IVrR7d3SM1slU8/UB/FC5HZYeZl+Wc0/4ICWYPRK7HPy4+DZUU\nHPXbWSZTRSJT/Z9TYFLofbtVbKZHIHAvDN9a0iTQINSHr2DroaG/KE6NtRXLfydZ\nl4A6ElzmWCkl3YfHzzchZKPVDpDd+qF7U0euoJNJPQIDAQABo1MwUTAdBgNVHQ4E\nFgQUwABfnsldWZacqMWth3C8Y42iQhswHwYDVR0jBBgwFoAUwABfnsldWZacqMWt\nh3C8Y42iQhswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAciEv\nmM3HUMdVSjWwZMAqr07UgLGGbHFfPJQweiCMNaah+HFRrOEyEru6NXeoFieHcgbn\nB1H332eJTy47uBJKAvbYwCHMe68Ll2an2OB6Vn30WrickrIWh6mPH3geeIwOU6g+\nxUdfmyiiWdPBZzne4PWr9qWNmoZYnVcC4o05NZHYH6mBXRFq4wZCVRL0TkO/eozO\nL3OnekGkevo5fhH3oUvUIb8ZGcPi8Uny8gcl2lNfy/WFlfieybF03adFPf0zC1J5\no/I65bT/NKumMtYdJvyHL+WfRpnkwjPDFCLb8hNWI0CLqDpAJaLX6AfLDlJJYuT5\nXXroMiFxioVHVoBkyJDSawRzvJa62bhhznBUSR9gYgN/XnDkbeDshQCYS4UZZFXv\nBwgDKKI+m2PkdzcqZqbpIVV+ezubsJ+gQIg5K9fRhyw7BCN/vPU23TjxQ/5Ns/Ul\npCR/bHAW9FEy/hM7qXVedmv9tJ2zOFXd/5FUn8wvQFakBBBLKqnY+ueLSCYf1g/F\n4Ex0VrZRy7pBY2/w2RSng6LEnBwRLjJnFxrvVsk9Ciqju27F7FGiHcNel8M8GiMW\n88+UN5hVddCHwVsFiiB/dGcHiAtsN3FQEkxkMWvo4PCuIU+RXPhjfr11xw0Q2F7t\nR5U+Of7xVw43UYt+2ogd87hZNMM82w6EWYICJdY=\n-----END CERTIFICATE-----" - TG_ELASTIC_BASIC: "elastic:password" - TG_BLOG_POSTGRES: "postgresql://postgres:password@localhost:5432/db?schema=blog" - -typegraphs: - python: - include: "typegraphs/**/*.py" - materializers: - prisma: - migrations_path: "prisma/migrations" diff --git a/examples/templates/new/compose.yml b/examples/templates/new/compose.yml index 4ec3f24404..4fb81b37c9 100644 --- a/examples/templates/new/compose.yml +++ b/examples/templates/new/compose.yml @@ -1,6 +1,6 @@ services: typegate: - image: ghcr.io/metatypedev/typegate:v0.1.12-0+dev + image: ghcr.io/metatypedev/typegate:v0.1.12 platform: linux/amd64 restart: always ports: diff --git a/examples/templates/new/pyproject.toml b/examples/templates/new/pyproject.toml index f6dfcdd944..9b838029eb 100644 --- a/examples/templates/new/pyproject.toml +++ b/examples/templates/new/pyproject.toml @@ -1,13 +1,13 @@ [tool.poetry] name = "example" -version = "0.1.12-0+dev" +version = "0.1.12" description = "" authors = [] readme = "README.md" [tool.poetry.dependencies] python = ">=3.8,<4.0" -typegraph = "0.1.12-0+dev" +typegraph = "0.1.12" [build-system] requires = ["poetry-core"] diff --git a/libs/common/Cargo.toml b/libs/common/Cargo.toml index 3969a63393..cf88fb24a3 100644 --- a/libs/common/Cargo.toml +++ b/libs/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "common" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" [dependencies] diff --git a/libs/macros/Cargo.toml b/libs/macros/Cargo.toml index facf76986e..b777c832f9 100644 --- a/libs/macros/Cargo.toml +++ b/libs/macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "macros" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" [lib] diff --git a/libs/typescript/Cargo.toml b/libs/typescript/Cargo.toml index 8f6f34c901..141aa79376 100644 --- a/libs/typescript/Cargo.toml +++ b/libs/typescript/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "typescript" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" [dependencies] diff --git a/libs/xtask/Cargo.toml b/libs/xtask/Cargo.toml index acea9bd9fe..1d86d13181 100644 --- a/libs/xtask/Cargo.toml +++ b/libs/xtask/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xtask" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" [dependencies] diff --git a/meta-cli/Cargo.toml b/meta-cli/Cargo.toml index 636c8dc0fb..9a16af2769 100644 --- a/meta-cli/Cargo.toml +++ b/meta-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "meta-cli" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" description = "Declarative API development platform. Build serverless backends with zero-trust and less code, no matter where and how your (legacy) systems are." diff --git a/meta-cli/src/cli/deploy.rs b/meta-cli/src/cli/deploy.rs index 16731a0802..6eb7f08a33 100644 --- a/meta-cli/src/cli/deploy.rs +++ b/meta-cli/src/cli/deploy.rs @@ -190,10 +190,8 @@ impl Deploy { trace!("Loading typegraphs..."); for path in paths.into_iter() { - info!( - "Loading typegraphs from {rel_path:?}.", - rel_path = diff_paths(&path, &self.base_dir).unwrap() - ); + let rel_path = diff_paths(&path, &self.base_dir).unwrap(); + info!("Loading typegraphs from {}.", rel_path.display()); let tgs = Self::load_typegraphs(&path, &self.base_dir, &self.loader, OnRewrite::Reload).await; let tgs = match tgs { @@ -207,6 +205,11 @@ impl Deploy { let mut tgs: VecDeque<_> = tgs.into_iter().collect(); + if tgs.is_empty() { + warn!("No typegraph found in {}.", rel_path.display()); + continue; + } + while let Some(tg) = tgs.pop_front() { let tg_name = tg.full_name().unwrap().cyan(); info!("Pushing typegraph {tg_name}..."); diff --git a/meta-cli/src/cli/serialize.rs b/meta-cli/src/cli/serialize.rs index 839a4b6c9d..6136e05778 100644 --- a/meta-cli/src/cli/serialize.rs +++ b/meta-cli/src/cli/serialize.rs @@ -81,7 +81,6 @@ impl Action for Serialize { }; if paths.is_empty() { - warn!("No typegraph definition module found."); bail!("No typegraph definition module found."); } @@ -90,7 +89,7 @@ impl Action for Serialize { match loader.load_file(&path).await { LoaderResult::Loaded(tgs) => { if tgs.is_empty() { - log::warn!("no typegraph"); + log::warn!("no typegraph in {path:?}"); } for tg in tgs.into_iter() { loaded.push(tg); diff --git a/poetry.lock b/poetry.lock index d23673d5ab..4574b28514 100644 --- a/poetry.lock +++ b/poetry.lock @@ -687,29 +687,29 @@ files = [ [[package]] name = "pathspec" -version = "0.11.1" +version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.7" files = [ - {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, - {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, ] [[package]] name = "platformdirs" -version = "3.9.1" +version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.9.1-py3-none-any.whl", hash = "sha256:ad8291ae0ae5072f66c16945166cb11c63394c7a3ad1b1bc9828ca3162da8c2f"}, - {file = "platformdirs-3.9.1.tar.gz", hash = "sha256:1b42b450ad933e981d56e59f1b97495428c9bd60698baab9f3eb3d00d5822421"}, + {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, + {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] name = "pydoc-markdown" @@ -993,7 +993,7 @@ files = [ [[package]] name = "typegraph" -version = "0.1.10" +version = "0.1.12-0+dev" description = "Declarative API development platform. Build serverless backends with zero-trust and less code, no matter where and how your (legacy) systems are." optional = false python-versions = ">=3.8,<4.0" @@ -1022,7 +1022,7 @@ url = "typegraph/python" [[package]] name = "typegraph-next" -version = "0.1.10" +version = "0.1.12-0+dev" description = "Declarative API development platform. Build serverless backends with zero-trust and less code, no matter where and how your (legacy) systems are." optional = false python-versions = ">=3.8,<4.0" @@ -1031,7 +1031,7 @@ develop = true [package.dependencies] typing-extensions = "^4.7.1" -wasmtime = "^10.0.0" +wasmtime = "^10.0.1" [package.source] type = "directory" diff --git a/pyproject.toml b/pyproject.toml index 292701927a..9faca2bb44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "metatype" -version = "0.1.12-0+dev" +version = "0.1.12" description = "" authors = [] diff --git a/typegate/native/Cargo.toml b/typegate/native/Cargo.toml index 71dd019666..9ca48c36f7 100644 --- a/typegate/native/Cargo.toml +++ b/typegate/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "native" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" [lib] diff --git a/typegate/src/hooks.ts b/typegate/src/hooks.ts deleted file mode 100644 index 106af8eae4..0000000000 --- a/typegate/src/hooks.ts +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright Metatype OÜ, licensed under the Elastic License 2.0. -// SPDX-License-Identifier: Elastic-2.0 - -import { parseGraphQLTypeGraph } from "./graphql/graphql.ts"; -import { MessageEntry, Migrations } from "./register.ts"; -import { SecretManager, TypeGraph, TypeGraphDS } from "./typegraph.ts"; -import { upgradeTypegraph } from "./typegraph/versions.ts"; -import { getLogger } from "./log.ts"; -import { Logger } from "std/log/mod.ts"; - -const Message = { - INFO: "info", - WARNING: "warning", - ERROR: "error", -} as const; - -export class PushResponse { - messages: MessageEntry[] = []; - migrations: Migrations[] = []; - resetRequired: string[] = []; - logger: Logger; - - constructor(public readonly tgName: string) { - this.logger = getLogger(`hooks:${tgName}`); - } - - info(text: string) { - this.logger.info(text); - this.messages.push({ type: Message.INFO, text }); - } - - warn(text: string) { - this.logger.warning(text); - this.messages.push({ type: Message.WARNING, text }); - } - - error(text: string) { - this.logger.error(text); - this.messages.push({ type: Message.ERROR, text }); - } - - migration(rtName: string, migrations: string) { - this.migrations.push({ - runtime: rtName, - migrations, - }); - } - - resetDb(rtName: string) { - this.resetRequired.push(rtName); - } - - hasError() { - return this.messages.some((e) => e.type === Message.ERROR); - } -} - -interface PushHandler { - ( - tg: TypeGraphDS, - secretManager: SecretManager, - response: PushResponse, - ): Promise; -} - -interface InitHandler { - (tg: TypeGraph, secretManager: SecretManager, sync: boolean): Promise; -} - -interface Hooks { - onPush: PushHandler[]; // before redis synchronization -- only once - onInit: InitHandler[]; // after redis sync -- run on each typegate instance -} - -const hooks: Hooks = { - onPush: [ - (tg) => Promise.resolve(upgradeTypegraph(tg)), - (tg) => Promise.resolve(parseGraphQLTypeGraph(tg)), - ], - onInit: [], -}; - -export function registerHook(when: "onPush", handler: PushHandler): void; -export function registerHook(when: "onInit", handler: InitHandler): void; -export function registerHook( - when: keyof Hooks, - handler: Hooks[keyof Hooks][number], -): void { - (hooks[when] as unknown[]).push(handler); -} - -export async function handleOnPushHooks( - typegraph: TypeGraphDS, - secretManager: SecretManager, - response: PushResponse, -): Promise { - let res = typegraph; - - for (const handler of hooks.onPush) { - res = await handler(res, secretManager, response); - } - - return res; -} - -export async function handleOnInitHooks( - typegraph: TypeGraph, - secretManager: SecretManager, - sync: boolean, -): Promise { - await Promise.all( - hooks.onInit.map((handler) => handler(typegraph, secretManager, sync)), - ); -} diff --git a/typegate/src/log.ts b/typegate/src/log.ts index 291a03aaed..f06b059766 100644 --- a/typegate/src/log.ts +++ b/typegate/src/log.ts @@ -93,10 +93,18 @@ if (!config.rust_log) { const consoleHandler = new handlers.ConsoleHandler( config.log_level as LevelName, { - formatter: (log) => - `${log.datetime.toISOString()} ${log.levelName.padEnd(5)} ${ - log.loggerName.padEnd(12) - } ${log.msg}`, + formatter: (log) => { + let msg = log.msg; + for (const arg of log.args) { + msg = msg.replace( + "{}", + typeof arg === "string" ? arg : JSON.stringify(arg), + ); + } + return `${log.datetime.toISOString()} ${log.levelName.padEnd(5)} ${ + log.loggerName.padEnd(16) + } ${msg}`; + }, }, ); diff --git a/typegate/src/main.ts b/typegate/src/main.ts index 52b43f8b6a..04094dcf7b 100644 --- a/typegate/src/main.ts +++ b/typegate/src/main.ts @@ -12,6 +12,7 @@ import { RedisRateLimiter } from "./typegate/rate_limiter.ts"; import { SystemTypegraph } from "./system_typegraphs.ts"; import * as Sentry from "sentry"; import { getLogger } from "./log.ts"; +import { init_runtimes } from "./runtimes/mod.ts"; const logger = getLogger(import.meta); logger.info(`typegate v${config.version} starting`); @@ -26,7 +27,7 @@ Sentry.init({ new Sentry.Integrations.Context({ app: true, os: true, - device: false, // off due to buggy/unstable "TypeError: DenoOsUptime is not a function" + device: true, culture: true, }), ], @@ -42,17 +43,24 @@ addEventListener("unhandledrejection", (e) => { // init rust native libs init_native(); +// load all runtimes +await init_runtimes(); + const deferredTypegate = deferred(); const register = await ReplicatedRegister.init( - () => deferredTypegate, + deferredTypegate, redisConfig, ); -register.startSync(); - const limiter = await RedisRateLimiter.init(redisConfig); - const typegate = new Typegate(register, limiter); deferredTypegate.resolve(typegate); + +const lastSync = await register.historySync().catch((err) => { + logger.error(err); + throw new Error(`failed to load history at boot, aborting: {err.message}`); +}); +register.startSync(lastSync); + await SystemTypegraph.loadAll(typegate, !config.packaged); const server = serve( diff --git a/typegate/src/replicated_map.ts b/typegate/src/replicated_map.ts index 62257babc7..0ee95ae1f6 100644 --- a/typegate/src/replicated_map.ts +++ b/typegate/src/replicated_map.ts @@ -5,7 +5,7 @@ import { connect, Redis, RedisConnectOptions, XIdInput } from "redis"; import * as Sentry from "sentry"; import { getLogger } from "./log.ts"; -const logger = getLogger("sync"); +const logger = getLogger(import.meta); type SyncContext = { start: (cursor: XIdInput) => AsyncIterableIterator>; @@ -27,6 +27,9 @@ redis.call('HDEL', KEYS[1], ARGV[1]) redis.call('XADD', KEYS[2], 'MAXLEN', '~', '10000', '*', 'name', ARGV[1], 'event', '${RM}', 'instance', ARGV[2]) `.trim(); +type Serializer = (elem: T) => Promise | string; +type Deserializer = (value: string, initialLoad: boolean) => Promise | T; + export class RedisReplicatedMap { instance: string; redis: Redis; @@ -34,16 +37,16 @@ export class RedisReplicatedMap { memory: Map; key: string; ekey: string; - serializer: (elem: T) => Promise | string; - deserializer: (value: string) => Promise | T; + serializer: Serializer; + deserializer: Deserializer; sync: SyncContext | null; private constructor( name: string, redis: Redis, redisObs: Redis, - serializer: (elem: T) => Promise | string, - deserializer: (value: string) => Promise | T, + serializer: Serializer, + deserializer: Deserializer, ) { this.instance = crypto.randomUUID(); this.redis = redis; @@ -59,8 +62,8 @@ export class RedisReplicatedMap { static async init( name: string, connection: RedisConnectOptions, - serializer: (elem: T) => Promise | string, - deserializer: (value: string) => Promise | T, + serializer: Serializer, + deserializer: Deserializer, ) { // needs two connections because // 1. xread with block delays other commands @@ -77,25 +80,37 @@ export class RedisReplicatedMap { ); } - async startSync() { - if (this.sync) { - return; - } + async historySync(): Promise { const { key, redis, memory, deserializer } = this; - this.sync = this.subscribe(); + // get last received message before loading history const [lastMessage] = await redis.xrevrange(this.ekey, "+", "-", 1); + const lastId = lastMessage ? lastMessage.xid : 0; + logger.debug("last message loaded: {}", lastId); + const all = await redis.hgetall(key); + logger.debug("history load start: {} elements", all.length); for (let i = 0; i < all.length; i += 2) { const name = all[i]; const payload = all[i + 1]; logger.info(`reloaded addition: ${name}`); - memory.set(name, await deserializer(payload)); + memory.set(name, await deserializer(payload, true)); } + logger.debug("history load end"); + return lastId; + } + + // never ending function + async startSync(xid: XIdInput): Promise { + if (this.sync) { + return; + } + const { key, redis, memory, deserializer } = this; + this.sync = this.subscribe(); for await ( const { name, event, instance } of this.sync.start( - lastMessage ? lastMessage.xid : 0, + xid, ) ) { if (this.instance == instance) { @@ -108,7 +123,7 @@ export class RedisReplicatedMap { } logger.info(`received addition: ${name}`); - memory.set(name, await deserializer(payload)); + memory.set(name, await deserializer(payload, false)); } else if (event === RM) { logger.info(`received removal: ${name}`); memory.delete(name); diff --git a/typegate/src/runtimes/mod.ts b/typegate/src/runtimes/mod.ts new file mode 100644 index 0000000000..5e26a77857 --- /dev/null +++ b/typegate/src/runtimes/mod.ts @@ -0,0 +1,14 @@ +// Copyright Metatype OÜ, licensed under the Elastic License 2.0. +// SPDX-License-Identifier: Elastic-2.0 + +import { dirname, fromFileUrl, resolve } from "std/path/mod.ts"; + +const localDir = dirname(fromFileUrl(import.meta.url)); + +export async function init_runtimes(): Promise { + for await (const file of Deno.readDir(localDir)) { + if (file.isFile && file.name.endsWith(".ts") && file.name !== "mod.ts") { + await import(resolve(localDir, file.name)); + } + } +} diff --git a/typegate/src/services/auth/mod.ts b/typegate/src/services/auth/mod.ts index 875d63c673..badf283a1e 100644 --- a/typegate/src/services/auth/mod.ts +++ b/typegate/src/services/auth/mod.ts @@ -98,7 +98,7 @@ export async function handleAuth( headers: Headers, ): Promise { if (request.method !== "GET") { - return methodNotAllowed; + return methodNotAllowed(); } const url = new URL(request.url); diff --git a/typegate/src/services/auth/protocols/jwt.ts b/typegate/src/services/auth/protocols/jwt.ts index 8d50c8be6d..ba2f230f2c 100644 --- a/typegate/src/services/auth/protocols/jwt.ts +++ b/typegate/src/services/auth/protocols/jwt.ts @@ -8,7 +8,7 @@ import { Protocol } from "./protocol.ts"; import { DenoRuntime } from "../../../runtimes/deno/deno.ts"; import { Auth } from "../../../types/typegraph.ts"; -const logger = getLogger(import.meta.url); +const logger = getLogger(import.meta); const encoder = new TextEncoder(); export class JWTAuth extends Protocol { diff --git a/typegate/src/services/auth/protocols/oauth2.ts b/typegate/src/services/auth/protocols/oauth2.ts index 3917a21c01..887869f222 100644 --- a/typegate/src/services/auth/protocols/oauth2.ts +++ b/typegate/src/services/auth/protocols/oauth2.ts @@ -16,7 +16,7 @@ import { Protocol } from "./protocol.ts"; import { DenoRuntime } from "../../../runtimes/deno/deno.ts"; import { Auth, Materializer } from "../../../types/typegraph.ts"; -const logger = getLogger(import.meta.url); +const logger = getLogger(import.meta); export class OAuth2Auth extends Protocol { static init( diff --git a/typegate/src/services/auth/protocols/protocol.ts b/typegate/src/services/auth/protocols/protocol.ts index 156eec3057..12b5b2f296 100644 --- a/typegate/src/services/auth/protocols/protocol.ts +++ b/typegate/src/services/auth/protocols/protocol.ts @@ -7,7 +7,7 @@ export abstract class Protocol { protected constructor(public typegraphName: string) {} authMiddleware(_request: Request): Promise { - return Promise.resolve(notFound); + return Promise.resolve(notFound()); } abstract tokenMiddleware( diff --git a/typegate/src/services/graphql_service.ts b/typegate/src/services/graphql_service.ts index 3ee66627ab..a4b4c09116 100644 --- a/typegate/src/services/graphql_service.ts +++ b/typegate/src/services/graphql_service.ts @@ -12,7 +12,7 @@ import { Engine } from "../engine.ts"; import * as ast from "graphql/ast"; import { BadContext, ResolverError } from "../errors.ts"; -const logger = getLogger("graphql"); +const logger = getLogger(import.meta); export function isIntrospectionQuery( operation: ast.OperationDefinitionNode, diff --git a/typegate/src/services/middlewares.ts b/typegate/src/services/middlewares.ts index eed7caac3b..8cee7c0aff 100644 --- a/typegate/src/services/middlewares.ts +++ b/typegate/src/services/middlewares.ts @@ -4,6 +4,10 @@ import { ConnInfo } from "std/http/server.ts"; import config from "../config.ts"; import { Engine } from "../engine.ts"; +import { getLogger } from "../log.ts"; + +const logger = getLogger(import.meta); + export function baseUrl(request: Request): string { const { headers, url } = request; @@ -22,7 +26,17 @@ export function resolveIdentifier( connInfo: ConnInfo, ): string { if (engine.tg.tg.meta.rate?.context_identifier) { - return context[engine.tg.tg.meta.rate?.context_identifier] as string; + const contextId = context[engine.tg.tg.meta.rate?.context_identifier] as + | string + | undefined; + if (contextId) { + if (typeof contextId === "string") { + return contextId; + } + logger.warning( + `invalid context identifier type at ${engine.tg.tg.meta.rate?.context_identifier}, only string is supported, got: ${contextId}`, + ); + } } if (config.trust_proxy) { diff --git a/typegate/src/services/playground_service.ts b/typegate/src/services/playground_service.ts index de1a0a5396..d47b12b67b 100644 --- a/typegate/src/services/playground_service.ts +++ b/typegate/src/services/playground_service.ts @@ -1,6 +1,7 @@ // Copyright Metatype OÜ, licensed under the Elastic License 2.0. // SPDX-License-Identifier: Elastic-2.0 +import config from "../config.ts"; import { Engine } from "../engine.ts"; import { baseUrl } from "./middlewares.ts"; @@ -9,6 +10,9 @@ export const handlePlaygroundGraphQL = ( engine: Engine, ): Response => { const url = `${baseUrl(request)}/${engine.name}`; + const auth = engine.name === "typegate" && config.debug + ? "Basic YWRtaW46cGFzc3dvcmQ=" + : ""; const html = ` @@ -77,8 +81,15 @@ export const handlePlaygroundGraphQL = ( const fetcher = GraphiQL.createFetcher({ url: "${url}" }); + const headers = localStorage.getItem("graphiql:headers") || JSON.stringify({ + Authorization: "${auth}", + }, null, 2); const app = ( - +
diff --git a/typegate/src/services/responses.ts b/typegate/src/services/responses.ts index 5ecce9b2e5..f491905df4 100644 --- a/typegate/src/services/responses.ts +++ b/typegate/src/services/responses.ts @@ -1,10 +1,12 @@ // Copyright Metatype OÜ, licensed under the Elastic License 2.0. // SPDX-License-Identifier: Elastic-2.0 -export const notFound = new Response("not found", { - status: 404, -}); +export const notFound = () => + new Response("not found", { + status: 404, + }); -export const methodNotAllowed = new Response("method not allowed", { - status: 405, -}); +export const methodNotAllowed = () => + new Response("method not allowed", { + status: 405, + }); diff --git a/typegate/src/typegate/mod.ts b/typegate/src/typegate/mod.ts index 2df86ebf0e..c9eb93c735 100644 --- a/typegate/src/typegate/mod.ts +++ b/typegate/src/typegate/mod.ts @@ -24,7 +24,7 @@ import { } from "../typegraph.ts"; import { SystemTypegraph } from "../system_typegraphs.ts"; import { TypeGraphRuntime } from "../runtimes/typegraph.ts"; -import { dirname, fromFileUrl, join, resolve } from "std/path/mod.ts"; +import { dirname, fromFileUrl, join } from "std/path/mod.ts"; import { RuntimeInit, RuntimeInitParams } from "../types.ts"; import { Runtime } from "../runtimes/Runtime.ts"; import { parseTypegraph } from "../typegraph/parser.ts"; @@ -61,23 +61,10 @@ export class Typegate { this.#registeredRuntimes.set(name, init); } - static async registerRuntimes() { - const runtimesDir = resolve(localDir, "../runtimes"); - for await (const file of Deno.readDir(runtimesDir)) { - if (file.isFile && file.name.endsWith(".ts")) { - await import(resolve(runtimesDir, file.name)); - } - } - } - static async initRuntime( name: string, params: RuntimeInitParams, ): Promise { - if (this.#registeredRuntimes.size === 0) { - await this.registerRuntimes(); - } - const init = this.#registeredRuntimes.get(name); if (!init) { throw new Error(`Runtime ${name} is not registered`); @@ -142,12 +129,12 @@ export class Typegate { const [engineName, serviceName] = parsePath(url.pathname); if (!engineName || ignoreList.has(engineName)) { - return notFound; + return notFound(); } const engine = this.register.get(engineName); if (!engine) { - return notFound; + return notFound(); } const cors = engine.tg.cors(request); @@ -179,7 +166,7 @@ export class Typegate { } if (serviceName !== undefined) { - return notFound; + return notFound(); } // default to graphql service @@ -188,11 +175,11 @@ export class Typegate { } if (!engine.tg.tg.meta.queries.dynamic) { - return notFound; + return notFound(); } if (request.method !== "POST") { - return methodNotAllowed; + return methodNotAllowed(); } return handleGraphQL( diff --git a/typegate/src/typegate/register.ts b/typegate/src/typegate/register.ts index 72f71d7531..d21456d4dd 100644 --- a/typegate/src/typegate/register.ts +++ b/typegate/src/typegate/register.ts @@ -3,11 +3,15 @@ import { Engine } from "../engine.ts"; import { RedisReplicatedMap } from "../replicated_map.ts"; -import { RedisConnectOptions } from "redis"; +import { RedisConnectOptions, XIdInput } from "redis"; import { SystemTypegraph } from "../system_typegraphs.ts"; import { decrypt, encrypt } from "../crypto.ts"; import { SecretManager, TypeGraphDS } from "../typegraph.ts"; import { Typegate } from "./mod.ts"; +import { + isTypegraphUpToDate, + upgradeTypegraph, +} from "../typegraph/versions.ts"; export interface MessageEntry { type: "info" | "warning" | "error"; @@ -33,7 +37,7 @@ export abstract class Register { export class ReplicatedRegister extends Register { static async init( - getTypegate: () => Promise, + deferredTypegate: Promise, redisConfig: RedisConnectOptions, ): Promise { const replicatedMap = await RedisReplicatedMap.init( @@ -45,22 +49,33 @@ export class ReplicatedRegister extends Register { ); return JSON.stringify([engine.tg.tg, encryptedSecrets]); }, - async (json: string) => { - const typegate = await getTypegate(); + async (json: string, initialLoad: boolean) => { + const typegate = await deferredTypegate; const [tg, encryptedSecrets] = JSON.parse(json) as [ TypeGraphDS, string, ]; const secrets = JSON.parse(await decrypt(encryptedSecrets)); - // typegraph name without prefix + + // typegraph is updated while being pushed, this is only for iniial load + const hasUpgrade = initialLoad && isTypegraphUpToDate(tg); + + // name without prefix const secretManager = new SecretManager(tg.types[0].title, secrets); - return typegate.initEngine( - tg, + const engine = await typegate.initEngine( + hasUpgrade ? upgradeTypegraph(tg) : tg, secretManager, true, SystemTypegraph.getCustomRuntimes(typegate), true, ); + + if (hasUpgrade) { + // update typegraph in storage, will trigger replica reloads but that's ok + replicatedMap.set(engine.name, engine); + } + + return engine; }, ); @@ -100,7 +115,11 @@ export class ReplicatedRegister extends Register { return this.replicatedMap.has(name); } - startSync(): void { - this.replicatedMap.startSync(); + historySync(): Promise { + return this.replicatedMap.historySync(); + } + + startSync(xid: XIdInput): void { + void this.replicatedMap.startSync(xid); } } diff --git a/typegate/src/typegraph.ts b/typegate/src/typegraph.ts index 0bdcdb4b6a..1b2b5e9e54 100644 --- a/typegate/src/typegraph.ts +++ b/typegate/src/typegraph.ts @@ -47,8 +47,6 @@ export { Cors, Rate, TypeGraphDS, TypeMaterializer, TypePolicy, TypeRuntime }; export type RuntimeResolver = Record; -export const typegraphVersion = "0.0.2"; - export class SecretManager { constructor( private typegraph: string, diff --git a/typegate/src/typegraph/versions.ts b/typegate/src/typegraph/versions.ts index 31ac8fd557..e0081d05fc 100644 --- a/typegate/src/typegraph/versions.ts +++ b/typegate/src/typegraph/versions.ts @@ -1,10 +1,12 @@ // Copyright Metatype OÜ, licensed under the Elastic License 2.0. // SPDX-License-Identifier: Elastic-2.0 -import { TypeGraph, TypeGraphDS, typegraphVersion } from "../typegraph.ts"; +import { TypeGraph, TypeGraphDS } from "../typegraph.ts"; import config from "../config.ts"; import * as semver from "std/semver/mod.ts"; +const typegraphVersion = "0.0.2"; + const typegraphChangelog: Record< string, { next: string; transform: (x: any) => TypeGraphDS } @@ -27,6 +29,11 @@ const typegraphChangelog: Record< }, }; +export function isTypegraphUpToDate(typegraph: TypeGraphDS): boolean { + const { meta } = typegraph; + return semver.eq(semver.parse(typegraphVersion), semver.parse(meta.version)); +} + export function upgradeTypegraph(typegraph: TypeGraphDS): TypeGraphDS { const typegraphName = TypeGraph.formatName(typegraph); const { meta } = typegraph; diff --git a/typegate/tests/runtimes/python_wasi/python_wasi.py b/typegate/tests/runtimes/python_wasi/python_wasi.py index dca571c2e7..73e50f4989 100644 --- a/typegate/tests/runtimes/python_wasi/python_wasi.py +++ b/typegate/tests/runtimes/python_wasi/python_wasi.py @@ -1,5 +1,5 @@ from typegraph import TypeGraph, policies, t -from typegraph.runtimes.python import Python, PyModuleMat +from typegraph.runtimes.python import PyModuleMat, Python def test(x): diff --git a/typegate/tests/runtimes/python_wasi/python_wasi_test.ts b/typegate/tests/runtimes/python_wasi/python_wasi_test.ts index eb93d42d35..863f961df5 100644 --- a/typegate/tests/runtimes/python_wasi/python_wasi_test.ts +++ b/typegate/tests/runtimes/python_wasi/python_wasi_test.ts @@ -138,6 +138,7 @@ Meta.test("Python WASI runtime", async (t) => { const end = performance.now(); const duration = end - start; + console.log(`duration: ${duration}ms`); assert(duration < 600, `Python WASI runtime was too slow: ${duration}ms`); }); }); diff --git a/typegate/tests/runtimes/wasmedge/rust/Cargo.toml b/typegate/tests/runtimes/wasmedge/rust/Cargo.toml index ea922f702c..96d7a16b15 100644 --- a/typegate/tests/runtimes/wasmedge/rust/Cargo.toml +++ b/typegate/tests/runtimes/wasmedge/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rust" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" [lib] diff --git a/typegate/tests/utils/mod.ts b/typegate/tests/utils/mod.ts index 92b084dd79..0512d894db 100644 --- a/typegate/tests/utils/mod.ts +++ b/typegate/tests/utils/mod.ts @@ -15,10 +15,14 @@ import { test } from "./test.ts"; import { meta } from "./meta.ts"; import { testDir } from "./dir.ts"; import { autoTest } from "./autotest.ts"; +import { init_runtimes } from "../../src/runtimes/mod.ts"; // native must load first to avoid import race conditions and panic init_native(); +// same for loading runtimes +await init_runtimes(); + export function gql(query: readonly string[], ...args: any[]) { const template = query .map((q, i) => `${q}${args[i] ? JSON.stringify(args[i]) : ""}`) diff --git a/typegate/tests/utils/test.ts b/typegate/tests/utils/test.ts index 1a8355e26b..ea6512455a 100644 --- a/typegate/tests/utils/test.ts +++ b/typegate/tests/utils/test.ts @@ -208,8 +208,6 @@ export const test = ((name, fn, opts = {}): void => { return Deno.test({ name, async fn(t) { - await Typegate.registerRuntimes(); - const typegate = new Typegate(new MemoryRegister(), new NoLimiter()); const { systemTypegraphs = false, diff --git a/typegraph/core/Cargo.toml b/typegraph/core/Cargo.toml index 16fdce82a8..ca33b23758 100644 --- a/typegraph/core/Cargo.toml +++ b/typegraph/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "typegraph_core" -version = "0.1.12-0+dev" +version = "0.1.12" edition = "2021" [lib] diff --git a/typegraph/core/src/snapshots/typegraph_core__tests__successful_serialization.snap b/typegraph/core/src/snapshots/typegraph_core__tests__successful_serialization.snap index 7897f2818c..b6439b8370 100644 --- a/typegraph/core/src/snapshots/typegraph_core__tests__successful_serialization.snap +++ b/typegraph/core/src/snapshots/typegraph_core__tests__successful_serialization.snap @@ -2,4 +2,4 @@ source: typegraph/core/src/lib.rs expression: typegraph --- -{"$id":"https://metatype.dev/specs/0.0.2.json","types":[{"type":"object","title":"test","runtime":0,"policies":[],"config":{},"as_id":false,"properties":{"one":1},"required":["one"]},{"type":"function","title":"func_3","runtime":0,"policies":[],"config":{},"as_id":false,"input":2,"output":4,"materializer":0,"rate_weight":null,"rate_calls":false},{"type":"object","title":"object_2","runtime":0,"policies":[],"config":{},"as_id":false,"properties":{"one":3,"two":4},"required":[]},{"type":"integer","title":"integer_0","runtime":0,"policies":[],"config":{},"as_id":false},{"type":"integer","title":"integer_1","runtime":0,"policies":[],"config":{},"as_id":false,"minimum":12,"maximum":44}],"materializers":[{"name":"function","runtime":0,"effect":{"effect":"none","idempotent":true},"data":{"script":"var _my_lambda = () => 12","secrets":[]}}],"runtimes":[{"name":"deno","data":{"worker":"default"}}],"policies":[],"meta":{"prefix":null,"secrets":[],"queries":{"dynamic":true,"endpoints":[]},"cors":{"allow_origin":[],"allow_headers":[],"expose_headers":[],"allow_methods":[],"allow_credentials":false,"max_age_sec":null},"auths":[],"rate":null,"version":"0.0.2"}} +{"$id":"https://metatype.dev/specs/0.0.2.json","types":[{"type":"object","title":"test","runtime":0,"policies":[],"config":{},"as_id":false,"properties":{"one":1},"required":["one"]},{"type":"function","title":"func_3","runtime":0,"policies":[],"config":{},"as_id":false,"input":2,"output":4,"materializer":0,"rate_weight":null,"rate_calls":false},{"type":"object","title":"object_2","runtime":0,"policies":[],"config":{},"as_id":false,"properties":{"one":3,"two":4},"required":[]},{"type":"integer","title":"integer_0","runtime":0,"policies":[],"config":{},"as_id":false},{"type":"integer","title":"integer_1","runtime":0,"policies":[],"config":{},"as_id":false,"minimum":12,"maximum":44}],"materializers":[{"name":"function","runtime":0,"effect":{"effect":"none","idempotent":true},"data":{"script":"var _my_lambda = () => 12","secrets":[]}}],"runtimes":[{"name":"deno","data":{"worker":"default","permissions":{}}}],"policies":[],"meta":{"prefix":null,"secrets":[],"queries":{"dynamic":true,"endpoints":[]},"cors":{"allow_origin":[],"allow_headers":[],"expose_headers":[],"allow_methods":[],"allow_credentials":false,"max_age_sec":null},"auths":[],"rate":null,"version":"0.0.2"}} diff --git a/typegraph/python/pyproject.toml b/typegraph/python/pyproject.toml index ad0c17169d..fa3fb9312c 100644 --- a/typegraph/python/pyproject.toml +++ b/typegraph/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "typegraph" -version = "0.1.12-0+dev" +version = "0.1.12" description = "Declarative API development platform. Build serverless backends with zero-trust and less code, no matter where and how your (legacy) systems are." authors = ["Metatype Contributors "] license = "MPL-2.0" diff --git a/typegraph/python/typegraph/__init__.py b/typegraph/python/typegraph/__init__.py index 8cd0fea89f..dff9983c5b 100644 --- a/typegraph/python/typegraph/__init__.py +++ b/typegraph/python/typegraph/__init__.py @@ -5,4 +5,4 @@ from typegraph import types as t # noqa from typegraph.graph.typegraph import TypeGraph # noqa -version = "0.1.12-0+dev" +version = "0.1.12" diff --git a/typegraph/python_next/pyproject.toml b/typegraph/python_next/pyproject.toml index 818cc09055..4795634604 100644 --- a/typegraph/python_next/pyproject.toml +++ b/typegraph/python_next/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "typegraph_next" -version = "0.1.12-0+dev" +version = "0.1.12" description = "Declarative API development platform. Build serverless backends with zero-trust and less code, no matter where and how your (legacy) systems are." authors = ["Metatype Contributors "] license = "MPL-2.0" diff --git a/typegraph/python_next/typegraph_next/__init__.py b/typegraph/python_next/typegraph_next/__init__.py index 1ae40caf1b..fbd829c516 100644 --- a/typegraph/python_next/typegraph_next/__init__.py +++ b/typegraph/python_next/typegraph_next/__init__.py @@ -3,4 +3,4 @@ from typegraph_next.graph.typegraph import typegraph # noqa -version = "0.1.12-0+dev" +version = "0.1.12" diff --git a/website/docs/reference/changelog.mdx b/website/docs/reference/changelog.mdx index 07142088cc..15ea081266 100644 --- a/website/docs/reference/changelog.mdx +++ b/website/docs/reference/changelog.mdx @@ -7,6 +7,29 @@ comments: false +## [v0.1.11](https://github.com/metatypedev/metatype/releases/tag/v0.1.11) (8/2/2023) + + + +### What's Changed + +#### New features 🎉 + +* docs: Documentation for types by @Natoandro in [#348](https://github.com/metatypedev/metatype/pull/348) +* feat(Deno): support deno function defined in multiple files by @afmika in [#345](https://github.com/metatypedev/metatype/pull/345) +* feat: improve SDKs and rest support by @zifeo in [#350](https://github.com/metatypedev/metatype/pull/350) +* fix: Ensure hooks logging by @Natoandro in [#357](https://github.com/metatypedev/metatype/pull/357) +* feat: wit component 3 by @zifeo in [#366](https://github.com/metatypedev/metatype/pull/366) +* feat(gate): generate openapi over rest endpoints by @afmika in [#365](https://github.com/metatypedev/metatype/pull/365) +* fix: enable introspection on system typegraphs by @afmika in [#373](https://github.com/metatypedev/metatype/pull/373) +* docs: move some examples typegraph into how to guides reference or tests by @afmika in [#374](https://github.com/metatypedev/metatype/pull/374) +* feat: Customize the generated prisma schema with the target database by @Natoandro in [#359](https://github.com/metatypedev/metatype/pull/359) +* feat(wasi): add support for python def and python module by @afmika in [#360](https://github.com/metatypedev/metatype/pull/360) +* feat: improve installer script + release 0.1.11 by @zifeo in [#381](https://github.com/metatypedev/metatype/pull/381) + + +**Full Changelog**: [v0.1.10...v0.1.11](https://github.com/metatypedev/metatype/compare/v0.1.10...v0.1.11) + ## [v0.1.10](https://github.com/metatypedev/metatype/releases/tag/v0.1.10) (6/29/2023) diff --git a/website/metatype.yaml b/website/metatype.yaml index 6701cf0fc4..2ce87f80a8 100644 --- a/website/metatype.yaml +++ b/website/metatype.yaml @@ -30,7 +30,7 @@ typegates: TG_RETREND_S3_REGION: local TG_RETREND_S3_ACCESS_KEY: minio TG_RETREND_S3_SECRET_KEY: password - deploy: + prd: url: https://demo.metatype.dev username: admin password: infisical://app.infisical.com/643057c5bb17b13ef6e73d99/prod/TG_ADMIN_PASSWORD diff --git a/whiz.yaml b/whiz.yaml index fe3d784179..18a12d22c9 100644 --- a/whiz.yaml +++ b/whiz.yaml @@ -64,7 +64,7 @@ typegate_native: env: OUT_DIR: "target" command: | - rm -rfv $(deno info --json | jq -r .denoDir)/plug/file native/bindings.json + rm -rfv $(deno info --json | jq -r .denoDir)/plug/file typegate/native/bindings.json deno_bindgen -- -p native -F deno depends_on: - libs