Netlify Blobs: accessing from function (inside SvelteKit app) requiring explicit token, siteId, deployId

I’ve attempted to write an adapter for SvelteKit to be able to use Functions API v2, and in turn, Netlify Blobs as well. It seems to be working fine for me. I could submit a PR to SvelteKit repo, but it might not be merged any time soon. I could also release this as a separate NPM package, but before I do that, it would be great if others can let me know their experience. To opt it, add the following code to a JS file (call it adapter.js for example):

import { build } from 'esbuild';
import { builtinModules } from 'node:module';
import { cwd } from 'node:process';
import { join, relative } from 'node:path';
import { resolveConfig } from '@netlify/config';
import { writeFileSync } from 'node:fs';
const fn_name = 'SvelteKit Server';
const generator = '@netlify/adapter-sveltekit@5.0.0';
const working_dir = cwd();
const ntl_frameworks_api_dir = join(working_dir, './.netlify/v1/');
const sk_server_dir = join(working_dir, './.svelte-kit/netlify/');
async function init(builder) {
    const ntl_config = await resolveConfig({});
    const ntl_config_json = {
        build: {
            publish: ntl_config.config.build.publish
        },
        headers: [{
                for: `/${builder.getAppPath()}/immutable/*`,
                values: {
                    'cache-control': 'immutable, public, max-age=3153600'
                }
            }]
    };
    if (ntl_config_json.build.publish === working_dir || !ntl_config_json.build.publish) {
        ntl_config_json.build.publish = join(working_dir, './build/');
    }
    const sk_publish_path = join(ntl_config_json.build.publish, builder.config.kit.paths.base);
    builder.rimraf(ntl_config_json.build.publish);
    builder.rimraf(ntl_frameworks_api_dir);
    builder.rimraf(sk_server_dir);
    builder.mkdirp(ntl_frameworks_api_dir);
    builder.writeClient(sk_publish_path);
    builder.writePrerendered(sk_publish_path);
    builder.writeServer(sk_server_dir);
    writeFileSync(join(ntl_frameworks_api_dir, './config.json'), JSON.stringify(ntl_config_json));
}
export function adapterNetlifyEdgeFunctions(options = {}) {
    return {
        async adapt(builder) {
            await init(builder);
            const ntl_edge_functions_dir = join(ntl_frameworks_api_dir, './edge-functions/');
            const efn = `import {Server} from '${join(builder.getServerDirectory(), './index.js')}'
const server = new Server(${builder.generateManifest({
                relativePath: './'
            })})
await server.init({
  env: Deno.env.toObject()
})
export default async function(req, context) {
  return server.respond(req, {
    getClientAddress() {
      return context.ip
    },
    platform: {
      context
    }
  })
}
export const config = {
  excludedPath: ${JSON.stringify([
                '/.netlify/*',
                `/${builder.getAppPath()}/immutable/*`
            ].concat(builder.prerendered.paths).concat(options.excludedPath || []))},
  generator: '${generator}',
  name: '${fn_name}',
  onError: ${JSON.stringify(options.onError || undefined)},
  path: '/*',
  rateLimit: ${JSON.stringify(options.rateLimit || {})}
}`;
            builder.mkdirp(ntl_edge_functions_dir);
            writeFileSync(join(sk_server_dir, './sk-server.js'), efn);
            await build({
                alias: Object.fromEntries(builtinModules.map(id => [
                    id,
                    `node:${id}`
                ])),
                bundle: true,
                entryPoints: [
                    join(sk_server_dir, './sk-server.js')
                ],
                external: builtinModules.map(id => `node:${id}`),
                format: 'esm',
                outfile: join(ntl_edge_functions_dir, './sk-server.js'),
                platform: 'browser',
                target: 'esnext'
            });
        },
        name: generator,
        supports: {
            read(config) {
                throw new Error(`${generator} cannot use \`read\` from \`$apps/server\' in route \`${config.route.id}\`, switch to \`adapterNetlifyFunctions\``);
            }
        }
    };
}
export function adapterNetlifyFunctions(options = {}) {
    return {
        async adapt(builder) {
            await init(builder);
            const ntl_functions_dir = join(ntl_frameworks_api_dir, './functions/');
            const fn = `import {env} from 'node:process'
import {File} from 'node:buffer'
import {Server} from '${join(builder.getServerDirectory(), './index.js')}'
import {webcrypto} from 'node:crypto'
for (const name in {
  crypto: webcrypto,
  File
}) {
  if (name in globalThis) {
    continue
  }
  Object.defineProperty(globalThis, name, {
    configurable: true,
    enumerable: true,
    value: globals[name],
    writable: true
  })
}
const server = new Server(${builder.generateManifest({
                relativePath: relative(ntl_functions_dir, sk_server_dir)
            })})
await server.init({
  env
})
export default async function(req, context) {
  return server.respond(req, {
    getClientAddress() {
      return context.ip
    },
    platform: {
      context
    }
  })
}
export const config = {
  displayName: '${fn_name}',
  excludedPath: ${JSON.stringify([
                '/.netlify/*'
            ].concat(options.excludedPath || []))},
  generator: '${generator}',
  path: '/*',
  preferStatic: true,
  rateLimit: ${JSON.stringify(options.rateLimit || {})}
}`;
            builder.mkdirp(ntl_functions_dir);
            writeFileSync(join(ntl_functions_dir, './sk-server.js'), fn);
        },
        name: generator
    };
}

In your svelte.config.js:

- import adapter from '@sveltejs/adapter-netlify'
+ import {adapterNetlifyFunctions} from './adapter.js' // change the path to the adapter.js file
const config = {
  ...
  kit: {
    adapter: adapterNetlifyFunctions({}),
  }
  ...
}

Also, install the following dependencies:

esbuild
@netlify/config

Feel free to let me know if someone runs into any issues due to this adapter. The feedback will help to test and release this.