diff --git a/examples/deploy-node/deploy-static.mjs b/examples/deploy-node/deploy-static.mjs new file mode 100644 index 00000000..94acf1fc --- /dev/null +++ b/examples/deploy-node/deploy-static.mjs @@ -0,0 +1,64 @@ +import { init, Wasmer, walkDir } from "@wasmer/sdk/node"; + +const WASMER_TOKEN = process.env.WASMER_TOKEN; +const APP_OWNER = process.env.APP_OWNER; +const APP_NAME = process.env.APP_NAME || "my-echo-env-app"; +if (!WASMER_TOKEN) { + throw new Error( + "Please set the `WASMER_TOKEN` environment variable.\nYou can create a token in https://wasmer.io/settings/access-tokens", + ); +} +if (!APP_OWNER) { + throw new Error( + "Please set the `APP_OWNER` to your username in Wasmer (or a namespace you own).", + ); +} + +await init({ + // registryUrl: process.env.WASMER_REGISTRY, + token: WASMER_TOKEN, +}); + +const php_file = `"; + +var_dump($_ENV);`; + +const manifest = { + command: [ + { + module: "wasmer/static-web-server:webserver", + name: "script", + runner: "https://webc.org/runner/wasi", + annotations: { + wasi: { + "main-args": ["--directory-listing=true"], + }, + }, + }, + ], + dependencies: { + "wasmer/static-web-server": "^1", + }, + fs: { + "/public": { + "myfile.txt": "My file", + "other": await walkDir("./static"), + }, + }, +}; + +// console.log(JSON.stringify(manifest.fs, null, 2)); + +console.log("Creating Package..."); +let wasmerPackage = await Wasmer.createPackage(manifest); + +let appConfig = { + name: APP_NAME, + owner: APP_OWNER, + package: wasmerPackage, +}; + +console.log("Deploying app..."); +let res = await Wasmer.deployApp(appConfig); +console.log(`Deployed successfully: ${res.url}`); diff --git a/examples/deploy-node/index-php.mjs b/examples/deploy-node/index-php.mjs index 66e29c17..319055fe 100644 --- a/examples/deploy-node/index-php.mjs +++ b/examples/deploy-node/index-php.mjs @@ -24,7 +24,7 @@ echo "PHP app created from @wasmer/sdk!
"; var_dump($_ENV);`; -const manifest: PackageManifest = { +const manifest = { command: [ { module: "php/php:php", @@ -52,7 +52,7 @@ console.log("Creating Package..."); let wasmerPackage = await Wasmer.createPackage(manifest); // console.log("NISE"); -let appConfig: AppConfig = { +let appConfig = { name: APP_NAME, owner: APP_OWNER, package: wasmerPackage, diff --git a/src-js/node.ts b/src-js/node.ts index b0df3e0b..fea3598c 100644 --- a/src-js/node.ts +++ b/src-js/node.ts @@ -3,8 +3,10 @@ import { init as load, InitOutput, WasmerInitInput, + VolumeTree, } from "./"; -import fs from 'node:fs'; +import fs from 'node:fs/promises'; +import path from 'node:path'; /** * Initialize the underlying WebAssembly module, defaulting to an embedded @@ -17,7 +19,26 @@ export const init = async (initValue?: WasmerInitInput): Promise => if (!initValue.module) { const path = new URL('wasmer_js_bg.wasm', import.meta.url).pathname; - initValue.module = fs.readFileSync(path); + initValue.module = await fs.readFile(path); } return load(initValue); }; + +export async function walkDir(dir: string, result: VolumeTree = {}) { + let list = await fs.readdir(dir); + for(let item of list) { + const itemPath = path.join(dir, item); + let stats = await fs.stat(itemPath) + if (await stats.isDirectory()) { + result[item] = {}; + await walkDir(itemPath, result[item] as VolumeTree); + } else { + const fileName = path.basename(item); + result[fileName] = { + data: new Uint8Array(await fs.readFile(itemPath)), // , { encoding: 'utf-8'} + modified: stats.mtime, + }; + } + } + return result; +} diff --git a/src/registry/app.rs b/src/registry/app.rs index 8a78e50b..50d05e60 100644 --- a/src/registry/app.rs +++ b/src/registry/app.rs @@ -22,6 +22,7 @@ pub struct DeployedApp { pub config: String, pub json_config: String, pub url: String, + pub app_id: Option, } impl From for DeployedApp { @@ -36,6 +37,7 @@ impl From for DeployedApp { config: value.config, json_config: value.json_config, url: value.url, + app_id: value.app.map(|app| app.id.inner().to_string()), } } } diff --git a/src/registry/package/mod.rs b/src/registry/package/mod.rs index 0790227f..10ef7d9a 100644 --- a/src/registry/package/mod.rs +++ b/src/registry/package/mod.rs @@ -51,6 +51,14 @@ export type PackageCommand = { } }; }; + +export type VolumeFileData = string | Uint8Array; +export type VolumeFileDate = Date | Number; +export type VolumeFile = VolumeFileData | { data: VolumeFileData, modified: VolumeFileDate} +export type VolumeTree = { + [name: string]: VolumeFile | VolumeTree +}; + /** * Manifest of a package. * For more information, please check the package manifest docs: @@ -61,7 +69,7 @@ export type PackageManifest = { dependencies?: { [name:string]: string }, - fs: Record; + fs: VolumeTree; }; "#; diff --git a/tests/registry.test.ts b/tests/registry.test.ts index 71a8fe5f..878d3499 100644 --- a/tests/registry.test.ts +++ b/tests/registry.test.ts @@ -36,7 +36,25 @@ describe("Registry", function () { default: true, }; - await Wasmer.deployApp(appConfig); + let appVersion = await Wasmer.deployApp(appConfig); + assert(appVersion.id.startsWith("dav_")); + assert(appVersion.app_id.startsWith("da_")); + }); + + it("can delete apps", async () => { + let appConfig = { + name: app_name, + owner: WASMER_TEST_OWNER, + package: + "sha256:34a3b5f5a9108c2b258eb51e9d0978b6778a3696b9c7e713adab33293fb5e4f1", + env: [["test", "new_value"]], + }; + + let appVersion = await Wasmer.deployApp(appConfig); + assert(appVersion.id.startsWith("dav_")); + assert(appVersion.app_id.startsWith("da_")); + + await Wasmer.deleteApp({id: appVersion.app_id}); }); it("can create a package with atoms", async () => {