Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make wrangler an optional peer dependency #12452

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/fast-mayflies-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@sveltejs/adapter-cloudflare-workers': minor
'@sveltejs/adapter-cloudflare': minor
---

feat: make wrangler an optional peer dependency
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
link-workspace-packages = true
auto-install-peers = false
3 changes: 3 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default [
'**/.svelte-kit',
'packages/adapter-static/test/apps/*/build',
'packages/adapter-cloudflare/files',
'packages/adapter-cloudflare-workers/files',
'packages/adapter-netlify/files',
'packages/adapter-node/files'
]
Expand All @@ -29,6 +30,8 @@ export default [
'@typescript-eslint/require-await': 'error'
},
ignores: [
'packages/adapter-cloudflare/index.js',
'packages/adapter-cloudflare-workers/index.js',
'packages/adapter-node/rollup.config.js',
'packages/adapter-node/tests/smoke.spec.js',
'packages/adapter-static/test/apps/**/*',
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@
},
"devDependencies": {
"@changesets/cli": "^2.27.8",
"@stylistic/eslint-plugin-js": "^2.3.0",
"@sveltejs/eslint-config": "^8.1.0",
"@svitejs/changesets-changelog-github-compact": "^1.1.0",
"eslint": "^9.6.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-n": "^17.9.0",
"eslint-plugin-svelte": "^2.41.0",
"playwright": "^1.44.1",
"typescript-eslint": "^8.0.0"
},
Expand Down
3 changes: 1 addition & 2 deletions packages/adapter-cloudflare-workers/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
.DS_Store
node_modules
/files
52 changes: 29 additions & 23 deletions packages/adapter-cloudflare-workers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { execSync } from 'node:child_process';
import esbuild from 'esbuild';
import toml from '@iarna/toml';
import { fileURLToPath } from 'node:url';
import { getPlatformProxy } from 'wrangler';

let wrangler;
try {
wrangler = await import('wrangler');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of TLA with swallowing the error, what about lazily importing it when a feature is used that requires it and then logging a message asking the user to install wrangler to support it?

} catch {}

/**
* @typedef {{
Expand Down Expand Up @@ -149,33 +153,35 @@ export default function ({ config = 'wrangler.toml', platformProxy = {} } = {})
builder.writePrerendered(bucket_dir);
},

async emulate() {
const proxy = await getPlatformProxy(platformProxy);
const platform = /** @type {App.Platform} */ ({
env: proxy.env,
context: proxy.ctx,
caches: proxy.caches,
cf: proxy.cf
});
emulate: !wrangler
? undefined
: async function () {
const proxy = await getPlatformProxy(platformProxy);
const platform = /** @type {App.Platform} */ ({
env: proxy.env,
context: proxy.ctx,
caches: proxy.caches,
cf: proxy.cf
});

/** @type {Record<string, any>} */
const env = {};
const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env }));
/** @type {Record<string, any>} */
const env = {};
const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env }));

for (const key in proxy.env) {
Object.defineProperty(env, key, {
get: () => {
throw new Error(`Cannot access platform.env.${key} in a prerenderable route`);
for (const key in proxy.env) {
Object.defineProperty(env, key, {
get: () => {
throw new Error(`Cannot access platform.env.${key} in a prerenderable route`);
}
});
}
});
}

return {
platform: ({ prerender }) => {
return prerender ? prerender_platform : platform;
return {
platform: ({ prerender }) => {
return prerender ? prerender_platform : platform;
}
};
}
};
}
};
}

Expand Down
5 changes: 5 additions & 0 deletions packages/adapter-cloudflare-workers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@
"peerDependencies": {
"@sveltejs/kit": "^2.0.0",
"wrangler": "^3.28.4"
},
"peerDependenciesMeta": {
"wrangler": {
"optional": true
}
}
}
2 changes: 1 addition & 1 deletion packages/adapter-cloudflare-workers/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
"@sveltejs/kit": ["../kit/types/index"]
}
},
"include": ["**/*.js", "placeholders.d.ts"]
"include": ["*.js", "*.d.ts"]
}
116 changes: 116 additions & 0 deletions packages/adapter-cloudflare-workers/wrangler.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import type { IncomingRequestCfProperties } from '@cloudflare/workers-types/experimental';

declare class ExecutionContext {
waitUntil(promise: Promise<any>): void;
passThroughOnException(): void;
}

declare type CacheQueryOptions_2 = {
ignoreMethod?: boolean;
};

declare type CacheRequest = any;

declare type CacheResponse = any;

/**
* No-op implementation of Cache
*/
declare class Cache_2 {
delete(request: CacheRequest, options?: CacheQueryOptions_2): Promise<boolean>;
match(request: CacheRequest, options?: CacheQueryOptions_2): Promise<CacheResponse | undefined>;
put(request: CacheRequest, response: CacheResponse): Promise<void>;
}

