@statewalker/cellb 0.0.0-stage → 0.1.1
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 +21 -0
- package/README.md +323 -2
- package/dist/adapters/files-backup.d.ts +16 -0
- package/dist/adapters/files-backup.js +32 -0
- package/dist/adapters/files-backup.js.map +1 -0
- package/dist/adapters/files-changelog.d.ts +33 -0
- package/dist/adapters/files-changelog.js +96 -0
- package/dist/adapters/files-changelog.js.map +1 -0
- package/dist/adapters/files-ltx.d.ts +35 -0
- package/dist/adapters/files-ltx.js +9 -0
- package/dist/adapters/files-ltx.js.map +1 -0
- package/dist/adapters/ltx-vfs.d.ts +21 -0
- package/dist/adapters/ltx-vfs.js +286 -0
- package/dist/adapters/ltx-vfs.js.map +1 -0
- package/dist/adapters/node-sqlite.d.ts +45 -0
- package/dist/adapters/node-sqlite.js +254 -0
- package/dist/adapters/node-sqlite.js.map +1 -0
- package/dist/adapters/wasm-page-hook.d.ts +26 -0
- package/dist/adapters/wasm-page-hook.js +55 -0
- package/dist/adapters/wasm-page-hook.js.map +1 -0
- package/dist/adapters/wasm-session.d.ts +11 -0
- package/dist/adapters/wasm-session.js +76 -0
- package/dist/adapters/wasm-session.js.map +1 -0
- package/dist/adapters/wasm-sqlite.d.ts +89 -0
- package/dist/adapters/wasm-sqlite.js +258 -0
- package/dist/adapters/wasm-sqlite.js.map +1 -0
- package/dist/bindings/assets.d.ts +26 -0
- package/dist/bindings/assets.js +260 -0
- package/dist/bindings/assets.js.map +1 -0
- package/dist/bindings/cache.d.ts +16 -0
- package/dist/bindings/cache.js +34 -0
- package/dist/bindings/cache.js.map +1 -0
- package/dist/bindings/celld-kv.d.ts +26 -0
- package/dist/bindings/celld-kv.js +81 -0
- package/dist/bindings/celld-kv.js.map +1 -0
- package/dist/bindings/celld-queues.d.ts +56 -0
- package/dist/bindings/celld-queues.js +223 -0
- package/dist/bindings/celld-queues.js.map +1 -0
- package/dist/bindings/celld-workflows.d.ts +22 -0
- package/dist/bindings/celld-workflows.js +54 -0
- package/dist/bindings/celld-workflows.js.map +1 -0
- package/dist/bindings/cron.d.ts +27 -0
- package/dist/bindings/cron.js +232 -0
- package/dist/bindings/cron.js.map +1 -0
- package/dist/bindings/d1-migrations.d.ts +22 -0
- package/dist/bindings/d1-migrations.js +32 -0
- package/dist/bindings/d1-migrations.js.map +1 -0
- package/dist/bindings/html-rewriter.d.ts +8 -0
- package/dist/bindings/html-rewriter.js +75 -0
- package/dist/bindings/html-rewriter.js.map +1 -0
- package/dist/bindings/r2-celld.d.ts +3 -0
- package/dist/bindings/r2-celld.js +113 -0
- package/dist/bindings/r2-celld.js.map +1 -0
- package/dist/bindings/r2.d.ts +236 -0
- package/dist/bindings/r2.js +419 -0
- package/dist/bindings/r2.js.map +1 -0
- package/dist/bindings/worker-loader.d.ts +83 -0
- package/dist/bindings/worker-loader.js +183 -0
- package/dist/bindings/worker-loader.js.map +1 -0
- package/dist/bindings/workers-ai.d.ts +39 -0
- package/dist/bindings/workers-ai.js +175 -0
- package/dist/bindings/workers-ai.js.map +1 -0
- package/dist/browser.d.ts +7 -0
- package/dist/browser.js +8 -0
- package/dist/browser.js.map +1 -0
- package/dist/bucket/celld-cells.d.ts +86 -0
- package/dist/bucket/celld-cells.js +273 -0
- package/dist/bucket/celld-cells.js.map +1 -0
- package/dist/bucket/celld-format.d.ts +10 -0
- package/dist/bucket/celld-format.js +27 -0
- package/dist/bucket/celld-format.js.map +1 -0
- package/dist/bucket/idb-object-store.d.ts +9 -0
- package/dist/bucket/idb-object-store.js +73 -0
- package/dist/bucket/idb-object-store.js.map +1 -0
- package/dist/bucket/ltx-log.d.ts +34 -0
- package/dist/bucket/ltx-log.js +289 -0
- package/dist/bucket/ltx-log.js.map +1 -0
- package/dist/bucket/object-store.d.ts +51 -0
- package/dist/bucket/object-store.js +114 -0
- package/dist/bucket/object-store.js.map +1 -0
- package/dist/bucket/s3-object-store.d.ts +25 -0
- package/dist/bucket/s3-object-store.js +151 -0
- package/dist/bucket/s3-object-store.js.map +1 -0
- package/dist/bucket/sqlite-object-store.d.ts +10 -0
- package/dist/bucket/sqlite-object-store.js +107 -0
- package/dist/bucket/sqlite-object-store.js.map +1 -0
- package/dist/core/alarms.d.ts +27 -0
- package/dist/core/alarms.js +88 -0
- package/dist/core/alarms.js.map +1 -0
- package/dist/core/async-context.d.ts +34 -0
- package/dist/core/async-context.js +50 -0
- package/dist/core/async-context.js.map +1 -0
- package/dist/core/celld-schema.d.ts +14 -0
- package/dist/core/celld-schema.js +34 -0
- package/dist/core/celld-schema.js.map +1 -0
- package/dist/core/durable-object.d.ts +28 -0
- package/dist/core/durable-object.js +31 -0
- package/dist/core/durable-object.js.map +1 -0
- package/dist/core/gates.d.ts +33 -0
- package/dist/core/gates.js +89 -0
- package/dist/core/gates.js.map +1 -0
- package/dist/core/handles.d.ts +90 -0
- package/dist/core/handles.js +224 -0
- package/dist/core/handles.js.map +1 -0
- package/dist/core/id.d.ts +19 -0
- package/dist/core/id.js +64 -0
- package/dist/core/id.js.map +1 -0
- package/dist/core/namespace.d.ts +38 -0
- package/dist/core/namespace.js +141 -0
- package/dist/core/namespace.js.map +1 -0
- package/dist/core/object-host.d.ts +91 -0
- package/dist/core/object-host.js +616 -0
- package/dist/core/object-host.js.map +1 -0
- package/dist/core/request-body.d.ts +9 -0
- package/dist/core/request-body.js +55 -0
- package/dist/core/request-body.js.map +1 -0
- package/dist/core/runtime.d.ts +121 -0
- package/dist/core/runtime.js +366 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/shard.d.ts +7 -0
- package/dist/core/shard.js +10 -0
- package/dist/core/shard.js.map +1 -0
- package/dist/core/sql-split.d.ts +15 -0
- package/dist/core/sql-split.js +101 -0
- package/dist/core/sql-split.js.map +1 -0
- package/dist/core/sql-storage.d.ts +53 -0
- package/dist/core/sql-storage.js +407 -0
- package/dist/core/sql-storage.js.map +1 -0
- package/dist/core/state.d.ts +44 -0
- package/dist/core/state.js +93 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/storage.d.ts +103 -0
- package/dist/core/storage.js +351 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/worker-rejections.d.ts +21 -0
- package/dist/core/worker-rejections.js +55 -0
- package/dist/core/worker-rejections.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/isolate/browser.d.ts +16 -0
- package/dist/isolate/browser.js +37 -0
- package/dist/isolate/browser.js.map +1 -0
- package/dist/isolate/host.d.ts +24 -0
- package/dist/isolate/host.js +74 -0
- package/dist/isolate/host.js.map +1 -0
- package/dist/isolate/isolate-worker.d.ts +1 -0
- package/dist/isolate/isolate-worker.js +53 -0
- package/dist/isolate/isolate-worker.js.map +1 -0
- package/dist/isolate/isolate.d.ts +10 -0
- package/dist/isolate/isolate.js +169 -0
- package/dist/isolate/isolate.js.map +1 -0
- package/dist/isolate/node-entry.d.ts +1 -0
- package/dist/isolate/node-entry.js +12 -0
- package/dist/isolate/node-entry.js.map +1 -0
- package/dist/isolate/protocol.d.ts +66 -0
- package/dist/isolate/protocol.js +205 -0
- package/dist/isolate/protocol.js.map +1 -0
- package/dist/ltx/crc64.d.ts +6 -0
- package/dist/ltx/crc64.js +46 -0
- package/dist/ltx/crc64.js.map +1 -0
- package/dist/ltx/ltx-page-server.d.ts +65 -0
- package/dist/ltx/ltx-page-server.js +309 -0
- package/dist/ltx/ltx-page-server.js.map +1 -0
- package/dist/ltx/ltx-pages.d.ts +81 -0
- package/dist/ltx/ltx-pages.js +315 -0
- package/dist/ltx/ltx-pages.js.map +1 -0
- package/dist/ltx/ltx-store-worker.d.ts +1 -0
- package/dist/ltx/ltx-store-worker.js +38 -0
- package/dist/ltx/ltx-store-worker.js.map +1 -0
- package/dist/ltx/ltx.d.ts +45 -0
- package/dist/ltx/ltx.js +203 -0
- package/dist/ltx/ltx.js.map +1 -0
- package/dist/ltx/lz4.d.ts +9 -0
- package/dist/ltx/lz4.js +156 -0
- package/dist/ltx/lz4.js.map +1 -0
- package/dist/ltx/opfs-sync-files.d.ts +23 -0
- package/dist/ltx/opfs-sync-files.js +191 -0
- package/dist/ltx/opfs-sync-files.js.map +1 -0
- package/dist/ltx/xxh32.d.ts +1 -0
- package/dist/ltx/xxh32.js +43 -0
- package/dist/ltx/xxh32.js.map +1 -0
- package/dist/miniflare-compat/blob-service.d.ts +13 -0
- package/dist/miniflare-compat/blob-service.js +66 -0
- package/dist/miniflare-compat/blob-service.js.map +1 -0
- package/dist/miniflare-compat/kv-binding.d.ts +44 -0
- package/dist/miniflare-compat/kv-binding.js +99 -0
- package/dist/miniflare-compat/kv-binding.js.map +1 -0
- package/dist/miniflare-compat/shims/assert.d.ts +15 -0
- package/dist/miniflare-compat/shims/assert.js +24 -0
- package/dist/miniflare-compat/shims/assert.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-cloudflare.d.ts +7 -0
- package/dist/miniflare-compat/shims/workerd-cloudflare.js +6 -0
- package/dist/miniflare-compat/shims/workerd-cloudflare.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-globals.d.ts +1 -0
- package/dist/miniflare-compat/shims/workerd-globals.js +30 -0
- package/dist/miniflare-compat/shims/workerd-globals.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-internal.d.ts +20 -0
- package/dist/miniflare-compat/shims/workerd-internal.js +23 -0
- package/dist/miniflare-compat/shims/workerd-internal.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-performance.d.ts +4 -0
- package/dist/miniflare-compat/shims/workerd-performance.js +17 -0
- package/dist/miniflare-compat/shims/workerd-performance.js.map +1 -0
- package/dist/miniflare-compat/simulator-fetcher.d.ts +9 -0
- package/dist/miniflare-compat/simulator-fetcher.js +14 -0
- package/dist/miniflare-compat/simulator-fetcher.js.map +1 -0
- package/dist/miniflare-compat/vendored.d.ts +15 -0
- package/dist/miniflare-compat/vendored.js +27 -0
- package/dist/miniflare-compat/vendored.js.map +1 -0
- package/dist/node-compat/async_hooks.d.ts +22 -0
- package/dist/node-compat/async_hooks.js +176 -0
- package/dist/node-compat/async_hooks.js.map +1 -0
- package/dist/node-compat/browser-registry.d.ts +3 -0
- package/dist/node-compat/browser-registry.js +39 -0
- package/dist/node-compat/browser-registry.js.map +1 -0
- package/dist/node-compat/crypto.d.ts +60 -0
- package/dist/node-compat/crypto.js +143 -0
- package/dist/node-compat/crypto.js.map +1 -0
- package/dist/node-compat/diagnostics_channel.d.ts +27 -0
- package/dist/node-compat/diagnostics_channel.js +46 -0
- package/dist/node-compat/diagnostics_channel.js.map +1 -0
- package/dist/node-compat/fs.d.ts +35 -0
- package/dist/node-compat/fs.js +40 -0
- package/dist/node-compat/fs.js.map +1 -0
- package/dist/node-compat/globals.d.ts +3 -0
- package/dist/node-compat/globals.js +4 -0
- package/dist/node-compat/globals.js.map +1 -0
- package/dist/node-compat/install.d.ts +5 -0
- package/dist/node-compat/install.js +12 -0
- package/dist/node-compat/install.js.map +1 -0
- package/dist/node-compat/module.d.ts +12 -0
- package/dist/node-compat/module.js +36 -0
- package/dist/node-compat/module.js.map +1 -0
- package/dist/node-compat/modules.d.ts +8 -0
- package/dist/node-compat/modules.js +23 -0
- package/dist/node-compat/modules.js.map +1 -0
- package/dist/node-compat/os.d.ts +36 -0
- package/dist/node-compat/os.js +36 -0
- package/dist/node-compat/os.js.map +1 -0
- package/dist/node-compat/process.d.ts +14 -0
- package/dist/node-compat/process.js +16 -0
- package/dist/node-compat/process.js.map +1 -0
- package/dist/node-compat/shims.d.ts +4 -0
- package/dist/node.d.ts +5 -0
- package/dist/node.js +6 -0
- package/dist/node.js.map +1 -0
- package/dist/peer/celld-peer.d.ts +53 -0
- package/dist/peer/celld-peer.js +555 -0
- package/dist/peer/celld-peer.js.map +1 -0
- package/dist/ports.d.ts +183 -0
- package/dist/ports.js +10 -0
- package/dist/ports.js.map +1 -0
- package/dist/project/browser-bundle.d.ts +17 -0
- package/dist/project/browser-bundle.js +125 -0
- package/dist/project/browser-bundle.js.map +1 -0
- package/dist/project/browser-cookies.d.ts +12 -0
- package/dist/project/browser-cookies.js +90 -0
- package/dist/project/browser-cookies.js.map +1 -0
- package/dist/project/browser-host.d.ts +173 -0
- package/dist/project/browser-host.js +200 -0
- package/dist/project/browser-host.js.map +1 -0
- package/dist/project/browser-modules.d.ts +17 -0
- package/dist/project/browser-modules.js +89 -0
- package/dist/project/browser-modules.js.map +1 -0
- package/dist/project/browser-shards.d.ts +62 -0
- package/dist/project/browser-shards.js +210 -0
- package/dist/project/browser-shards.js.map +1 -0
- package/dist/project/browser-tabs.d.ts +103 -0
- package/dist/project/browser-tabs.js +418 -0
- package/dist/project/browser-tabs.js.map +1 -0
- package/dist/project/cloudflare-email.d.ts +8 -0
- package/dist/project/cloudflare-email.js +11 -0
- package/dist/project/cloudflare-email.js.map +1 -0
- package/dist/project/cloudflare-workers.d.ts +12 -0
- package/dist/project/cloudflare-workers.js +16 -0
- package/dist/project/cloudflare-workers.js.map +1 -0
- package/dist/project/host-modules.d.ts +4 -0
- package/dist/project/host-modules.js +40 -0
- package/dist/project/host-modules.js.map +1 -0
- package/dist/project/jsonc.d.ts +2 -0
- package/dist/project/jsonc.js +27 -0
- package/dist/project/jsonc.js.map +1 -0
- package/dist/project/lower-await.d.ts +2 -0
- package/dist/project/lower-await.js +151 -0
- package/dist/project/lower-await.js.map +1 -0
- package/dist/project/node-project.d.ts +38 -0
- package/dist/project/node-project.js +373 -0
- package/dist/project/node-project.js.map +1 -0
- package/dist/project/own-module.d.ts +6 -0
- package/dist/project/own-module.js +13 -0
- package/dist/project/own-module.js.map +1 -0
- package/dist/project/scheduler.d.ts +2 -0
- package/dist/project/scheduler.js +3 -0
- package/dist/project/scheduler.js.map +1 -0
- package/dist/project/site.d.ts +74 -0
- package/dist/project/site.js +206 -0
- package/dist/project/site.js.map +1 -0
- package/dist/project/virtual-modules.d.ts +3 -0
- package/dist/project/worker-scope.d.ts +27 -0
- package/dist/project/worker-scope.js +46 -0
- package/dist/project/worker-scope.js.map +1 -0
- package/dist/project/workerd-message-channel.d.ts +13 -0
- package/dist/project/workerd-message-channel.js +137 -0
- package/dist/project/workerd-message-channel.js.map +1 -0
- package/dist/project/workers-global-names.d.ts +6 -0
- package/dist/project/workers-global-names.js +15 -0
- package/dist/project/workers-global-names.js.map +1 -0
- package/dist/project/workers-globals-module.d.ts +8 -0
- package/dist/project/workers-globals-module.js +9 -0
- package/dist/project/workers-globals-module.js.map +1 -0
- package/dist/project/workers-globals.d.ts +9 -0
- package/dist/project/workers-globals.js +19 -0
- package/dist/project/workers-globals.js.map +1 -0
- package/dist/project/wrangler.d.ts +116 -0
- package/dist/project/wrangler.js +342 -0
- package/dist/project/wrangler.js.map +1 -0
- package/dist/router/cell-router.d.ts +72 -0
- package/dist/router/cell-router.js +247 -0
- package/dist/router/cell-router.js.map +1 -0
- package/dist/router/shard-worker.d.ts +44 -0
- package/dist/router/shard-worker.js +163 -0
- package/dist/router/shard-worker.js.map +1 -0
- package/dist/transport/cells-http.d.ts +25 -0
- package/dist/transport/cells-http.js +141 -0
- package/dist/transport/cells-http.js.map +1 -0
- package/dist/transport/cells-link.d.ts +27 -0
- package/dist/transport/cells-link.js +71 -0
- package/dist/transport/cells-link.js.map +1 -0
- package/dist/transport/port.d.ts +26 -0
- package/dist/transport/port.js +100 -0
- package/dist/transport/port.js.map +1 -0
- package/dist/v8/codec.d.ts +6 -0
- package/dist/v8/codec.js +9 -0
- package/dist/v8/codec.js.map +1 -0
- package/dist/v8/serialize.d.ts +10 -0
- package/dist/v8/serialize.js +601 -0
- package/dist/v8/serialize.js.map +1 -0
- package/dist/ws/client.d.ts +25 -0
- package/dist/ws/client.js +203 -0
- package/dist/ws/client.js.map +1 -0
- package/dist/ws/control.d.ts +48 -0
- package/dist/ws/control.js +44 -0
- package/dist/ws/control.js.map +1 -0
- package/dist/ws/frames.d.ts +38 -0
- package/dist/ws/frames.js +39 -0
- package/dist/ws/frames.js.map +1 -0
- package/dist/ws/server.d.ts +99 -0
- package/dist/ws/server.js +295 -0
- package/dist/ws/server.js.map +1 -0
- package/dist/ws/sw-connector.d.ts +10 -0
- package/dist/ws/sw-connector.js +25 -0
- package/dist/ws/sw-connector.js.map +1 -0
- package/dist/ws/upgrade.d.ts +28 -0
- package/dist/ws/upgrade.js +75 -0
- package/dist/ws/upgrade.js.map +1 -0
- package/package.json +111 -3
- package/vendor/celld/LICENSE +202 -0
- package/vendor/celld/kv.js +1131 -0
- package/vendor/celld/queues.js +1656 -0
- package/vendor/celld/workflows.js +1610 -0
- package/vendor/html-rewriter-wasm/html_rewriter.js +925 -0
- package/vendor/html-rewriter-wasm/html_rewriter_bg.wasm +0 -0
- package/vendor/miniflare/d1-api.js +738 -0
- package/vendor/miniflare/d1-database.js +6978 -0
- package/vendor/miniflare/kv-namespace.js +3061 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/bindings/cron.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cron Triggers in celld's dialect (docs/services/cron-triggers.md, = Cloudflare's):\n * five fields — minute, hour, day of month, month, day of week — UTC, one-minute resolution.\n * `*`, values, `a-b`, `a,b`, `/n`; month and weekday names; weekdays 1–7 from SUNDAY;\n * day of month `L`, `L-<n>`, `LW`, `L-<n>W`, `<d>W`; day of week `<dow>L`, `<dow>#<n>`.\n * When both day fields are restricted they form a union. Refused like celld: descending\n * ranges, lists containing `*`, steps wider than the field.\n */\nconst MONTHS = [\"JAN\", \"FEB\", \"MAR\", \"APR\", \"MAY\", \"JUN\", \"JUL\", \"AUG\", \"SEP\", \"OCT\", \"NOV\", \"DEC\"];\nconst DAYS = [\"SUN\", \"MON\", \"TUE\", \"WED\", \"THU\", \"FRI\", \"SAT\"];\n\ninterface Field {\n any: boolean;\n values: Set<number>;\n}\n\nfunction parseSimple(\n text: string,\n min: number,\n max: number,\n names?: string[],\n nameBase = 1,\n): Field {\n if (text === \"*\") return { any: true, values: new Set(range(min, max)) };\n const parts = text.split(\",\");\n if (parts.length > 1 && parts.includes(\"*\"))\n throw new Error(`cron: a list cannot contain \"*\": ${text}`);\n const values = new Set<number>();\n const value = (v: string) => {\n const i = names?.indexOf(v.toUpperCase()) ?? -1;\n const n = i >= 0 ? i + nameBase : Number(v);\n if (!Number.isInteger(n) || n < min || n > max)\n throw new Error(`cron: value out of range: ${v}`);\n return n;\n };\n for (const part of parts) {\n const [base, stepText] = part.split(\"/\");\n const step = stepText === undefined ? 1 : Number(stepText);\n if (!Number.isInteger(step) || step < 1 || step > max - min)\n throw new Error(`cron: bad step: ${part}`);\n let lo: number;\n let hi: number;\n if (base === \"*\") [lo, hi] = [min, max];\n else if (base.includes(\"-\")) {\n const [a, b] = base.split(\"-\");\n [lo, hi] = [value(a), value(b)];\n if (lo > hi) throw new Error(`cron: descending range: ${base}`);\n } else {\n lo = value(base);\n hi = stepText === undefined ? lo : max;\n }\n for (let v = lo; v <= hi; v += step) values.add(v);\n }\n return { any: false, values };\n}\n\nconst range = (a: number, b: number) => Array.from({ length: b - a + 1 }, (_, i) => a + i);\nconst daysInMonth = (y: number, m: number) => new Date(Date.UTC(y, m + 1, 0)).getUTCDate();\n\ntype DayRule = (y: number, m: number, d: number) => boolean;\n\nfunction parseDom(text: string): { any: boolean; match: DayRule } {\n if (text === \"*\") return { any: true, match: () => true };\n const rules: DayRule[] = [];\n for (const part of text.split(\",\")) {\n const up = part.toUpperCase();\n const last = /^L(?:-(\\d+))?(W?)$/.exec(up);\n const weekdayOf = /^(\\d+)W$/.exec(up);\n if (last) {\n const m = last;\n const back = Number(m[1] ?? 0);\n const weekday = m[2] === \"W\";\n rules.push((y, mo, d) => {\n const target = daysInMonth(y, mo) - back;\n return d === (weekday ? nearestWeekday(y, mo, target) : target);\n });\n } else if (weekdayOf) {\n const day = Number(weekdayOf[1]);\n rules.push((y, mo, d) => d === nearestWeekday(y, mo, Math.min(day, daysInMonth(y, mo))));\n } else {\n const f = parseSimple(part, 1, 31);\n rules.push((_y, _m, d) => f.values.has(d));\n }\n }\n return { any: false, match: (y, mo, d) => rules.some((r) => r(y, mo, d)) };\n}\n\nfunction nearestWeekday(y: number, m: number, day: number): number {\n const dow = new Date(Date.UTC(y, m, day)).getUTCDay();\n if (dow === 6) return day > 1 ? day - 1 : day + 2;\n if (dow === 0) return day < daysInMonth(y, m) ? day + 1 : day - 2;\n return day;\n}\n\nfunction parseDow(text: string): { any: boolean; match: DayRule } {\n if (text === \"*\") return { any: true, match: () => true };\n const rules: DayRule[] = [];\n const dowOf = (v: string) => {\n const i = DAYS.indexOf(v.toUpperCase());\n const n = i >= 0 ? i + 1 : Number(v);\n if (!Number.isInteger(n) || n < 1 || n > 7) throw new Error(`cron: weekday out of range: ${v}`);\n return n - 1; // JS getUTCDay(): 0 = Sunday\n };\n for (const part of text.split(\",\")) {\n const lastOf = /^(\\w+)L$/i.exec(part);\n const nthOf = /^(\\w+)#(\\d)$/.exec(part);\n if (lastOf && !/^\\d+$/.test(part)) {\n const dow = dowOf(lastOf[1]);\n rules.push(\n (y, mo, d) =>\n new Date(Date.UTC(y, mo, d)).getUTCDay() === dow && d + 7 > daysInMonth(y, mo),\n );\n } else if (nthOf) {\n const dow = dowOf(nthOf[1]);\n const nth = Number(nthOf[2]);\n rules.push(\n (y, mo, d) => new Date(Date.UTC(y, mo, d)).getUTCDay() === dow && Math.ceil(d / 7) === nth,\n );\n } else {\n const f = parseSimple(part, 1, 7, DAYS, 1);\n rules.push((y, mo, d) => f.values.has(new Date(Date.UTC(y, mo, d)).getUTCDay() + 1));\n }\n }\n return { any: false, match: (y, mo, d) => rules.some((r) => r(y, mo, d)) };\n}\n\nexport interface CronSchedule {\n readonly text: string;\n matches(t: number): boolean;\n /** First occurrence strictly after `t` (ms), at a whole minute. */\n next(t: number): number;\n}\n\nexport function parseCron(text: string): CronSchedule {\n const fields = text.trim().split(/\\s+/);\n if (fields.length !== 5) throw new Error(`cron: expected 5 fields: ${text}`);\n const minute = parseSimple(fields[0], 0, 59);\n const hour = parseSimple(fields[1], 0, 23);\n const dom = parseDom(fields[2]);\n const month = parseSimple(fields[3], 1, 12, MONTHS, 1);\n const dow = parseDow(fields[4]);\n const dayOk = (y: number, m: number, d: number) =>\n dom.any && dow.any\n ? true\n : dom.any\n ? dow.match(y, m, d)\n : dow.any\n ? dom.match(y, m, d)\n : dom.match(y, m, d) || dow.match(y, m, d);\n const matches = (t: number) => {\n const x = new Date(t);\n return (\n minute.values.has(x.getUTCMinutes()) &&\n hour.values.has(x.getUTCHours()) &&\n month.values.has(x.getUTCMonth() + 1) &&\n dayOk(x.getUTCFullYear(), x.getUTCMonth(), x.getUTCDate())\n );\n };\n return {\n text,\n matches,\n next(t: number) {\n let c = Math.floor(t / 60_000) * 60_000 + 60_000;\n const limit = c + 5 * 366 * 86_400_000;\n while (c < limit) {\n const x = new Date(c);\n if (\n !month.values.has(x.getUTCMonth() + 1) ||\n !dayOk(x.getUTCFullYear(), x.getUTCMonth(), x.getUTCDate())\n ) {\n c = Date.UTC(x.getUTCFullYear(), x.getUTCMonth(), x.getUTCDate() + 1); // next day, 00:00\n continue;\n }\n if (matches(c)) return c;\n c += 60_000;\n }\n throw new Error(`cron: no occurrence within 5 years: ${text}`);\n },\n };\n}\n\nexport interface CronClock {\n now(): number;\n setTimeout(fn: () => void, ms: number): unknown;\n clearTimeout(h: unknown): void;\n}\n\n/**\n * Runs the Worker's `scheduled(controller, env, ctx)` for each expression, as celld does:\n * one invocation at a time with its `waitUntil()` work drained before the next; a throwing\n * handler retries after 4 s, doubling, until six failures, `controller.noRetry()` or the next\n * occurrence; `scheduledTime` names the occurrence, not the attempt.\n */\n/** Where the last fired occurrence of each expression is kept (for the downtime catch-up). */\nexport interface CronStateStore {\n get(expression: string): number | undefined;\n set(expression: string, scheduledTime: number): void;\n}\n\nexport function startCronTriggers(\n expressions: string[],\n handler: (\n controller: unknown,\n ctx: { waitUntil(p: Promise<unknown>): void; passThroughOnException(): void },\n ) => unknown,\n clock: CronClock,\n state?: CronStateStore,\n): () => void {\n const schedules = expressions.map(parseCron);\n const timers = new Set<unknown>();\n let chain: Promise<void> = Promise.resolve();\n let stopped = false;\n const at = (t: number, fn: () => void) => {\n const h = clock.setTimeout(\n () => {\n timers.delete(h);\n if (!stopped) fn();\n },\n Math.max(0, t - clock.now()),\n );\n timers.add(h);\n };\n const run = (\n s: CronSchedule,\n scheduledTime: number,\n failures: number,\n nextOccurrence: number,\n ) => {\n chain = chain.then(async () => {\n let retry = true;\n const pending: Promise<unknown>[] = [];\n const controller = {\n cron: s.text,\n scheduledTime,\n type: \"scheduled\",\n noRetry: () => {\n retry = false;\n },\n };\n try {\n await handler(controller, {\n waitUntil: (p) => pending.push(p),\n passThroughOnException() {},\n });\n await Promise.allSettled(pending);\n } catch {\n await Promise.allSettled(pending);\n const delay = 4_000 * 2 ** failures;\n if (retry && failures + 1 < 6 && clock.now() + delay < nextOccurrence)\n at(clock.now() + delay, () => run(s, scheduledTime, failures + 1, nextOccurrence));\n }\n });\n };\n const arm = (s: CronSchedule, from: number) => {\n const t = s.next(from);\n at(t, () => {\n state?.set(s.text, t);\n run(s, t, 0, s.next(t));\n arm(s, t);\n });\n };\n // After downtime: run ONE missed occurrence (the latest) and skip the rest, as celld does.\n for (const s of schedules) {\n const last = state?.get(s.text);\n if (last === undefined) continue;\n let missed: number | undefined;\n const now = clock.now();\n for (let t = s.next(last), n = 0; t <= now && n < 600_000; t = s.next(t), n++) missed = t;\n if (missed !== undefined) {\n state?.set(s.text, missed);\n run(s, missed, 0, s.next(missed));\n }\n }\n for (const s of schedules) arm(s, clock.now());\n return () => {\n stopped = true;\n for (const h of timers) clock.clearTimeout(h);\n timers.clear();\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D1 migrations as celld (and wrangler) apply them: files `NNNN_description.sql` (extension
|
|
3
|
+
* ASCII case-insensitive) in `migrations_dir` (default `migrations/`), applied in the order of
|
|
4
|
+
* their numeric prefixes, each recorded in `migrations_table` (default `d1_migrations`, the
|
|
5
|
+
* table and columns `wrangler d1 migrations` uses). celld runs this from its CLI against a
|
|
6
|
+
* fleet; cellb exposes it as a function on the D1 binding, for any host.
|
|
7
|
+
*/
|
|
8
|
+
export interface D1Like {
|
|
9
|
+
exec(sql: string): Promise<unknown>;
|
|
10
|
+
prepare(sql: string): {
|
|
11
|
+
bind(...v: unknown[]): {
|
|
12
|
+
run(): Promise<unknown>;
|
|
13
|
+
};
|
|
14
|
+
all<T>(): Promise<{
|
|
15
|
+
results: T[];
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare function sortMigrations(files: [string, string][]): [string, string][];
|
|
20
|
+
export declare function listAppliedMigrations(db: D1Like, table?: string): Promise<string[]>;
|
|
21
|
+
/** Applies the migrations not yet recorded; returns the names applied now. */
|
|
22
|
+
export declare function applyD1Migrations(db: D1Like, files: [string, string][], table?: string): Promise<string[]>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const FILE = /^(\d+)_.+\.sql$/i;
|
|
2
|
+
export function sortMigrations(files) {
|
|
3
|
+
return files
|
|
4
|
+
.filter(([name]) => FILE.test(name))
|
|
5
|
+
.sort(([a], [b]) => Number(FILE.exec(a)[1]) - Number(FILE.exec(b)[1]) || a.localeCompare(b));
|
|
6
|
+
}
|
|
7
|
+
export async function listAppliedMigrations(db, table = "d1_migrations") {
|
|
8
|
+
await ensureTable(db, table);
|
|
9
|
+
const { results } = await db
|
|
10
|
+
.prepare(`SELECT name FROM ${table} ORDER BY id`)
|
|
11
|
+
.all();
|
|
12
|
+
return results.map((r) => r.name);
|
|
13
|
+
}
|
|
14
|
+
/** Applies the migrations not yet recorded; returns the names applied now. */
|
|
15
|
+
export async function applyD1Migrations(db, files, table = "d1_migrations") {
|
|
16
|
+
const done = new Set(await listAppliedMigrations(db, table));
|
|
17
|
+
const applied = [];
|
|
18
|
+
for (const [name, sql] of sortMigrations(files)) {
|
|
19
|
+
if (done.has(name))
|
|
20
|
+
continue;
|
|
21
|
+
await db.exec(sql);
|
|
22
|
+
await db.prepare(`INSERT INTO ${table} (name) VALUES (?)`).bind(name).run();
|
|
23
|
+
applied.push(name);
|
|
24
|
+
}
|
|
25
|
+
return applied;
|
|
26
|
+
}
|
|
27
|
+
async function ensureTable(db, table) {
|
|
28
|
+
if (!/^\w+$/.test(table))
|
|
29
|
+
throw new Error(`invalid migrations_table: ${table}`);
|
|
30
|
+
await db.exec(`CREATE TABLE IF NOT EXISTS ${table} (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE, applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL)`);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=d1-migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d1-migrations.js","sourceRoot":"","sources":["../../src/bindings/d1-migrations.ts"],"names":[],"mappings":"AAeA,MAAM,IAAI,GAAG,kBAAkB,CAAC;AAEhC,MAAM,UAAU,cAAc,CAAC,KAAyB;IACtD,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACnC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,EAAU,EACV,KAAK,GAAG,eAAe;IAEvB,MAAM,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC7B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE;SACzB,OAAO,CAAC,oBAAoB,KAAK,cAAc,CAAC;SAChD,GAAG,EAAoB,CAAC;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAU,EACV,KAAyB,EACzB,KAAK,GAAG,eAAe;IAEvB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,qBAAqB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7B,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,MAAM,EAAE,CAAC,OAAO,CAAC,eAAe,KAAK,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,EAAU,EAAE,KAAa;IAClD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;IAChF,MAAM,EAAE,CAAC,IAAI,CACX,8BAA8B,KAAK,oHAAoH,CACxJ,CAAC;AACJ,CAAC","sourcesContent":["/**\n * D1 migrations as celld (and wrangler) apply them: files `NNNN_description.sql` (extension\n * ASCII case-insensitive) in `migrations_dir` (default `migrations/`), applied in the order of\n * their numeric prefixes, each recorded in `migrations_table` (default `d1_migrations`, the\n * table and columns `wrangler d1 migrations` uses). celld runs this from its CLI against a\n * fleet; cellb exposes it as a function on the D1 binding, for any host.\n */\nexport interface D1Like {\n exec(sql: string): Promise<unknown>;\n prepare(sql: string): {\n bind(...v: unknown[]): { run(): Promise<unknown> };\n all<T>(): Promise<{ results: T[] }>;\n };\n}\n\nconst FILE = /^(\\d+)_.+\\.sql$/i;\n\nexport function sortMigrations(files: [string, string][]): [string, string][] {\n return files\n .filter(([name]) => FILE.test(name))\n .sort(([a], [b]) => Number(FILE.exec(a)![1]) - Number(FILE.exec(b)![1]) || a.localeCompare(b));\n}\n\nexport async function listAppliedMigrations(\n db: D1Like,\n table = \"d1_migrations\",\n): Promise<string[]> {\n await ensureTable(db, table);\n const { results } = await db\n .prepare(`SELECT name FROM ${table} ORDER BY id`)\n .all<{ name: string }>();\n return results.map((r) => r.name);\n}\n\n/** Applies the migrations not yet recorded; returns the names applied now. */\nexport async function applyD1Migrations(\n db: D1Like,\n files: [string, string][],\n table = \"d1_migrations\",\n): Promise<string[]> {\n const done = new Set(await listAppliedMigrations(db, table));\n const applied: string[] = [];\n for (const [name, sql] of sortMigrations(files)) {\n if (done.has(name)) continue;\n await db.exec(sql);\n await db.prepare(`INSERT INTO ${table} (name) VALUES (?)`).bind(name).run();\n applied.push(name);\n }\n return applied;\n}\n\nasync function ensureTable(db: D1Like, table: string): Promise<void> {\n if (!/^\\w+$/.test(table)) throw new Error(`invalid migrations_table: ${table}`);\n await db.exec(\n `CREATE TABLE IF NOT EXISTS ${table} (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE, applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL)`,\n );\n}\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workers `HTMLRewriter` on lol-html compiled to WASM: Miniflare's `html-rewriter-wasm`
|
|
3
|
+
* (async handlers via asyncify), vendored as an ES module by scripts/vendor-html-rewriter.mjs.
|
|
4
|
+
* The WASM is instantiated on first use — from the file system on Node, with fetch() in
|
|
5
|
+
* browsers — so importing the runtime costs nothing until a Worker rewrites HTML.
|
|
6
|
+
* The streaming wrapper follows Miniflare 2's (packages/html-rewriter/src/rewriter.ts).
|
|
7
|
+
*/
|
|
8
|
+
// @ts-expect-error — generated JS, no declarations
|
|
9
|
+
import glue from "../../vendor/html-rewriter-wasm/html_rewriter.js";
|
|
10
|
+
const wasmUrl = new URL("../../vendor/html-rewriter-wasm/html_rewriter_bg.wasm", import.meta.url);
|
|
11
|
+
let ready;
|
|
12
|
+
function instantiate() {
|
|
13
|
+
ready ??= (async () => {
|
|
14
|
+
let source;
|
|
15
|
+
if (wasmUrl.protocol === "file:") {
|
|
16
|
+
const fsName = "node:fs"; // not statically visible to browser bundlers
|
|
17
|
+
const fs = (await import(/* @vite-ignore */ fsName));
|
|
18
|
+
source = fs.readFileSync(wasmUrl);
|
|
19
|
+
}
|
|
20
|
+
else
|
|
21
|
+
source = await fetch(wasmUrl);
|
|
22
|
+
await glue.__instantiate(source);
|
|
23
|
+
})();
|
|
24
|
+
return ready;
|
|
25
|
+
}
|
|
26
|
+
export class HTMLRewriter {
|
|
27
|
+
#elements = [];
|
|
28
|
+
#documents = [];
|
|
29
|
+
on(selector, handlers) {
|
|
30
|
+
this.#elements.push([selector, handlers]);
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
onDocument(handlers) {
|
|
34
|
+
this.#documents.push(handlers);
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
transform(response) {
|
|
38
|
+
const body = response.body;
|
|
39
|
+
// No body: the end handler would not run anyway.
|
|
40
|
+
if (body === null)
|
|
41
|
+
return new Response(null, response);
|
|
42
|
+
let rewriter;
|
|
43
|
+
const stream = new TransformStream({
|
|
44
|
+
start: async (controller) => {
|
|
45
|
+
await instantiate();
|
|
46
|
+
const Raw = glue.HTMLRewriter;
|
|
47
|
+
rewriter = new Raw((out) => {
|
|
48
|
+
if (out.length !== 0)
|
|
49
|
+
controller.enqueue(out); // enqueue throws on empty chunks
|
|
50
|
+
}, { enableEsiTags: false });
|
|
51
|
+
for (const [selector, handlers] of this.#elements)
|
|
52
|
+
rewriter.on(selector, handlers);
|
|
53
|
+
for (const handlers of this.#documents)
|
|
54
|
+
rewriter.onDocument(handlers);
|
|
55
|
+
},
|
|
56
|
+
transform: (chunk) => rewriter.write(typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk),
|
|
57
|
+
flush: async () => {
|
|
58
|
+
try {
|
|
59
|
+
await rewriter.end();
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
rewriter.free();
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const headers = new Headers(response.headers);
|
|
67
|
+
headers.delete("content-length"); // the rewritten body has another length
|
|
68
|
+
return new Response(body.pipeThrough(stream), {
|
|
69
|
+
status: response.status,
|
|
70
|
+
statusText: response.statusText,
|
|
71
|
+
headers,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=html-rewriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-rewriter.js","sourceRoot":"","sources":["../../src/bindings/html-rewriter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Workers `HTMLRewriter` on lol-html compiled to WASM: Miniflare's `html-rewriter-wasm`\n * (async handlers via asyncify), vendored as an ES module by scripts/vendor-html-rewriter.mjs.\n * The WASM is instantiated on first use — from the file system on Node, with fetch() in\n * browsers — so importing the runtime costs nothing until a Worker rewrites HTML.\n * The streaming wrapper follows Miniflare 2's (packages/html-rewriter/src/rewriter.ts).\n */\n// @ts-expect-error — generated JS, no declarations\nimport glue from \"../../vendor/html-rewriter-wasm/html_rewriter.js\";\n\ntype Handlers = Record<string, unknown>;\ninterface RawRewriter {\n on(selector: string, handlers: Handlers): void;\n onDocument(handlers: Handlers): void;\n write(chunk: Uint8Array): Promise<void>;\n end(): Promise<void>;\n free(): void;\n}\n\nconst wasmUrl = new URL(\"../../vendor/html-rewriter-wasm/html_rewriter_bg.wasm\", import.meta.url);\nlet ready: Promise<void> | undefined;\nfunction instantiate(): Promise<void> {\n ready ??= (async () => {\n let source: unknown;\n if (wasmUrl.protocol === \"file:\") {\n const fsName = \"node:fs\"; // not statically visible to browser bundlers\n const fs = (await import(/* @vite-ignore */ fsName)) as { readFileSync(u: URL): Uint8Array };\n source = fs.readFileSync(wasmUrl);\n } else source = await fetch(wasmUrl);\n await (glue as { __instantiate(s: unknown): Promise<void> }).__instantiate(source);\n })();\n return ready;\n}\n\nexport class HTMLRewriter {\n readonly #elements: [string, Handlers][] = [];\n readonly #documents: Handlers[] = [];\n\n on(selector: string, handlers: Handlers): this {\n this.#elements.push([selector, handlers]);\n return this;\n }\n\n onDocument(handlers: Handlers): this {\n this.#documents.push(handlers);\n return this;\n }\n\n transform(response: Response): Response {\n const body = response.body;\n // No body: the end handler would not run anyway.\n if (body === null) return new Response(null, response);\n let rewriter: RawRewriter | undefined;\n const stream = new TransformStream<Uint8Array, Uint8Array>({\n start: async (controller) => {\n await instantiate();\n const Raw = (\n glue as { HTMLRewriter: new (sink: (out: Uint8Array) => void, o?: object) => RawRewriter }\n ).HTMLRewriter;\n rewriter = new Raw(\n (out) => {\n if (out.length !== 0) controller.enqueue(out); // enqueue throws on empty chunks\n },\n { enableEsiTags: false },\n );\n for (const [selector, handlers] of this.#elements) rewriter.on(selector, handlers);\n for (const handlers of this.#documents) rewriter.onDocument(handlers);\n },\n transform: (chunk) =>\n rewriter!.write(typeof chunk === \"string\" ? new TextEncoder().encode(chunk) : chunk),\n flush: async () => {\n try {\n await rewriter!.end();\n } finally {\n rewriter!.free();\n }\n },\n });\n const headers = new Headers(response.headers);\n headers.delete(\"content-length\"); // the rewritten body has another length\n return new Response(body.pipeThrough(stream), {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* R2 objects as celld stores them (celld/r2_store.rs): not in a cell but directly in the fleet
|
|
3
|
+
* bucket, one object per R2 object at `r2/<bucket_name>/<key>`. The five content headers are
|
|
4
|
+
* stored as the object's own headers; everything else R2 has — case-sensitive custom metadata,
|
|
5
|
+
* cacheExpiry, checksums, storage class — is one JSON record, escaped to ASCII, under the user
|
|
6
|
+
* metadata name `celld-r2`:
|
|
7
|
+
*
|
|
8
|
+
* {"custom":{…},"http":{"contentType":…,"cacheExpiry":…},"checksums":{"md5":"…"},"storageClass":…}
|
|
9
|
+
*
|
|
10
|
+
* An object without the record (written by another tool) still reads: its user metadata is its
|
|
11
|
+
* customMetadata and its headers its httpMetadata. etag and upload time are the store's own.
|
|
12
|
+
* Multipart parts wait under `r2-uploads/<bucket_name>/<uploadId>/` until completion.
|
|
13
|
+
*/
|
|
14
|
+
const ENVELOPE = "celld-r2";
|
|
15
|
+
const HTTP = [
|
|
16
|
+
"contentType",
|
|
17
|
+
"contentLanguage",
|
|
18
|
+
"contentDisposition",
|
|
19
|
+
"contentEncoding",
|
|
20
|
+
"cacheControl",
|
|
21
|
+
];
|
|
22
|
+
/** serde_json escaped to ASCII: every non-ASCII UTF-16 unit as \uXXXX. */
|
|
23
|
+
const asciiJson = (v) => JSON.stringify(v).replace(/[\u007f-\uffff]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
24
|
+
export function celldR2Backend(store, bucketName) {
|
|
25
|
+
const prefix = `r2/${bucketName}/`;
|
|
26
|
+
const uploads = `r2-uploads/${bucketName}/`;
|
|
27
|
+
const metaOf = (key, o) => {
|
|
28
|
+
const raw = o.attrs?.metadata?.[ENVELOPE];
|
|
29
|
+
let env;
|
|
30
|
+
try {
|
|
31
|
+
env = raw ? JSON.parse(raw) : undefined;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
env = undefined;
|
|
35
|
+
}
|
|
36
|
+
const http = {};
|
|
37
|
+
for (const f of HTTP)
|
|
38
|
+
if (o.attrs?.[f] !== undefined)
|
|
39
|
+
http[f] = o.attrs[f];
|
|
40
|
+
if (env?.http?.cacheExpiry !== undefined)
|
|
41
|
+
http.cacheExpiry = new Date(env.http.cacheExpiry);
|
|
42
|
+
const custom = env
|
|
43
|
+
? { ...env.custom }
|
|
44
|
+
: Object.fromEntries(Object.entries(o.attrs?.metadata ?? {}).filter(([k]) => k !== ENVELOPE));
|
|
45
|
+
const etag = o.etag.replace(/^"(.*)"$/, "$1");
|
|
46
|
+
return {
|
|
47
|
+
key,
|
|
48
|
+
size: o.body.byteLength,
|
|
49
|
+
etag,
|
|
50
|
+
version: etag,
|
|
51
|
+
uploaded: o.modifiedMs ?? Date.now(),
|
|
52
|
+
httpMetadata: http,
|
|
53
|
+
customMetadata: custom,
|
|
54
|
+
// The store's etag is never an MD5: an object without one (celld's multipart) has none.
|
|
55
|
+
md5: env?.checksums?.md5 ?? "",
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
async meta(key) {
|
|
60
|
+
const o = await store.get(prefix + key);
|
|
61
|
+
return o ? metaOf(key, o) : undefined;
|
|
62
|
+
},
|
|
63
|
+
async body(key) {
|
|
64
|
+
return (await store.get(prefix + key))?.body;
|
|
65
|
+
},
|
|
66
|
+
async write(key, bytes, m) {
|
|
67
|
+
const attrs = {};
|
|
68
|
+
const httpRecord = {};
|
|
69
|
+
for (const f of HTTP) {
|
|
70
|
+
const v = m.httpMetadata[f];
|
|
71
|
+
if (typeof v === "string") {
|
|
72
|
+
attrs[f] = v;
|
|
73
|
+
httpRecord[f] = v;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const expiry = m.httpMetadata.cacheExpiry;
|
|
77
|
+
if (expiry !== undefined)
|
|
78
|
+
httpRecord.cacheExpiry = expiry instanceof Date ? expiry.getTime() : Number(expiry);
|
|
79
|
+
// Field order and omissions as celld's serde struct (empty maps skipped).
|
|
80
|
+
const env = {};
|
|
81
|
+
if (Object.keys(m.customMetadata).length)
|
|
82
|
+
env.custom = Object.fromEntries(Object.entries(m.customMetadata).sort());
|
|
83
|
+
env.http = httpRecord;
|
|
84
|
+
if (m.md5 !== undefined)
|
|
85
|
+
env.checksums = { md5: m.md5 };
|
|
86
|
+
attrs.metadata = { [ENVELOPE]: asciiJson(env) };
|
|
87
|
+
await store.put(prefix + key, bytes, undefined, attrs);
|
|
88
|
+
const o = await store.get(prefix + key);
|
|
89
|
+
if (!o)
|
|
90
|
+
throw new Error(`R2 put: ${key} vanished after its write`);
|
|
91
|
+
return metaOf(key, o);
|
|
92
|
+
},
|
|
93
|
+
async remove(key) {
|
|
94
|
+
await store.delete(prefix + key);
|
|
95
|
+
},
|
|
96
|
+
async keys() {
|
|
97
|
+
return (await store.list(prefix)).map((k) => k.slice(prefix.length));
|
|
98
|
+
},
|
|
99
|
+
scratch: {
|
|
100
|
+
async write(path, bytes) {
|
|
101
|
+
await store.put(uploads + path, bytes);
|
|
102
|
+
},
|
|
103
|
+
async read(path) {
|
|
104
|
+
return (await store.get(uploads + path))?.body;
|
|
105
|
+
},
|
|
106
|
+
async removeDir(path) {
|
|
107
|
+
for (const k of await store.list(`${uploads}${path}/`))
|
|
108
|
+
await store.delete(k);
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=r2-celld.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2-celld.js","sourceRoot":"","sources":["../../src/bindings/r2-celld.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ObjectAttributes, ObjectStore } from \"../bucket/object-store.js\";\nimport type { R2Backend, R2HTTPMetadata, StoredMeta } from \"./r2.js\";\n\n/**\n * R2 objects as celld stores them (celld/r2_store.rs): not in a cell but directly in the fleet\n * bucket, one object per R2 object at `r2/<bucket_name>/<key>`. The five content headers are\n * stored as the object's own headers; everything else R2 has — case-sensitive custom metadata,\n * cacheExpiry, checksums, storage class — is one JSON record, escaped to ASCII, under the user\n * metadata name `celld-r2`:\n *\n * {\"custom\":{…},\"http\":{\"contentType\":…,\"cacheExpiry\":…},\"checksums\":{\"md5\":\"…\"},\"storageClass\":…}\n *\n * An object without the record (written by another tool) still reads: its user metadata is its\n * customMetadata and its headers its httpMetadata. etag and upload time are the store's own.\n * Multipart parts wait under `r2-uploads/<bucket_name>/<uploadId>/` until completion.\n */\nconst ENVELOPE = \"celld-r2\";\ntype HttpField =\n | \"contentType\"\n | \"contentLanguage\"\n | \"contentDisposition\"\n | \"contentEncoding\"\n | \"cacheControl\";\nconst HTTP: HttpField[] = [\n \"contentType\",\n \"contentLanguage\",\n \"contentDisposition\",\n \"contentEncoding\",\n \"cacheControl\",\n];\n\n/** serde_json escaped to ASCII: every non-ASCII UTF-16 unit as \\uXXXX. */\nconst asciiJson = (v: unknown) =>\n JSON.stringify(v).replace(\n /[\\u007f-\\uffff]/g,\n (c) => `\\\\u${c.charCodeAt(0).toString(16).padStart(4, \"0\")}`,\n );\n\ninterface Envelope {\n custom?: Record<string, string>;\n http?: R2HTTPMetadata & { cacheExpiry?: number };\n checksums?: Record<string, string>;\n storageClass?: string;\n}\n\nexport function celldR2Backend(store: ObjectStore, bucketName: string): R2Backend {\n const prefix = `r2/${bucketName}/`;\n const uploads = `r2-uploads/${bucketName}/`;\n const metaOf = (\n key: string,\n o: { body: Uint8Array; etag: string; attrs?: ObjectAttributes; modifiedMs?: number },\n ): StoredMeta => {\n const raw = o.attrs?.metadata?.[ENVELOPE];\n let env: Envelope | undefined;\n try {\n env = raw ? (JSON.parse(raw) as Envelope) : undefined;\n } catch {\n env = undefined;\n }\n const http: Record<string, unknown> = {};\n for (const f of HTTP) if (o.attrs?.[f] !== undefined) http[f] = o.attrs[f];\n if (env?.http?.cacheExpiry !== undefined) http.cacheExpiry = new Date(env.http.cacheExpiry);\n const custom: Record<string, string> = env\n ? { ...env.custom }\n : Object.fromEntries(Object.entries(o.attrs?.metadata ?? {}).filter(([k]) => k !== ENVELOPE));\n const etag = o.etag.replace(/^\"(.*)\"$/, \"$1\");\n return {\n key,\n size: o.body.byteLength,\n etag,\n version: etag,\n uploaded: o.modifiedMs ?? Date.now(),\n httpMetadata: http as R2HTTPMetadata,\n customMetadata: custom,\n // The store's etag is never an MD5: an object without one (celld's multipart) has none.\n md5: env?.checksums?.md5 ?? \"\",\n };\n };\n return {\n async meta(key) {\n const o = await store.get(prefix + key);\n return o ? metaOf(key, o) : undefined;\n },\n async body(key) {\n return (await store.get(prefix + key))?.body;\n },\n async write(key, bytes, m) {\n const attrs: ObjectAttributes = {};\n const httpRecord: Record<string, unknown> = {};\n for (const f of HTTP) {\n const v = (m.httpMetadata as Record<string, unknown>)[f];\n if (typeof v === \"string\") {\n attrs[f] = v;\n httpRecord[f] = v;\n }\n }\n const expiry = (m.httpMetadata as { cacheExpiry?: Date | number }).cacheExpiry;\n if (expiry !== undefined)\n httpRecord.cacheExpiry = expiry instanceof Date ? expiry.getTime() : Number(expiry);\n // Field order and omissions as celld's serde struct (empty maps skipped).\n const env: Envelope = {};\n if (Object.keys(m.customMetadata).length)\n env.custom = Object.fromEntries(Object.entries(m.customMetadata).sort());\n env.http = httpRecord as Envelope[\"http\"];\n if (m.md5 !== undefined) env.checksums = { md5: m.md5 };\n attrs.metadata = { [ENVELOPE]: asciiJson(env) };\n await store.put(prefix + key, bytes, undefined, attrs);\n const o = await store.get(prefix + key);\n if (!o) throw new Error(`R2 put: ${key} vanished after its write`);\n return metaOf(key, o);\n },\n async remove(key) {\n await store.delete(prefix + key);\n },\n async keys() {\n return (await store.list(prefix)).map((k) => k.slice(prefix.length));\n },\n scratch: {\n async write(path, bytes) {\n await store.put(uploads + path, bytes);\n },\n async read(path) {\n return (await store.get(uploads + path))?.body;\n },\n async removeDir(path) {\n for (const k of await store.list(`${uploads}${path}/`)) await store.delete(k);\n },\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import type { FilesApi } from "@statewalker/webrun-files";
|
|
2
|
+
/**
|
|
3
|
+
* The R2 binding (`env.BUCKET.get/put/head/delete/list`, conditional requests, multipart
|
|
4
|
+
* uploads) on an R2Backend: a webrun-files FilesApi here, or celld's fleet bucket layout
|
|
5
|
+
* (r2-celld.ts). Like celld — whose R2 bindings read and write objects directly in the fleet
|
|
6
|
+
* bucket, not through a cell — the FilesApi backend keeps objects as files:
|
|
7
|
+
* {root}/objects/<encoded key> the bytes
|
|
8
|
+
* {root}/meta/<encoded key>.json key, size, etag (MD5; a multipart object has none), version,
|
|
9
|
+
* uploaded, metadata
|
|
10
|
+
* {root}/multipart/<uploadId>/ an open upload's description and parts, until complete or abort
|
|
11
|
+
*/
|
|
12
|
+
export interface R2HTTPMetadata {
|
|
13
|
+
contentType?: string;
|
|
14
|
+
contentLanguage?: string;
|
|
15
|
+
contentDisposition?: string;
|
|
16
|
+
contentEncoding?: string;
|
|
17
|
+
cacheControl?: string;
|
|
18
|
+
cacheExpiry?: Date;
|
|
19
|
+
}
|
|
20
|
+
export interface StoredMeta {
|
|
21
|
+
/** Hex MD5 of the bytes when the etag is something else (a store's own etag); "" for none. */
|
|
22
|
+
md5?: string;
|
|
23
|
+
key: string;
|
|
24
|
+
size: number;
|
|
25
|
+
etag: string;
|
|
26
|
+
version: string;
|
|
27
|
+
uploaded: number;
|
|
28
|
+
httpMetadata: R2HTTPMetadata;
|
|
29
|
+
customMetadata: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
export declare class R2Object {
|
|
32
|
+
readonly key: string;
|
|
33
|
+
readonly version: string;
|
|
34
|
+
readonly size: number;
|
|
35
|
+
readonly etag: string;
|
|
36
|
+
readonly httpEtag: string;
|
|
37
|
+
readonly uploaded: Date;
|
|
38
|
+
readonly httpMetadata: R2HTTPMetadata;
|
|
39
|
+
readonly customMetadata: Record<string, string>;
|
|
40
|
+
readonly checksums: {
|
|
41
|
+
md5?: ArrayBuffer;
|
|
42
|
+
};
|
|
43
|
+
readonly storageClass = "Standard";
|
|
44
|
+
readonly range?: {
|
|
45
|
+
offset: number;
|
|
46
|
+
length: number;
|
|
47
|
+
};
|
|
48
|
+
constructor(m: StoredMeta, range?: {
|
|
49
|
+
offset: number;
|
|
50
|
+
length: number;
|
|
51
|
+
});
|
|
52
|
+
/** The JSON form celld gives an R2Object (r2-details project): checksums as hex. */
|
|
53
|
+
toJSON(): {
|
|
54
|
+
key: string;
|
|
55
|
+
version: string;
|
|
56
|
+
size: number;
|
|
57
|
+
etag: string;
|
|
58
|
+
httpEtag: string;
|
|
59
|
+
uploaded: string;
|
|
60
|
+
httpMetadata: R2HTTPMetadata;
|
|
61
|
+
customMetadata: Record<string, string>;
|
|
62
|
+
range?: {
|
|
63
|
+
offset: number;
|
|
64
|
+
length: number;
|
|
65
|
+
} | undefined;
|
|
66
|
+
checksums: {
|
|
67
|
+
md5: string;
|
|
68
|
+
} | {
|
|
69
|
+
md5?: undefined;
|
|
70
|
+
};
|
|
71
|
+
storageClass: string;
|
|
72
|
+
};
|
|
73
|
+
writeHttpMetadata(headers: Headers): void;
|
|
74
|
+
}
|
|
75
|
+
export declare class R2ObjectBody extends R2Object {
|
|
76
|
+
#private;
|
|
77
|
+
constructor(m: StoredMeta, bytes: Uint8Array, range?: {
|
|
78
|
+
offset: number;
|
|
79
|
+
length: number;
|
|
80
|
+
});
|
|
81
|
+
get bodyUsed(): boolean;
|
|
82
|
+
get body(): ReadableStream<Uint8Array>;
|
|
83
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
84
|
+
bytes(): Promise<Uint8Array>;
|
|
85
|
+
text(): Promise<string>;
|
|
86
|
+
json<T = unknown>(): Promise<T>;
|
|
87
|
+
blob(): Promise<Blob>;
|
|
88
|
+
}
|
|
89
|
+
export type R2PutValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob | null;
|
|
90
|
+
export interface R2ListOptions {
|
|
91
|
+
limit?: number;
|
|
92
|
+
prefix?: string;
|
|
93
|
+
cursor?: string;
|
|
94
|
+
delimiter?: string;
|
|
95
|
+
startAfter?: string;
|
|
96
|
+
include?: ("httpMetadata" | "customMetadata")[];
|
|
97
|
+
}
|
|
98
|
+
/** R2 conditional request: an object or the equivalent HTTP headers. */
|
|
99
|
+
export interface R2Conditional {
|
|
100
|
+
etagMatches?: string;
|
|
101
|
+
etagDoesNotMatch?: string;
|
|
102
|
+
uploadedBefore?: Date;
|
|
103
|
+
uploadedAfter?: Date;
|
|
104
|
+
secondsGranularity?: boolean;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Where an R2 binding keeps objects: a FilesApi (cellb's own layout) or a celld bucket
|
|
108
|
+
* (`r2/<bucket>/<key>` with celld's `celld-r2` record — r2-celld.ts).
|
|
109
|
+
*/
|
|
110
|
+
export interface R2Backend {
|
|
111
|
+
meta(key: string): Promise<StoredMeta | undefined>;
|
|
112
|
+
body(key: string): Promise<Uint8Array | undefined>;
|
|
113
|
+
/** Stores the object; the backend decides etag, version and upload time. No md5: multipart. */
|
|
114
|
+
write(key: string, bytes: Uint8Array, m: {
|
|
115
|
+
httpMetadata: R2HTTPMetadata;
|
|
116
|
+
customMetadata: Record<string, string>;
|
|
117
|
+
md5?: string;
|
|
118
|
+
}): Promise<StoredMeta>;
|
|
119
|
+
remove(key: string): Promise<void>;
|
|
120
|
+
keys(): Promise<string[]>;
|
|
121
|
+
/** Scratch space for multipart uploads. */
|
|
122
|
+
scratch: {
|
|
123
|
+
write(path: string, bytes: Uint8Array): Promise<void>;
|
|
124
|
+
read(path: string): Promise<Uint8Array | undefined>;
|
|
125
|
+
removeDir(path: string): Promise<void>;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export declare function filesR2Backend(files: FilesApi, root: string): R2Backend;
|
|
129
|
+
export declare function r2Bucket(files: FilesApi, root: string, binding?: string): {
|
|
130
|
+
head(key: string): Promise<R2Object | null>;
|
|
131
|
+
get(key: string, options?: {
|
|
132
|
+
range?: {
|
|
133
|
+
offset?: number;
|
|
134
|
+
length?: number;
|
|
135
|
+
suffix?: number;
|
|
136
|
+
} | Headers;
|
|
137
|
+
onlyIf?: R2Conditional | Headers;
|
|
138
|
+
}): Promise<R2ObjectBody | R2Object | null>;
|
|
139
|
+
put(key: string, value: R2PutValue, options?: {
|
|
140
|
+
httpMetadata?: R2HTTPMetadata | Headers;
|
|
141
|
+
customMetadata?: Record<string, string>;
|
|
142
|
+
md5?: string | ArrayBuffer;
|
|
143
|
+
onlyIf?: R2Conditional | Headers;
|
|
144
|
+
}): Promise<R2Object | null>;
|
|
145
|
+
createMultipartUpload(key: string, options?: {
|
|
146
|
+
httpMetadata?: R2HTTPMetadata | Headers;
|
|
147
|
+
customMetadata?: Record<string, string>;
|
|
148
|
+
}): Promise<{
|
|
149
|
+
key: string;
|
|
150
|
+
uploadId: string;
|
|
151
|
+
uploadPart(partNumber: number, value: R2PutValue): Promise<{
|
|
152
|
+
partNumber: number;
|
|
153
|
+
etag: string;
|
|
154
|
+
}>;
|
|
155
|
+
abort(): Promise<void>;
|
|
156
|
+
complete(parts: {
|
|
157
|
+
partNumber: number;
|
|
158
|
+
etag: string;
|
|
159
|
+
}[]): Promise<R2Object>;
|
|
160
|
+
}>;
|
|
161
|
+
/** A handle on an open upload; parts live under {root}/multipart/{uploadId}/ until complete or abort. */
|
|
162
|
+
resumeMultipartUpload(key: string, uploadId: string): {
|
|
163
|
+
key: string;
|
|
164
|
+
uploadId: string;
|
|
165
|
+
uploadPart(partNumber: number, value: R2PutValue): Promise<{
|
|
166
|
+
partNumber: number;
|
|
167
|
+
etag: string;
|
|
168
|
+
}>;
|
|
169
|
+
abort(): Promise<void>;
|
|
170
|
+
complete(parts: {
|
|
171
|
+
partNumber: number;
|
|
172
|
+
etag: string;
|
|
173
|
+
}[]): Promise<R2Object>;
|
|
174
|
+
};
|
|
175
|
+
delete(keys: string | string[]): Promise<void>;
|
|
176
|
+
list(options?: R2ListOptions): Promise<{
|
|
177
|
+
objects: R2Object[];
|
|
178
|
+
truncated: boolean;
|
|
179
|
+
cursor: string | undefined;
|
|
180
|
+
delimitedPrefixes: string[];
|
|
181
|
+
}>;
|
|
182
|
+
};
|
|
183
|
+
export declare function r2BucketOn(backend: R2Backend, binding?: string): {
|
|
184
|
+
head(key: string): Promise<R2Object | null>;
|
|
185
|
+
get(key: string, options?: {
|
|
186
|
+
range?: {
|
|
187
|
+
offset?: number;
|
|
188
|
+
length?: number;
|
|
189
|
+
suffix?: number;
|
|
190
|
+
} | Headers;
|
|
191
|
+
onlyIf?: R2Conditional | Headers;
|
|
192
|
+
}): Promise<R2ObjectBody | R2Object | null>;
|
|
193
|
+
put(key: string, value: R2PutValue, options?: {
|
|
194
|
+
httpMetadata?: R2HTTPMetadata | Headers;
|
|
195
|
+
customMetadata?: Record<string, string>;
|
|
196
|
+
md5?: string | ArrayBuffer;
|
|
197
|
+
onlyIf?: R2Conditional | Headers;
|
|
198
|
+
}): Promise<R2Object | null>;
|
|
199
|
+
createMultipartUpload(key: string, options?: {
|
|
200
|
+
httpMetadata?: R2HTTPMetadata | Headers;
|
|
201
|
+
customMetadata?: Record<string, string>;
|
|
202
|
+
}): Promise<{
|
|
203
|
+
key: string;
|
|
204
|
+
uploadId: string;
|
|
205
|
+
uploadPart(partNumber: number, value: R2PutValue): Promise<{
|
|
206
|
+
partNumber: number;
|
|
207
|
+
etag: string;
|
|
208
|
+
}>;
|
|
209
|
+
abort(): Promise<void>;
|
|
210
|
+
complete(parts: {
|
|
211
|
+
partNumber: number;
|
|
212
|
+
etag: string;
|
|
213
|
+
}[]): Promise<R2Object>;
|
|
214
|
+
}>;
|
|
215
|
+
/** A handle on an open upload; parts live under {root}/multipart/{uploadId}/ until complete or abort. */
|
|
216
|
+
resumeMultipartUpload(key: string, uploadId: string): {
|
|
217
|
+
key: string;
|
|
218
|
+
uploadId: string;
|
|
219
|
+
uploadPart(partNumber: number, value: R2PutValue): Promise<{
|
|
220
|
+
partNumber: number;
|
|
221
|
+
etag: string;
|
|
222
|
+
}>;
|
|
223
|
+
abort(): Promise<void>;
|
|
224
|
+
complete(parts: {
|
|
225
|
+
partNumber: number;
|
|
226
|
+
etag: string;
|
|
227
|
+
}[]): Promise<R2Object>;
|
|
228
|
+
};
|
|
229
|
+
delete(keys: string | string[]): Promise<void>;
|
|
230
|
+
list(options?: R2ListOptions): Promise<{
|
|
231
|
+
objects: R2Object[];
|
|
232
|
+
truncated: boolean;
|
|
233
|
+
cursor: string | undefined;
|
|
234
|
+
delimitedPrefixes: string[];
|
|
235
|
+
}>;
|
|
236
|
+
};
|