Skip to content

Commit

Permalink
pins the sdk to another version, and adds escape wrapper around headers
Browse files Browse the repository at this point in the history
Signed-off-by: Derek Anderson <[email protected]>
  • Loading branch information
dmikey committed Jul 1, 2024
1 parent 399a5bc commit c75710b
Show file tree
Hide file tree
Showing 3 changed files with 470 additions and 428 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@blockless/cli",
"version": "0.0.4-development",
"version": "0.0.5-development",
"description": "blockless cli client, manage, interact with and deploy blockless applications.",
"main": "dist/src/index.js",
"private": false,
Expand Down
384 changes: 196 additions & 188 deletions src/commands/sites/preview.ts
Original file line number Diff line number Diff line change
@@ -1,191 +1,199 @@
import fs from "fs"
import Chalk from "chalk"
import { store } from "../../store"
import { execSync } from "child_process"
import { resolve } from "path"
import { parseBlsConfig } from "../../lib/blsConfig"
import { logger } from "../../lib/logger"
import { run as runBuild } from "./build"
import { run as runInstall } from "../offchain/install"
import prompRuntimeConfirm from "../../prompts/runtime/confirm"
import Fastify from "fastify"
import fs from "fs";
import Chalk from "chalk";
import { store } from "../../store";
import { execSync } from "child_process";
import { resolve } from "path";
import { parseBlsConfig } from "../../lib/blsConfig";
import { logger } from "../../lib/logger";
import { run as runBuild } from "./build";
import { run as runInstall } from "../offchain/install";
import prompRuntimeConfirm from "../../prompts/runtime/confirm";
import Fastify from "fastify";
import { getPortPromise } from "portfinder";

