@opennextjs/cloudflare 0.0.0-11802c4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +25 -0
- package/README.md +84 -0
- package/dist/api/chunk-VTBEIZPQ.mjs +32 -0
- package/dist/api/get-cloudflare-context.d.mts +26 -0
- package/dist/api/get-cloudflare-context.mjs +6 -0
- package/dist/api/index.d.mts +1 -0
- package/dist/api/index.mjs +6 -0
- package/dist/cli/cache-handler.mjs +48 -0
- package/dist/cli/chunk-UJCSKKID.mjs +30 -0
- package/dist/cli/index.mjs +7213 -0
- package/dist/cli/templates/shims/empty.ts +1 -0
- package/dist/cli/templates/shims/env.ts +1 -0
- package/dist/cli/templates/shims/node-fs.ts +69 -0
- package/dist/cli/templates/shims/throw.ts +1 -0
- package/dist/cli/templates/worker.ts +145 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Copyright (c) 2020 Cloudflare, Inc.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any
|
|
4
|
+
person obtaining a copy of this software and associated
|
|
5
|
+
documentation files (the "Software"), to deal in the
|
|
6
|
+
Software without restriction, including without
|
|
7
|
+
limitation the rights to use, copy, modify, merge,
|
|
8
|
+
publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software
|
|
10
|
+
is furnished to do so, subject to the following
|
|
11
|
+
conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice
|
|
14
|
+
shall be included in all copies or substantial portions
|
|
15
|
+
of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
18
|
+
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
19
|
+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
20
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
21
|
+
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
22
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
23
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
24
|
+
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
25
|
+
DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# OpenNext for Cloudflare
|
|
2
|
+
|
|
3
|
+
Deploy Next.js apps to Cloudflare!
|
|
4
|
+
|
|
5
|
+
[OpenNext for Cloudflare](https://opennext.js.org/cloudflare) is Cloudflare specific adapter that enables deployment of Next.js applications to Cloudflare.
|
|
6
|
+
|
|
7
|
+
## Getting started
|
|
8
|
+
|
|
9
|
+
You can use [`create-next-app`](https://nextjs.org/docs/pages/api-reference/cli/create-next-app) to start a new application or take an existing Next.js application and deploy it to Cloudflare using the following few steps:
|
|
10
|
+
|
|
11
|
+
## Configure your app
|
|
12
|
+
|
|
13
|
+
- add the following `devDependencies` to the `package.json`:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add -D wrangler@latest @opennextjs/cloudflare
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- add a `wrangler.toml` at the root of your project
|
|
20
|
+
|
|
21
|
+
```toml
|
|
22
|
+
#:schema node_modules/wrangler/config-schema.json
|
|
23
|
+
name = "<your-app-name>"
|
|
24
|
+
main = ".worker-next/index.mjs"
|
|
25
|
+
|
|
26
|
+
compatibility_date = "2024-09-23"
|
|
27
|
+
compatibility_flags = ["nodejs_compat"]
|
|
28
|
+
|
|
29
|
+
# Use the new Workers + Assets to host the static frontend files
|
|
30
|
+
assets = { directory = ".worker-next/assets", binding = "ASSETS" }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
You can enable Incremental Static Regeneration ([ISR](https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration)) by adding a KV binding named `NEXT_CACHE_WORKERS_KV` to your `wrangler.toml`:
|
|
34
|
+
|
|
35
|
+
- Create the binding
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx wrangler kv namespace create NEXT_CACHE_WORKERS_KV
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- Paste the snippet to your `wrangler.toml`:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
[[kv_namespaces]]
|
|
45
|
+
binding = "NEXT_CACHE_WORKERS_KV"
|
|
46
|
+
id = "..."
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> [!WARNING]
|
|
50
|
+
> The current support for ISR is limited.
|
|
51
|
+
|
|
52
|
+
## Local development
|
|
53
|
+
|
|
54
|
+
- you can use the regular `next` CLI to start the Next.js dev server:
|
|
55
|
+
|
|
56
|
+
## Local preview
|
|
57
|
+
|
|
58
|
+
Run the following commands to preview the production build of your application locally:
|
|
59
|
+
|
|
60
|
+
- build the app and adapt it for Cloudflare
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pnpx cloudflare
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Preview the app in Wrangler
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pnpm wrangler dev
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Deploy your app
|
|
73
|
+
|
|
74
|
+
Deploy your application to production with the following:
|
|
75
|
+
|
|
76
|
+
- build the app and adapt it for Cloudflare
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pnpx cloudflare
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm wrangler deploy
|
|
84
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/api/get-cloudflare-context.ts
|
|
2
|
+
import "server-only";
|
|
3
|
+
var cloudflareContextSymbol = Symbol.for("__cloudflare-context__");
|
|
4
|
+
async function getCloudflareContext() {
|
|
5
|
+
const global = globalThis;
|
|
6
|
+
const cloudflareContext = global[cloudflareContextSymbol];
|
|
7
|
+
if (!cloudflareContext) {
|
|
8
|
+
return getCloudflareContextInNextDev();
|
|
9
|
+
}
|
|
10
|
+
return cloudflareContext;
|
|
11
|
+
}
|
|
12
|
+
var cloudflareContextInNextDevSymbol = Symbol.for("__next-dev/cloudflare-context__");
|
|
13
|
+
async function getCloudflareContextInNextDev() {
|
|
14
|
+
const global = globalThis;
|
|
15
|
+
if (!global[cloudflareContextInNextDevSymbol]) {
|
|
16
|
+
const { getPlatformProxy } = await import(
|
|
17
|
+
/* webpackIgnore: true */
|
|
18
|
+
`${"__wrangler".replaceAll("_", "")}`
|
|
19
|
+
);
|
|
20
|
+
const { env, cf, ctx } = await getPlatformProxy();
|
|
21
|
+
global[cloudflareContextInNextDevSymbol] = {
|
|
22
|
+
env,
|
|
23
|
+
cf,
|
|
24
|
+
ctx
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return global[cloudflareContextInNextDevSymbol];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
getCloudflareContext
|
|
32
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface CloudflareEnv {
|
|
3
|
+
}
|
|
4
|
+
}
|
|
5
|
+
type CloudflareContext<CfProperties extends Record<string, unknown> = IncomingRequestCfProperties, Context = ExecutionContext> = {
|
|
6
|
+
/**
|
|
7
|
+
* the worker's [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/)
|
|
8
|
+
*/
|
|
9
|
+
env: CloudflareEnv;
|
|
10
|
+
/**
|
|
11
|
+
* the request's [cf properties](https://developers.cloudflare.com/workers/runtime-apis/request/#the-cf-property-requestinitcfproperties)
|
|
12
|
+
*/
|
|
13
|
+
cf: CfProperties;
|
|
14
|
+
/**
|
|
15
|
+
* the current [execution context](https://developers.cloudflare.com/workers/runtime-apis/context)
|
|
16
|
+
*/
|
|
17
|
+
ctx: Context;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Utility to get the current Cloudflare context
|
|
21
|
+
*
|
|
22
|
+
* @returns the cloudflare context
|
|
23
|
+
*/
|
|
24
|
+
declare function getCloudflareContext<CfProperties extends Record<string, unknown> = IncomingRequestCfProperties, Context = ExecutionContext>(): Promise<CloudflareContext<CfProperties, Context>>;
|
|
25
|
+
|
|
26
|
+
export { type CloudflareContext, getCloudflareContext };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CloudflareContext, getCloudflareContext } from './get-cloudflare-context.mjs';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import "./chunk-UJCSKKID.mjs";
|
|
2
|
+
|
|
3
|
+
// src/cli/cache-handler.ts
|
|
4
|
+
var CfWorkersKvCacheHandler = class _CfWorkersKvCacheHandler {
|
|
5
|
+
constructor(ctx) {
|
|
6
|
+
this.ctx = ctx;
|
|
7
|
+
}
|
|
8
|
+
static maybeKVNamespace = void 0;
|
|
9
|
+
async get(key) {
|
|
10
|
+
if (_CfWorkersKvCacheHandler.maybeKVNamespace === void 0) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
console.log(`[Cf] Getting cache[${key}]`);
|
|
14
|
+
try {
|
|
15
|
+
return await _CfWorkersKvCacheHandler.maybeKVNamespace.get(key, "json") ?? null;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.error(`Failed to get value for key = ${key}: ${e}`);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async set(key, entry, ctx) {
|
|
22
|
+
if (_CfWorkersKvCacheHandler.maybeKVNamespace === void 0) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log(`[Cf] Setting cache[${key}]`);
|
|
26
|
+
try {
|
|
27
|
+
const data = {
|
|
28
|
+
lastModified: Date.now(),
|
|
29
|
+
value: entry
|
|
30
|
+
};
|
|
31
|
+
await _CfWorkersKvCacheHandler.maybeKVNamespace.put(key, JSON.stringify(data));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.error(`Failed to set value for key = ${key}: ${e}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async revalidateTag(tags) {
|
|
37
|
+
if (_CfWorkersKvCacheHandler.maybeKVNamespace === void 0) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
tags = [tags].flat();
|
|
41
|
+
console.log(`[Cf] revalidateTag ${JSON.stringify(tags)}}`);
|
|
42
|
+
}
|
|
43
|
+
resetRequestCache() {
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export {
|
|
47
|
+
CfWorkersKvCacheHandler as default
|
|
48
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
__commonJS,
|
|
29
|
+
__toESM
|
|
30
|
+
};
|