devflare 1.0.0-next.14 → 1.0.0-next.16
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/LLM.md +9360 -1784
- package/README.md +391 -32
- package/bin/devflare.js +17 -7
- package/dist/account-0w8wdzjv.js +475 -0
- package/dist/account-eygq6qx7.js +475 -0
- package/dist/account-fw8nafav.js +475 -0
- package/dist/account-pzq69nys.js +475 -0
- package/dist/account-s66jb15j.js +475 -0
- package/dist/api-d6ekexs5.js +25 -0
- package/dist/bridge/index.d.ts +1 -1
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/miniflare.d.ts.map +1 -1
- package/dist/bridge/protocol.d.ts +1 -1
- package/dist/bridge/protocol.d.ts.map +1 -1
- package/dist/bridge/proxy.d.ts +0 -4
- package/dist/bridge/proxy.d.ts.map +1 -1
- package/dist/bridge/serialization.d.ts.map +1 -1
- package/dist/bridge/server.d.ts +1 -1
- package/dist/bridge/server.d.ts.map +1 -1
- package/dist/browser-shim/handler.d.ts +1 -1
- package/dist/browser-shim/handler.d.ts.map +1 -1
- package/dist/browser.d.ts +1651 -34
- package/dist/browser.d.ts.map +1 -1
- package/dist/build-1kmkwqgh.js +53 -0
- package/dist/build-506kjhcm.js +53 -0
- package/dist/build-66866ahs.js +53 -0
- package/dist/build-g1adm3ww.js +53 -0
- package/dist/build-p3r3117t.js +53 -0
- package/dist/bundler/do-bundler.d.ts.map +1 -1
- package/dist/bundler/rolldown-shared.d.ts +24 -0
- package/dist/bundler/rolldown-shared.d.ts.map +1 -0
- package/dist/bundler/worker-bundler.d.ts +0 -1
- package/dist/bundler/worker-bundler.d.ts.map +1 -1
- package/dist/cli/command-utils.d.ts +18 -0
- package/dist/cli/command-utils.d.ts.map +1 -0
- package/dist/cli/commands/account.d.ts +1 -1
- package/dist/cli/commands/account.d.ts.map +1 -1
- package/dist/cli/commands/build-artifacts.d.ts +27 -0
- package/dist/cli/commands/build-artifacts.d.ts.map +1 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/config.d.ts +4 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/login.d.ts +4 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/cleanup.d.ts +9 -0
- package/dist/cli/commands/previews-support/cleanup.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/family.d.ts +10 -0
- package/dist/cli/commands/previews-support/family.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/render.d.ts +8 -0
- package/dist/cli/commands/previews-support/render.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/theme.d.ts +10 -0
- package/dist/cli/commands/previews-support/theme.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/types.d.ts +70 -0
- package/dist/cli/commands/previews-support/types.d.ts.map +1 -0
- package/dist/cli/commands/previews.d.ts +4 -0
- package/dist/cli/commands/previews.d.ts.map +1 -0
- package/dist/cli/commands/productions.d.ts +4 -0
- package/dist/cli/commands/productions.d.ts.map +1 -0
- package/dist/cli/commands/token.d.ts +4 -0
- package/dist/cli/commands/token.d.ts.map +1 -0
- package/dist/cli/commands/type-generation/discovery.d.ts +7 -0
- package/dist/cli/commands/type-generation/discovery.d.ts.map +1 -0
- package/dist/cli/commands/type-generation/generator.d.ts +44 -0
- package/dist/cli/commands/type-generation/generator.d.ts.map +1 -0
- package/dist/cli/commands/type-generation/models.d.ts +27 -0
- package/dist/cli/commands/type-generation/models.d.ts.map +1 -0
- package/dist/cli/commands/types.d.ts.map +1 -1
- package/dist/cli/commands/worker.d.ts +4 -0
- package/dist/cli/commands/worker.d.ts.map +1 -0
- package/dist/cli/config-path.d.ts +2 -1
- package/dist/cli/config-path.d.ts.map +1 -1
- package/dist/cli/deploy-strategy.d.ts +17 -0
- package/dist/cli/deploy-strategy.d.ts.map +1 -0
- package/dist/cli/deploy-target.d.ts +17 -0
- package/dist/cli/deploy-target.d.ts.map +1 -0
- package/dist/cli/generated-artifacts.d.ts +12 -0
- package/dist/cli/generated-artifacts.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/account.d.ts +3 -0
- package/dist/cli/help-pages/pages/account.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/core.d.ts +4 -0
- package/dist/cli/help-pages/pages/core.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/index.d.ts +3 -0
- package/dist/cli/help-pages/pages/index.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/misc.d.ts +3 -0
- package/dist/cli/help-pages/pages/misc.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/previews.d.ts +3 -0
- package/dist/cli/help-pages/pages/previews.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/productions.d.ts +3 -0
- package/dist/cli/help-pages/pages/productions.d.ts.map +1 -0
- package/dist/cli/help-pages/render.d.ts +12 -0
- package/dist/cli/help-pages/render.d.ts.map +1 -0
- package/dist/cli/help-pages/shared.d.ts +15 -0
- package/dist/cli/help-pages/shared.d.ts.map +1 -0
- package/dist/cli/help-pages/types.d.ts +23 -0
- package/dist/cli/help-pages/types.d.ts.map +1 -0
- package/dist/cli/help.d.ts +6 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/preview-bindings.d.ts +42 -0
- package/dist/cli/preview-bindings.d.ts.map +1 -0
- package/dist/cli/preview.d.ts +11 -0
- package/dist/cli/preview.d.ts.map +1 -0
- package/dist/cli/ui.d.ts +37 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/workspace-build-guard.d.ts +14 -0
- package/dist/cli/workspace-build-guard.d.ts.map +1 -0
- package/dist/cloudflare/account-core.d.ts +6 -0
- package/dist/cloudflare/account-core.d.ts.map +1 -0
- package/dist/cloudflare/account-resources.d.ts +40 -0
- package/dist/cloudflare/account-resources.d.ts.map +1 -0
- package/dist/cloudflare/account-status.d.ts +11 -0
- package/dist/cloudflare/account-status.d.ts.map +1 -0
- package/dist/cloudflare/account-workers.d.ts +14 -0
- package/dist/cloudflare/account-workers.d.ts.map +1 -0
- package/dist/cloudflare/account.d.ts +7 -64
- package/dist/cloudflare/account.d.ts.map +1 -1
- package/dist/cloudflare/api.d.ts +4 -0
- package/dist/cloudflare/api.d.ts.map +1 -1
- package/dist/cloudflare/index.d.ts +57 -2
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/kv-namespace.d.ts +3 -0
- package/dist/cloudflare/kv-namespace.d.ts.map +1 -0
- package/dist/cloudflare/preferences.d.ts.map +1 -1
- package/dist/cloudflare/preview-registry-cache.d.ts +6 -0
- package/dist/cloudflare/preview-registry-cache.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-records.d.ts +61 -0
- package/dist/cloudflare/preview-registry-records.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-store.d.ts +14 -0
- package/dist/cloudflare/preview-registry-store.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-types.d.ts +103 -0
- package/dist/cloudflare/preview-registry-types.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry.d.ts +42 -0
- package/dist/cloudflare/preview-registry.d.ts.map +1 -0
- package/dist/cloudflare/registry-schema.d.ts +253 -0
- package/dist/cloudflare/registry-schema.d.ts.map +1 -0
- package/dist/cloudflare/tokens.d.ts +18 -0
- package/dist/cloudflare/tokens.d.ts.map +1 -0
- package/dist/cloudflare/types.d.ts +122 -5
- package/dist/cloudflare/types.d.ts.map +1 -1
- package/dist/cloudflare/usage.d.ts.map +1 -1
- package/dist/config/compiler.d.ts +4 -0
- package/dist/config/compiler.d.ts.map +1 -1
- package/dist/config/framework-providers.d.ts +9 -0
- package/dist/config/framework-providers.d.ts.map +1 -0
- package/dist/config/index.d.ts +5 -3
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/loader.d.ts +1 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/preview-resources.d.ts +77 -0
- package/dist/config/preview-resources.d.ts.map +1 -0
- package/dist/config/preview.d.ts +31 -0
- package/dist/config/preview.d.ts.map +1 -0
- package/dist/config/ref.d.ts +0 -22
- package/dist/config/ref.d.ts.map +1 -1
- package/dist/config/resolve.d.ts +1 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resource-resolution.d.ts +60 -0
- package/dist/config/resource-resolution.d.ts.map +1 -0
- package/dist/config/schema-bindings.d.ts +693 -0
- package/dist/config/schema-bindings.d.ts.map +1 -0
- package/dist/config/schema-build.d.ts +67 -0
- package/dist/config/schema-build.d.ts.map +1 -0
- package/dist/config/schema-env.d.ts +1341 -0
- package/dist/config/schema-env.d.ts.map +1 -0
- package/dist/config/schema-normalization.d.ts +64 -0
- package/dist/config/schema-normalization.d.ts.map +1 -0
- package/dist/config/schema-runtime.d.ts +230 -0
- package/dist/config/schema-runtime.d.ts.map +1 -0
- package/dist/config/schema.d.ts +640 -3669
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config-entry.d.ts +5 -0
- package/dist/config-entry.d.ts.map +1 -0
- package/dist/config-fjwke42y.js +59 -0
- package/dist/config-hwdqjse7.js +59 -0
- package/dist/config-pxvewrhv.js +59 -0
- package/dist/config-q0g5qdga.js +59 -0
- package/dist/decorators/durable-object.d.ts.map +1 -1
- package/dist/deploy-7nmzc9r8.js +609 -0
- package/dist/deploy-csfhdr64.js +691 -0
- package/dist/deploy-ex4g5avz.js +621 -0
- package/dist/deploy-jnb0bhka.js +609 -0
- package/dist/deploy-tp0g6qdp.js +609 -0
- package/dist/deploy-ykpcjkc2.js +690 -0
- package/dist/{dev-c1xc1gq9.js → dev-2pd33m28.js} +392 -348
- package/dist/dev-7ef5e2j1.js +2409 -0
- package/dist/dev-8nssqatr.js +2409 -0
- package/dist/dev-grznx8fn.js +2409 -0
- package/dist/dev-server/d1-migrations.d.ts +14 -0
- package/dist/dev-server/d1-migrations.d.ts.map +1 -0
- package/dist/dev-server/gateway-script.d.ts +8 -0
- package/dist/dev-server/gateway-script.d.ts.map +1 -0
- package/dist/dev-server/runtime-stdio.d.ts.map +1 -1
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/dev-server/vite-process.d.ts +14 -0
- package/dist/dev-server/vite-process.d.ts.map +1 -0
- package/dist/dev-server/vite-utils.d.ts +1 -1
- package/dist/dev-server/vite-utils.d.ts.map +1 -1
- package/dist/dev-server/worker-source-watcher.d.ts +11 -0
- package/dist/dev-server/worker-source-watcher.d.ts.map +1 -0
- package/dist/dev-server/worker-surface-paths.d.ts +6 -0
- package/dist/dev-server/worker-surface-paths.d.ts.map +1 -0
- package/dist/{doctor-z4ffybce.js → doctor-04ammrrh.js} +67 -31
- package/dist/doctor-fmjj65mc.js +245 -0
- package/dist/doctor-fzkznce1.js +245 -0
- package/dist/doctor-sa5xv1bz.js +245 -0
- package/dist/index-091sh1ma.js +1229 -0
- package/dist/index-0apbm26n.js +788 -0
- package/dist/index-0eqksag4.js +418 -0
- package/dist/{index-dr6sbp8d.js → index-0kfzdywd.js} +15 -2
- package/dist/index-0w826dsr.js +379 -0
- package/dist/{index-rfhx0yd5.js → index-11m5a8wd.js} +110 -32
- package/dist/{index-xxwbb2nt.js → index-1sp39f2f.js} +114 -58
- package/dist/index-2jnrqbny.js +1301 -0
- package/dist/index-2pb7b9mw.js +378 -0
- package/dist/{index-0kzg8wed.js → index-2x53aqjm.js} +1071 -890
- package/dist/index-3ke5d2vn.js +1229 -0
- package/dist/index-43dq8yx8.js +788 -0
- package/dist/index-4rrttqj5.js +378 -0
- package/dist/index-4v9bc2pc.js +1367 -0
- package/dist/index-61jsjnsv.js +280 -0
- package/dist/index-6jef5emv.js +176 -0
- package/dist/index-6psz1h4c.js +788 -0
- package/dist/index-72mve6vh.js +168 -0
- package/dist/{index-zbvmtcn2.js → index-74198nxd.js} +179 -77
- package/dist/index-7g8zyws4.js +192 -0
- package/dist/index-7kcxjhta.js +456 -0
- package/dist/index-7v583xan.js +418 -0
- package/dist/index-7x0ybbtx.js +133 -0
- package/dist/index-816krz9p.js +52 -0
- package/dist/index-82f1z98k.js +41 -0
- package/dist/index-8t5nb4qx.js +133 -0
- package/dist/index-9az6s7ad.js +52 -0
- package/dist/{index-59df49vn.js → index-9ba1etyz.js} +29 -51
- package/dist/{index-001mw014.js → index-9fbtk7gv.js} +134 -248
- package/dist/index-9n6djthj.js +490 -0
- package/dist/index-aabgympv.js +39 -0
- package/dist/index-b8m6883k.js +74 -0
- package/dist/{index-5yxg30va.js → index-cgbvmse6.js} +15 -6
- package/dist/index-d8etnfef.js +1229 -0
- package/dist/index-e9yw4d6y.js +133 -0
- package/dist/index-epw1jxz5.js +1204 -0
- package/dist/index-f85s8gj3.js +2649 -0
- package/dist/index-fe2ngvh7.js +1229 -0
- package/dist/index-fvsadj32.js +192 -0
- package/dist/index-gs4y9gdf.js +456 -0
- package/dist/{index-fef08w43.js → index-h18pxvzs.js} +7 -6
- package/dist/index-hfj1a2c4.js +2649 -0
- package/dist/{index-8gtqgb3q.js → index-hjy8ctpc.js} +14 -92
- package/dist/index-htzf0py1.js +1204 -0
- package/dist/index-j185x270.js +897 -0
- package/dist/index-jb75kwa4.js +519 -0
- package/dist/index-jwd8pcb2.js +897 -0
- package/dist/index-k29yjhv0.js +52 -0
- package/dist/index-k6vq6kkt.js +456 -0
- package/dist/{index-vky23txa.js → index-m3fmw6mx.js} +2 -2
- package/dist/index-maxpsfk8.js +402 -0
- package/dist/index-mbdmrner.js +402 -0
- package/dist/index-mea5bc45.js +418 -0
- package/dist/index-mqekt778.js +185 -0
- package/dist/index-na3mnm1k.js +74 -0
- package/dist/index-p03n4qet.js +1367 -0
- package/dist/index-p296ban8.js +191 -0
- package/dist/index-pnbs1b8k.js +280 -0
- package/dist/index-q4kaz181.js +1207 -0
- package/dist/index-ry131z23.js +378 -0
- package/dist/index-sgb7c8nm.js +402 -0
- package/dist/index-sqrksgb2.js +133 -0
- package/dist/index-stgn34cr.js +148 -0
- package/dist/{index-v8vvsn9x.js → index-t08te69w.js} +1 -18
- package/dist/index-thna1tkd.js +280 -0
- package/dist/index-v5nmqthy.js +74 -0
- package/dist/{index-n932ytmq.js → index-vt4yxkmf.js} +2 -2
- package/dist/index-wyq6c6yj.js +402 -0
- package/dist/index-wztc9stx.js +418 -0
- package/dist/index-x9cwdxw5.js +456 -0
- package/dist/index-xk9djfjp.js +519 -0
- package/dist/index-yc0gcchc.js +418 -0
- package/dist/index-yqbxjysa.js +897 -0
- package/dist/index-yzddwp02.js +788 -0
- package/dist/index-zfhq6s96.js +74 -0
- package/dist/index-zt22fe2j.js +54 -0
- package/dist/index-zyt5byt6.js +2649 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/{init-na2atvz2.js → init-r4hnxan3.js} +24 -17
- package/dist/login-2hnz4m4n.js +77 -0
- package/dist/login-5bsxxpvc.js +77 -0
- package/dist/login-6tzvczw2.js +77 -0
- package/dist/login-bhaw72zc.js +77 -0
- package/dist/login-x8tgckqm.js +77 -0
- package/dist/previews-3rn8mz2c.js +1168 -0
- package/dist/previews-d487qde5.js +1200 -0
- package/dist/previews-gm3z0syj.js +1168 -0
- package/dist/previews-j9ymq4ys.js +1169 -0
- package/dist/previews-q031mx34.js +1168 -0
- package/dist/productions-120xg0aq.js +505 -0
- package/dist/productions-5ev5qweg.js +505 -0
- package/dist/productions-me3tdvr9.js +505 -0
- package/dist/productions-p5rbgp2f.js +505 -0
- package/dist/productions-x9p0pym1.js +505 -0
- package/dist/runtime/context-events.d.ts +13 -0
- package/dist/runtime/context-events.d.ts.map +1 -0
- package/dist/runtime/context-types.d.ts +82 -0
- package/dist/runtime/context-types.d.ts.map +1 -0
- package/dist/runtime/context.d.ts +6 -267
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/exports.d.ts +3 -3
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/middleware.d.ts +8 -38
- package/dist/runtime/middleware.d.ts.map +1 -1
- package/dist/src/browser.js +23 -14
- package/dist/src/cli/index.js +3 -1
- package/dist/src/cloudflare/index.js +49 -2
- package/dist/src/config-entry.js +14 -0
- package/dist/src/index.js +33 -20
- package/dist/src/runtime/index.js +3 -9
- package/dist/src/sveltekit/index.js +10 -7
- package/dist/src/test/index.js +16 -18
- package/dist/src/vite/index.js +7 -4
- package/dist/sveltekit/platform.d.ts +1 -1
- package/dist/sveltekit/platform.d.ts.map +1 -1
- package/dist/test/cf.d.ts +10 -10
- package/dist/test/email.d.ts.map +1 -1
- package/dist/test/index.d.ts +1 -6
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/queue.d.ts.map +1 -1
- package/dist/test/remote-ai.d.ts.map +1 -1
- package/dist/test/remote-cloudflare.d.ts +13 -0
- package/dist/test/remote-cloudflare.d.ts.map +1 -0
- package/dist/test/remote-vectorize.d.ts.map +1 -1
- package/dist/test/resolve-service-bindings.d.ts.map +1 -1
- package/dist/test/scheduled.d.ts.map +1 -1
- package/dist/test/should-skip.d.ts +0 -18
- package/dist/test/should-skip.d.ts.map +1 -1
- package/dist/test/simple-context-durable-objects.d.ts +6 -0
- package/dist/test/simple-context-durable-objects.d.ts.map +1 -0
- package/dist/test/simple-context-gateway-script.d.ts +2 -0
- package/dist/test/simple-context-gateway-script.d.ts.map +1 -0
- package/dist/test/simple-context-paths.d.ts +40 -0
- package/dist/test/simple-context-paths.d.ts.map +1 -0
- package/dist/test/simple-context.d.ts +1 -23
- package/dist/test/simple-context.d.ts.map +1 -1
- package/dist/test/tail.d.ts.map +1 -1
- package/dist/test/worker.d.ts.map +1 -1
- package/dist/token-kedhcret.js +419 -0
- package/dist/token-m8jmnjwk.js +419 -0
- package/dist/{types-sffr9681.js → types-0sqwkp7x.js} +244 -139
- package/dist/types-1gwr2ex6.js +572 -0
- package/dist/types-6e5yx6km.js +572 -0
- package/dist/types-p0gckpn6.js +572 -0
- package/dist/utils/send-email.d.ts.map +1 -1
- package/dist/vite/config-file.d.ts.map +1 -1
- package/dist/vite/plugin.d.ts.map +1 -1
- package/dist/worker-0srh2jfr.js +513 -0
- package/dist/worker-4xrfd10a.js +513 -0
- package/dist/worker-entry/composed-worker.d.ts +0 -7
- package/dist/worker-entry/composed-worker.d.ts.map +1 -1
- package/dist/worker-entry/surface-paths.d.ts +15 -0
- package/dist/worker-entry/surface-paths.d.ts.map +1 -0
- package/dist/worker-qtam8grz.js +513 -0
- package/dist/worker-qzm0b7br.js +513 -0
- package/dist/worker-y9ha6g44.js +513 -0
- package/package.json +17 -10
- package/R2.md +0 -200
- package/dist/account-8psavtg6.js +0 -420
- package/dist/build-n639efmn.js +0 -101
- package/dist/deploy-zvnq6xh7.js +0 -117
- package/dist/index-2q3pmzrx.js +0 -90
- package/dist/index-f4q0jbnj.js +0 -195
- package/dist/index-n7rs26ft.js +0 -77
- package/dist/index-tfyxa77h.js +0 -850
- package/dist/index-wyf3s77s.js +0 -343
- package/dist/test/multi-worker-context.d.ts +0 -114
- package/dist/test/multi-worker-context.d.ts.map +0 -1
package/R2.md
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
# R2
|
|
2
|
-
|
|
3
|
-
A short guide for handling uploads and file delivery with Cloudflare R2.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Quick rules
|
|
8
|
-
|
|
9
|
-
- Use **presigned `PUT` URLs** for direct user uploads to R2
|
|
10
|
-
- Use a **public bucket on a custom domain** for truly public assets
|
|
11
|
-
- Use a **private bucket + Worker authorization** for authenticated/private assets
|
|
12
|
-
- Use **Cloudflare Access** for teammate/org-only buckets
|
|
13
|
-
- Use **WAF token auth / HMAC validation** or a **Worker** for expiring custom-domain media links
|
|
14
|
-
- Do **not** use `r2.dev` for production delivery
|
|
15
|
-
- If you protect a custom-domain bucket with Access or WAF, **disable `r2.dev`** or the bucket may still be reachable there
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Uploads
|
|
20
|
-
|
|
21
|
-
The usual safe upload flow is:
|
|
22
|
-
|
|
23
|
-
1. frontend asks your app for upload permission
|
|
24
|
-
2. your Worker/app authenticates the user and validates file type, size, and target key
|
|
25
|
-
3. your backend returns a short-lived **presigned `PUT` URL**
|
|
26
|
-
4. the browser uploads **directly to R2**
|
|
27
|
-
5. your app stores the **object key + metadata**, not the presigned URL
|
|
28
|
-
|
|
29
|
-
Good practice:
|
|
30
|
-
|
|
31
|
-
- generate keys server-side, for example `users/<userId>/<uuid>.jpg`
|
|
32
|
-
- restrict `Content-Type` when signing uploads
|
|
33
|
-
- keep upload URLs short-lived
|
|
34
|
-
- configure bucket **CORS** if the browser uploads directly
|
|
35
|
-
|
|
36
|
-
Cloudflare docs:
|
|
37
|
-
|
|
38
|
-
- [Presigned URLs](https://developers.cloudflare.com/r2/api/s3/presigned-urls/)
|
|
39
|
-
- [Configure CORS](https://developers.cloudflare.com/r2/buckets/cors/)
|
|
40
|
-
- [Storing user generated content](https://developers.cloudflare.com/reference-architecture/diagrams/storage/storing-user-generated-content/)
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Viewing / serving files
|
|
45
|
-
|
|
46
|
-
### Public files
|
|
47
|
-
|
|
48
|
-
For public images, media, and assets:
|
|
49
|
-
|
|
50
|
-
- use a **public bucket**
|
|
51
|
-
- attach a **custom domain**
|
|
52
|
-
- serve stable URLs from that domain
|
|
53
|
-
- let Cloudflare cache them
|
|
54
|
-
|
|
55
|
-
This is the best fit for avatars, product images, blog images, and other content that anyone may view.
|
|
56
|
-
|
|
57
|
-
Cloudflare docs:
|
|
58
|
-
|
|
59
|
-
- [Public buckets](https://developers.cloudflare.com/r2/buckets/public-buckets/)
|
|
60
|
-
|
|
61
|
-
### Private or authenticated files
|
|
62
|
-
|
|
63
|
-
For invoices, receipts, private user uploads, paid content, or tenant-scoped assets:
|
|
64
|
-
|
|
65
|
-
- keep the bucket **private**
|
|
66
|
-
- store only the object key in your database
|
|
67
|
-
- serve through a **Worker** that checks session/JWT/permissions before reading from R2
|
|
68
|
-
|
|
69
|
-
This is usually the best default when access depends on the current user.
|
|
70
|
-
|
|
71
|
-
Cloudflare docs:
|
|
72
|
-
|
|
73
|
-
- [Use R2 from Workers](https://developers.cloudflare.com/r2/api/workers/workers-api-usage/)
|
|
74
|
-
|
|
75
|
-
### Time-limited direct access
|
|
76
|
-
|
|
77
|
-
You can also mint a **presigned `GET` URL** for temporary direct viewing or download.
|
|
78
|
-
|
|
79
|
-
Important caveat:
|
|
80
|
-
|
|
81
|
-
- presigned URLs work on the **R2 S3 endpoint**
|
|
82
|
-
- they **do not work with custom domains**
|
|
83
|
-
- treat them as **bearer tokens**
|
|
84
|
-
|
|
85
|
-
So they are good for short-lived direct access, but not for polished custom-domain media delivery.
|
|
86
|
-
|
|
87
|
-
Cloudflare docs:
|
|
88
|
-
|
|
89
|
-
- [Presigned URLs](https://developers.cloudflare.com/r2/api/s3/presigned-urls/)
|
|
90
|
-
|
|
91
|
-
### Team-only / org-only files
|
|
92
|
-
|
|
93
|
-
If access should be limited to employees or teammates, protect the R2 custom domain with **Cloudflare Access**.
|
|
94
|
-
|
|
95
|
-
Cloudflare docs:
|
|
96
|
-
|
|
97
|
-
- [Protect an R2 Bucket with Cloudflare Access](https://developers.cloudflare.com/r2/tutorials/cloudflare-access/)
|
|
98
|
-
|
|
99
|
-
### Signed links on a custom domain
|
|
100
|
-
|
|
101
|
-
If you want expiring links on `https://cdn.example.com/...`, R2 presigned URLs are not the right tool.
|
|
102
|
-
|
|
103
|
-
Instead use:
|
|
104
|
-
|
|
105
|
-
- a **Worker** that signs and verifies access tokens, or
|
|
106
|
-
- **Cloudflare WAF token authentication / HMAC validation** on the custom domain
|
|
107
|
-
|
|
108
|
-
Cloudflare docs:
|
|
109
|
-
|
|
110
|
-
- [Configure token authentication](https://developers.cloudflare.com/waf/custom-rules/use-cases/configure-token-authentication/)
|
|
111
|
-
- [HMAC validation function](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#hmac-validation)
|
|
112
|
-
- [Workers request signing example](https://developers.cloudflare.com/workers/examples/signing-requests/)
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## Development vs production
|
|
117
|
-
|
|
118
|
-
### Development
|
|
119
|
-
|
|
120
|
-
By default, local Worker development uses **local simulated bindings**, including local R2-style storage.
|
|
121
|
-
|
|
122
|
-
Use this for normal development.
|
|
123
|
-
|
|
124
|
-
Devflare-specific local note:
|
|
125
|
-
|
|
126
|
-
- local R2 bindings are available to your Worker code, tests, and bridge helpers
|
|
127
|
-
- Devflare does **not** currently publish a stable browser-facing local bucket URL contract
|
|
128
|
-
- do **not** build frontend code around an assumed local bucket origin
|
|
129
|
-
- for browser-visible local flows, serve objects through your Worker or app routes instead
|
|
130
|
-
|
|
131
|
-
Practical local-serving example:
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
// src/routes/files/[...key].ts
|
|
135
|
-
import type { FetchEvent } from 'devflare/runtime'
|
|
136
|
-
|
|
137
|
-
export async function GET({ env, params }: FetchEvent<DevflareEnv>): Promise<Response> {
|
|
138
|
-
const object = await env.FILES.get(params.key)
|
|
139
|
-
if (!object) {
|
|
140
|
-
return new Response('Not Found', { status: 404 })
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return new Response(object.body, {
|
|
144
|
-
headers: {
|
|
145
|
-
'Content-Type': object.httpMetadata?.contentType ?? 'application/octet-stream',
|
|
146
|
-
'Cache-Control': 'private, max-age=0'
|
|
147
|
-
}
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
With that pattern, your browser talks to your app URL, not to an assumed local bucket URL. That keeps local behavior aligned with the Worker-auth or custom-domain patterns you are likely to use in production.
|
|
153
|
-
|
|
154
|
-
Only connect to real remote buckets when you intentionally need integration testing, and prefer **separate dev/staging buckets** instead of production buckets.
|
|
155
|
-
|
|
156
|
-
Important remote-dev reality:
|
|
157
|
-
|
|
158
|
-
- remote bindings touch **real data**
|
|
159
|
-
- remote bindings incur **real costs**
|
|
160
|
-
- avoid pointing local development at production uploads unless absolutely necessary
|
|
161
|
-
|
|
162
|
-
Cloudflare docs:
|
|
163
|
-
|
|
164
|
-
- [Workers development & testing](https://developers.cloudflare.com/workers/development-testing/)
|
|
165
|
-
- [Remote bindings](https://developers.cloudflare.com/workers/development-testing/#remote-bindings)
|
|
166
|
-
|
|
167
|
-
### Production
|
|
168
|
-
|
|
169
|
-
For production:
|
|
170
|
-
|
|
171
|
-
- use a **custom domain**, not `r2.dev`
|
|
172
|
-
- choose public vs private intentionally per bucket or per content class
|
|
173
|
-
- keep sensitive content private behind a Worker, Access, or token validation
|
|
174
|
-
- configure **CORS** intentionally for browser upload/download flows
|
|
175
|
-
- use separate **dev**, **staging**, and **prod** buckets
|
|
176
|
-
|
|
177
|
-
Optional performance feature:
|
|
178
|
-
|
|
179
|
-
- if users upload from many regions, consider **Local Uploads** for better upload performance
|
|
180
|
-
|
|
181
|
-
Cloudflare docs:
|
|
182
|
-
|
|
183
|
-
- [Public buckets](https://developers.cloudflare.com/r2/buckets/public-buckets/)
|
|
184
|
-
- [Local uploads](https://developers.cloudflare.com/r2/buckets/local-uploads/)
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## Recommended defaults
|
|
189
|
-
|
|
190
|
-
If you need a sane default architecture:
|
|
191
|
-
|
|
192
|
-
- **public assets** → public bucket + custom domain
|
|
193
|
-
- **user uploads** → presigned `PUT` upload + object key stored in DB
|
|
194
|
-
- **private assets** → private bucket + Worker-gated reads
|
|
195
|
-
- **internal assets** → custom domain + Cloudflare Access
|
|
196
|
-
- **custom-domain expiring links** → Worker token auth or WAF HMAC validation
|
|
197
|
-
|
|
198
|
-
If you only remember one rule, remember this:
|
|
199
|
-
|
|
200
|
-
> Use **presigned URLs** for short-lived direct R2 access, but use a **Worker/custom domain auth layer** for polished private media delivery.
|
package/dist/account-8psavtg6.js
DELETED
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BOLD,
|
|
3
|
-
CYAN,
|
|
4
|
-
CYAN_BOLD,
|
|
5
|
-
DIM,
|
|
6
|
-
RESET
|
|
7
|
-
} from "./index-3t6rypgc.js";
|
|
8
|
-
import {
|
|
9
|
-
account
|
|
10
|
-
} from "./index-n7rs26ft.js";
|
|
11
|
-
import {
|
|
12
|
-
AuthenticationError,
|
|
13
|
-
CloudflareAPIError,
|
|
14
|
-
getGlobalDefaultAccountId,
|
|
15
|
-
getWorkspaceAccountId,
|
|
16
|
-
setGlobalDefaultAccountId,
|
|
17
|
-
setWorkspaceAccountId
|
|
18
|
-
} from "./index-tfyxa77h.js";
|
|
19
|
-
import"./index-37x76zdn.js";
|
|
20
|
-
|
|
21
|
-
// src/cli/commands/account.ts
|
|
22
|
-
var ACCOUNT_SUBCOMMANDS = [
|
|
23
|
-
"info",
|
|
24
|
-
"workers",
|
|
25
|
-
"kv",
|
|
26
|
-
"d1",
|
|
27
|
-
"r2",
|
|
28
|
-
"vectorize",
|
|
29
|
-
"limits",
|
|
30
|
-
"usage",
|
|
31
|
-
"global",
|
|
32
|
-
"workspace"
|
|
33
|
-
];
|
|
34
|
-
function isAccountSubcommand(value) {
|
|
35
|
-
return ACCOUNT_SUBCOMMANDS.includes(value);
|
|
36
|
-
}
|
|
37
|
-
var CLI_API_OPTIONS = { timeout: 1e4 };
|
|
38
|
-
function formatDate(date) {
|
|
39
|
-
if (!date)
|
|
40
|
-
return "N/A";
|
|
41
|
-
return date.toLocaleDateString("en-US", {
|
|
42
|
-
year: "numeric",
|
|
43
|
-
month: "short",
|
|
44
|
-
day: "numeric"
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function formatPercent(value) {
|
|
48
|
-
if (value === undefined)
|
|
49
|
-
return "N/A";
|
|
50
|
-
return `${value.toFixed(1)}%`;
|
|
51
|
-
}
|
|
52
|
-
async function runAccountCommand(parsed, logger, _options) {
|
|
53
|
-
const isAuth = await account.isAuthenticated();
|
|
54
|
-
if (!isAuth) {
|
|
55
|
-
logger.error("Not authenticated with Cloudflare");
|
|
56
|
-
logger.info("Run: bunx wrangler login");
|
|
57
|
-
return { exitCode: 1 };
|
|
58
|
-
}
|
|
59
|
-
const subcommand = parsed.args[0];
|
|
60
|
-
const rawSubcommand = parsed.args[0];
|
|
61
|
-
if (rawSubcommand && !isAccountSubcommand(rawSubcommand)) {
|
|
62
|
-
logger.error(`Unknown account subcommand: ${rawSubcommand}`);
|
|
63
|
-
logger.info(`Available account subcommands: ${ACCOUNT_SUBCOMMANDS.join(", ")}`);
|
|
64
|
-
return { exitCode: 1 };
|
|
65
|
-
}
|
|
66
|
-
if (subcommand === "global") {
|
|
67
|
-
return await selectGlobalAccount(logger);
|
|
68
|
-
}
|
|
69
|
-
if (subcommand === "workspace") {
|
|
70
|
-
return await selectWorkspaceAccount(logger);
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
let accountId = parsed.options.account;
|
|
74
|
-
if (!accountId) {
|
|
75
|
-
const primary = await account.getPrimaryAccount();
|
|
76
|
-
if (!primary) {
|
|
77
|
-
logger.error("No Cloudflare accounts found");
|
|
78
|
-
return { exitCode: 1 };
|
|
79
|
-
}
|
|
80
|
-
accountId = primary.id;
|
|
81
|
-
}
|
|
82
|
-
switch (subcommand) {
|
|
83
|
-
case "workers":
|
|
84
|
-
return await showWorkers(accountId, logger);
|
|
85
|
-
case "kv":
|
|
86
|
-
return await showKV(accountId, logger);
|
|
87
|
-
case "d1":
|
|
88
|
-
return await showD1(accountId, logger);
|
|
89
|
-
case "r2":
|
|
90
|
-
return await showR2(accountId, logger);
|
|
91
|
-
case "vectorize":
|
|
92
|
-
return await showVectorize(accountId, logger);
|
|
93
|
-
case "limits":
|
|
94
|
-
return await handleLimits(accountId, parsed, logger);
|
|
95
|
-
case "usage":
|
|
96
|
-
return await showUsage(accountId, logger);
|
|
97
|
-
case "info":
|
|
98
|
-
default:
|
|
99
|
-
return await showAccountOverview(accountId, logger);
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
if (error instanceof AuthenticationError) {
|
|
103
|
-
logger.error(error.message);
|
|
104
|
-
return { exitCode: 1 };
|
|
105
|
-
}
|
|
106
|
-
if (error instanceof CloudflareAPIError) {
|
|
107
|
-
logger.error(`API Error: ${error.message}`);
|
|
108
|
-
return { exitCode: 1 };
|
|
109
|
-
}
|
|
110
|
-
if (error instanceof Error) {
|
|
111
|
-
if (error.name === "AbortError" || error.message.includes("timed out")) {
|
|
112
|
-
logger.error("Request timed out. The Cloudflare API is slow or unavailable.");
|
|
113
|
-
return { exitCode: 1 };
|
|
114
|
-
}
|
|
115
|
-
logger.error(`Error: ${error.message}`);
|
|
116
|
-
return { exitCode: 1 };
|
|
117
|
-
}
|
|
118
|
-
throw error;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
async function showAccountOverview(accountId, logger) {
|
|
122
|
-
logger.info(`\uD83D\uDCCA Cloudflare Account Overview
|
|
123
|
-
`);
|
|
124
|
-
const accounts = await account.getAccounts();
|
|
125
|
-
if (accounts.length === 0) {
|
|
126
|
-
logger.error("No Cloudflare accounts found");
|
|
127
|
-
return { exitCode: 1 };
|
|
128
|
-
}
|
|
129
|
-
const workspaceId = getWorkspaceAccountId();
|
|
130
|
-
const globalId = await getGlobalDefaultAccountId(accountId);
|
|
131
|
-
for (let i = 0;i < accounts.length; i++) {
|
|
132
|
-
const acc = accounts[i];
|
|
133
|
-
const isWorkspace = acc.id === workspaceId;
|
|
134
|
-
const isGlobal = acc.id === globalId;
|
|
135
|
-
let badge = "";
|
|
136
|
-
if (isWorkspace) {
|
|
137
|
-
badge = ` ${CYAN_BOLD}(workspace)${RESET}`;
|
|
138
|
-
} else if (isGlobal) {
|
|
139
|
-
badge = workspaceId ? ` ${DIM}(global)${RESET}` : ` ${CYAN}(global)${RESET}`;
|
|
140
|
-
}
|
|
141
|
-
if (i > 0)
|
|
142
|
-
logger.info("");
|
|
143
|
-
logger.info(`${BOLD}Account${RESET} ${acc.name}${badge}`);
|
|
144
|
-
logger.info(`${BOLD}ID${RESET} ${acc.id}`);
|
|
145
|
-
logger.info(`${BOLD}Type${RESET} ${acc.type}`);
|
|
146
|
-
}
|
|
147
|
-
logger.info("");
|
|
148
|
-
logger.info(`${BOLD}Commands${RESET}`);
|
|
149
|
-
logger.info(" devflare account global — Set global default account");
|
|
150
|
-
logger.info(" devflare account workspace — Set workspace account");
|
|
151
|
-
logger.info(" devflare account workers — List Workers");
|
|
152
|
-
logger.info(" devflare account kv — List KV namespaces");
|
|
153
|
-
logger.info(" devflare account d1 — List D1 databases");
|
|
154
|
-
logger.info(" devflare account r2 — List R2 buckets");
|
|
155
|
-
logger.info(" devflare account vectorize — List Vectorize indexes");
|
|
156
|
-
logger.info(" devflare account limits — View/set usage limits");
|
|
157
|
-
logger.info(" devflare account usage — View detailed usage");
|
|
158
|
-
logger.info("");
|
|
159
|
-
logger.info(" devflare ai — View AI models and pricing");
|
|
160
|
-
return { exitCode: 0 };
|
|
161
|
-
}
|
|
162
|
-
async function selectGlobalAccount(logger) {
|
|
163
|
-
const accounts = await account.getAccounts();
|
|
164
|
-
if (accounts.length === 0) {
|
|
165
|
-
logger.error("No Cloudflare accounts found");
|
|
166
|
-
return { exitCode: 1 };
|
|
167
|
-
}
|
|
168
|
-
if (accounts.length === 1) {
|
|
169
|
-
await setGlobalDefaultAccountId(accounts[0].id);
|
|
170
|
-
logger.success(`Global default set to: ${accounts[0].name}`);
|
|
171
|
-
return { exitCode: 0 };
|
|
172
|
-
}
|
|
173
|
-
const currentGlobal = await getGlobalDefaultAccountId(accounts[0].id);
|
|
174
|
-
const options = accounts.map((acc) => {
|
|
175
|
-
const isCurrent = acc.id === currentGlobal;
|
|
176
|
-
return {
|
|
177
|
-
label: isCurrent ? `${acc.name} ${CYAN}(default)${RESET}` : acc.name,
|
|
178
|
-
value: acc.id,
|
|
179
|
-
hint: acc.id.substring(0, 8) + "..."
|
|
180
|
-
};
|
|
181
|
-
});
|
|
182
|
-
const selected = await logger.prompt("Select global default account:", {
|
|
183
|
-
type: "select",
|
|
184
|
-
options,
|
|
185
|
-
initial: currentGlobal ?? accounts[0].id
|
|
186
|
-
});
|
|
187
|
-
if (!selected || typeof selected === "symbol") {
|
|
188
|
-
logger.info("Cancelled");
|
|
189
|
-
return { exitCode: 0 };
|
|
190
|
-
}
|
|
191
|
-
await setGlobalDefaultAccountId(selected, accounts[0].id);
|
|
192
|
-
const selectedAccount = accounts.find((a) => a.id === selected);
|
|
193
|
-
logger.success(`Global default set to: ${selectedAccount?.name}`);
|
|
194
|
-
logger.info(`Saved to: ~/.devflare/preferences.json + cloud KV`);
|
|
195
|
-
return { exitCode: 0 };
|
|
196
|
-
}
|
|
197
|
-
async function selectWorkspaceAccount(logger) {
|
|
198
|
-
const accounts = await account.getAccounts();
|
|
199
|
-
if (accounts.length === 0) {
|
|
200
|
-
logger.error("No Cloudflare accounts found");
|
|
201
|
-
return { exitCode: 1 };
|
|
202
|
-
}
|
|
203
|
-
if (accounts.length === 1) {
|
|
204
|
-
const pkgPath2 = setWorkspaceAccountId(accounts[0].id);
|
|
205
|
-
logger.success(`Workspace account set to: ${accounts[0].name}`);
|
|
206
|
-
logger.info(`Saved to: ${pkgPath2}`);
|
|
207
|
-
return { exitCode: 0 };
|
|
208
|
-
}
|
|
209
|
-
const currentWorkspace = getWorkspaceAccountId();
|
|
210
|
-
const options = accounts.map((acc) => {
|
|
211
|
-
const isCurrent = acc.id === currentWorkspace;
|
|
212
|
-
return {
|
|
213
|
-
label: isCurrent ? `${acc.name} ${CYAN}(workspace)${RESET}` : acc.name,
|
|
214
|
-
value: acc.id,
|
|
215
|
-
hint: acc.id.substring(0, 8) + "..."
|
|
216
|
-
};
|
|
217
|
-
});
|
|
218
|
-
const selected = await logger.prompt("Select workspace account:", {
|
|
219
|
-
type: "select",
|
|
220
|
-
options,
|
|
221
|
-
initial: currentWorkspace ?? accounts[0].id
|
|
222
|
-
});
|
|
223
|
-
if (!selected || typeof selected === "symbol") {
|
|
224
|
-
logger.info("Cancelled");
|
|
225
|
-
return { exitCode: 0 };
|
|
226
|
-
}
|
|
227
|
-
const pkgPath = setWorkspaceAccountId(selected);
|
|
228
|
-
const selectedAccount = accounts.find((a) => a.id === selected);
|
|
229
|
-
logger.success(`Workspace account set to: ${selectedAccount?.name}`);
|
|
230
|
-
logger.info(`Saved to: ${pkgPath}`);
|
|
231
|
-
return { exitCode: 0 };
|
|
232
|
-
}
|
|
233
|
-
async function showWorkers(accountId, logger) {
|
|
234
|
-
logger.info(`\uD83D\uDC77 Workers Scripts
|
|
235
|
-
`);
|
|
236
|
-
const workers = await account.workers(accountId, CLI_API_OPTIONS);
|
|
237
|
-
if (workers.length === 0) {
|
|
238
|
-
logger.info("No Workers found");
|
|
239
|
-
return { exitCode: 0 };
|
|
240
|
-
}
|
|
241
|
-
logger.info("─".repeat(60));
|
|
242
|
-
logger.info(`${"Name".padEnd(30)} ${"Modified".padEnd(20)}`);
|
|
243
|
-
logger.info("─".repeat(60));
|
|
244
|
-
for (const worker of workers) {
|
|
245
|
-
logger.info(`${worker.name.padEnd(30)} ${formatDate(worker.modifiedOn).padEnd(20)}`);
|
|
246
|
-
}
|
|
247
|
-
logger.info("─".repeat(60));
|
|
248
|
-
logger.info(`Total: ${workers.length} worker(s)`);
|
|
249
|
-
return { exitCode: 0 };
|
|
250
|
-
}
|
|
251
|
-
async function showKV(accountId, logger) {
|
|
252
|
-
logger.info(`\uD83D\uDDC4️ KV Namespaces
|
|
253
|
-
`);
|
|
254
|
-
const namespaces = await account.kv(accountId, CLI_API_OPTIONS);
|
|
255
|
-
if (namespaces.length === 0) {
|
|
256
|
-
logger.info("No KV namespaces found");
|
|
257
|
-
return { exitCode: 0 };
|
|
258
|
-
}
|
|
259
|
-
logger.info("─".repeat(70));
|
|
260
|
-
logger.info(`${"Name".padEnd(35)} ${"ID".padEnd(35)}`);
|
|
261
|
-
logger.info("─".repeat(70));
|
|
262
|
-
for (const ns of namespaces) {
|
|
263
|
-
logger.info(`${ns.name.padEnd(35)} ${ns.id.padEnd(35)}`);
|
|
264
|
-
}
|
|
265
|
-
logger.info("─".repeat(70));
|
|
266
|
-
logger.info(`Total: ${namespaces.length} namespace(s)`);
|
|
267
|
-
return { exitCode: 0 };
|
|
268
|
-
}
|
|
269
|
-
async function showD1(accountId, logger) {
|
|
270
|
-
logger.info(`\uD83D\uDDC3️ D1 Databases
|
|
271
|
-
`);
|
|
272
|
-
const databases = await account.d1(accountId, CLI_API_OPTIONS);
|
|
273
|
-
if (databases.length === 0) {
|
|
274
|
-
logger.info("No D1 databases found");
|
|
275
|
-
return { exitCode: 0 };
|
|
276
|
-
}
|
|
277
|
-
logger.info("─".repeat(80));
|
|
278
|
-
logger.info(`${"Name".padEnd(25)} ${"ID".padEnd(40)} ${"Tables".padEnd(8)}`);
|
|
279
|
-
logger.info("─".repeat(80));
|
|
280
|
-
for (const db of databases) {
|
|
281
|
-
const tables = db.tableCount !== undefined ? db.tableCount.toString() : "N/A";
|
|
282
|
-
logger.info(`${db.name.padEnd(25)} ${db.id.padEnd(40)} ${tables.padEnd(8)}`);
|
|
283
|
-
}
|
|
284
|
-
logger.info("─".repeat(80));
|
|
285
|
-
logger.info(`Total: ${databases.length} database(s)`);
|
|
286
|
-
return { exitCode: 0 };
|
|
287
|
-
}
|
|
288
|
-
async function showR2(accountId, logger) {
|
|
289
|
-
logger.info(`\uD83D\uDCE6 R2 Buckets
|
|
290
|
-
`);
|
|
291
|
-
const buckets = await account.r2(accountId, CLI_API_OPTIONS);
|
|
292
|
-
if (buckets.length === 0) {
|
|
293
|
-
logger.info("No R2 buckets found");
|
|
294
|
-
return { exitCode: 0 };
|
|
295
|
-
}
|
|
296
|
-
logger.info("─".repeat(60));
|
|
297
|
-
logger.info(`${"Name".padEnd(30)} ${"Created".padEnd(20)} ${"Location".padEnd(10)}`);
|
|
298
|
-
logger.info("─".repeat(60));
|
|
299
|
-
for (const bucket of buckets) {
|
|
300
|
-
const location = bucket.location ?? "auto";
|
|
301
|
-
logger.info(`${bucket.name.padEnd(30)} ${formatDate(bucket.createdOn).padEnd(20)} ${location.padEnd(10)}`);
|
|
302
|
-
}
|
|
303
|
-
logger.info("─".repeat(60));
|
|
304
|
-
logger.info(`Total: ${buckets.length} bucket(s)`);
|
|
305
|
-
return { exitCode: 0 };
|
|
306
|
-
}
|
|
307
|
-
async function showVectorize(accountId, logger) {
|
|
308
|
-
logger.info(`\uD83D\uDD0D Vectorize Indexes
|
|
309
|
-
`);
|
|
310
|
-
const indexes = await account.vectorize(accountId, CLI_API_OPTIONS);
|
|
311
|
-
if (indexes.length === 0) {
|
|
312
|
-
logger.info("No Vectorize indexes found");
|
|
313
|
-
return { exitCode: 0 };
|
|
314
|
-
}
|
|
315
|
-
logger.info("─".repeat(70));
|
|
316
|
-
logger.info(`${"Name".padEnd(25)} ${"Dimensions".padEnd(12)} ${"Metric".padEnd(15)}`);
|
|
317
|
-
logger.info("─".repeat(70));
|
|
318
|
-
for (const idx of indexes) {
|
|
319
|
-
logger.info(`${idx.name.padEnd(25)} ${idx.dimensions.toString().padEnd(12)} ${idx.metric.padEnd(15)}`);
|
|
320
|
-
}
|
|
321
|
-
logger.info("─".repeat(70));
|
|
322
|
-
logger.info(`Total: ${indexes.length} index(es)`);
|
|
323
|
-
return { exitCode: 0 };
|
|
324
|
-
}
|
|
325
|
-
async function showUsage(accountId, logger) {
|
|
326
|
-
logger.info(`\uD83D\uDCC8 Usage Report
|
|
327
|
-
`);
|
|
328
|
-
const usages = await account.getAllUsageSummaries(accountId);
|
|
329
|
-
const limits = await account.getLimits(accountId);
|
|
330
|
-
logger.info(`Limits Enabled: ${limits.enabled ? "Yes" : "No"}`);
|
|
331
|
-
logger.info("");
|
|
332
|
-
if (usages.length === 0) {
|
|
333
|
-
logger.info("No usage tracked yet");
|
|
334
|
-
return { exitCode: 0 };
|
|
335
|
-
}
|
|
336
|
-
logger.info("─".repeat(60));
|
|
337
|
-
logger.info(`${"Service".padEnd(15)} ${"Today".padEnd(10)} ${"Limit".padEnd(10)} ${"%".padEnd(10)} ${"Status".padEnd(10)}`);
|
|
338
|
-
logger.info("─".repeat(60));
|
|
339
|
-
for (const usage of usages) {
|
|
340
|
-
const limitStr = usage.limit?.toString() ?? "∞";
|
|
341
|
-
const percentStr = formatPercent(usage.percentUsed);
|
|
342
|
-
const status = usage.withinLimit ? "✅ OK" : "⛔ LIMIT";
|
|
343
|
-
logger.info(`${usage.service.padEnd(15)} ${usage.today.toString().padEnd(10)} ${limitStr.padEnd(10)} ${percentStr.padEnd(10)} ${status.padEnd(10)}`);
|
|
344
|
-
}
|
|
345
|
-
logger.info("─".repeat(60));
|
|
346
|
-
return { exitCode: 0 };
|
|
347
|
-
}
|
|
348
|
-
async function handleLimits(accountId, parsed, logger) {
|
|
349
|
-
const action = parsed.args[1];
|
|
350
|
-
switch (action) {
|
|
351
|
-
case "set":
|
|
352
|
-
return await setLimit(accountId, parsed, logger);
|
|
353
|
-
case "enable":
|
|
354
|
-
await account.setLimitsEnabled(accountId, true);
|
|
355
|
-
logger.success("Usage limits enabled");
|
|
356
|
-
return { exitCode: 0 };
|
|
357
|
-
case "disable":
|
|
358
|
-
await account.setLimitsEnabled(accountId, false);
|
|
359
|
-
logger.success("Usage limits disabled");
|
|
360
|
-
return { exitCode: 0 };
|
|
361
|
-
default:
|
|
362
|
-
return await showLimits(accountId, logger);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
async function showLimits(accountId, logger) {
|
|
366
|
-
logger.info(`⚙️ Usage Limits
|
|
367
|
-
`);
|
|
368
|
-
const limits = await account.getLimits(accountId);
|
|
369
|
-
logger.info(`Status: ${limits.enabled ? "✅ Enabled" : "❌ Disabled"}`);
|
|
370
|
-
logger.info("");
|
|
371
|
-
logger.info("Current Limits:");
|
|
372
|
-
logger.info("─".repeat(40));
|
|
373
|
-
logger.info(` AI Requests/Day: ${limits.aiRequestsPerDay ?? "Unlimited"}`);
|
|
374
|
-
logger.info(` AI Tokens/Day: ${limits.aiTokensPerDay ?? "Unlimited"}`);
|
|
375
|
-
logger.info(` Vectorize Ops/Day: ${limits.vectorizeOpsPerDay ?? "Unlimited"}`);
|
|
376
|
-
logger.info("");
|
|
377
|
-
logger.info("Commands:");
|
|
378
|
-
logger.info(" devflare account limits set ai-requests 50");
|
|
379
|
-
logger.info(" devflare account limits set ai-tokens 5000");
|
|
380
|
-
logger.info(" devflare account limits set vectorize-ops 500");
|
|
381
|
-
logger.info(" devflare account limits enable");
|
|
382
|
-
logger.info(" devflare account limits disable");
|
|
383
|
-
return { exitCode: 0 };
|
|
384
|
-
}
|
|
385
|
-
async function setLimit(accountId, parsed, logger) {
|
|
386
|
-
const limitName = parsed.args[2];
|
|
387
|
-
const limitValue = parsed.args[3];
|
|
388
|
-
if (!limitName || !limitValue) {
|
|
389
|
-
logger.error("Usage: devflare account limits set <limit-name> <value>");
|
|
390
|
-
logger.info("Limit names: ai-requests, ai-tokens, vectorize-ops");
|
|
391
|
-
return { exitCode: 1 };
|
|
392
|
-
}
|
|
393
|
-
const value = parseInt(limitValue, 10);
|
|
394
|
-
if (isNaN(value) || value < 0) {
|
|
395
|
-
logger.error("Limit value must be a positive number");
|
|
396
|
-
return { exitCode: 1 };
|
|
397
|
-
}
|
|
398
|
-
switch (limitName) {
|
|
399
|
-
case "ai-requests":
|
|
400
|
-
await account.setLimits(accountId, { aiRequestsPerDay: value });
|
|
401
|
-
logger.success(`AI requests limit set to ${value}/day`);
|
|
402
|
-
break;
|
|
403
|
-
case "ai-tokens":
|
|
404
|
-
await account.setLimits(accountId, { aiTokensPerDay: value });
|
|
405
|
-
logger.success(`AI tokens limit set to ${value}/day`);
|
|
406
|
-
break;
|
|
407
|
-
case "vectorize-ops":
|
|
408
|
-
await account.setLimits(accountId, { vectorizeOpsPerDay: value });
|
|
409
|
-
logger.success(`Vectorize ops limit set to ${value}/day`);
|
|
410
|
-
break;
|
|
411
|
-
default:
|
|
412
|
-
logger.error(`Unknown limit: ${limitName}`);
|
|
413
|
-
logger.info("Valid limits: ai-requests, ai-tokens, vectorize-ops");
|
|
414
|
-
return { exitCode: 1 };
|
|
415
|
-
}
|
|
416
|
-
return { exitCode: 0 };
|
|
417
|
-
}
|
|
418
|
-
export {
|
|
419
|
-
runAccountCommand
|
|
420
|
-
};
|