/**
* No-op implementation of CacheStorage
*/
declare class CacheStorage_2 {
constructor();
open(cacheName: string): Promise<Cache_2>;
get default(): Cache_2;
}

/**
* Result of the `getPlatformProxy` utility
*/
export declare type PlatformProxy<
Env = Record<string, unknown>,
CfProperties extends Record<string, unknown> = IncomingRequestCfProperties
> = {
/**
* Environment object containing the various Cloudflare bindings
*/
env: Env;
/**
* Mock of the context object that Workers received in their request handler, all the object's methods are no-op
*/
cf: CfProperties;
/**
* Mock of the context object that Workers received in their request handler, all the object's methods are no-op
*/
ctx: ExecutionContext;
/**
* Caches object emulating the Workers Cache runtime API
*/
caches: CacheStorage_2;
/**
* Function used to dispose of the child process providing the bindings implementation
*/
dispose: () => Promise<void>;
};

/**
* By reading from a `wrangler.toml` file this function generates proxy objects that can be
* used to simulate the interaction with the Cloudflare platform during local development
* in a Node.js environment
*
* @param options The various options that can tweak this function's behavior
* @returns An Object containing the generated proxies alongside other related utilities
*/
export declare function getPlatformProxy<
Env = Record<string, unknown>,
CfProperties extends Record<string, unknown> = IncomingRequestCfProperties
>(options?: GetPlatformProxyOptions): Promise<PlatformProxy<Env, CfProperties>>;

/**
* Options for the `getPlatformProxy` utility
*/
export declare type GetPlatformProxyOptions = {
/**
* The name of the environment to use
*/
environment?: string;
/**
* The path to the config file to use.
* If no path is specified the default behavior is to search from the
* current directory up the filesystem for a `wrangler.toml` to use.
*
* Note: this field is optional but if a path is specified it must
* point to a valid file on the filesystem
*/
configPath?: string;
/**
* Flag to indicate the utility to read a json config file (`wrangler.json`)
* instead of the toml one (`wrangler.toml`)
*
* Note: this feature is experimental
*/
experimentalJsonConfig?: boolean;
/**
* Indicates if and where to persist the bindings data, if not present or `true` it defaults to the same location
* used by wrangler v3: `.wrangler/state/v3` (so that the same data can be easily used by the caller and wrangler).
* If `false` is specified no data is persisted on the filesystem.
*/
persist?:
| boolean
| {
path: string;
};
/**
* Use the experimental file-based dev registry for service discovery
*
* Note: this feature is experimental
*/
experimentalRegistry?: boolean;
};
52 changes: 29 additions & 23 deletions packages/adapter-cloudflare/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { existsSync, writeFileSync } from 'node:fs';
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
import * as esbuild from 'esbuild';
import { getPlatformProxy } from 'wrangler';

let wrangler;
try {
wrangler = await import('wrangler');
} catch {}

// list from https://developers.cloudflare.com/workers/runtime-apis/nodejs/
const compatible_node_modules = [
Expand Down Expand Up @@ -144,33 +148,35 @@ export default function (options = {}) {
);
}
},
async emulate() {
const proxy = await getPlatformProxy(options.platformProxy);
const platform = /** @type {App.Platform} */ ({
env: proxy.env,
context: proxy.ctx,
caches: proxy.caches,
cf: proxy.cf
});
emulate: !wrangler
? undefined
: async function () {
const proxy = await wrangler.getPlatformProxy(options.platformProxy);
const platform = /** @type {App.Platform} */ ({
env: proxy.env,
context: proxy.ctx,
caches: proxy.caches,
cf: proxy.cf
});

/** @type {Record<string, any>} */
const env = {};
const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env }));
/** @type {Record<string, any>} */
const env = {};
const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env }));

for (const key in proxy.env) {
Object.defineProperty(env, key, {
get: () => {
throw new Error(`Cannot access platform.env.${key} in a prerenderable route`);
for (const key in proxy.env) {
Object.defineProperty(env, key, {
get: () => {
throw new Error(`Cannot access platform.env.${key} in a prerenderable route`);
}
});
}
});
}

return {
platform: ({ prerender }) => {
return prerender ? prerender_platform : platform;
return {
platform: ({ prerender }) => {
return prerender ? prerender_platform : platform;
}
};
}
};
}
};
}

Expand Down
8 changes: 8 additions & 0 deletions packages/adapter-cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,13 @@
"peerDependencies": {
"@sveltejs/kit": "^2.0.0",
"wrangler": "^3.28.4"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"wrangler": "^3.28.4"
"wrangler": "^3.80.0"

},
"peerDependenciesMeta": {
"wrangler": {
"optional": true
}
},
"publishConfig": {
"access": "public"
}
}
2 changes: 1 addition & 1 deletion packages/adapter-cloudflare/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
"@sveltejs/kit": ["../kit/types/index"]
}
},
"include": ["index.js", "placeholders.d.ts", "src/worker.js"]
"include": ["*.js", "src/*.js", "*.d.ts"]
}
Loading
Loading