export const run = async (options: any) => {
const {
systemPath = `${store.system.homedir}/.bls/`,
path = process.cwd(),
debug = true,
rebuild = false,
} = options

const runtimePath = `${systemPath}runtime/bls-runtime`

// Validate Runtime Path
try {
if (!fs.existsSync(runtimePath)) {
const { confirm } = await prompRuntimeConfirm()

if (!confirm) {
throw new Error("Cancelled by user, aborting invoke.")
} else {
await runInstall({ yes: true, inline: true })
console.log(Chalk.green('Installation successful!'))
console.log('')
console.log('')
}
}
} catch (error) {
logger.error('Failed to install blockless runtime, please try installing the runtime manually.')
return
}

try {
// Fetch BLS config
const { build, build_release } = parseBlsConfig()

// Execute the build command
await runBuild({ path, debug, rebuild })

// check for and store unmodified wasm file name to change later
const buildConfig = !debug ? build_release : build
const buildDir = resolve(path, buildConfig.dir || 'build')
const manifestPath = resolve(buildDir, 'manifest.json')

// the runtime requires absolute paths
let manifestData = fs.readFileSync(manifestPath, "utf8")
let manifest = JSON.parse(manifestData)
manifest.drivers_root_path = `${systemPath}/extensions`
manifest.modules = manifest.modules.map((m: any) => {
m.file = resolve(buildDir, m.file)
return m
})
fs.writeFileSync(manifestPath, JSON.stringify(manifest))

// prepare environment variables
// pass environment variables to bls runtime
let envString = ''

if (!!options.env) {
let envVars = [] as string[]
let envVarsKeys = [] as string[]

// Validate environment variables
const vars = typeof options.env === 'string' ? [options.env] : options.env
vars.map((v: string) => {
const split = v.split('=')
if (split.length !== 2) return

envVars.push(v)
envVarsKeys.push(split[0])
})

// Include environment string if there are variables
if (envVars.length > 0) {
envString = `env ${envVars.join(' ')} BLS_LIST_VARS=\"${envVarsKeys.join(';')}\"`
}
}

const fastify = Fastify({
logger: false,
maxParamLength: 10000
})

await fastify.register(import('@fastify/rate-limit'), {
max: 100,
timeWindow: '1 minute'
})

await fastify.register(import('@fastify/cors'))

fastify.get("*", async (request, reply) => {
let qs = ''
let headerString = ''
let requestPath = decodeURIComponent(request.url.trim())

if (requestPath.includes('?')) {
qs = requestPath.split('?')[1]
requestPath = requestPath.split('?')[0]
}

if (request.headers) {
headerString = Object.entries(request.headers)
.map(([key, value]) => `${key}=${value}`)
.join('&')
}

let envString = ''
let envVars = [] as string[]
let envVarsKeys = [] as string[]

if (!!options.env) {
// Validate environment variables
const vars = typeof options.env === 'string' ? [options.env] : options.env
vars.map((v: string) => {
const split = v.split('=')
if (split.length !== 2) return

envVars.push(v)
envVarsKeys.push(split[0])
})
}

envVars.push(`BLS_REQUEST_PATH="${requestPath}"`)
envVars.push(`BLS_REQUEST_QUERY="${qs}"`)
envVars.push(`BLS_REQUEST_METHOD="${request.method}"`)
envVars.push(`BLS_REQUEST_HEADERS="${headerString}"`)
envVarsKeys.push('BLS_REQUEST_PATH')
envVarsKeys.push('BLS_REQUEST_QUERY')
envVarsKeys.push('BLS_REQUEST_METHOD')
envVarsKeys.push('BLS_REQUEST_HEADERS')

if (request.body) {
envVars.push(`BLS_REQUEST_BODY="${encodeURIComponent(JSON.stringify(request.body))}"`)
envVarsKeys.push('BLS_REQUEST_BODY')
}

// Include environment string if there are variables
if (envVars.length > 0) {
envString = `env ${envVars.join(' ')} BLS_LIST_VARS=\"${envVarsKeys.join(';')}\"`
}

const result = execSync(`echo "${decodeURIComponent(request.url.trim())}" | ${envString} ${runtimePath} ${manifestPath}`, {
cwd: path,
maxBuffer: (10000 * 1024)
}).toString()

if (!manifest.contentType || manifest.contentType === 'json' && result) {
try {
const resultJson = JSON.parse(result)

reply
.header("Content-Type", "application/json")
.send(resultJson)
} catch (error) { }
} else if (manifest.contentType === "html" && result) {
const body = result

if (body.startsWith("data:")) {
const data = body.split(",")[1]
const contentType = body.split(",")[0].split(":")[1].split(";")[0]
const base64data = Buffer.from(data, "base64")
reply.type(contentType).send(base64data)
} else {
reply
.header("Content-Type", "text/html")
.send(body)
}
} else {
reply.send(result)
}
})

const port = await getPortPromise({ port: 3000, stopPort: 4000 })

fastify.listen({ port }).then(async () => {
console.log(`Serving http://127.0.0.1:${port} ...`)
})
} catch (error: any) {
logger.error('Failed to invoke function.', error.message)
}
}
const {
systemPath = `${store.system.homedir}/.bls/`,
path = process.cwd(),
debug = true,
rebuild = false,
} = options;

const runtimePath = `${systemPath}runtime/bls-runtime`;

// Validate Runtime Path
try {
if (!fs.existsSync(runtimePath)) {
const { confirm } = await prompRuntimeConfirm();

if (!confirm) {
throw new Error("Cancelled by user, aborting invoke.");
} else {
await runInstall({ yes: true, inline: true });
console.log(Chalk.green("Installation successful!"));
console.log("");
console.log("");
}
}
} catch (error) {
logger.error(
"Failed to install blockless runtime, please try installing the runtime manually.",
);
return;
}

