From 89136c6375837a8bfb2f1b97675488a1330bfc97 Mon Sep 17 00:00:00 2001 From: afmika Date: Mon, 5 Feb 2024 17:59:30 +0300 Subject: [PATCH 01/21] feat(sdk/prisma): prepare interfaces --- examples/deploy/deploy.mjs | 7 +++- typegraph/core/src/typegraph.rs | 6 ++- typegraph/core/src/utils/postprocess/mod.rs | 1 + .../core/src/utils/postprocess/prisma_rt.rs | 29 +++++++++++++ typegraph/core/wit/typegraph.wit | 21 ++++++++-- typegraph/node/sdk/src/tg_deploy.ts | 6 ++- typegraph/node/sdk/src/typegraph.ts | 31 ++++++++------ typegraph/python/typegraph/graph/tg_deploy.py | 4 +- typegraph/python/typegraph/graph/typegraph.py | 41 ++++++++++++------- 9 files changed, 111 insertions(+), 35 deletions(-) create mode 100644 typegraph/core/src/utils/postprocess/prisma_rt.rs diff --git a/examples/deploy/deploy.mjs b/examples/deploy/deploy.mjs index e079ed5d15..e37a388e74 100644 --- a/examples/deploy/deploy.mjs +++ b/examples/deploy/deploy.mjs @@ -61,8 +61,13 @@ tgDeploy(tg, { username: "admin", password: "password", }, + artifactsConfig: { + prismaMigration: { + action: "create", + pathDir: "./migrations" + } + } }).then((result) => { console.log("gate:", result); - // console.log(result, tg); }) .catch(console.error); diff --git a/typegraph/core/src/typegraph.rs b/typegraph/core/src/typegraph.rs index ddf1de65a9..a3d8d8c336 100644 --- a/typegraph/core/src/typegraph.rs +++ b/typegraph/core/src/typegraph.rs @@ -6,6 +6,7 @@ use crate::conversion::types::TypeConversion; use crate::global_store::SavedState; use crate::types::{TypeDef, TypeDefExt, TypeId}; use crate::utils::postprocess::deno_rt::DenoProcessor; +use crate::utils::postprocess::prisma_rt::PrismaProcessor; use crate::utils::postprocess::python_rt::PythonProcessor; use crate::utils::postprocess::wasmedge_rt::WasmedgeProcessor; use crate::utils::postprocess::PostProcessor; @@ -217,10 +218,13 @@ pub fn finalize(mode: TypegraphFinalizeMode) -> Result { }; match mode { - TypegraphFinalizeMode::ResolveArtifacts => { + TypegraphFinalizeMode::ResolveArtifacts(config) => { DenoProcessor.postprocess(&mut tg)?; PythonProcessor.postprocess(&mut tg)?; WasmedgeProcessor.postprocess(&mut tg)?; + if let Some(config) = config { + PrismaProcessor::new(config.prisma_migration).postprocess(&mut tg)?; + } } TypegraphFinalizeMode::Simple => {} } diff --git a/typegraph/core/src/utils/postprocess/mod.rs b/typegraph/core/src/utils/postprocess/mod.rs index 1b9c2bbe13..f0684e85e3 100644 --- a/typegraph/core/src/utils/postprocess/mod.rs +++ b/typegraph/core/src/utils/postprocess/mod.rs @@ -5,6 +5,7 @@ use crate::utils::fs_host; use common::typegraph::Typegraph; use std::path::Path; pub mod deno_rt; +pub mod prisma_rt; pub mod python_rt; pub mod wasmedge_rt; diff --git a/typegraph/core/src/utils/postprocess/prisma_rt.rs b/typegraph/core/src/utils/postprocess/prisma_rt.rs new file mode 100644 index 0000000000..162f06692c --- /dev/null +++ b/typegraph/core/src/utils/postprocess/prisma_rt.rs @@ -0,0 +1,29 @@ +// Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0. +// SPDX-License-Identifier: MPL-2.0 + +use common::typegraph::Typegraph; + +use crate::utils::postprocess::PostProcessor; +use crate::wit::core::MigrationConfig; + +pub struct PrismaProcessor { + #[allow(unused)] + config: MigrationConfig, +} + +impl PrismaProcessor { + pub fn new(config: MigrationConfig) -> Self { + Self { config } + } +} + +impl PostProcessor for PrismaProcessor { + fn postprocess(self, _tg: &mut Typegraph) -> Result<(), String> { + Ok(()) + } +} + +// TODO: +// reset +// create +// +take basedir into account diff --git a/typegraph/core/wit/typegraph.wit b/typegraph/core/wit/typegraph.wit index b763e70c13..f82211d525 100644 --- a/typegraph/core/wit/typegraph.wit +++ b/typegraph/core/wit/typegraph.wit @@ -34,12 +34,27 @@ interface core { rate: option, } - enum typegraph-finalize-mode { + init-typegraph: func(params: typegraph-init-params) -> result<_, error> + + enum migration-action { + create, + reset + } + + record migration-config { + path-dir: string, + action: migration-action + } + + record artifact-resolution-config { + prisma-migration: migration-config + } + + variant typegraph-finalize-mode { simple, - resolve-artifacts + resolve-artifacts(option) } - init-typegraph: func(params: typegraph-init-params) -> result<_, error> finalize-typegraph: func(mode: typegraph-finalize-mode) -> result type type-id = u32 diff --git a/typegraph/node/sdk/src/tg_deploy.ts b/typegraph/node/sdk/src/tg_deploy.ts index 20f593b88a..872485c725 100644 --- a/typegraph/node/sdk/src/tg_deploy.ts +++ b/typegraph/node/sdk/src/tg_deploy.ts @@ -1,6 +1,7 @@ // Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0. // SPDX-License-Identifier: MPL-2.0 +import { ArtifactResolutionConfig } from "./gen/interfaces/metatype-typegraph-core.js"; import { TypegraphOutput } from "./typegraph.js"; import { wit_utils } from "./wit.js"; @@ -12,6 +13,7 @@ export interface BasicAuth { export interface TypegraphDeployParams { baseUrl: string; auth?: BasicAuth; + artifactsConfig?: ArtifactResolutionConfig; secrets: Record; cliVersion: string; } @@ -20,8 +22,8 @@ export async function tgDeploy( typegraph: TypegraphOutput, params: TypegraphDeployParams, ) { - const { baseUrl, cliVersion, secrets, auth } = params; - const { serialized } = typegraph; + const { baseUrl, cliVersion, secrets, auth, artifactsConfig } = params; + const serialized = typegraph.serialize(artifactsConfig); const headers = new Headers(); headers.append("Content-Type", "application/json"); diff --git a/typegraph/node/sdk/src/typegraph.ts b/typegraph/node/sdk/src/typegraph.ts index fd2d7b94c5..6ef4478ca4 100644 --- a/typegraph/node/sdk/src/typegraph.ts +++ b/typegraph/node/sdk/src/typegraph.ts @@ -13,6 +13,7 @@ import { import { Auth, Cors as CorsWit, Rate, wit_utils } from "./wit.js"; import Policy from "./policy.js"; import { getPolicyChain } from "./types.js"; +import { ArtifactResolutionConfig } from "./gen/interfaces/metatype-typegraph-core.js"; type Exports = Record; @@ -72,8 +73,8 @@ export class RawAuth { } export interface TypegraphOutput { - serialized: string; - args: Omit; + serialize: (config?: ArtifactResolutionConfig) => string; + name: string; } export function typegraph( @@ -168,21 +169,25 @@ export function typegraph( builder(g); - const tgJson = core.finalizeTypegraph( - disableAutoSerialization ? "resolve-artifacts" : "simple", - ); + let serialize = () => ""; if (!disableAutoSerialization) { + const tgJson = core.finalizeTypegraph({ tag: "simple" }); console.log(tgJson); + serialize = () => tgJson; + } else { + // config is known at deploy time + serialize = (config?: ArtifactResolutionConfig) => { + const tgJson = core.finalizeTypegraph({ + tag: "resolve-artifacts", + val: config, + }); + // console.log(tgJson); + return tgJson; + }; } return { - serialized: tgJson, - args: { - name, - cors, - dynamic, - rate, - secrets, - }, + serialize, + name, }; } diff --git a/typegraph/python/typegraph/graph/tg_deploy.py b/typegraph/python/typegraph/graph/tg_deploy.py index 1b1a7fbc75..f9b2ba3e17 100644 --- a/typegraph/python/typegraph/graph/tg_deploy.py +++ b/typegraph/python/typegraph/graph/tg_deploy.py @@ -6,6 +6,7 @@ from urllib import request import json from base64 import b64encode +from typegraph.gen.exports.core import ArtifactResolutionConfig from typegraph.gen.types import Err from typegraph.graph.typegraph import TypegraphOutput @@ -25,6 +26,7 @@ class TypegraphDeployParams: cli_version: str auth: Optional[BasicAuth] = None secrets: Optional[Dict[str, any]] = None + artifacts_config: Optional[ArtifactResolutionConfig] = None def tg_deploy(tg: TypegraphOutput, params: TypegraphDeployParams): @@ -41,7 +43,7 @@ def tg_deploy(tg: TypegraphOutput, params: TypegraphDeployParams): res = wit_utils.gen_gqlquery( store, params=QueryBodyParams( - tg=tg.serialized, + tg=tg.serialize(params.artifacts_config), cli_version=params.cli_version, secrets=[(k, v) for k, v in (params.secrets or {})], ), diff --git a/typegraph/python/typegraph/graph/typegraph.py b/typegraph/python/typegraph/graph/typegraph.py index 2b06340377..76b722565b 100644 --- a/typegraph/python/typegraph/graph/typegraph.py +++ b/typegraph/python/typegraph/graph/typegraph.py @@ -7,8 +7,10 @@ from typing import TYPE_CHECKING, Callable, List, Optional, Union from typegraph.gen.exports.core import ( + ArtifactResolutionConfig, Rate, TypegraphFinalizeMode, + TypegraphFinalizeModeResolveArtifacts, TypegraphInitParams, ) from typegraph.gen.exports.core import ( @@ -122,8 +124,8 @@ def ref(self, name: str) -> "t.typedef": @dataclass class TypegraphOutput: - tg: Typegraph - serialized: str + name: str + serialize: Callable[[Optional[ArtifactResolutionConfig]], str] def typegraph( @@ -170,20 +172,31 @@ def decorator(builder: Callable[[Graph], None]) -> TypegraphOutput: popped = Typegraph._context.pop() assert tg == popped - tg_json = core.finalize_typegraph( - store, - TypegraphFinalizeMode.RESOLVE_ARTIFACTS - if disable_auto_serialization - else TypegraphFinalizeMode.SIMPLE, - ) - - if isinstance(tg_json, Err): - raise Exception(tg_json.value) + serialize = None if not disable_auto_serialization: - print(tg_json.value) - - return lambda: TypegraphOutput(tg=tg, serialized=tg_json.value) + tg_json = core.finalize_typegraph(store, TypegraphFinalizeMode.SIMPLE) + if isinstance(tg_json, Err): + raise Exception(tg_json.value) + + def no_conf(): + return tg_json.value + + serialize = no_conf + else: + # config is only known at deploy time + def serialize_with_artifacts( + config: Optional[ArtifactResolutionConfig] = None, + ): + mode = TypegraphFinalizeModeResolveArtifacts(config) + tg_json = core.finalize_typegraph(store, mode) + if isinstance(tg_json, Err): + raise Exception(tg_json.value) + return tg_json.value + + serialize = serialize_with_artifacts + + return lambda: TypegraphOutput(name=tg.name, serialize=serialize) return decorator From 89e5021c0b3f771aaea0f37f9fc316e57c91024e Mon Sep 17 00:00:00 2001 From: afmika Date: Mon, 5 Feb 2024 18:04:12 +0300 Subject: [PATCH 02/21] fix(sdk/python): bad types, missing print --- typegraph/python/typegraph/graph/typegraph.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/typegraph/python/typegraph/graph/typegraph.py b/typegraph/python/typegraph/graph/typegraph.py index 76b722565b..11f307566b 100644 --- a/typegraph/python/typegraph/graph/typegraph.py +++ b/typegraph/python/typegraph/graph/typegraph.py @@ -9,8 +9,8 @@ from typegraph.gen.exports.core import ( ArtifactResolutionConfig, Rate, - TypegraphFinalizeMode, TypegraphFinalizeModeResolveArtifacts, + TypegraphFinalizeModeSimple, TypegraphInitParams, ) from typegraph.gen.exports.core import ( @@ -175,10 +175,12 @@ def decorator(builder: Callable[[Graph], None]) -> TypegraphOutput: serialize = None if not disable_auto_serialization: - tg_json = core.finalize_typegraph(store, TypegraphFinalizeMode.SIMPLE) + tg_json = core.finalize_typegraph(store, TypegraphFinalizeModeSimple()) if isinstance(tg_json, Err): raise Exception(tg_json.value) + print(tg_json.value) + def no_conf(): return tg_json.value From 469ae4af73ba0ec1a78719597e127525e3e20394 Mon Sep 17 00:00:00 2001 From: afmika Date: Mon, 5 Feb 2024 18:53:11 +0300 Subject: [PATCH 03/21] feat(sdk/prisma): handle migrations (wip) --- .../core/src/utils/postprocess/prisma_rt.rs | 48 ++++++++++++++++++- typegraph/core/wit/typegraph.wit | 8 ++-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/typegraph/core/src/utils/postprocess/prisma_rt.rs b/typegraph/core/src/utils/postprocess/prisma_rt.rs index 162f06692c..4f6be6b2f2 100644 --- a/typegraph/core/src/utils/postprocess/prisma_rt.rs +++ b/typegraph/core/src/utils/postprocess/prisma_rt.rs @@ -1,10 +1,16 @@ // Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0. // SPDX-License-Identifier: MPL-2.0 +use std::path::PathBuf; + +use common::typegraph::runtimes::prisma::MigrationOptions; +use common::typegraph::runtimes::{KnownRuntime::Prisma, TGRuntime}; use common::typegraph::Typegraph; +use crate::utils::fs_host; use crate::utils::postprocess::PostProcessor; use crate::wit::core::MigrationConfig; +use crate::wit::metatype::typegraph::host::get_cwd; pub struct PrismaProcessor { #[allow(unused)] @@ -18,11 +24,51 @@ impl PrismaProcessor { } impl PostProcessor for PrismaProcessor { - fn postprocess(self, _tg: &mut Typegraph) -> Result<(), String> { + fn postprocess(self, tg: &mut Typegraph) -> Result<(), String> { + self.embed_prisma_migrations(tg)?; Ok(()) } } +impl PrismaProcessor { + pub fn embed_prisma_migrations(&self, tg: &mut Typegraph) -> Result<(), String> { + let tg_name = tg.name().map_err(|e| e.to_string())?; + let base_migration_path = self.prisma_migrations_dir(&tg_name)?; + + for rt in tg.runtimes.iter_mut() { + if let TGRuntime::Known(Prisma(rt_data)) = rt { + let rt_name = &rt_data.name; + let path = base_migration_path.join(rt_name); + rt_data.migration_options = Some(MigrationOptions { + migration_files: { + let path = fs_host::make_absolute(&path)?; + let base64 = + fs_host::compress_and_encode_base64(path.display().to_string())?; + match base64.is_empty() { + true => Some(base64), + false => None, + } + }, + create: self.config.action.create, + reset: self.config.action.reset, + }); + } + } + Ok(()) + } + + pub fn prisma_migrations_dir(&self, tg_name: &str) -> Result { + let mut path = PathBuf::from(get_cwd()?).join(PathBuf::from( + self.config + .migration_dir + .clone() + .unwrap_or("prisma/migrations".to_string()), + )); + path.push(tg_name); + Ok(path) + } +} + // TODO: // reset // create diff --git a/typegraph/core/wit/typegraph.wit b/typegraph/core/wit/typegraph.wit index f82211d525..9fbe340b26 100644 --- a/typegraph/core/wit/typegraph.wit +++ b/typegraph/core/wit/typegraph.wit @@ -36,13 +36,13 @@ interface core { init-typegraph: func(params: typegraph-init-params) -> result<_, error> - enum migration-action { - create, - reset + record migration-action { + create: bool, + reset: bool } record migration-config { - path-dir: string, + migration-dir: option, action: migration-action } From 7ab2a76ba2a3c193bfd6f4394845c119d72f5839 Mon Sep 17 00:00:00 2001 From: afmika Date: Tue, 6 Feb 2024 17:32:52 +0300 Subject: [PATCH 04/21] feat(sdk/prisma): finalize fs ops --- examples/deploy/deploy.mjs | 7 +++++-- examples/deploy/deploy.py | 6 ++++++ libs/common/src/archive.rs | 25 ++++++++++++++++++++++++- typegraph/node/sdk/src/host/host.ts | 16 ++++++++++------ typegraph/python/typegraph/host/host.py | 2 ++ typegraph/python/typegraph/wit.py | 5 +++++ 6 files changed, 52 insertions(+), 9 deletions(-) diff --git a/examples/deploy/deploy.mjs b/examples/deploy/deploy.mjs index e37a388e74..9f7d0870f5 100644 --- a/examples/deploy/deploy.mjs +++ b/examples/deploy/deploy.mjs @@ -63,8 +63,11 @@ tgDeploy(tg, { }, artifactsConfig: { prismaMigration: { - action: "create", - pathDir: "./migrations" + action: { + create: true, + reset: false + }, + migrationDir: "prisma/migrations" } } }).then((result) => { diff --git a/examples/deploy/deploy.py b/examples/deploy/deploy.py index 71d6c3def3..cbcf78c941 100644 --- a/examples/deploy/deploy.py +++ b/examples/deploy/deploy.py @@ -4,6 +4,7 @@ from typegraph.graph.tg_deploy import tg_deploy, TypegraphDeployParams, BasicAuth from typegraph.runtimes.python import PythonRuntime from typegraph.runtimes.wasmedge import WasmEdgeRuntime +from typegraph.wit import ArtifactResolutionConfig, MigrationConfig, MigrationAction @typegraph(disable_auto_serialization=True) # disable print @@ -52,12 +53,17 @@ def deploy_example_python(g: Graph): auth = BasicAuth(username="admin", password="password") +migration_config = MigrationConfig( + migration_dir="prisma/migration", action=MigrationAction(create=True, reset=False) +) + res = tg_deploy( deploy_example_python(), TypegraphDeployParams( base_url="http://localhost:7890", auth=auth, cli_version="0.3.3", + artifacts_config=ArtifactResolutionConfig(migration_config), ), ) diff --git a/libs/common/src/archive.rs b/libs/common/src/archive.rs index d1ba62947b..da0619daa9 100644 --- a/libs/common/src/archive.rs +++ b/libs/common/src/archive.rs @@ -6,7 +6,11 @@ use base64::{engine::general_purpose::STANDARD, Engine}; use flate2::{read::GzDecoder, write::GzEncoder, Compression}; use ignore::{Walk, WalkBuilder}; use indexmap::IndexMap; -use std::{fs, path::Path}; +use std::{ + fs, + io::Read, + path::{Path, PathBuf}, +}; use tar::{Archive, Header}; pub fn unpack>(dest: P, migrations: Option>) -> Result<()> { @@ -21,6 +25,25 @@ pub fn unpack>(dest: P, migrations: Option>) -> Ok(()) } +pub fn iter_tar_entries>( + tar: impl AsRef<[u8]>, +) -> Result>> { + let bytes = STANDARD.decode(tar)?; + let decoder = GzDecoder::new(bytes.as_slice()); + let mut archive = Archive::new(decoder); + + archive + .entries()? + .filter_map(|e| e.ok()) + .map(|mut entry| -> Result<(PathBuf, Vec)> { + let path = entry.path()?.to_path_buf(); + let mut buff = vec![]; + entry.read_to_end(&mut buff)?; + Ok((path, buff)) + }) + .collect::>>>() +} + pub fn archive>(folder: P) -> Result> { if !folder.as_ref().try_exists()? { return Ok(None); diff --git a/typegraph/node/sdk/src/host/host.ts b/typegraph/node/sdk/src/host/host.ts index c3bed43142..d677933901 100644 --- a/typegraph/node/sdk/src/host/host.ts +++ b/typegraph/node/sdk/src/host/host.ts @@ -52,26 +52,30 @@ export function getCwd(): string { } } -export function fileExists(path: string): boolean { +export function fileExists(filePath: string): boolean { try { - return fs.existsSync(path); + return fs.existsSync(filePath); } catch (err) { throw (err instanceof Error ? err.message : err); } } -export function readFile(path: string): Uint8Array { +export function readFile(filePath: string): Uint8Array { try { - const buffer = fs.readFileSync(path, null); + const buffer = fs.readFileSync(filePath, null); return new Uint8Array(buffer); } catch (err) { throw (err instanceof Error ? err.message : err); } } -export function writeFile(path: string, data: Uint8Array): void { +export function writeFile(filePath: string, data: Uint8Array): void { try { - void fs.writeFileSync(path, data); + const dir = path.dirname(filePath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + void fs.writeFileSync(filePath, data); } catch (err) { throw (err instanceof Error ? err.message : err); } diff --git a/typegraph/python/typegraph/host/host.py b/typegraph/python/typegraph/host/host.py index a65cf1ecc6..05820bcca5 100644 --- a/typegraph/python/typegraph/host/host.py +++ b/typegraph/python/typegraph/host/host.py @@ -47,6 +47,8 @@ def read_file(self, path: str) -> Result[bytes, str]: def write_file(self, path: str, data: bytes) -> Result[None, str]: try: + dirname = os.path.dirname(path) + os.makedirs(dirname, exist_ok=True) file = open(path, "wb") file.write(data) return Ok(None) diff --git a/typegraph/python/typegraph/wit.py b/typegraph/python/typegraph/wit.py index 881ef20007..0dc7b802e4 100644 --- a/typegraph/python/typegraph/wit.py +++ b/typegraph/python/typegraph/wit.py @@ -9,6 +9,11 @@ from typegraph.gen.exports.runtimes import Runtimes from typegraph.gen.exports.utils import Utils from typegraph.host.host import HostImpl +from typegraph.gen.exports.core import ( + ArtifactResolutionConfig, # noqa + MigrationConfig, # noqa + MigrationAction, # noqa +) store = Store() _typegraph_core = Root(store, RootImports(HostImpl())) From 16c36b6c71c3d038b04fae88843c8fd897004734 Mon Sep 17 00:00:00 2001 From: afmika Date: Tue, 6 Feb 2024 20:39:57 +0300 Subject: [PATCH 05/21] feat(sdk/prisma): handle migrations --- examples/deploy/deploy.mjs | 50 +++++++++++++++---- libs/common/src/archive.rs | 36 +++++++------ typegraph/core/src/utils/fs_host.rs | 26 ++++++++-- typegraph/core/src/utils/mod.rs | 4 ++ .../core/src/utils/postprocess/prisma_rt.rs | 21 ++++---- typegraph/core/wit/typegraph.wit | 2 + typegraph/node/sdk/src/host/host.ts | 2 +- 7 files changed, 100 insertions(+), 41 deletions(-) diff --git a/examples/deploy/deploy.mjs b/examples/deploy/deploy.mjs index 9f7d0870f5..62a7d8cb17 100644 --- a/examples/deploy/deploy.mjs +++ b/examples/deploy/deploy.mjs @@ -2,7 +2,11 @@ import { Policy, t, typegraph } from "@typegraph/sdk/index.js"; import { DenoRuntime } from "@typegraph/sdk/runtimes/deno.js"; import { PythonRuntime } from "@typegraph/sdk/runtimes/python.js"; import { WasmEdgeRuntime } from "@typegraph/sdk/runtimes/wasmedge.js"; +import { PrismaRuntime } from "@typegraph/sdk/providers/prisma.js"; import { tgDeploy } from "@typegraph/sdk/tg_deploy.js"; +import { wit_utils } from "@typegraph/sdk/wit.js"; +import * as path from "path"; + // deno // import { Policy, t, typegraph } from "../../typegraph/node/sdk/dist/index.js"; @@ -18,8 +22,16 @@ const tg = typegraph({ const deno = new DenoRuntime(); const python = new PythonRuntime(); const wasmedge = new WasmEdgeRuntime(); + const prisma = new PrismaRuntime("prisma", "POSTGRES") const pub = Policy.public(); - + const student = t.struct( + { + id: t.integer({}, { asId: true }), + name: t.string(), + }, + { name: "Student" }, + ); + g.expose({ test: deno.static(t.struct({ a: t.string() }), { a: "HELLO" }), // Deno @@ -50,10 +62,24 @@ const tg = typegraph({ t.integer(), { wasm: "wasi/rust.wasm", func: "add" } ), + // Prisma + createStudent: prisma.create(student), + findManyStudent: prisma.findMany(student), }, pub); }, ); +const artifactsConfig = { + prismaMigration: { + action: { + create: true, + reset: false + }, + migrationDir: "prisma-migrations" + } +}; + + tgDeploy(tg, { baseUrl: "http://localhost:7890", cliVersion: "0.3.3", @@ -61,16 +87,20 @@ tgDeploy(tg, { username: "admin", password: "password", }, - artifactsConfig: { - prismaMigration: { - action: { - create: true, - reset: false - }, - migrationDir: "prisma/migrations" - } - } + secrets: { + TG_DEPLOY_EXAMPLE_NODE_POSTGRES: "postgresql://postgres:password@localhost:5432/db?schema=e2e7894" + }, + artifactsConfig, }).then((result) => { console.log("gate:", result); + if (result.data.addTypegraph) { + const migrations = result.data.addTypegraph.migrations ?? []; + migrations.map(({ runtime, migrations }) => { + const baseDir = artifactsConfig.prismaMigration.migrationDir; + const fullPath = path.join(baseDir, tg.name, runtime); + wit_utils.unpackTarb64(migrations, fullPath); + console.log(`Unpacked migration at ${fullPath}`) + }); + } }) .catch(console.error); diff --git a/libs/common/src/archive.rs b/libs/common/src/archive.rs index da0619daa9..05f8580f0f 100644 --- a/libs/common/src/archive.rs +++ b/libs/common/src/archive.rs @@ -25,21 +25,30 @@ pub fn unpack>(dest: P, migrations: Option>) -> Ok(()) } -pub fn iter_tar_entries>( - tar: impl AsRef<[u8]>, +pub fn tarb64_unpack_entries_as_map( + tarb64: Option>, ) -> Result>> { - let bytes = STANDARD.decode(tar)?; - let decoder = GzDecoder::new(bytes.as_slice()); + let Some(tarb64) = tarb64 else { + return Ok(IndexMap::new()); + }; + let tar_bytes = STANDARD.decode(tarb64)?; + let decoder = GzDecoder::new(tar_bytes.as_slice()); let mut archive = Archive::new(decoder); - archive .entries()? - .filter_map(|e| e.ok()) - .map(|mut entry| -> Result<(PathBuf, Vec)> { + .filter_map(|e| match e { + Ok(entry) => { + if entry.header().entry_type().is_dir() { + return None; + } + Some(entry) + } + _ => None, + }) + .map(|entry| -> Result<(PathBuf, Vec)> { let path = entry.path()?.to_path_buf(); - let mut buff = vec![]; - entry.read_to_end(&mut buff)?; - Ok((path, buff)) + let bytes = entry.bytes().collect::, _>>()?; + Ok((path, bytes)) }) .collect::>>>() } @@ -83,9 +92,7 @@ pub fn archive_entries(dir_walker: Walk, prefix: Option<&Path>) -> Result