Skip to content

Commit

Permalink
Add support for text_blobs (#228)
Browse files Browse the repository at this point in the history
* ???

* code review + add tests

* nits from code review

* fix priority in test

* F
  • Loading branch information
caass authored Mar 30, 2022
1 parent 85a8f39 commit 57dd23d
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 11 deletions.
30 changes: 26 additions & 4 deletions packages/core/src/plugins/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface BindingsOptions {
bindings?: Record<string, any>;
globals?: Record<string, any>;
wasmBindings?: Record<string, string>;
textBlobBindings?: Record<string, string>;
serviceBindings?: ServiceBindingsOptions;
}

Expand Down Expand Up @@ -164,6 +165,16 @@ export class BindingsPlugin
})
wasmBindings?: Record<string, string>;

@Option({
type: OptionType.OBJECT,
typeFormat: "NAME=PATH",
name: "text-blob",
description: "Text blob to bind",
logName: "Text Blob Bindings",
fromWrangler: ({ text_blobs }) => text_blobs,
})
textBlobBindings?: Record<string, string>;

@Option({
type: OptionType.OBJECT,
typeFormat: "NAME=MOUNT[@ENV]",
Expand Down Expand Up @@ -246,8 +257,9 @@ export class BindingsPlugin
// 1) Wrangler [vars]
// 2) .env Variables
// 3) WASM Module Bindings
// 4) Service Bindings
// 5) Custom Bindings
// 4) Text blob Bindings
// 5) Service Bindings
// 6) Custom Bindings

const bindings: Context = {};
const watch: string[] = [];
Expand Down Expand Up @@ -281,12 +293,22 @@ export class BindingsPlugin
}
}

// 4) Load service bindings
// 4) Load text blobs from files
if (this.textBlobBindings) {
// eslint-disable-next-line prefer-const
for (let [name, textPath] of Object.entries(this.textBlobBindings)) {
textPath = path.resolve(this.ctx.rootPath, textPath);
bindings[name] = await fs.readFile(textPath, "utf-8");
watch.push(textPath);
}
}