try {
// Fetch BLS config
const { build, build_release } = parseBlsConfig();

// Execute the build command
await runBuild({ path, debug, rebuild });

// check for and store unmodified wasm file name to change later
const buildConfig = !debug ? build_release : build;
const buildDir = resolve(path, buildConfig.dir || "build");
const manifestPath = resolve(buildDir, "manifest.json");

// the runtime requires absolute paths
let manifestData = fs.readFileSync(manifestPath, "utf8");
let manifest = JSON.parse(manifestData);
manifest.drivers_root_path = `${systemPath}/extensions`;
manifest.modules = manifest.modules.map((m: any) => {
m.file = resolve(buildDir, m.file);
return m;
});
fs.writeFileSync(manifestPath, JSON.stringify(manifest));

// prepare environment variables
// pass environment variables to bls runtime
let envString = "";

if (!!options.env) {
let envVars = [] as string[];
let envVarsKeys = [] as string[];

// Validate environment variables
const vars =
typeof options.env === "string" ? [options.env] : options.env;
vars.map((v: string) => {
const split = v.split("=");
if (split.length !== 2) return;

envVars.push(v);
envVarsKeys.push(split[0]);
});

// Include environment string if there are variables
if (envVars.length > 0) {
envString = `env ${envVars.join(" ")} BLS_LIST_VARS=\"${envVarsKeys.join(";")}\"`;
}
}

const fastify = Fastify({
logger: false,
maxParamLength: 10000,
});

await fastify.register(import("@fastify/rate-limit"), {
max: 100,
timeWindow: "1 minute",
});

await fastify.register(import("@fastify/cors"));

fastify.get("*", async (request, reply) => {
let qs = "";
let headerString = "";
let requestPath = decodeURIComponent(request.url.trim());

if (requestPath.includes("?")) {
qs = requestPath.split("?")[1];
requestPath = requestPath.split("?")[0];
}

if (request.headers) {
headerString = Object.entries(request.headers)
.map(([key, value]) => `${key}=${encodeURIComponent(`${value}`)}`)
.join("&");
}

let envString = "";
let envVars = [] as string[];
let envVarsKeys = [] as string[];

if (!!options.env) {
// Validate environment variables
const vars =
typeof options.env === "string" ? [options.env] : options.env;
vars.map((v: string) => {
const split = v.split("=");
if (split.length !== 2) return;

envVars.push(v);
envVarsKeys.push(split[0]);
});
}

envVars.push(`BLS_REQUEST_PATH="${requestPath}"`);
envVars.push(`BLS_REQUEST_QUERY="${qs}"`);
envVars.push(`BLS_REQUEST_METHOD="${request.method}"`);
envVars.push(`BLS_REQUEST_HEADERS="${headerString}"`);
envVarsKeys.push("BLS_REQUEST_PATH");
envVarsKeys.push("BLS_REQUEST_QUERY");
envVarsKeys.push("BLS_REQUEST_METHOD");
envVarsKeys.push("BLS_REQUEST_HEADERS");

if (request.body) {
envVars.push(
`BLS_REQUEST_BODY="${encodeURIComponent(JSON.stringify(request.body))}"`,
);
envVarsKeys.push("BLS_REQUEST_BODY");
}

// Include environment string if there are variables
if (envVars.length > 0) {
envString = `env ${envVars.join(" ")} BLS_LIST_VARS=\"${envVarsKeys.join(";")}\"`;
}

const result = execSync(
`echo "${decodeURIComponent(request.url.trim())}" | ${envString} ${runtimePath} ${manifestPath}`,
{
cwd: path,
maxBuffer: 10000 * 1024,
},
).toString();

if (
!manifest.contentType ||
(manifest.contentType === "json" && result)
) {
try {
const resultJson = JSON.parse(result);

reply.header("Content-Type", "application/json").send(resultJson);
} catch (error) {}
} else if (manifest.contentType === "html" && result) {
const body = result;

if (body.startsWith("data:")) {
const data = body.split(",")[1];
const contentType = body.split(",")[0].split(":")[1].split(";")[0];
const base64data = Buffer.from(data, "base64");
reply.type(contentType).send(base64data);
} else {
reply.header("Content-Type", "text/html").send(body);
}
} else {
reply.send(result);
}
});

const port = await getPortPromise({ port: 3000, stopPort: 4000 });

fastify.listen({ port }).then(async () => {
console.log(`Serving http://127.0.0.1:${port} ...`);
});
} catch (error: any) {
logger.error("Failed to invoke function.", error.message);
}
};
Loading

0 comments on commit c75710b

Please sign in to comment.