@notionx/core 0.1.0
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/dist/admin/index.d.ts +137 -0
- package/dist/admin/index.js +206 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/index.d.ts +324 -0
- package/dist/admin/pages/index.js +827 -0
- package/dist/admin/pages/index.js.map +1 -0
- package/dist/auth/auth-pages/forgot-password.d.ts +20 -0
- package/dist/auth/auth-pages/forgot-password.js +70 -0
- package/dist/auth/auth-pages/forgot-password.js.map +1 -0
- package/dist/auth/auth-pages/index.d.ts +6 -0
- package/dist/auth/auth-pages/index.js +342 -0
- package/dist/auth/auth-pages/index.js.map +1 -0
- package/dist/auth/auth-pages/login.d.ts +30 -0
- package/dist/auth/auth-pages/login.js +125 -0
- package/dist/auth/auth-pages/login.js.map +1 -0
- package/dist/auth/auth-pages/register.d.ts +17 -0
- package/dist/auth/auth-pages/register.js +81 -0
- package/dist/auth/auth-pages/register.js.map +1 -0
- package/dist/auth/auth-pages/reset-password.d.ts +18 -0
- package/dist/auth/auth-pages/reset-password.js +72 -0
- package/dist/auth/auth-pages/reset-password.js.map +1 -0
- package/dist/auth/index.d.ts +72 -0
- package/dist/auth/index.js +1011 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/passwords.d.ts +6 -0
- package/dist/auth/passwords.js +79 -0
- package/dist/auth/passwords.js.map +1 -0
- package/dist/auth/rate-limit.d.ts +28 -0
- package/dist/auth/rate-limit.js +245 -0
- package/dist/auth/rate-limit.js.map +1 -0
- package/dist/auth/routes/google-callback.d.ts +6 -0
- package/dist/auth/routes/google-callback.js +404 -0
- package/dist/auth/routes/google-callback.js.map +1 -0
- package/dist/auth/routes/google.d.ts +6 -0
- package/dist/auth/routes/google.js +250 -0
- package/dist/auth/routes/google.js.map +1 -0
- package/dist/auth/routes/index.d.ts +22 -0
- package/dist/auth/routes/index.js +619 -0
- package/dist/auth/routes/index.js.map +1 -0
- package/dist/auth/routes/verify-email.d.ts +6 -0
- package/dist/auth/routes/verify-email.js +317 -0
- package/dist/auth/routes/verify-email.js.map +1 -0
- package/dist/auth/routes/viewer.d.ts +6 -0
- package/dist/auth/routes/viewer.js +372 -0
- package/dist/auth/routes/viewer.js.map +1 -0
- package/dist/auth/session.d.ts +9 -0
- package/dist/auth/session.js +1 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/auth/turnstile.d.ts +20 -0
- package/dist/auth/turnstile.js +301 -0
- package/dist/auth/turnstile.js.map +1 -0
- package/dist/auth/user-session.d.ts +42 -0
- package/dist/auth/user-session.js +419 -0
- package/dist/auth/user-session.js.map +1 -0
- package/dist/auth/users.d.ts +112 -0
- package/dist/auth/users.js +558 -0
- package/dist/auth/users.js.map +1 -0
- package/dist/bootstrap-CN2g76M6.d.ts +67 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.js +47 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/content/admin-summary.d.ts +24 -0
- package/dist/content/admin-summary.js +36 -0
- package/dist/content/admin-summary.js.map +1 -0
- package/dist/content/index.d.ts +9 -0
- package/dist/content/index.js +473 -0
- package/dist/content/index.js.map +1 -0
- package/dist/content/models.d.ts +69 -0
- package/dist/content/models.js +24 -0
- package/dist/content/models.js.map +1 -0
- package/dist/content/prewarm.d.ts +28 -0
- package/dist/content/prewarm.js +56 -0
- package/dist/content/prewarm.js.map +1 -0
- package/dist/content/revalidate.d.ts +37 -0
- package/dist/content/revalidate.js +170 -0
- package/dist/content/revalidate.js.map +1 -0
- package/dist/content/search-index.d.ts +54 -0
- package/dist/content/search-index.js +172 -0
- package/dist/content/search-index.js.map +1 -0
- package/dist/content/search.d.ts +8 -0
- package/dist/content/search.js +57 -0
- package/dist/content/search.js.map +1 -0
- package/dist/doctor/cli.d.ts +1 -0
- package/dist/doctor/cli.js +360 -0
- package/dist/doctor/cli.js.map +1 -0
- package/dist/doctor/index.d.ts +139 -0
- package/dist/doctor/index.js +289 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/email/index.d.ts +38 -0
- package/dist/email/index.js +126 -0
- package/dist/email/index.js.map +1 -0
- package/dist/env-C5qu-0R-.d.ts +35 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/i18n/index.d.ts +26 -0
- package/dist/i18n/index.js +73 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +1281 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/admin/index.d.ts +75 -0
- package/dist/internal/admin/index.js +365 -0
- package/dist/internal/admin/index.js.map +1 -0
- package/dist/media/index.d.ts +24 -0
- package/dist/media/index.js +86 -0
- package/dist/media/index.js.map +1 -0
- package/dist/media/routes/index.d.ts +1 -0
- package/dist/media/routes/index.js +585 -0
- package/dist/media/routes/index.js.map +1 -0
- package/dist/media/routes/notion-media.d.ts +19 -0
- package/dist/media/routes/notion-media.js +588 -0
- package/dist/media/routes/notion-media.js.map +1 -0
- package/dist/middleware.d.ts +95 -0
- package/dist/middleware.js +79 -0
- package/dist/middleware.js.map +1 -0
- package/dist/notion/block-text.d.ts +5 -0
- package/dist/notion/block-text.js +37 -0
- package/dist/notion/block-text.js.map +1 -0
- package/dist/notion/blocks.d.ts +24 -0
- package/dist/notion/blocks.js +46 -0
- package/dist/notion/blocks.js.map +1 -0
- package/dist/notion/client.d.ts +7 -0
- package/dist/notion/client.js +13 -0
- package/dist/notion/client.js.map +1 -0
- package/dist/notion/config.d.ts +25 -0
- package/dist/notion/config.js +147 -0
- package/dist/notion/config.js.map +1 -0
- package/dist/notion/content-cache.d.ts +45 -0
- package/dist/notion/content-cache.js +166 -0
- package/dist/notion/content-cache.js.map +1 -0
- package/dist/notion/generic-source.d.ts +61 -0
- package/dist/notion/generic-source.js +408 -0
- package/dist/notion/generic-source.js.map +1 -0
- package/dist/notion/index.d.ts +13 -0
- package/dist/notion/index.js +1278 -0
- package/dist/notion/index.js.map +1 -0
- package/dist/notion/mappers.d.ts +1 -0
- package/dist/notion/mappers.js +152 -0
- package/dist/notion/mappers.js.map +1 -0
- package/dist/notion/media.d.ts +22 -0
- package/dist/notion/media.js +209 -0
- package/dist/notion/media.js.map +1 -0
- package/dist/notion/property-mappers.d.ts +24 -0
- package/dist/notion/property-mappers.js +152 -0
- package/dist/notion/property-mappers.js.map +1 -0
- package/dist/notion/routes/index.d.ts +8 -0
- package/dist/notion/routes/index.js +428 -0
- package/dist/notion/routes/index.js.map +1 -0
- package/dist/notion/routes/webhook.d.ts +98 -0
- package/dist/notion/routes/webhook.js +428 -0
- package/dist/notion/routes/webhook.js.map +1 -0
- package/dist/notion/types.d.ts +152 -0
- package/dist/notion/types.js +1 -0
- package/dist/notion/types.js.map +1 -0
- package/dist/notion/webhook.d.ts +83 -0
- package/dist/notion/webhook.js +490 -0
- package/dist/notion/webhook.js.map +1 -0
- package/dist/platform/capabilities.d.ts +34 -0
- package/dist/platform/capabilities.js +42 -0
- package/dist/platform/capabilities.js.map +1 -0
- package/dist/platform/current.d.ts +13 -0
- package/dist/platform/current.js +181 -0
- package/dist/platform/current.js.map +1 -0
- package/dist/platform/index.d.ts +5 -0
- package/dist/platform/index.js +269 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/runtime.d.ts +118 -0
- package/dist/platform/runtime.js +160 -0
- package/dist/platform/runtime.js.map +1 -0
- package/dist/platform/selection.d.ts +10 -0
- package/dist/platform/selection.js +22 -0
- package/dist/platform/selection.js.map +1 -0
- package/dist/storage/index.d.ts +17 -0
- package/dist/storage/index.js +218 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/routes/cdn.d.ts +19 -0
- package/dist/storage/routes/cdn.js +289 -0
- package/dist/storage/routes/cdn.js.map +1 -0
- package/dist/storage/routes/files.d.ts +27 -0
- package/dist/storage/routes/files.js +216 -0
- package/dist/storage/routes/files.js.map +1 -0
- package/dist/storage/routes/index.d.ts +2 -0
- package/dist/storage/routes/index.js +352 -0
- package/dist/storage/routes/index.js.map +1 -0
- package/dist/types-BsAcZSNX.d.ts +94 -0
- package/dist/types.d.ts +78 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/util/index.d.ts +18 -0
- package/dist/util/index.js +48 -0
- package/dist/util/index.js.map +1 -0
- package/dist/worker/index.d.ts +6 -0
- package/dist/worker/index.js +1026 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/routes/content-prewarm.d.ts +34 -0
- package/dist/worker/routes/content-prewarm.js +38 -0
- package/dist/worker/routes/content-prewarm.js.map +1 -0
- package/dist/worker/routes/content-revalidate.d.ts +81 -0
- package/dist/worker/routes/content-revalidate.js +64 -0
- package/dist/worker/routes/content-revalidate.js.map +1 -0
- package/dist/worker/routes/health.d.ts +14 -0
- package/dist/worker/routes/health.js +278 -0
- package/dist/worker/routes/health.js.map +1 -0
- package/dist/worker/routes/index.d.ts +6 -0
- package/dist/worker/routes/index.js +373 -0
- package/dist/worker/routes/index.js.map +1 -0
- package/package.json +124 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SqlDatabaseAdapter, KeyValueCacheAdapter, PublicCacheAdapter, RuntimePlatform } from './runtime.js';
|
|
2
|
+
import { currentRuntimeId } from './selection.js';
|
|
3
|
+
import '../env-C5qu-0R-.js';
|
|
4
|
+
|
|
5
|
+
declare function getRuntimePlatform(): RuntimePlatform;
|
|
6
|
+
declare function getDatabase(): SqlDatabaseAdapter;
|
|
7
|
+
declare function getPublicCache(): PublicCacheAdapter;
|
|
8
|
+
declare function getKeyValueCache(): KeyValueCacheAdapter | null;
|
|
9
|
+
declare const runtimeSelection: {
|
|
10
|
+
currentRuntimeId: typeof currentRuntimeId;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { getDatabase, getKeyValueCache, getPublicCache, getRuntimePlatform, runtimeSelection };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// src/util/env.ts
|
|
2
|
+
import { env } from "cloudflare:workers";
|
|
3
|
+
var workerEnv = env;
|
|
4
|
+
|
|
5
|
+
// src/platform/runtime.ts
|
|
6
|
+
function cacheRequestForKey(key) {
|
|
7
|
+
return new Request(key, { method: "GET" });
|
|
8
|
+
}
|
|
9
|
+
function createCloudflarePublicCacheAdapter(cache) {
|
|
10
|
+
return {
|
|
11
|
+
kind: "cloudflare-cache",
|
|
12
|
+
async match(key) {
|
|
13
|
+
return await cache.match(cacheRequestForKey(key)) ?? null;
|
|
14
|
+
},
|
|
15
|
+
put(key, response) {
|
|
16
|
+
return cache.put(cacheRequestForKey(key), response);
|
|
17
|
+
},
|
|
18
|
+
delete(key) {
|
|
19
|
+
return cache.delete(cacheRequestForKey(key));
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function createCloudflareKeyValueCacheAdapter(namespace) {
|
|
24
|
+
return {
|
|
25
|
+
kind: "workers-kv",
|
|
26
|
+
async get(key, options) {
|
|
27
|
+
return await namespace.get(key, {
|
|
28
|
+
type: "json",
|
|
29
|
+
cacheTtl: options?.cacheTtl
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
async put(key, value, options) {
|
|
33
|
+
await namespace.put(key, JSON.stringify(value), {
|
|
34
|
+
expirationTtl: options?.expirationTtl,
|
|
35
|
+
metadata: options?.metadata
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
delete(key) {
|
|
39
|
+
return namespace.delete(key);
|
|
40
|
+
},
|
|
41
|
+
async list(options) {
|
|
42
|
+
const result = await namespace.list({
|
|
43
|
+
prefix: options?.prefix,
|
|
44
|
+
limit: options?.limit,
|
|
45
|
+
cursor: options?.cursor
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
keys: result.keys.map((key) => ({ name: key.name })),
|
|
49
|
+
cursor: result.list_complete ? void 0 : result.cursor,
|
|
50
|
+
listComplete: result.list_complete
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function r2ObjectToStoredObject(object) {
|
|
56
|
+
return {
|
|
57
|
+
body: object.body,
|
|
58
|
+
size: object.size,
|
|
59
|
+
etag: object.etag,
|
|
60
|
+
contentType: object.httpMetadata?.contentType
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function createCloudflareRuntimePlatform(env2, options) {
|
|
64
|
+
const database = env2.DB ? {
|
|
65
|
+
kind: "d1",
|
|
66
|
+
prepare(query) {
|
|
67
|
+
return env2.DB.prepare(query);
|
|
68
|
+
},
|
|
69
|
+
async batch(statements) {
|
|
70
|
+
return await env2.DB.batch(
|
|
71
|
+
statements
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
} : null;
|
|
75
|
+
const objectStorage = env2.ASSETS_BUCKET ? {
|
|
76
|
+
kind: "r2",
|
|
77
|
+
async get(key) {
|
|
78
|
+
const object = await env2.ASSETS_BUCKET?.get(key);
|
|
79
|
+
return object ? r2ObjectToStoredObject(object) : null;
|
|
80
|
+
},
|
|
81
|
+
async put(key, value, options2) {
|
|
82
|
+
await env2.ASSETS_BUCKET?.put(key, value, {
|
|
83
|
+
httpMetadata: {
|
|
84
|
+
contentType: options2?.contentType,
|
|
85
|
+
cacheControl: options2?.cacheControl
|
|
86
|
+
},
|
|
87
|
+
customMetadata: options2?.metadata
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
async delete(key) {
|
|
91
|
+
await env2.ASSETS_BUCKET?.delete(key);
|
|
92
|
+
},
|
|
93
|
+
async list(options2) {
|
|
94
|
+
const listed = await env2.ASSETS_BUCKET?.list({
|
|
95
|
+
prefix: options2?.prefix,
|
|
96
|
+
limit: options2?.limit
|
|
97
|
+
});
|
|
98
|
+
return listed?.objects.map((object) => ({
|
|
99
|
+
key: object.key,
|
|
100
|
+
size: object.size,
|
|
101
|
+
uploaded: object.uploaded
|
|
102
|
+
})) ?? [];
|
|
103
|
+
}
|
|
104
|
+
} : null;
|
|
105
|
+
const imageTransformer = env2.IMAGES ? {
|
|
106
|
+
kind: "cloudflare-images",
|
|
107
|
+
async transform(body, options2) {
|
|
108
|
+
const result = await env2.IMAGES.input(body).transform(options2.width ? { width: options2.width } : {}).output({
|
|
109
|
+
format: options2.format,
|
|
110
|
+
quality: options2.quality
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
body: result.image(),
|
|
114
|
+
contentType: result.contentType(),
|
|
115
|
+
response: () => result.response()
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
} : null;
|
|
119
|
+
const keyValueCache = env2.CONTENT_CACHE ? createCloudflareKeyValueCacheAdapter(env2.CONTENT_CACHE) : null;
|
|
120
|
+
return {
|
|
121
|
+
id: "cloudflare-workers",
|
|
122
|
+
database,
|
|
123
|
+
objectStorage,
|
|
124
|
+
imageTransformer,
|
|
125
|
+
keyValueCache,
|
|
126
|
+
publicCache: options?.publicCache ? createCloudflarePublicCacheAdapter(options.publicCache) : null
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/platform/cloudflare-runtime.ts
|
|
131
|
+
function getDefaultCloudflareCache() {
|
|
132
|
+
const globalWithCaches = globalThis;
|
|
133
|
+
return globalWithCaches.caches?.default ?? null;
|
|
134
|
+
}
|
|
135
|
+
function getRuntimePlatform() {
|
|
136
|
+
return createCloudflareRuntimePlatform(workerEnv, {
|
|
137
|
+
publicCache: getDefaultCloudflareCache()
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function getPublicCache() {
|
|
141
|
+
const cache = getDefaultCloudflareCache();
|
|
142
|
+
if (!cache) {
|
|
143
|
+
throw new Error("Cloudflare cache binding not configured");
|
|
144
|
+
}
|
|
145
|
+
return createCloudflarePublicCacheAdapter(cache);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/platform/selection.ts
|
|
149
|
+
function currentRuntimeId() {
|
|
150
|
+
return "cloudflare-workers";
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// src/platform/current.ts
|
|
154
|
+
function getRuntimePlatform2() {
|
|
155
|
+
return getRuntimePlatform();
|
|
156
|
+
}
|
|
157
|
+
function getDatabase() {
|
|
158
|
+
const platform = getRuntimePlatform2();
|
|
159
|
+
const database = platform.database;
|
|
160
|
+
if (!database) {
|
|
161
|
+
throw new Error(`SQL database adapter not configured for ${platform.id}`);
|
|
162
|
+
}
|
|
163
|
+
return database;
|
|
164
|
+
}
|
|
165
|
+
function getPublicCache2() {
|
|
166
|
+
return getPublicCache();
|
|
167
|
+
}
|
|
168
|
+
function getKeyValueCache() {
|
|
169
|
+
return getRuntimePlatform2().keyValueCache;
|
|
170
|
+
}
|
|
171
|
+
var runtimeSelection = {
|
|
172
|
+
currentRuntimeId
|
|
173
|
+
};
|
|
174
|
+
export {
|
|
175
|
+
getDatabase,
|
|
176
|
+
getKeyValueCache,
|
|
177
|
+
getPublicCache2 as getPublicCache,
|
|
178
|
+
getRuntimePlatform2 as getRuntimePlatform,
|
|
179
|
+
runtimeSelection
|
|
180
|
+
};
|
|
181
|
+
//# sourceMappingURL=current.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/env.ts","../../src/platform/runtime.ts","../../src/platform/cloudflare-runtime.ts","../../src/platform/selection.ts","../../src/platform/current.ts"],"sourcesContent":["// lib/env.ts - 集中获取 Cloudflare bindings\n// 用 cloudflare:workers 模块(workerd 内置),作为平台 adapter 的绑定入口\n\n/// <reference types=\"@cloudflare/workers-types\" />\nimport { env } from \"cloudflare:workers\";\n\nexport type AppEnv = {\n DB: D1Database;\n ASSETS: Fetcher;\n IMAGES: ImagesBinding;\n ASSETS_BUCKET?: R2Bucket;\n CONTENT_CACHE?: KVNamespace;\n ADMIN_PASSWORD: string;\n ADMIN_EMAIL?: string;\n SITE_URL?: string;\n RESEND_API_KEY?: string;\n RESEND_FROM?: string;\n // Google OAuth 仍然兼容 Cloudflare Secret 作为兜底。\n // 实际生效值以 app_settings.google_client_id / google_client_secret 为准。\n GOOGLE_CLIENT_ID?: string;\n GOOGLE_CLIENT_SECRET?: string;\n /** Turnstile site key fallback when not stored in app_settings */\n TURNSTILE_SITE_KEY?: string;\n /** Turnstile secret — set via `wrangler secret put TURNSTILE_SECRET_KEY` */\n TURNSTILE_SECRET_KEY?: string;\n /** Notion integration token for the blog data source */\n NOTION_TOKEN?: string;\n /** Notion data source ID used by dataSources.query */\n NOTION_DATA_SOURCE_ID?: string;\n /** Notion data source ID for the public movie catalog */\n NOTION_MOVIES_DATA_SOURCE_ID?: string;\n /** Notion data source ID for localized movie copy */\n NOTION_MOVIE_TRANSLATIONS_DATA_SOURCE_ID?: string;\n /** Optional Notion API base URL for tests or proxies */\n NOTION_API_BASE_URL?: string;\n /** Optional Notion edit URL for admin handoff screens */\n NOTION_EDIT_BASE_URL?: string;\n /** Optional webhook verification token for Notion invalidation */\n NOTION_WEBHOOK_VERIFICATION_TOKEN?: string;\n};\n\n// 强制类型:vinext 把 env 类型放在 env.d.ts(interface VinextEnv extends Env),\n// 但 TS server 经常解析不到。运行时一定有 DB,类型断言保证编译通过。\nexport const workerEnv = env as unknown as AppEnv;\n","import type { AppEnv } from \"../util/env\";\n\nexport type PlatformBindingEnv = Pick<\n AppEnv,\n \"ASSETS_BUCKET\" | \"CONTENT_CACHE\" | \"DB\" | \"IMAGES\"\n>;\n\nexport type StoredObject = {\n body: ReadableStream;\n size: number;\n etag?: string;\n contentType?: string;\n};\n\nexport type ObjectStoragePutOptions = {\n contentType?: string;\n cacheControl?: string;\n metadata?: Record<string, string>;\n};\n\nexport type ObjectStorageListItem = {\n key: string;\n size: number;\n uploaded: Date;\n};\n\nexport type ObjectStorageAdapter = {\n kind: \"r2\";\n get(key: string): Promise<StoredObject | null>;\n put(\n key: string,\n value: ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob,\n options?: ObjectStoragePutOptions\n ): Promise<void>;\n delete(key: string): Promise<void>;\n list(\n options?: { prefix?: string; limit?: number }\n ): Promise<ObjectStorageListItem[]>;\n};\n\nexport type ImageTransformOptions = {\n width?: number;\n format: \"image/avif\" | \"image/webp\";\n quality: number;\n};\n\nexport type ImageTransformResult = {\n body: ReadableStream;\n contentType: string;\n response(): Response;\n};\n\nexport type ImageTransformerAdapter = {\n kind: \"cloudflare-images\" | \"external\";\n transform(\n body: ReadableStream,\n options: ImageTransformOptions\n ): Promise<ImageTransformResult>;\n};\n\nexport type PublicCacheAdapter = {\n kind: \"cloudflare-cache\" | \"noop\" | \"external\";\n match(key: string): Promise<Response | null>;\n put(key: string, response: Response): Promise<void>;\n delete(key: string): Promise<boolean>;\n};\n\nexport type KeyValueCacheGetOptions = {\n cacheTtl?: number;\n};\n\nexport type KeyValueCachePutOptions = {\n expirationTtl?: number;\n metadata?: Record<string, string | number | boolean | null>;\n};\n\nexport type KeyValueCacheListOptions = {\n prefix?: string;\n limit?: number;\n cursor?: string;\n};\n\nexport type KeyValueCacheListResult = {\n keys: Array<{ name: string }>;\n cursor?: string;\n listComplete: boolean;\n};\n\nexport type KeyValueCacheAdapter = {\n kind: \"workers-kv\" | \"noop\" | \"external\";\n get<T = unknown>(\n key: string,\n options?: KeyValueCacheGetOptions\n ): Promise<T | null>;\n put<T = unknown>(\n key: string,\n value: T,\n options?: KeyValueCachePutOptions\n ): Promise<void>;\n delete(key: string): Promise<void>;\n list(options?: KeyValueCacheListOptions): Promise<KeyValueCacheListResult>;\n};\n\nexport type SqlValue = string | number | boolean | null;\n\nexport type SqlResult<T = Record<string, unknown>> = {\n results?: T[];\n success?: boolean;\n meta?: {\n changes?: number;\n duration?: number;\n last_row_id?: number;\n rows_read?: number;\n rows_written?: number;\n [key: string]: unknown;\n };\n};\n\nexport type SqlPreparedStatement = {\n bind(...values: SqlValue[]): SqlPreparedStatement;\n all<T = Record<string, unknown>>(): Promise<SqlResult<T>>;\n first<T = Record<string, unknown>>(columnName?: string): Promise<T | null>;\n run<T = Record<string, unknown>>(): Promise<SqlResult<T>>;\n};\n\nexport type SqlDatabaseAdapter = {\n kind: \"d1\";\n prepare(query: string): SqlPreparedStatement;\n batch<T = Record<string, unknown>>(\n statements: SqlPreparedStatement[]\n ): Promise<SqlResult<T>[]>;\n};\n\nexport type RuntimePlatform = {\n id: \"cloudflare-workers\";\n database: SqlDatabaseAdapter | null;\n objectStorage: ObjectStorageAdapter | null;\n imageTransformer: ImageTransformerAdapter | null;\n publicCache: PublicCacheAdapter | null;\n keyValueCache: KeyValueCacheAdapter | null;\n};\n\ntype CloudflareCacheLike = Pick<Cache, \"match\" | \"put\" | \"delete\">;\ntype CloudflareKvLike = Pick<KVNamespace, \"get\" | \"put\" | \"delete\" | \"list\">;\n\nfunction cacheRequestForKey(key: string) {\n return new Request(key, { method: \"GET\" });\n}\n\nexport function createCloudflarePublicCacheAdapter(\n cache: CloudflareCacheLike\n): PublicCacheAdapter {\n return {\n kind: \"cloudflare-cache\",\n async match(key) {\n return (await cache.match(cacheRequestForKey(key))) ?? null;\n },\n put(key, response) {\n return cache.put(cacheRequestForKey(key), response);\n },\n delete(key) {\n return cache.delete(cacheRequestForKey(key));\n },\n };\n}\n\nexport function createNoopPublicCacheAdapter(kind: \"noop\" = \"noop\"): PublicCacheAdapter {\n return {\n kind,\n async match() {\n return null;\n },\n async put() {},\n async delete() {\n return false;\n },\n };\n}\n\nexport function createCloudflareKeyValueCacheAdapter(\n namespace: CloudflareKvLike\n): KeyValueCacheAdapter {\n return {\n kind: \"workers-kv\",\n async get<T = unknown>(\n key: string,\n options?: KeyValueCacheGetOptions\n ): Promise<T | null> {\n return (await namespace.get(key, {\n type: \"json\",\n cacheTtl: options?.cacheTtl,\n })) as T | null;\n },\n async put(key, value, options) {\n await namespace.put(key, JSON.stringify(value), {\n expirationTtl: options?.expirationTtl,\n metadata: options?.metadata,\n });\n },\n delete(key) {\n return namespace.delete(key);\n },\n async list(options) {\n const result = await namespace.list({\n prefix: options?.prefix,\n limit: options?.limit,\n cursor: options?.cursor,\n });\n return {\n keys: result.keys.map((key) => ({ name: key.name })),\n cursor: result.list_complete ? undefined : result.cursor,\n listComplete: result.list_complete,\n };\n },\n };\n}\n\nexport function createNoopKeyValueCacheAdapter(\n kind: \"noop\" = \"noop\"\n): KeyValueCacheAdapter {\n return {\n kind,\n async get() {\n return null;\n },\n async put() {},\n async delete() {},\n async list() {\n return { keys: [], listComplete: true };\n },\n };\n}\n\nfunction r2ObjectToStoredObject(object: R2ObjectBody): StoredObject {\n return {\n body: object.body,\n size: object.size,\n etag: object.etag,\n contentType: object.httpMetadata?.contentType,\n };\n}\n\nexport function createCloudflareRuntimePlatform(\n env: PlatformBindingEnv,\n options?: { publicCache?: CloudflareCacheLike | null }\n): RuntimePlatform {\n const database: SqlDatabaseAdapter | null = env.DB\n ? ({\n kind: \"d1\",\n prepare(query: string) {\n return env.DB.prepare(query) as unknown as SqlPreparedStatement;\n },\n async batch(statements: SqlPreparedStatement[]) {\n return (await env.DB.batch(\n statements as unknown as D1PreparedStatement[]\n )) as unknown as SqlResult<Record<string, unknown>>[];\n },\n } as unknown as SqlDatabaseAdapter)\n : null;\n\n const objectStorage: ObjectStorageAdapter | null = env.ASSETS_BUCKET\n ? {\n kind: \"r2\",\n async get(key) {\n const object = await env.ASSETS_BUCKET?.get(key);\n return object ? r2ObjectToStoredObject(object) : null;\n },\n async put(key, value, options) {\n await env.ASSETS_BUCKET?.put(key, value, {\n httpMetadata: {\n contentType: options?.contentType,\n cacheControl: options?.cacheControl,\n },\n customMetadata: options?.metadata,\n });\n },\n async delete(key) {\n await env.ASSETS_BUCKET?.delete(key);\n },\n async list(options) {\n const listed = await env.ASSETS_BUCKET?.list({\n prefix: options?.prefix,\n limit: options?.limit,\n });\n return (\n listed?.objects.map((object) => ({\n key: object.key,\n size: object.size,\n uploaded: object.uploaded,\n })) ?? []\n );\n },\n }\n : null;\n\n const imageTransformer: ImageTransformerAdapter | null = env.IMAGES\n ? {\n kind: \"cloudflare-images\",\n async transform(body, options) {\n const result = await env.IMAGES.input(body)\n .transform(options.width ? { width: options.width } : {})\n .output({\n format: options.format,\n quality: options.quality,\n });\n return {\n body: result.image(),\n contentType: result.contentType(),\n response: () => result.response(),\n };\n },\n }\n : null;\n\n const keyValueCache: KeyValueCacheAdapter | null = env.CONTENT_CACHE\n ? createCloudflareKeyValueCacheAdapter(env.CONTENT_CACHE)\n : null;\n\n return {\n id: \"cloudflare-workers\",\n database,\n objectStorage,\n imageTransformer,\n keyValueCache,\n publicCache: options?.publicCache\n ? createCloudflarePublicCacheAdapter(options.publicCache)\n : null,\n };\n}\n","import { workerEnv } from \"../util/env\";\nimport {\n createCloudflarePublicCacheAdapter,\n createCloudflareRuntimePlatform,\n} from \"./runtime\";\n\nfunction getDefaultCloudflareCache() {\n const globalWithCaches = globalThis as typeof globalThis & {\n caches?: CacheStorage & { default?: Cache };\n };\n return globalWithCaches.caches?.default ?? null;\n}\n\nexport function getRuntimePlatform() {\n return createCloudflareRuntimePlatform(workerEnv, {\n publicCache: getDefaultCloudflareCache(),\n });\n}\n\nexport function getDatabase() {\n const database = getRuntimePlatform().database;\n if (!database) {\n throw new Error(\"SQL database binding not configured\");\n }\n return database;\n}\n\nexport function getPublicCache() {\n const cache = getDefaultCloudflareCache();\n if (!cache) {\n throw new Error(\"Cloudflare cache binding not configured\");\n }\n return createCloudflarePublicCacheAdapter(cache);\n}\n","export type RuntimeId = \"cloudflare-workers\";\n\nexport type RuntimeKind = \"cloudflare\";\n\nexport interface RuntimeSelection {\n kind: RuntimeKind;\n runtimeId: RuntimeId;\n}\n\nfunction hasCloudflareBindings(env: unknown): boolean {\n if (!env || typeof env !== \"object\") return false;\n const record = env as Record<string, unknown>;\n return (\n \"DB\" in record ||\n \"ASSETS_BUCKET\" in record ||\n \"R2\" in record ||\n \"IMAGES\" in record ||\n \"CONTENT_CACHE\" in record\n );\n}\n\nexport function selectRuntime(env: unknown): RuntimeSelection {\n if (hasCloudflareBindings(env)) {\n return { kind: \"cloudflare\", runtimeId: \"cloudflare-workers\" };\n }\n throw new Error(\n \"No supported runtime detected. Expected Cloudflare Workers bindings \" +\n \"(DB, ASSETS_BUCKET, R2, IMAGES, or CONTENT_CACHE).\",\n );\n}\n\nexport function currentRuntimeId(): RuntimeId {\n return \"cloudflare-workers\";\n}\n","import {\n getPublicCache as getCloudflarePublicCache,\n getRuntimePlatform as getCloudflareRuntimePlatform,\n} from \"./cloudflare-runtime\";\nimport { currentRuntimeId } from \"./selection\";\n\nexport function getRuntimePlatform() {\n return getCloudflareRuntimePlatform();\n}\n\nexport function getDatabase() {\n const platform = getRuntimePlatform();\n const database = platform.database;\n if (!database) {\n throw new Error(`SQL database adapter not configured for ${platform.id}`);\n }\n return database;\n}\n\nexport function getPublicCache() {\n return getCloudflarePublicCache();\n}\n\nexport function getKeyValueCache() {\n return getRuntimePlatform().keyValueCache;\n}\n\nexport const runtimeSelection = {\n currentRuntimeId,\n};\n"],"mappings":"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","names":["env","options","getRuntimePlatform","getPublicCache"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ImageTransformOptions, ImageTransformResult, ImageTransformerAdapter, KeyValueCacheAdapter, KeyValueCacheGetOptions, KeyValueCacheListOptions, KeyValueCacheListResult, KeyValueCachePutOptions, ObjectStorageAdapter, ObjectStorageListItem, ObjectStoragePutOptions, PlatformBindingEnv, PublicCacheAdapter, RuntimePlatform, SqlDatabaseAdapter, SqlPreparedStatement, SqlResult, SqlValue, StoredObject, createCloudflareKeyValueCacheAdapter, createCloudflarePublicCacheAdapter, createCloudflareRuntimePlatform, createNoopKeyValueCacheAdapter, createNoopPublicCacheAdapter } from './runtime.js';
|
|
2
|
+
export { RuntimeAdapterDefinition, RuntimeCapability, RuntimeServiceStatus, cloudflareWorkersAdapter, getRuntimeAdapter, runtimeAdapters, runtimeServiceStatus } from './capabilities.js';
|
|
3
|
+
export { getDatabase, getKeyValueCache, getPublicCache, getRuntimePlatform, runtimeSelection } from './current.js';
|
|
4
|
+
export { RuntimeId, RuntimeKind, RuntimeSelection, currentRuntimeId, selectRuntime } from './selection.js';
|
|
5
|
+
import '../env-C5qu-0R-.js';
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// src/platform/runtime.ts
|
|
2
|
+
function cacheRequestForKey(key) {
|
|
3
|
+
return new Request(key, { method: "GET" });
|
|
4
|
+
}
|
|
5
|
+
function createCloudflarePublicCacheAdapter(cache) {
|
|
6
|
+
return {
|
|
7
|
+
kind: "cloudflare-cache",
|
|
8
|
+
async match(key) {
|
|
9
|
+
return await cache.match(cacheRequestForKey(key)) ?? null;
|
|
10
|
+
},
|
|
11
|
+
put(key, response) {
|
|
12
|
+
return cache.put(cacheRequestForKey(key), response);
|
|
13
|
+
},
|
|
14
|
+
delete(key) {
|
|
15
|
+
return cache.delete(cacheRequestForKey(key));
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function createNoopPublicCacheAdapter(kind = "noop") {
|
|
20
|
+
return {
|
|
21
|
+
kind,
|
|
22
|
+
async match() {
|
|
23
|
+
return null;
|
|
24
|
+
},
|
|
25
|
+
async put() {
|
|
26
|
+
},
|
|
27
|
+
async delete() {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function createCloudflareKeyValueCacheAdapter(namespace) {
|
|
33
|
+
return {
|
|
34
|
+
kind: "workers-kv",
|
|
35
|
+
async get(key, options) {
|
|
36
|
+
return await namespace.get(key, {
|
|
37
|
+
type: "json",
|
|
38
|
+
cacheTtl: options?.cacheTtl
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
async put(key, value, options) {
|
|
42
|
+
await namespace.put(key, JSON.stringify(value), {
|
|
43
|
+
expirationTtl: options?.expirationTtl,
|
|
44
|
+
metadata: options?.metadata
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
delete(key) {
|
|
48
|
+
return namespace.delete(key);
|
|
49
|
+
},
|
|
50
|
+
async list(options) {
|
|
51
|
+
const result = await namespace.list({
|
|
52
|
+
prefix: options?.prefix,
|
|
53
|
+
limit: options?.limit,
|
|
54
|
+
cursor: options?.cursor
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
keys: result.keys.map((key) => ({ name: key.name })),
|
|
58
|
+
cursor: result.list_complete ? void 0 : result.cursor,
|
|
59
|
+
listComplete: result.list_complete
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function createNoopKeyValueCacheAdapter(kind = "noop") {
|
|
65
|
+
return {
|
|
66
|
+
kind,
|
|
67
|
+
async get() {
|
|
68
|
+
return null;
|
|
69
|
+
},
|
|
70
|
+
async put() {
|
|
71
|
+
},
|
|
72
|
+
async delete() {
|
|
73
|
+
},
|
|
74
|
+
async list() {
|
|
75
|
+
return { keys: [], listComplete: true };
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function r2ObjectToStoredObject(object) {
|
|
80
|
+
return {
|
|
81
|
+
body: object.body,
|
|
82
|
+
size: object.size,
|
|
83
|
+
etag: object.etag,
|
|
84
|
+
contentType: object.httpMetadata?.contentType
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function createCloudflareRuntimePlatform(env2, options) {
|
|
88
|
+
const database = env2.DB ? {
|
|
89
|
+
kind: "d1",
|
|
90
|
+
prepare(query) {
|
|
91
|
+
return env2.DB.prepare(query);
|
|
92
|
+
},
|
|
93
|
+
async batch(statements) {
|
|
94
|
+
return await env2.DB.batch(
|
|
95
|
+
statements
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
} : null;
|
|
99
|
+
const objectStorage = env2.ASSETS_BUCKET ? {
|
|
100
|
+
kind: "r2",
|
|
101
|
+
async get(key) {
|
|
102
|
+
const object = await env2.ASSETS_BUCKET?.get(key);
|
|
103
|
+
return object ? r2ObjectToStoredObject(object) : null;
|
|
104
|
+
},
|
|
105
|
+
async put(key, value, options2) {
|
|
106
|
+
await env2.ASSETS_BUCKET?.put(key, value, {
|
|
107
|
+
httpMetadata: {
|
|
108
|
+
contentType: options2?.contentType,
|
|
109
|
+
cacheControl: options2?.cacheControl
|
|
110
|
+
},
|
|
111
|
+
customMetadata: options2?.metadata
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
async delete(key) {
|
|
115
|
+
await env2.ASSETS_BUCKET?.delete(key);
|
|
116
|
+
},
|
|
117
|
+
async list(options2) {
|
|
118
|
+
const listed = await env2.ASSETS_BUCKET?.list({
|
|
119
|
+
prefix: options2?.prefix,
|
|
120
|
+
limit: options2?.limit
|
|
121
|
+
});
|
|
122
|
+
return listed?.objects.map((object) => ({
|
|
123
|
+
key: object.key,
|
|
124
|
+
size: object.size,
|
|
125
|
+
uploaded: object.uploaded
|
|
126
|
+
})) ?? [];
|
|
127
|
+
}
|
|
128
|
+
} : null;
|
|
129
|
+
const imageTransformer = env2.IMAGES ? {
|
|
130
|
+
kind: "cloudflare-images",
|
|
131
|
+
async transform(body, options2) {
|
|
132
|
+
const result = await env2.IMAGES.input(body).transform(options2.width ? { width: options2.width } : {}).output({
|
|
133
|
+
format: options2.format,
|
|
134
|
+
quality: options2.quality
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
body: result.image(),
|
|
138
|
+
contentType: result.contentType(),
|
|
139
|
+
response: () => result.response()
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
} : null;
|
|
143
|
+
const keyValueCache = env2.CONTENT_CACHE ? createCloudflareKeyValueCacheAdapter(env2.CONTENT_CACHE) : null;
|
|
144
|
+
return {
|
|
145
|
+
id: "cloudflare-workers",
|
|
146
|
+
database,
|
|
147
|
+
objectStorage,
|
|
148
|
+
imageTransformer,
|
|
149
|
+
keyValueCache,
|
|
150
|
+
publicCache: options?.publicCache ? createCloudflarePublicCacheAdapter(options.publicCache) : null
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// src/platform/capabilities.ts
|
|
155
|
+
var cloudflareWorkersAdapter = {
|
|
156
|
+
id: "cloudflare-workers",
|
|
157
|
+
label: "Cloudflare Workers + D1",
|
|
158
|
+
status: "active",
|
|
159
|
+
services: {
|
|
160
|
+
compute: "Cloudflare Workers via vinext",
|
|
161
|
+
relationalStorage: "D1 through the runtime SQL adapter",
|
|
162
|
+
objectStorage: "R2",
|
|
163
|
+
imageOptimization: "Cloudflare Images",
|
|
164
|
+
cache: "vinext CDN/data adapters and caches.default for media",
|
|
165
|
+
authStorage: "D1 users and signed cookies"
|
|
166
|
+
},
|
|
167
|
+
capabilities: [
|
|
168
|
+
"server-rendering",
|
|
169
|
+
"edge-cache",
|
|
170
|
+
"relational-storage",
|
|
171
|
+
"object-storage",
|
|
172
|
+
"image-optimization",
|
|
173
|
+
"secrets",
|
|
174
|
+
"observability"
|
|
175
|
+
]
|
|
176
|
+
};
|
|
177
|
+
var runtimeAdapters = [cloudflareWorkersAdapter];
|
|
178
|
+
function getRuntimeAdapter(id) {
|
|
179
|
+
return runtimeAdapters.find((adapter) => adapter.id === id);
|
|
180
|
+
}
|
|
181
|
+
function runtimeServiceStatus(platform) {
|
|
182
|
+
return {
|
|
183
|
+
database: Boolean(platform.database),
|
|
184
|
+
objectStorage: Boolean(platform.objectStorage),
|
|
185
|
+
imageTransformer: Boolean(platform.imageTransformer),
|
|
186
|
+
publicCache: Boolean(platform.publicCache)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/util/env.ts
|
|
191
|
+
import { env } from "cloudflare:workers";
|
|
192
|
+
var workerEnv = env;
|
|
193
|
+
|
|
194
|
+
// src/platform/cloudflare-runtime.ts
|
|
195
|
+
function getDefaultCloudflareCache() {
|
|
196
|
+
const globalWithCaches = globalThis;
|
|
197
|
+
return globalWithCaches.caches?.default ?? null;
|
|
198
|
+
}
|
|
199
|
+
function getRuntimePlatform() {
|
|
200
|
+
return createCloudflareRuntimePlatform(workerEnv, {
|
|
201
|
+
publicCache: getDefaultCloudflareCache()
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function getPublicCache() {
|
|
205
|
+
const cache = getDefaultCloudflareCache();
|
|
206
|
+
if (!cache) {
|
|
207
|
+
throw new Error("Cloudflare cache binding not configured");
|
|
208
|
+
}
|
|
209
|
+
return createCloudflarePublicCacheAdapter(cache);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/platform/selection.ts
|
|
213
|
+
function hasCloudflareBindings(env2) {
|
|
214
|
+
if (!env2 || typeof env2 !== "object") return false;
|
|
215
|
+
const record = env2;
|
|
216
|
+
return "DB" in record || "ASSETS_BUCKET" in record || "R2" in record || "IMAGES" in record || "CONTENT_CACHE" in record;
|
|
217
|
+
}
|
|
218
|
+
function selectRuntime(env2) {
|
|
219
|
+
if (hasCloudflareBindings(env2)) {
|
|
220
|
+
return { kind: "cloudflare", runtimeId: "cloudflare-workers" };
|
|
221
|
+
}
|
|
222
|
+
throw new Error(
|
|
223
|
+
"No supported runtime detected. Expected Cloudflare Workers bindings (DB, ASSETS_BUCKET, R2, IMAGES, or CONTENT_CACHE)."
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
function currentRuntimeId() {
|
|
227
|
+
return "cloudflare-workers";
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/platform/current.ts
|
|
231
|
+
function getRuntimePlatform2() {
|
|
232
|
+
return getRuntimePlatform();
|
|
233
|
+
}
|
|
234
|
+
function getDatabase() {
|
|
235
|
+
const platform = getRuntimePlatform2();
|
|
236
|
+
const database = platform.database;
|
|
237
|
+
if (!database) {
|
|
238
|
+
throw new Error(`SQL database adapter not configured for ${platform.id}`);
|
|
239
|
+
}
|
|
240
|
+
return database;
|
|
241
|
+
}
|
|
242
|
+
function getPublicCache2() {
|
|
243
|
+
return getPublicCache();
|
|
244
|
+
}
|
|
245
|
+
function getKeyValueCache() {
|
|
246
|
+
return getRuntimePlatform2().keyValueCache;
|
|
247
|
+
}
|
|
248
|
+
var runtimeSelection = {
|
|
249
|
+
currentRuntimeId
|
|
250
|
+
};
|
|
251
|
+
export {
|
|
252
|
+
cloudflareWorkersAdapter,
|
|
253
|
+
createCloudflareKeyValueCacheAdapter,
|
|
254
|
+
createCloudflarePublicCacheAdapter,
|
|
255
|
+
createCloudflareRuntimePlatform,
|
|
256
|
+
createNoopKeyValueCacheAdapter,
|
|
257
|
+
createNoopPublicCacheAdapter,
|
|
258
|
+
currentRuntimeId,
|
|
259
|
+
getDatabase,
|
|
260
|
+
getKeyValueCache,
|
|
261
|
+
getPublicCache2 as getPublicCache,
|
|
262
|
+
getRuntimeAdapter,
|
|
263
|
+
getRuntimePlatform2 as getRuntimePlatform,
|
|
264
|
+
runtimeAdapters,
|
|
265
|
+
runtimeSelection,
|
|
266
|
+
runtimeServiceStatus,
|
|
267
|
+
selectRuntime
|
|
268
|
+
};
|
|
269
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/platform/runtime.ts","../../src/platform/capabilities.ts","../../src/util/env.ts","../../src/platform/cloudflare-runtime.ts","../../src/platform/selection.ts","../../src/platform/current.ts"],"sourcesContent":["import type { AppEnv } from \"../util/env\";\n\nexport type PlatformBindingEnv = Pick<\n AppEnv,\n \"ASSETS_BUCKET\" | \"CONTENT_CACHE\" | \"DB\" | \"IMAGES\"\n>;\n\nexport type StoredObject = {\n body: ReadableStream;\n size: number;\n etag?: string;\n contentType?: string;\n};\n\nexport type ObjectStoragePutOptions = {\n contentType?: string;\n cacheControl?: string;\n metadata?: Record<string, string>;\n};\n\nexport type ObjectStorageListItem = {\n key: string;\n size: number;\n uploaded: Date;\n};\n\nexport type ObjectStorageAdapter = {\n kind: \"r2\";\n get(key: string): Promise<StoredObject | null>;\n put(\n key: string,\n value: ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob,\n options?: ObjectStoragePutOptions\n ): Promise<void>;\n delete(key: string): Promise<void>;\n list(\n options?: { prefix?: string; limit?: number }\n ): Promise<ObjectStorageListItem[]>;\n};\n\nexport type ImageTransformOptions = {\n width?: number;\n format: \"image/avif\" | \"image/webp\";\n quality: number;\n};\n\nexport type ImageTransformResult = {\n body: ReadableStream;\n contentType: string;\n response(): Response;\n};\n\nexport type ImageTransformerAdapter = {\n kind: \"cloudflare-images\" | \"external\";\n transform(\n body: ReadableStream,\n options: ImageTransformOptions\n ): Promise<ImageTransformResult>;\n};\n\nexport type PublicCacheAdapter = {\n kind: \"cloudflare-cache\" | \"noop\" | \"external\";\n match(key: string): Promise<Response | null>;\n put(key: string, response: Response): Promise<void>;\n delete(key: string): Promise<boolean>;\n};\n\nexport type KeyValueCacheGetOptions = {\n cacheTtl?: number;\n};\n\nexport type KeyValueCachePutOptions = {\n expirationTtl?: number;\n metadata?: Record<string, string | number | boolean | null>;\n};\n\nexport type KeyValueCacheListOptions = {\n prefix?: string;\n limit?: number;\n cursor?: string;\n};\n\nexport type KeyValueCacheListResult = {\n keys: Array<{ name: string }>;\n cursor?: string;\n listComplete: boolean;\n};\n\nexport type KeyValueCacheAdapter = {\n kind: \"workers-kv\" | \"noop\" | \"external\";\n get<T = unknown>(\n key: string,\n options?: KeyValueCacheGetOptions\n ): Promise<T | null>;\n put<T = unknown>(\n key: string,\n value: T,\n options?: KeyValueCachePutOptions\n ): Promise<void>;\n delete(key: string): Promise<void>;\n list(options?: KeyValueCacheListOptions): Promise<KeyValueCacheListResult>;\n};\n\nexport type SqlValue = string | number | boolean | null;\n\nexport type SqlResult<T = Record<string, unknown>> = {\n results?: T[];\n success?: boolean;\n meta?: {\n changes?: number;\n duration?: number;\n last_row_id?: number;\n rows_read?: number;\n rows_written?: number;\n [key: string]: unknown;\n };\n};\n\nexport type SqlPreparedStatement = {\n bind(...values: SqlValue[]): SqlPreparedStatement;\n all<T = Record<string, unknown>>(): Promise<SqlResult<T>>;\n first<T = Record<string, unknown>>(columnName?: string): Promise<T | null>;\n run<T = Record<string, unknown>>(): Promise<SqlResult<T>>;\n};\n\nexport type SqlDatabaseAdapter = {\n kind: \"d1\";\n prepare(query: string): SqlPreparedStatement;\n batch<T = Record<string, unknown>>(\n statements: SqlPreparedStatement[]\n ): Promise<SqlResult<T>[]>;\n};\n\nexport type RuntimePlatform = {\n id: \"cloudflare-workers\";\n database: SqlDatabaseAdapter | null;\n objectStorage: ObjectStorageAdapter | null;\n imageTransformer: ImageTransformerAdapter | null;\n publicCache: PublicCacheAdapter | null;\n keyValueCache: KeyValueCacheAdapter | null;\n};\n\ntype CloudflareCacheLike = Pick<Cache, \"match\" | \"put\" | \"delete\">;\ntype CloudflareKvLike = Pick<KVNamespace, \"get\" | \"put\" | \"delete\" | \"list\">;\n\nfunction cacheRequestForKey(key: string) {\n return new Request(key, { method: \"GET\" });\n}\n\nexport function createCloudflarePublicCacheAdapter(\n cache: CloudflareCacheLike\n): PublicCacheAdapter {\n return {\n kind: \"cloudflare-cache\",\n async match(key) {\n return (await cache.match(cacheRequestForKey(key))) ?? null;\n },\n put(key, response) {\n return cache.put(cacheRequestForKey(key), response);\n },\n delete(key) {\n return cache.delete(cacheRequestForKey(key));\n },\n };\n}\n\nexport function createNoopPublicCacheAdapter(kind: \"noop\" = \"noop\"): PublicCacheAdapter {\n return {\n kind,\n async match() {\n return null;\n },\n async put() {},\n async delete() {\n return false;\n },\n };\n}\n\nexport function createCloudflareKeyValueCacheAdapter(\n namespace: CloudflareKvLike\n): KeyValueCacheAdapter {\n return {\n kind: \"workers-kv\",\n async get<T = unknown>(\n key: string,\n options?: KeyValueCacheGetOptions\n ): Promise<T | null> {\n return (await namespace.get(key, {\n type: \"json\",\n cacheTtl: options?.cacheTtl,\n })) as T | null;\n },\n async put(key, value, options) {\n await namespace.put(key, JSON.stringify(value), {\n expirationTtl: options?.expirationTtl,\n metadata: options?.metadata,\n });\n },\n delete(key) {\n return namespace.delete(key);\n },\n async list(options) {\n const result = await namespace.list({\n prefix: options?.prefix,\n limit: options?.limit,\n cursor: options?.cursor,\n });\n return {\n keys: result.keys.map((key) => ({ name: key.name })),\n cursor: result.list_complete ? undefined : result.cursor,\n listComplete: result.list_complete,\n };\n },\n };\n}\n\nexport function createNoopKeyValueCacheAdapter(\n kind: \"noop\" = \"noop\"\n): KeyValueCacheAdapter {\n return {\n kind,\n async get() {\n return null;\n },\n async put() {},\n async delete() {},\n async list() {\n return { keys: [], listComplete: true };\n },\n };\n}\n\nfunction r2ObjectToStoredObject(object: R2ObjectBody): StoredObject {\n return {\n body: object.body,\n size: object.size,\n etag: object.etag,\n contentType: object.httpMetadata?.contentType,\n };\n}\n\nexport function createCloudflareRuntimePlatform(\n env: PlatformBindingEnv,\n options?: { publicCache?: CloudflareCacheLike | null }\n): RuntimePlatform {\n const database: SqlDatabaseAdapter | null = env.DB\n ? ({\n kind: \"d1\",\n prepare(query: string) {\n return env.DB.prepare(query) as unknown as SqlPreparedStatement;\n },\n async batch(statements: SqlPreparedStatement[]) {\n return (await env.DB.batch(\n statements as unknown as D1PreparedStatement[]\n )) as unknown as SqlResult<Record<string, unknown>>[];\n },\n } as unknown as SqlDatabaseAdapter)\n : null;\n\n const objectStorage: ObjectStorageAdapter | null = env.ASSETS_BUCKET\n ? {\n kind: \"r2\",\n async get(key) {\n const object = await env.ASSETS_BUCKET?.get(key);\n return object ? r2ObjectToStoredObject(object) : null;\n },\n async put(key, value, options) {\n await env.ASSETS_BUCKET?.put(key, value, {\n httpMetadata: {\n contentType: options?.contentType,\n cacheControl: options?.cacheControl,\n },\n customMetadata: options?.metadata,\n });\n },\n async delete(key) {\n await env.ASSETS_BUCKET?.delete(key);\n },\n async list(options) {\n const listed = await env.ASSETS_BUCKET?.list({\n prefix: options?.prefix,\n limit: options?.limit,\n });\n return (\n listed?.objects.map((object) => ({\n key: object.key,\n size: object.size,\n uploaded: object.uploaded,\n })) ?? []\n );\n },\n }\n : null;\n\n const imageTransformer: ImageTransformerAdapter | null = env.IMAGES\n ? {\n kind: \"cloudflare-images\",\n async transform(body, options) {\n const result = await env.IMAGES.input(body)\n .transform(options.width ? { width: options.width } : {})\n .output({\n format: options.format,\n quality: options.quality,\n });\n return {\n body: result.image(),\n contentType: result.contentType(),\n response: () => result.response(),\n };\n },\n }\n : null;\n\n const keyValueCache: KeyValueCacheAdapter | null = env.CONTENT_CACHE\n ? createCloudflareKeyValueCacheAdapter(env.CONTENT_CACHE)\n : null;\n\n return {\n id: \"cloudflare-workers\",\n database,\n objectStorage,\n imageTransformer,\n keyValueCache,\n publicCache: options?.publicCache\n ? createCloudflarePublicCacheAdapter(options.publicCache)\n : null,\n };\n}\n","import type { RuntimeId } from \"./selection\";\n\nexport type RuntimeCapability =\n | \"server-rendering\"\n | \"edge-cache\"\n | \"relational-storage\"\n | \"object-storage\"\n | \"image-optimization\"\n | \"secrets\"\n | \"observability\";\n\nexport type RuntimeAdapterDefinition = {\n id: RuntimeId;\n label: string;\n status: \"active\" | \"partial\" | \"planned\";\n services: {\n compute: string;\n relationalStorage: string;\n objectStorage: string;\n imageOptimization: string;\n cache: string;\n authStorage: string;\n };\n capabilities: readonly RuntimeCapability[];\n};\n\nexport type RuntimeServiceStatus = {\n database: boolean;\n objectStorage: boolean;\n imageTransformer: boolean;\n publicCache: boolean;\n};\n\nexport const cloudflareWorkersAdapter: RuntimeAdapterDefinition = {\n id: \"cloudflare-workers\",\n label: \"Cloudflare Workers + D1\",\n status: \"active\",\n services: {\n compute: \"Cloudflare Workers via vinext\",\n relationalStorage: \"D1 through the runtime SQL adapter\",\n objectStorage: \"R2\",\n imageOptimization: \"Cloudflare Images\",\n cache: \"vinext CDN/data adapters and caches.default for media\",\n authStorage: \"D1 users and signed cookies\",\n },\n capabilities: [\n \"server-rendering\",\n \"edge-cache\",\n \"relational-storage\",\n \"object-storage\",\n \"image-optimization\",\n \"secrets\",\n \"observability\",\n ],\n};\n\nexport const runtimeAdapters = [cloudflareWorkersAdapter] as const;\n\nexport function getRuntimeAdapter(id: RuntimeAdapterDefinition[\"id\"]) {\n return runtimeAdapters.find((adapter) => adapter.id === id);\n}\n\nexport function runtimeServiceStatus(\n platform: {\n database: unknown;\n objectStorage: unknown;\n imageTransformer: unknown;\n publicCache: unknown;\n }\n): RuntimeServiceStatus {\n return {\n database: Boolean(platform.database),\n objectStorage: Boolean(platform.objectStorage),\n imageTransformer: Boolean(platform.imageTransformer),\n publicCache: Boolean(platform.publicCache),\n };\n}\n","// lib/env.ts - 集中获取 Cloudflare bindings\n// 用 cloudflare:workers 模块(workerd 内置),作为平台 adapter 的绑定入口\n\n/// <reference types=\"@cloudflare/workers-types\" />\nimport { env } from \"cloudflare:workers\";\n\nexport type AppEnv = {\n DB: D1Database;\n ASSETS: Fetcher;\n IMAGES: ImagesBinding;\n ASSETS_BUCKET?: R2Bucket;\n CONTENT_CACHE?: KVNamespace;\n ADMIN_PASSWORD: string;\n ADMIN_EMAIL?: string;\n SITE_URL?: string;\n RESEND_API_KEY?: string;\n RESEND_FROM?: string;\n // Google OAuth 仍然兼容 Cloudflare Secret 作为兜底。\n // 实际生效值以 app_settings.google_client_id / google_client_secret 为准。\n GOOGLE_CLIENT_ID?: string;\n GOOGLE_CLIENT_SECRET?: string;\n /** Turnstile site key fallback when not stored in app_settings */\n TURNSTILE_SITE_KEY?: string;\n /** Turnstile secret — set via `wrangler secret put TURNSTILE_SECRET_KEY` */\n TURNSTILE_SECRET_KEY?: string;\n /** Notion integration token for the blog data source */\n NOTION_TOKEN?: string;\n /** Notion data source ID used by dataSources.query */\n NOTION_DATA_SOURCE_ID?: string;\n /** Notion data source ID for the public movie catalog */\n NOTION_MOVIES_DATA_SOURCE_ID?: string;\n /** Notion data source ID for localized movie copy */\n NOTION_MOVIE_TRANSLATIONS_DATA_SOURCE_ID?: string;\n /** Optional Notion API base URL for tests or proxies */\n NOTION_API_BASE_URL?: string;\n /** Optional Notion edit URL for admin handoff screens */\n NOTION_EDIT_BASE_URL?: string;\n /** Optional webhook verification token for Notion invalidation */\n NOTION_WEBHOOK_VERIFICATION_TOKEN?: string;\n};\n\n// 强制类型:vinext 把 env 类型放在 env.d.ts(interface VinextEnv extends Env),\n// 但 TS server 经常解析不到。运行时一定有 DB,类型断言保证编译通过。\nexport const workerEnv = env as unknown as AppEnv;\n","import { workerEnv } from \"../util/env\";\nimport {\n createCloudflarePublicCacheAdapter,\n createCloudflareRuntimePlatform,\n} from \"./runtime\";\n\nfunction getDefaultCloudflareCache() {\n const globalWithCaches = globalThis as typeof globalThis & {\n caches?: CacheStorage & { default?: Cache };\n };\n return globalWithCaches.caches?.default ?? null;\n}\n\nexport function getRuntimePlatform() {\n return createCloudflareRuntimePlatform(workerEnv, {\n publicCache: getDefaultCloudflareCache(),\n });\n}\n\nexport function getDatabase() {\n const database = getRuntimePlatform().database;\n if (!database) {\n throw new Error(\"SQL database binding not configured\");\n }\n return database;\n}\n\nexport function getPublicCache() {\n const cache = getDefaultCloudflareCache();\n if (!cache) {\n throw new Error(\"Cloudflare cache binding not configured\");\n }\n return createCloudflarePublicCacheAdapter(cache);\n}\n","export type RuntimeId = \"cloudflare-workers\";\n\nexport type RuntimeKind = \"cloudflare\";\n\nexport interface RuntimeSelection {\n kind: RuntimeKind;\n runtimeId: RuntimeId;\n}\n\nfunction hasCloudflareBindings(env: unknown): boolean {\n if (!env || typeof env !== \"object\") return false;\n const record = env as Record<string, unknown>;\n return (\n \"DB\" in record ||\n \"ASSETS_BUCKET\" in record ||\n \"R2\" in record ||\n \"IMAGES\" in record ||\n \"CONTENT_CACHE\" in record\n );\n}\n\nexport function selectRuntime(env: unknown): RuntimeSelection {\n if (hasCloudflareBindings(env)) {\n return { kind: \"cloudflare\", runtimeId: \"cloudflare-workers\" };\n }\n throw new Error(\n \"No supported runtime detected. Expected Cloudflare Workers bindings \" +\n \"(DB, ASSETS_BUCKET, R2, IMAGES, or CONTENT_CACHE).\",\n );\n}\n\nexport function currentRuntimeId(): RuntimeId {\n return \"cloudflare-workers\";\n}\n","import {\n getPublicCache as getCloudflarePublicCache,\n getRuntimePlatform as getCloudflareRuntimePlatform,\n} from \"./cloudflare-runtime\";\nimport { currentRuntimeId } from \"./selection\";\n\nexport function getRuntimePlatform() {\n return getCloudflareRuntimePlatform();\n}\n\nexport function getDatabase() {\n const platform = getRuntimePlatform();\n const database = platform.database;\n if (!database) {\n throw new Error(`SQL database adapter not configured for ${platform.id}`);\n }\n return database;\n}\n\nexport function getPublicCache() {\n return getCloudflarePublicCache();\n}\n\nexport function getKeyValueCache() {\n return getRuntimePlatform().keyValueCache;\n}\n\nexport const runtimeSelection = {\n currentRuntimeId,\n};\n"],"mappings":"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","names":["env","options","env","getRuntimePlatform","getPublicCache"]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { A as AppEnv } from '../env-C5qu-0R-.js';
|
|
2
|
+
|
|
3
|
+
type PlatformBindingEnv = Pick<AppEnv, "ASSETS_BUCKET" | "CONTENT_CACHE" | "DB" | "IMAGES">;
|
|
4
|
+
type StoredObject = {
|
|
5
|
+
body: ReadableStream;
|
|
6
|
+
size: number;
|
|
7
|
+
etag?: string;
|
|
8
|
+
contentType?: string;
|
|
9
|
+
};
|
|
10
|
+
type ObjectStoragePutOptions = {
|
|
11
|
+
contentType?: string;
|
|
12
|
+
cacheControl?: string;
|
|
13
|
+
metadata?: Record<string, string>;
|
|
14
|
+
};
|
|
15
|
+
type ObjectStorageListItem = {
|
|
16
|
+
key: string;
|
|
17
|
+
size: number;
|
|
18
|
+
uploaded: Date;
|
|
19
|
+
};
|
|
20
|
+
type ObjectStorageAdapter = {
|
|
21
|
+
kind: "r2";
|
|
22
|
+
get(key: string): Promise<StoredObject | null>;
|
|
23
|
+
put(key: string, value: ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob, options?: ObjectStoragePutOptions): Promise<void>;
|
|
24
|
+
delete(key: string): Promise<void>;
|
|
25
|
+
list(options?: {
|
|
26
|
+
prefix?: string;
|
|
27
|
+
limit?: number;
|
|
28
|
+
}): Promise<ObjectStorageListItem[]>;
|
|
29
|
+
};
|
|
30
|
+
type ImageTransformOptions = {
|
|
31
|
+
width?: number;
|
|
32
|
+
format: "image/avif" | "image/webp";
|
|
33
|
+
quality: number;
|
|
34
|
+
};
|
|
35
|
+
type ImageTransformResult = {
|
|
36
|
+
body: ReadableStream;
|
|
37
|
+
contentType: string;
|
|
38
|
+
response(): Response;
|
|
39
|
+
};
|
|
40
|
+
type ImageTransformerAdapter = {
|
|
41
|
+
kind: "cloudflare-images" | "external";
|
|
42
|
+
transform(body: ReadableStream, options: ImageTransformOptions): Promise<ImageTransformResult>;
|
|
43
|
+
};
|
|
44
|
+
type PublicCacheAdapter = {
|
|
45
|
+
kind: "cloudflare-cache" | "noop" | "external";
|
|
46
|
+
match(key: string): Promise<Response | null>;
|
|
47
|
+
put(key: string, response: Response): Promise<void>;
|
|
48
|
+
delete(key: string): Promise<boolean>;
|
|
49
|
+
};
|
|
50
|
+
type KeyValueCacheGetOptions = {
|
|
51
|
+
cacheTtl?: number;
|
|
52
|
+
};
|
|
53
|
+
type KeyValueCachePutOptions = {
|
|
54
|
+
expirationTtl?: number;
|
|
55
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
56
|
+
};
|
|
57
|
+
type KeyValueCacheListOptions = {
|
|
58
|
+
prefix?: string;
|
|
59
|
+
limit?: number;
|
|
60
|
+
cursor?: string;
|
|
61
|
+
};
|
|
62
|
+
type KeyValueCacheListResult = {
|
|
63
|
+
keys: Array<{
|
|
64
|
+
name: string;
|
|
65
|
+
}>;
|
|
66
|
+
cursor?: string;
|
|
67
|
+
listComplete: boolean;
|
|
68
|
+
};
|
|
69
|
+
type KeyValueCacheAdapter = {
|
|
70
|
+
kind: "workers-kv" | "noop" | "external";
|
|
71
|
+
get<T = unknown>(key: string, options?: KeyValueCacheGetOptions): Promise<T | null>;
|
|
72
|
+
put<T = unknown>(key: string, value: T, options?: KeyValueCachePutOptions): Promise<void>;
|
|
73
|
+
delete(key: string): Promise<void>;
|
|
74
|
+
list(options?: KeyValueCacheListOptions): Promise<KeyValueCacheListResult>;
|
|
75
|
+
};
|
|
76
|
+
type SqlValue = string | number | boolean | null;
|
|
77
|
+
type SqlResult<T = Record<string, unknown>> = {
|
|
78
|
+
results?: T[];
|
|
79
|
+
success?: boolean;
|
|
80
|
+
meta?: {
|
|
81
|
+
changes?: number;
|
|
82
|
+
duration?: number;
|
|
83
|
+
last_row_id?: number;
|
|
84
|
+
rows_read?: number;
|
|
85
|
+
rows_written?: number;
|
|
86
|
+
[key: string]: unknown;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
type SqlPreparedStatement = {
|
|
90
|
+
bind(...values: SqlValue[]): SqlPreparedStatement;
|
|
91
|
+
all<T = Record<string, unknown>>(): Promise<SqlResult<T>>;
|
|
92
|
+
first<T = Record<string, unknown>>(columnName?: string): Promise<T | null>;
|
|
93
|
+
run<T = Record<string, unknown>>(): Promise<SqlResult<T>>;
|
|
94
|
+
};
|
|
95
|
+
type SqlDatabaseAdapter = {
|
|
96
|
+
kind: "d1";
|
|
97
|
+
prepare(query: string): SqlPreparedStatement;
|
|
98
|
+
batch<T = Record<string, unknown>>(statements: SqlPreparedStatement[]): Promise<SqlResult<T>[]>;
|
|
99
|
+
};
|
|
100
|
+
type RuntimePlatform = {
|
|
101
|
+
id: "cloudflare-workers";
|
|
102
|
+
database: SqlDatabaseAdapter | null;
|
|
103
|
+
objectStorage: ObjectStorageAdapter | null;
|
|
104
|
+
imageTransformer: ImageTransformerAdapter | null;
|
|
105
|
+
publicCache: PublicCacheAdapter | null;
|
|
106
|
+
keyValueCache: KeyValueCacheAdapter | null;
|
|
107
|
+
};
|
|
108
|
+
type CloudflareCacheLike = Pick<Cache, "match" | "put" | "delete">;
|
|
109
|
+
type CloudflareKvLike = Pick<KVNamespace, "get" | "put" | "delete" | "list">;
|
|
110
|
+
declare function createCloudflarePublicCacheAdapter(cache: CloudflareCacheLike): PublicCacheAdapter;
|
|
111
|
+
declare function createNoopPublicCacheAdapter(kind?: "noop"): PublicCacheAdapter;
|
|
112
|
+
declare function createCloudflareKeyValueCacheAdapter(namespace: CloudflareKvLike): KeyValueCacheAdapter;
|
|
113
|
+
declare function createNoopKeyValueCacheAdapter(kind?: "noop"): KeyValueCacheAdapter;
|
|
114
|
+
declare function createCloudflareRuntimePlatform(env: PlatformBindingEnv, options?: {
|
|
115
|
+
publicCache?: CloudflareCacheLike | null;
|
|
116
|
+
}): RuntimePlatform;
|
|
117
|
+
|
|
118
|
+
export { type ImageTransformOptions, type ImageTransformResult, type ImageTransformerAdapter, type KeyValueCacheAdapter, type KeyValueCacheGetOptions, type KeyValueCacheListOptions, type KeyValueCacheListResult, type KeyValueCachePutOptions, type ObjectStorageAdapter, type ObjectStorageListItem, type ObjectStoragePutOptions, type PlatformBindingEnv, type PublicCacheAdapter, type RuntimePlatform, type SqlDatabaseAdapter, type SqlPreparedStatement, type SqlResult, type SqlValue, type StoredObject, createCloudflareKeyValueCacheAdapter, createCloudflarePublicCacheAdapter, createCloudflareRuntimePlatform, createNoopKeyValueCacheAdapter, createNoopPublicCacheAdapter };
|