// 5) Load service bindings
for (const { name, service } of this.#processedServiceBindings) {
bindings[name] = new Fetcher(service, this.#getServiceFetch);
}

// 5) Copy user's arbitrary bindings
// 6) Copy user's arbitrary bindings
Object.assign(bindings, this.bindings);

return { globals: this.globals, bindings, watch };
Expand Down
9 changes: 9 additions & 0 deletions packages/core/test/fixtures/lorem-ipsum.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet consectetur adipiscing elit duis tristique sollicitudin nibh sit amet. Parturient montes nascetur ridiculus mus mauris vitae ultricies leo integer. Nisi porta lorem mollis aliquam ut porttitor. Placerat duis ultricies lacus sed. Amet nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Hendrerit dolor magna eget est. Sed nisi lacus sed viverra. Id cursus metus aliquam eleifend mi in nulla posuere. Donec ultrices tincidunt arcu non sodales neque sodales ut etiam. Lectus proin nibh nisl condimentum id. Vitae tempus quam pellentesque nec nam aliquam sem.

Ipsum dolor sit amet consectetur adipiscing elit pellentesque habitant. Pellentesque massa placerat duis ultricies. Ultrices gravida dictum fusce ut placerat orci nulla. Quam pellentesque nec nam aliquam sem et tortor consequat id. Laoreet sit amet cursus sit amet dictum sit amet justo. Cursus metus aliquam eleifend mi in nulla. Mattis molestie a iaculis at erat pellentesque adipiscing commodo. Nulla aliquet porttitor lacus luctus. Tristique senectus et netus et. Donec adipiscing tristique risus nec feugiat in fermentum posuere urna.

Hac habitasse platea dictumst quisque sagittis purus sit. Adipiscing commodo elit at imperdiet dui accumsan sit. Etiam erat velit scelerisque in dictum non consectetur a. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Est velit egestas dui id ornare. Orci dapibus ultrices in iaculis. Quis vel eros donec ac odio tempor orci dapibus ultrices. Lectus arcu bibendum at varius vel. Eget egestas purus viverra accumsan in nisl nisi scelerisque eu. Elementum eu facilisis sed odio morbi quis. Etiam tempor orci eu lobortis elementum nibh tellus molestie. Enim nulla aliquet porttitor lacus luctus accumsan tortor posuere ac. Nunc lobortis mattis aliquam faucibus purus in massa. Quam id leo in vitae turpis massa. Mus mauris vitae ultricies leo integer malesuada nunc vel.

Et malesuada fames ac turpis egestas sed tempus urna et. Donec massa sapien faucibus et molestie ac feugiat. Amet cursus sit amet dictum sit amet justo donec enim. Ut etiam sit amet nisl purus. Risus in hendrerit gravida rutrum quisque non tellus. Nibh mauris cursus mattis molestie a. Elementum nisi quis eleifend quam adipiscing vitae proin. Mi quis hendrerit dolor magna eget est lorem ipsum. Ut morbi tincidunt augue interdum velit euismod in pellentesque massa. Proin sagittis nisl rhoncus mattis rhoncus urna neque. Ullamcorper sit amet risus nullam eget felis. Sit amet tellus cras adipiscing enim eu. Quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus. Convallis posuere morbi leo urna molestie at elementum eu facilisis. Sed adipiscing diam donec adipiscing tristique risus nec. Rhoncus aenean vel elit scelerisque mauris pellentesque. Leo in vitae turpis massa sed elementum tempus egestas sed. In hac habitasse platea dictumst quisque sagittis purus sit amet. Eros donec ac odio tempor orci. Eleifend mi in nulla posuere sollicitudin aliquam ultrices.

Amet facilisis magna etiam tempor orci eu lobortis. In ornare quam viverra orci. Convallis convallis tellus id interdum velit laoreet id. Rutrum tellus pellentesque eu tincidunt tortor aliquam. Tincidunt dui ut ornare lectus sit amet est placerat in. Nibh sed pulvinar proin gravida hendrerit lectus. Ornare aenean euismod elementum nisi quis eleifend quam adipiscing vitae. Amet luctus venenatis lectus magna fringilla urna. Nec ultrices dui sapien eget mi proin sed. Magna ac placerat vestibulum lectus. Risus nec feugiat in fermentum posuere urna. Cursus turpis massa tincidunt dui. Turpis egestas integer eget aliquet nibh praesent. Tincidunt vitae semper quis lectus. Massa id neque aliquam vestibulum morbi blandit cursus risus. Egestas fringilla phasellus faucibus scelerisque. In massa tempor nec feugiat nisl pretium fusce. A lacus vestibulum sed arcu non odio. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. Quam id leo in vitae turpis massa sed elementum.
55 changes: 48 additions & 7 deletions packages/core/test/plugins/bindings.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import assert from "assert";
import { readFileSync } from "fs";
import fs from "fs/promises";
import path from "path";
import { setImmediate } from "timers/promises";
Expand Down Expand Up @@ -37,6 +38,9 @@ const fixturesPath = path.join(__dirname, "..", "..", "..", "test", "fixtures");
// its 2 integer parameters together and returns the result, it is from:
// https://webassembly.github.io/wabt/demo/wat2wasm/
const addModulePath = path.join(fixturesPath, "add.wasm");
// lorem-ipsum.txt is five paragraphs of lorem ipsum nonsense text
const loremIpsumPath = path.join(fixturesPath, "lorem-ipsum.txt");
const loremIpsum = readFileSync(loremIpsumPath, "utf-8");

test("BindingsPlugin: parses options from argv", (t) => {
let options = parsePluginArgv(BindingsPlugin, [
Expand All @@ -54,6 +58,10 @@ test("BindingsPlugin: parses options from argv", (t) => {
"MODULE1=module1.wasm",
"--wasm",
"MODULE2=module2.wasm",
"--text-blob",
"TEXT1=text-blob-1.txt",
"--text-blob",
"TEXT2=text-blob-2.txt",
"--service",
"SERVICE1=service1",
"--service",
Expand All @@ -64,6 +72,7 @@ test("BindingsPlugin: parses options from argv", (t) => {
bindings: { KEY1: "value1", KEY2: "value2" },
globals: { KEY3: "value3", KEY4: "value4" },
wasmBindings: { MODULE1: "module1.wasm", MODULE2: "module2.wasm" },
textBlobBindings: { TEXT1: "text-blob-1.txt", TEXT2: "text-blob-2.txt" },
serviceBindings: {
SERVICE1: "service1",
SERVICE2: { service: "service2", environment: "development" },
Expand Down Expand Up @@ -96,6 +105,10 @@ test("BindingsPlugin: parses options from wrangler config", async (t) => {
MODULE1: "module1.wasm",
MODULE2: "module2.wasm",
},
text_blobs: {
TEXT1: "text-blob-1.txt",
TEXT2: "text-blob-2.txt",
},
experimental_services: [
{ name: "SERVICE1", service: "service1", environment: "development" },
{ name: "SERVICE2", service: "service2", environment: "production" },
Expand All @@ -109,6 +122,7 @@ test("BindingsPlugin: parses options from wrangler config", async (t) => {
envPath: ".env.test",
globals: { KEY5: "value5", KEY6: false, KEY7: 10 },
wasmBindings: { MODULE1: "module1.wasm", MODULE2: "module2.wasm" },
textBlobBindings: { TEXT1: "text-blob-1.txt", TEXT2: "text-blob-2.txt" },
serviceBindings: {
SERVICE1: { service: "service1", environment: "development" },
SERVICE2: { service: "service2", environment: "production" },
Expand Down Expand Up @@ -141,6 +155,7 @@ test("BindingsPlugin: logs options", (t) => {
bindings: { KEY3: "value3", KEY4: "value4" },
globals: { KEY5: "value5", KEY6: "value6" },
wasmBindings: { MODULE1: "module1.wasm", MODULE2: "module2.wasm" },
textBlobBindings: { TEXT1: "text-blob-1.txt", TEXT2: "text-blob-2.txt" },
serviceBindings: {
SERVICE1: "service1",
SERVICE2: { service: "service2", environment: "development" },
Expand All @@ -152,6 +167,7 @@ test("BindingsPlugin: logs options", (t) => {
"Custom Bindings: KEY3, KEY4",
"Custom Globals: KEY5, KEY6",
"WASM Bindings: MODULE1, MODULE2",
"Text Blob Bindings: TEXT1, TEXT2",
"Service Bindings: SERVICE1, SERVICE2",
]);
logs = logPluginOptions(BindingsPlugin, { envPath: true });
Expand Down Expand Up @@ -259,22 +275,40 @@ test("BindingsPlugin: setup: loads WebAssembly bindings", async (t) => {
result = await plugin.setup();
t.not(result.bindings?.ADD, undefined);
});

test("BindingsPlugin: setup: loads text blob bindings", async (t) => {
let plugin = new BindingsPlugin(ctx, {
textBlobBindings: { LOREM_IPSUM: loremIpsumPath },
});
let result = await plugin.setup();
t.is(result.bindings?.LOREM_IPSUM, loremIpsum);

// Check resolves text blob bindings path relative to rootPath
plugin = new BindingsPlugin(
{ log, compat, rootPath: path.dirname(loremIpsumPath) },
{ textBlobBindings: { LOREM_IPSUM: "lorem-ipsum.txt" } }
);
result = await plugin.setup();
t.is(result.bindings?.LOREM_IPSUM, loremIpsum);
});

test("BindingsPlugin: setup: loads bindings from all sources", async (t) => {
// Bindings should be loaded in this order, from lowest to highest priority:
// 1) Wrangler [vars]
// 2) .env Variables
// 3) WASM Module Bindings
// 4) Service Bindings
// 5) Custom Bindings
// 4) Text Blob Bindings
// 5) Service Bindings
// 6) Custom Bindings

// wranglerOptions should contain [kWranglerBindings]
const wranglerOptions = parsePluginWranglerConfig(BindingsPlugin, {
vars: { A: "w", B: "w", C: "w", D: "w", E: "w" },
vars: { A: "w", B: "w", C: "w", D: "w", E: "w", F: "w" },
});

const tmp = await useTmp(t);
const envPath = path.join(tmp, ".env");
await fs.writeFile(envPath, "A=env\nB=env\nC=env\nD=env");
await fs.writeFile(envPath, "A=env\nB=env\nC=env\nD=env\nE=env");

const obj = { ping: "pong" };
const throws = () => {
Expand All @@ -286,6 +320,12 @@ test("BindingsPlugin: setup: loads bindings from all sources", async (t) => {
A: addModulePath,
B: addModulePath,
C: addModulePath,
D: addModulePath,
},
textBlobBindings: {
A: loremIpsumPath,
B: loremIpsumPath,
C: loremIpsumPath,
},
serviceBindings: { A: throws, B: throws },
bindings: { A: obj },
Expand All @@ -294,9 +334,10 @@ test("BindingsPlugin: setup: loads bindings from all sources", async (t) => {
const result = await plugin.setup();
assert(result.bindings);

t.is(result.bindings.E, "w");
t.is(result.bindings.D, "env");
t.true(result.bindings.C instanceof WebAssembly.Module);
t.is(result.bindings.F, "w");
t.is(result.bindings.E, "env");
t.true(result.bindings.D instanceof WebAssembly.Module);
t.is(result.bindings.C, loremIpsum);
t.true(result.bindings.B instanceof Fetcher);
t.is(result.bindings.A, obj);
});
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/wrangler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface WranglerEnvironmentConfig {
}; // inherited
usage_model?: "bundled" | "unbound"; // inherited
wasm_modules?: Record<string, string>; // (probably) inherited
text_blobs?: Record<string, string>;
experimental_services?: {
name: string;
service: string;
Expand Down

0 comments on commit 57dd23d

Please sign in to comment.