Skip to content

Commit

Permalink
add dev-bindings internal-package
Browse files Browse the repository at this point in the history
  • Loading branch information
dario-piotrowicz committed Oct 6, 2023
1 parent 2423529 commit cfdbbc5
Show file tree
Hide file tree
Showing 8 changed files with 867 additions and 23 deletions.
7 changes: 7 additions & 0 deletions internal-packages/dev-bindings/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
root: true,
extends: ['@cloudflare/eslint-config-next-on-pages'],
rules: {
'no-console': 'off',
},
};
3 changes: 3 additions & 0 deletions internal-packages/dev-bindings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Next-on-pages Dev Bindings

## TODO: populate readme
34 changes: 34 additions & 0 deletions internal-packages/dev-bindings/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@cloudflare/next-on-pages-dev-bindings",
"version": "0.0.1",
"main": "dist/index.cjs",
"scripts": {
"lint": "eslint src",
"types-check": "tsc --noEmit",
"build:js": "esbuild --bundle --format=cjs ./src/index.ts --external:miniflare --outfile=./dist/index.cjs --platform=node",
"build:types": "tsc --emitDeclarationOnly --declaration --outDir ./dist",
"build:js:watch": "npm run build:js -- --watch=forever",
"build:types:watch": "npm run build:types -- --watch",
"build": "npm run build:js && npm run build:types",
"build:watch": "npm run build:js:watch & npm run build:types:watch",
"test": "npx vitest --config vitest.config.ts"
},
"files": [
"dist",
"dev-init.cjs",
"dev-init.d.ts",
"devBindingsOptions.ts"
],
"dependencies": {
"miniflare": "^3.20231002.0"
},
"devDependencies": {
"@cloudflare/workers-types": "4.20231002.0",
"@tsconfig/strictest": "^2.0.0",
"esbuild": "^0.15.3",
"eslint": "^8.35.0",
"tsconfig": "*",
"typescript": "^5.0.4",
"vitest": "^0.32.2"
}
}
106 changes: 106 additions & 0 deletions internal-packages/dev-bindings/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Miniflare } from 'miniflare';

export async function setupDevBindings(options: DevBindingsOptions) {
// we let the user define where to persist the data, we default back
// to .wrangler/state/v3 which is the currently used wrangler path
// (this is so that when they switch to wrangler pages dev they can
// still interact with the same data)
const persist = options?.persist ?? '.wrangler/state/v3';

const mf = new Miniflare({
modules: true,
script: '',
...(persist === false
? {
// no data persistence
}
: {
kvPersist: `${persist}/kv`,
durableObjectsPersist: `${persist}/do`,
r2Persist: `${persist}/r2`,
d1Persist: `${persist}/d1`,
}),
...(options ?? {}),
});

const bindingsCollections = await Promise.all([
collectBindings(mf, 'KV', options?.kvNamespaces ?? []),
collectBindings(mf, 'DO', options?.durableObjects ?? []),
collectBindings(mf, 'R2', options?.r2Buckets ?? []),
collectBindings(mf, 'D1', options?.d1Databases ?? []),
]);

const bindings = bindingsCollections.flat();

// eslint-disable-next-line @typescript-eslint/no-var-requires
const vmModule = require('vm');
const originalRunInContext = vmModule.runInContext.bind(vmModule);

vmModule.runInContext = (
...args: [
string,
{ process?: { env?: Record<string, unknown> } },
...[unknown],
]
) => {
const runtimeContext = args[1];
if (
runtimeContext.process?.env &&
!runtimeContext.process?.env?.['BINDINGS_PROXY_SET']
) {
for (const binding of bindings) {
runtimeContext.process.env[binding.name] = binding.binding;
}

runtimeContext.process.env['BINDINGS_PROXY_SET'] = true;
}

return originalRunInContext(...args);
};
}

async function collectBindings(
mf: Miniflare,
type: 'KV' | 'DO' | 'R2' | 'D1',
bindingsOpts: string[] | Record<string, unknown>,
) {
const bindingNames = getBindingsNames(bindingsOpts);
const bindingGetterFn = {
KV: mf.getKVNamespace.bind(mf),
DO: mf.getDurableObjectNamespace.bind(mf),
R2: mf.getR2Bucket.bind(mf),
D1: mf.getD1Database.bind(mf),
}[type];
return Promise.all(
bindingNames.map(async bindingName => {
return {
name: bindingName,
type,
binding: await bindingGetterFn(bindingName),
};
}),
);
}

function getBindingsNames(
bindings: string[] | Record<string, unknown>,
): string[] {
if (Array.isArray(bindings)) return bindings;
return Object.keys(bindings);
}

export type DevBindingsOptions = {
kvNamespaces?: string[] | Record<string, string>;
durableObjects?: Record<
string,
| string
| {
scriptName?: string | undefined;
unsafeUniqueKey?: string | undefined;
className: string;
}
>;
r2Buckets?: string[] | Record<string, string>;
d1Databases?: string[] | Record<string, string>;
persist?: false | string;
};
4 changes: 4 additions & 0 deletions internal-packages/dev-bindings/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "@cloudflare/next-on-pages-tsconfig/tsconfig.json",
"include": [".eslintrc.js", "src", "dev-init.cjs", "devBindingsOptions.ts"]
}
2 changes: 1 addition & 1 deletion internal-packages/docs-scraper/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "docs-scraper",
"name": "@cloudflare/next-on-pages-docs-scraper",
"private": true,
"scripts": {
"lint": "eslint scripts",
Expand Down
Loading

0 comments on commit cfdbbc5

Please sign in to comment.