devflare 1.0.0-next.2 → 1.0.0-next.4
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 +403 -15
- package/R2.md +170 -0
- package/dist/bridge/proxy.d.ts +4 -5
- package/dist/bridge/proxy.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/{dev-qnxet3j9.js → dev-pa8dhm20.js} +89 -23
- package/dist/dev-server/server.d.ts +2 -0
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/dev-server/vite-utils.d.ts +37 -0
- package/dist/dev-server/vite-utils.d.ts.map +1 -0
- package/dist/{doctor-e8fy6fj5.js → doctor-fmgb3d28.js} +38 -34
- package/dist/index-18hvb6gb.js +194 -0
- package/dist/index.js +7 -7
- package/dist/test/bridge-context.d.ts +4 -1
- package/dist/test/bridge-context.d.ts.map +1 -1
- package/package.json +3 -2
package/LLM.md
CHANGED
|
@@ -520,7 +520,7 @@ Bindings are the heart of the runtime contract.
|
|
|
520
520
|
|---|---|---|---|
|
|
521
521
|
| `kv` | `Record<string, string>` | Yes | binding name → KV namespace ID |
|
|
522
522
|
| `d1` | `Record<string, string>` | Yes | binding name → D1 database ID |
|
|
523
|
-
| `r2` | `Record<string, string>` | Yes | binding name → bucket name |
|
|
523
|
+
| `r2` | `Record<string, string>` | Yes | binding name → bucket name, not a delivery/auth strategy |
|
|
524
524
|
| `durableObjects` | `Record<string, string | { className, scriptName? }>` | Yes | string shorthand or object form, including cross-worker refs |
|
|
525
525
|
| `queues.producers` | `Record<string, string>` | Yes | binding name → queue name |
|
|
526
526
|
| `queues.consumers` | array of consumer objects | Yes | batch size, retries, timeout, DLQ, concurrency, retry delay |
|
|
@@ -550,6 +550,15 @@ bindings: {
|
|
|
550
550
|
}
|
|
551
551
|
```
|
|
552
552
|
|
|
553
|
+
An R2 binding declaration only makes the bucket available as a runtime `env` binding.
|
|
554
|
+
|
|
555
|
+
It does **not** by itself decide:
|
|
556
|
+
|
|
557
|
+
- how uploads should be authorized
|
|
558
|
+
- whether objects are public or private
|
|
559
|
+
- which URL shape should be stored in your database
|
|
560
|
+
- whether files should be served through a custom domain, presigned URL, Access, WAF token auth, or a Worker
|
|
561
|
+
|
|
553
562
|
### Durable Objects
|
|
554
563
|
|
|
555
564
|
Durable Object bindings support both shorthand and object form.
|
|
@@ -688,6 +697,199 @@ However, this binding is currently **not wired through the compiler/types/runtim
|
|
|
688
697
|
|
|
689
698
|
---
|
|
690
699
|
|
|
700
|
+
## R2 workflow: uploads, delivery, local development, and preview mindset
|
|
701
|
+
|
|
702
|
+
For a shorter strategy guide focused specifically on Cloudflare R2 delivery patterns, see `R2.md`.
|
|
703
|
+
|
|
704
|
+
This section explains how R2 fits into the **public Devflare mental model**.
|
|
705
|
+
|
|
706
|
+
### `bindings.r2` gives you storage access, not a complete delivery policy
|
|
707
|
+
|
|
708
|
+
When you configure:
|
|
709
|
+
|
|
710
|
+
```ts
|
|
711
|
+
bindings: {
|
|
712
|
+
r2: {
|
|
713
|
+
FILES: 'files-bucket'
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
Devflare is saying:
|
|
719
|
+
|
|
720
|
+
- your Worker should receive an `env.FILES` R2 binding
|
|
721
|
+
- local development can simulate that binding
|
|
722
|
+
- build/deploy compilation can emit the corresponding Wrangler binding declaration
|
|
723
|
+
|
|
724
|
+
Devflare is **not** automatically saying:
|
|
725
|
+
|
|
726
|
+
- uploads should come from the browser directly
|
|
727
|
+
- objects should be public
|
|
728
|
+
- objects should be private
|
|
729
|
+
- your app should store full URLs instead of object keys
|
|
730
|
+
- local dev URLs should look like production URLs
|
|
731
|
+
|
|
732
|
+
Those choices still belong to your application architecture.
|
|
733
|
+
|
|
734
|
+
### Store object keys, not full URLs
|
|
735
|
+
|
|
736
|
+
This is the safest default rule for R2-backed applications:
|
|
737
|
+
|
|
738
|
+
- store the **object key** as the durable identifier
|
|
739
|
+
- optionally store metadata such as content type, size, owner, visibility, or logical folder/prefix
|
|
740
|
+
- derive the actual viewing or download URL per environment and per access policy
|
|
741
|
+
|
|
742
|
+
Example durable record shape:
|
|
743
|
+
|
|
744
|
+
```ts
|
|
745
|
+
{
|
|
746
|
+
key: 'users/42/avatar/8d8b7f2a.png',
|
|
747
|
+
contentType: 'image/png',
|
|
748
|
+
visibility: 'private'
|
|
749
|
+
}
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
Why this is better than storing full URLs:
|
|
753
|
+
|
|
754
|
+
- local preview URLs can change without breaking your data model
|
|
755
|
+
- staging and production can use different delivery strategies for the same object key
|
|
756
|
+
- you do not couple persistent data to `localhost`, temporary signed URLs, or a specific CDN hostname
|
|
757
|
+
- you can move a file from private delivery to public delivery without rewriting the canonical identifier
|
|
758
|
+
|
|
759
|
+
### Recommended upload and serving models
|
|
760
|
+
|
|
761
|
+
These are the recommended patterns to pair with a Devflare R2 binding.
|
|
762
|
+
|
|
763
|
+
#### Direct user uploads
|
|
764
|
+
|
|
765
|
+
For normal browser uploads, the safest default is:
|
|
766
|
+
|
|
767
|
+
1. your frontend asks your app for upload permission
|
|
768
|
+
2. your Worker authenticates the user and validates file type, size, and target key
|
|
769
|
+
3. your Worker returns a short-lived presigned `PUT` URL
|
|
770
|
+
4. the browser uploads directly to R2
|
|
771
|
+
5. your app stores the resulting object key and metadata
|
|
772
|
+
|
|
773
|
+
This keeps large uploads out of your application request path while preserving control over authorization and naming.
|
|
774
|
+
|
|
775
|
+
#### Worker-generated or server-generated content
|
|
776
|
+
|
|
777
|
+
If the file is produced by your Worker, by Workers AI, or by another trusted backend process, it is normal for the Worker itself to write directly to R2.
|
|
778
|
+
|
|
779
|
+
That is different from browser-driven uploads, where presigned URLs are usually the cleaner fit.
|
|
780
|
+
|
|
781
|
+
#### Public files
|
|
782
|
+
|
|
783
|
+
For avatars, blog images, product images, and other content that anyone may read:
|
|
784
|
+
|
|
785
|
+
- use a public bucket or public custom-domain access pattern
|
|
786
|
+
- prefer a custom domain for stable production URLs and caching behavior
|
|
787
|
+
- do not treat `r2.dev` as the production answer
|
|
788
|
+
|
|
789
|
+
#### Private or authenticated files
|
|
790
|
+
|
|
791
|
+
For invoices, receipts, paid media, tenant-scoped files, or other user-specific objects:
|
|
792
|
+
|
|
793
|
+
- keep the bucket private
|
|
794
|
+
- store only object keys in durable data
|
|
795
|
+
- serve reads through a Worker that checks session, tenant, or authorization state before reading from R2
|
|
796
|
+
|
|
797
|
+
#### Temporary direct reads
|
|
798
|
+
|
|
799
|
+
Presigned `GET` URLs are useful when you need short-lived direct access.
|
|
800
|
+
|
|
801
|
+
Important caveats:
|
|
802
|
+
|
|
803
|
+
- they are bearer tokens
|
|
804
|
+
- they work on the R2 S3 endpoint, not on custom domains
|
|
805
|
+
- they are great for temporary access, but not the right long-term answer for polished custom-domain delivery
|
|
806
|
+
|
|
807
|
+
#### Team-only or org-only buckets
|
|
808
|
+
|
|
809
|
+
If the audience is your teammates or internal users, Cloudflare Access on a custom domain is often a better fit than inventing your own mini auth protocol.
|
|
810
|
+
|
|
811
|
+
#### Custom-domain expiring links
|
|
812
|
+
|
|
813
|
+
If you want URLs like `https://cdn.example.com/files/...` with time-limited access, use:
|
|
814
|
+
|
|
815
|
+
- a Worker-controlled token/signature layer, or
|
|
816
|
+
- Cloudflare WAF token authentication / HMAC validation
|
|
817
|
+
|
|
818
|
+
Do **not** confuse that with R2 presigned URLs. They solve different problems.
|
|
819
|
+
|
|
820
|
+
### Local development vs production
|
|
821
|
+
|
|
822
|
+
#### Local development
|
|
823
|
+
|
|
824
|
+
In local development, the correct default assumption is:
|
|
825
|
+
|
|
826
|
+
- your Worker code runs locally
|
|
827
|
+
- your R2 binding is simulated locally unless you intentionally opt into remote resources
|
|
828
|
+
|
|
829
|
+
This is good. It gives you fast feedback, zero surprise cloud writes, and predictable local iteration.
|
|
830
|
+
|
|
831
|
+
When you run `devflare dev --persist`, local Miniflare-backed state is persisted under `.devflare/data/`, including R2 object state under `.devflare/data/r2/`.
|
|
832
|
+
|
|
833
|
+
#### Remote bindings change the risk profile
|
|
834
|
+
|
|
835
|
+
If you connect development to remote resources, remember:
|
|
836
|
+
|
|
837
|
+
- reads and writes touch **real buckets**
|
|
838
|
+
- operations can incur **real cost**
|
|
839
|
+
- local experiments can now interact with non-local data
|
|
840
|
+
|
|
841
|
+
So the recommended pattern is:
|
|
842
|
+
|
|
843
|
+
- use local simulated R2 for normal development
|
|
844
|
+
- use separate dev or staging buckets when you need higher-fidelity integration testing
|
|
845
|
+
- avoid pointing local development at production user uploads unless you truly mean to
|
|
846
|
+
|
|
847
|
+
#### Production
|
|
848
|
+
|
|
849
|
+
Production is where you make the real delivery choice:
|
|
850
|
+
|
|
851
|
+
- public custom-domain access for public files
|
|
852
|
+
- Worker-gated reads for private/authenticated files
|
|
853
|
+
- Access for org-only content
|
|
854
|
+
- Worker/WAF token validation for custom-domain expiring links
|
|
855
|
+
|
|
856
|
+
That is why `R2.md` exists. It is the short operational guide for those production choices.
|
|
857
|
+
|
|
858
|
+
### Local preview and internal route guidance
|
|
859
|
+
|
|
860
|
+
Devflare already uses internal `/_devflare/*` routes during local development for gateway and bridge behavior.
|
|
861
|
+
|
|
862
|
+
Treat those routes as **internal dev-server implementation details**, not as part of your application’s public URL contract.
|
|
863
|
+
|
|
864
|
+
Important current rule:
|
|
865
|
+
|
|
866
|
+
- do **not** assume there is a stable public `/_devflare/r2/...` contract for browser-facing local file delivery
|
|
867
|
+
- do **not** persist `/_devflare/*` URLs in your database
|
|
868
|
+
- do **not** design production delivery around the hope that local preview URLs and production URLs will be the same
|
|
869
|
+
|
|
870
|
+
If you build custom local preview tooling or if Devflare gains a future R2 inspector surface, the safest mental model is:
|
|
871
|
+
|
|
872
|
+
- it is a **dev-only convenience or inspector URL**
|
|
873
|
+
- it should be treated as **read-only**
|
|
874
|
+
- it should help you inspect objects, not redefine your production delivery architecture
|
|
875
|
+
- the canonical identifier should still be the object key, not the preview URL
|
|
876
|
+
|
|
877
|
+
Also remember that R2 is object storage, not a real filesystem. Prefix browsing can be useful in tooling, but those “folders” are naming conventions, not first-class directories.
|
|
878
|
+
|
|
879
|
+
### Benefits of this model
|
|
880
|
+
|
|
881
|
+
This local-first but production-explicit R2 model has real benefits.
|
|
882
|
+
|
|
883
|
+
- **Faster local iteration:** you can develop upload and media flows against local simulated R2 without waiting on cloud round-trips
|
|
884
|
+
- **Safer production posture:** public, private, org-only, and expiring-link delivery can be chosen intentionally instead of collapsing into one accidental URL model
|
|
885
|
+
- **Better data durability:** storing keys instead of URLs keeps your database portable across local, staging, and production environments
|
|
886
|
+
- **Cleaner security boundaries:** auth policy stays where it belongs, in Workers, Access, or token validation, rather than being smuggled into a fragile client-side convention
|
|
887
|
+
- **Better debugging ergonomics:** local preview or inspector tooling can exist as a convenience layer without becoming the source of truth
|
|
888
|
+
- **Less environment coupling:** your app does not become dependent on `localhost`, temporary presigned URLs, or an implementation-specific dev route shape
|
|
889
|
+
- **Better media realism:** you can use local development for quick feedback, then use staging for production-like checks such as custom-domain caching, token auth, and large-media behavior
|
|
890
|
+
|
|
891
|
+
---
|
|
892
|
+
|
|
691
893
|
## `vars`, `secrets`, and generated types
|
|
692
894
|
|
|
693
895
|
### `vars`
|
|
@@ -1285,6 +1487,34 @@ Recommended invocation style:
|
|
|
1285
1487
|
bunx --bun devflare <command>
|
|
1286
1488
|
```
|
|
1287
1489
|
|
|
1490
|
+
### Global flags
|
|
1491
|
+
|
|
1492
|
+
These flags are parsed at the CLI entrypoint level.
|
|
1493
|
+
|
|
1494
|
+
| Flag | Meaning | Where it actually matters | Notes |
|
|
1495
|
+
|---|---|---|---|
|
|
1496
|
+
| `-h`, `--help` | show help text and exit | all invocations | short-circuits immediately to the help command |
|
|
1497
|
+
| `-v`, `--version` | show the CLI/package version and exit | all invocations | short-circuits immediately to the version command |
|
|
1498
|
+
| `--config <path>` | choose a config file instead of nearest default discovery | `dev`, `build`, `deploy`, `types` | currently not consumed by `doctor`, `account`, `ai`, or `remote` |
|
|
1499
|
+
| `--debug` | enable debug-oriented output | `dev`, `build`, `deploy`, `types` | in `dev`, this also implies verbose logging; in `build`/`deploy`/`types`, it mainly controls stack-trace output on failure |
|
|
1500
|
+
|
|
1501
|
+
There is also a current internal/testing-oriented `--cwd` path override used by the `dev` command implementation. Treat that as an unsupported internal hook rather than part of the stable public CLI contract.
|
|
1502
|
+
|
|
1503
|
+
### `init`
|
|
1504
|
+
|
|
1505
|
+
Usage:
|
|
1506
|
+
|
|
1507
|
+
```text
|
|
1508
|
+
devflare init [name] [--template <template>]
|
|
1509
|
+
```
|
|
1510
|
+
|
|
1511
|
+
Arguments and flags:
|
|
1512
|
+
|
|
1513
|
+
| Argument or flag | Meaning | Notes |
|
|
1514
|
+
|---|---|---|
|
|
1515
|
+
| `[name]` | project directory name | defaults to `my-devflare-app` |
|
|
1516
|
+
| `--template <template>` | choose a starter template | current built-in templates are `minimal` and `api`; default is `minimal` |
|
|
1517
|
+
|
|
1288
1518
|
### `dev`
|
|
1289
1519
|
|
|
1290
1520
|
`devflare dev` is not “just run Miniflare”.
|
|
@@ -1299,23 +1529,30 @@ It is a combined local development system that includes:
|
|
|
1299
1529
|
- browser-shim behavior for browser rendering
|
|
1300
1530
|
- local migration handling when relevant resources are configured
|
|
1301
1531
|
|
|
1302
|
-
|
|
1532
|
+
Usage:
|
|
1303
1533
|
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
- `--log`
|
|
1308
|
-
- `--log-temp`
|
|
1534
|
+
```text
|
|
1535
|
+
devflare dev [--config <path>] [--debug] [--port <port>] [--persist] [--verbose] [--log] [--log-temp]
|
|
1536
|
+
```
|
|
1309
1537
|
|
|
1310
|
-
|
|
1538
|
+
Flags:
|
|
1311
1539
|
|
|
1312
|
-
|
|
1540
|
+
| Flag | Meaning | Notes |
|
|
1541
|
+
|---|---|---|
|
|
1542
|
+
| `--config <path>` | load a specific `devflare.config.*` file | otherwise config is loaded from the current working directory |
|
|
1543
|
+
| `--debug` | enable debug mode | equivalent effect to setting `DEVFLARE_DEBUG=true` for the dev command and also implies verbose logging |
|
|
1544
|
+
| `--port <port>` | set the preferred Vite port | only matters when the current package has a local `vite.config.*` and Devflare actually starts Vite |
|
|
1545
|
+
| `--persist` | persist Miniflare storage across restarts | opt-in in the current CLI; persists KV, R2, D1, and Durable Object state under `.devflare/data/` |
|
|
1546
|
+
| `--verbose` | increase logging verbosity | debug mode also turns this on |
|
|
1547
|
+
| `--log` | tee log output to both terminal and a timestamped file | file name shape is `.log-YYYY-MM-DD_HH-MM-SS` in the project root |
|
|
1548
|
+
| `--log-temp` | tee log output to both terminal and `.log` | `.log` is overwritten each run; if both `--log` and `--log-temp` are passed, temp-log mode wins |
|
|
1313
1549
|
|
|
1314
|
-
|
|
1315
|
-
- `--env <name>` selects `config.env.<name>` during Devflare compilation
|
|
1316
|
-
- on `deploy`, the same `--env <name>` is also forwarded to `wrangler deploy`
|
|
1550
|
+
Important current CLI behavior:
|
|
1317
1551
|
|
|
1318
|
-
|
|
1552
|
+
- Devflare starts in **worker-only mode** unless the current package has a local `vite.config.ts`, `vite.config.js`, `vite.config.mts`, or `vite.config.mjs`
|
|
1553
|
+
- `--port` does not force Vite on by itself; it only affects startup if Vite is already enabled by local package structure
|
|
1554
|
+
- there is no public `--env` flag on the current `dev` command
|
|
1555
|
+
- without `--persist`, local Miniflare-backed state is ephemeral for that dev session
|
|
1319
1556
|
|
|
1320
1557
|
### `build`
|
|
1321
1558
|
|
|
@@ -1331,6 +1568,20 @@ The build subprocess receives `DEVFLARE_BUILD=true` in its environment.
|
|
|
1331
1568
|
|
|
1332
1569
|
That means project build code can branch on “Devflare build mode” if it needs to.
|
|
1333
1570
|
|
|
1571
|
+
Usage:
|
|
1572
|
+
|
|
1573
|
+
```text
|
|
1574
|
+
devflare build [--config <path>] [--env <name>] [--debug]
|
|
1575
|
+
```
|
|
1576
|
+
|
|
1577
|
+
Flags:
|
|
1578
|
+
|
|
1579
|
+
| Flag | Meaning | Notes |
|
|
1580
|
+
|---|---|---|
|
|
1581
|
+
| `--config <path>` | load a specific config file | otherwise uses config discovery from the current working directory |
|
|
1582
|
+
| `--env <name>` | select `config.env.<name>` before compilation | this affects the resolved config written to generated output |
|
|
1583
|
+
| `--debug` | show stack traces on failure | mainly useful when config loading, compilation, or the Vite build subprocess fails |
|
|
1584
|
+
|
|
1334
1585
|
### `deploy`
|
|
1335
1586
|
|
|
1336
1587
|
`devflare deploy` performs the same config-resolution step, then builds and runs Wrangler deploy.
|
|
@@ -1343,10 +1594,39 @@ Important nuances:
|
|
|
1343
1594
|
|
|
1344
1595
|
So do not assume build-time code sees identical environment flags under `build` and `deploy`.
|
|
1345
1596
|
|
|
1597
|
+
Usage:
|
|
1598
|
+
|
|
1599
|
+
```text
|
|
1600
|
+
devflare deploy [--config <path>] [--env <name>] [--dry-run] [--debug]
|
|
1601
|
+
```
|
|
1602
|
+
|
|
1603
|
+
Flags:
|
|
1604
|
+
|
|
1605
|
+
| Flag | Meaning | Notes |
|
|
1606
|
+
|---|---|---|
|
|
1607
|
+
| `--config <path>` | load a specific config file | otherwise uses config discovery from the current working directory |
|
|
1608
|
+
| `--env <name>` | select `config.env.<name>` during Devflare compilation and forward the same env to `wrangler deploy` | this is the most important CLI env flag to understand |
|
|
1609
|
+
| `--dry-run` | print the resolved compiled Wrangler config and exit | current implementation exits before writing `wrangler.jsonc`, running `vite build`, or calling Wrangler |
|
|
1610
|
+
| `--debug` | show stack traces on failure | useful for config/build/deploy debugging |
|
|
1611
|
+
|
|
1346
1612
|
### `types`
|
|
1347
1613
|
|
|
1348
1614
|
`devflare types` generates `env.d.ts`, which is a key part of the typed Devflare workflow.
|
|
1349
1615
|
|
|
1616
|
+
Usage:
|
|
1617
|
+
|
|
1618
|
+
```text
|
|
1619
|
+
devflare types [--config <path>] [--output <path>] [--debug]
|
|
1620
|
+
```
|
|
1621
|
+
|
|
1622
|
+
Flags:
|
|
1623
|
+
|
|
1624
|
+
| Flag | Meaning | Notes |
|
|
1625
|
+
|---|---|---|
|
|
1626
|
+
| `--config <path>` | load a specific config file | otherwise defaults to the current project’s normal config discovery |
|
|
1627
|
+
| `--output <path>` | choose the output path for generated types | defaults to `env.d.ts` |
|
|
1628
|
+
| `--debug` | show stack traces on failure | useful when discovery or generation fails |
|
|
1629
|
+
|
|
1350
1630
|
### `doctor`
|
|
1351
1631
|
|
|
1352
1632
|
`devflare doctor` is a project diagnostics command.
|
|
@@ -1363,12 +1643,113 @@ It currently checks for things such as:
|
|
|
1363
1643
|
|
|
1364
1644
|
Use it as a quick environment sanity check, not as a proof that every runtime behavior is correct.
|
|
1365
1645
|
|
|
1646
|
+
Usage:
|
|
1647
|
+
|
|
1648
|
+
```text
|
|
1649
|
+
devflare doctor
|
|
1650
|
+
```
|
|
1651
|
+
|
|
1652
|
+
Current flag behavior:
|
|
1653
|
+
|
|
1654
|
+
- there are no command-specific public flags documented for `doctor` right now
|
|
1655
|
+
- current implementation checks Vite-related files only when the current package appears to opt into Vite integration
|
|
1656
|
+
- do not assume `--config <path>` currently redirects `doctor` in the same way it does for `build`, `deploy`, `dev`, or `types`
|
|
1657
|
+
|
|
1658
|
+
### `account`
|
|
1659
|
+
|
|
1660
|
+
Usage:
|
|
1661
|
+
|
|
1662
|
+
```text
|
|
1663
|
+
devflare account [subcommand] [--account <accountId>]
|
|
1664
|
+
```
|
|
1665
|
+
|
|
1666
|
+
Flags:
|
|
1667
|
+
|
|
1668
|
+
| Flag | Meaning | Notes |
|
|
1669
|
+
|---|---|---|
|
|
1670
|
+
| `--account <accountId>` | inspect or mutate a specific Cloudflare account instead of the primary account | most useful for `info`, `workers`, `kv`, `d1`, `r2`, `vectorize`, `limits`, and `usage`; the interactive `global` and `workspace` selectors do not depend on it |
|
|
1671
|
+
|
|
1672
|
+
Subcommands:
|
|
1673
|
+
|
|
1674
|
+
| Subcommand | Meaning | Notes |
|
|
1675
|
+
|---|---|---|
|
|
1676
|
+
| `info` | show account overview | default when no subcommand is provided |
|
|
1677
|
+
| `workers` | list Workers scripts | requires Cloudflare auth |
|
|
1678
|
+
| `kv` | list KV namespaces | requires Cloudflare auth |
|
|
1679
|
+
| `d1` | list D1 databases | requires Cloudflare auth |
|
|
1680
|
+
| `r2` | list R2 buckets | requires Cloudflare auth |
|
|
1681
|
+
| `vectorize` | list Vectorize indexes | requires Cloudflare auth |
|
|
1682
|
+
| `limits` | show current Devflare-managed usage limits | supports nested actions described below |
|
|
1683
|
+
| `usage` | show current usage summary | requires Cloudflare auth |
|
|
1684
|
+
| `global` | interactively choose the global default account | stores selection under `~/.devflare/preferences.json` and may sync to cloud KV |
|
|
1685
|
+
| `workspace` | interactively choose the workspace account | writes nearest `package.json` |
|
|
1686
|
+
|
|
1687
|
+
Nested `limits` actions:
|
|
1688
|
+
|
|
1689
|
+
```text
|
|
1690
|
+
devflare account limits
|
|
1691
|
+
devflare account limits enable
|
|
1692
|
+
devflare account limits disable
|
|
1693
|
+
devflare account limits set <limit-name> <value>
|
|
1694
|
+
```
|
|
1695
|
+
|
|
1696
|
+
Valid current limit names are:
|
|
1697
|
+
|
|
1698
|
+
- `ai-requests`
|
|
1699
|
+
- `ai-tokens`
|
|
1700
|
+
- `vectorize-ops`
|
|
1701
|
+
|
|
1702
|
+
### `ai`
|
|
1703
|
+
|
|
1704
|
+
Usage:
|
|
1705
|
+
|
|
1706
|
+
```text
|
|
1707
|
+
devflare ai
|
|
1708
|
+
```
|
|
1709
|
+
|
|
1710
|
+
This command currently has no command-specific public flags. It prints Workers AI pricing/reference data.
|
|
1711
|
+
|
|
1712
|
+
### `remote`
|
|
1713
|
+
|
|
1714
|
+
Usage:
|
|
1715
|
+
|
|
1716
|
+
```text
|
|
1717
|
+
devflare remote [status]
|
|
1718
|
+
devflare remote enable [minutes]
|
|
1719
|
+
devflare remote disable
|
|
1720
|
+
```
|
|
1721
|
+
|
|
1722
|
+
This command currently has no command-specific flags. It is driven by subcommands and an optional positional minutes value.
|
|
1723
|
+
|
|
1724
|
+
Important current behavior:
|
|
1725
|
+
|
|
1726
|
+
- `status` is the default when you run `devflare remote` with no subcommand
|
|
1727
|
+
- `enable [minutes]` defaults to `30` when minutes are omitted or invalid
|
|
1728
|
+
- CLI enablement clamps duration into the current supported range of `1` to `1440` minutes
|
|
1729
|
+
- `disable` removes stored CLI remote-mode state, but does **not** unset `DEVFLARE_REMOTE`
|
|
1730
|
+
|
|
1731
|
+
### `help` and `version`
|
|
1732
|
+
|
|
1733
|
+
Usage:
|
|
1734
|
+
|
|
1735
|
+
```text
|
|
1736
|
+
devflare help
|
|
1737
|
+
devflare version
|
|
1738
|
+
devflare --help
|
|
1739
|
+
devflare --version
|
|
1740
|
+
devflare -h
|
|
1741
|
+
devflare -v
|
|
1742
|
+
```
|
|
1743
|
+
|
|
1744
|
+
The command forms and flag forms are equivalent public entrypoints.
|
|
1745
|
+
|
|
1366
1746
|
### Generated artifacts
|
|
1367
1747
|
|
|
1368
1748
|
Treat these as generated output:
|
|
1369
1749
|
|
|
1370
1750
|
- project-root `wrangler.jsonc` written by build/deploy flows
|
|
1371
1751
|
- `.devflare/` generated output used by the Vite/plugin side of the toolchain
|
|
1752
|
+
- `.devflare/data/` local persisted Miniflare state when you run `devflare dev --persist`
|
|
1372
1753
|
- `.devflare/wrangler.jsonc` generated by the Vite plugin integration
|
|
1373
1754
|
- generated `env.d.ts`
|
|
1374
1755
|
|
|
@@ -1610,7 +1991,12 @@ These are core Devflare strengths today:
|
|
|
1610
1991
|
- the default build/deploy commands still center on Vite output
|
|
1611
1992
|
- verify actual project behavior when relying on these fields
|
|
1612
1993
|
|
|
1613
|
-
14. **
|
|
1994
|
+
14. **there is no stable public local-R2 browser URL contract today**
|
|
1995
|
+
- Devflare uses internal `/_devflare/*` routes for dev-server behavior
|
|
1996
|
+
- treat those as implementation details rather than app-facing URLs
|
|
1997
|
+
- if you build local preview tooling, keep object keys as the durable identifier and treat preview URLs as disposable
|
|
1998
|
+
|
|
1999
|
+
15. **native config intentionally models only part of Wrangler’s total surface**
|
|
1614
2000
|
- for unsupported or not-yet-modeled Wrangler keys, use `wrangler.passthrough`
|
|
1615
2001
|
|
|
1616
2002
|
This is the right way to think about Devflare:
|
|
@@ -1748,4 +2134,6 @@ If you only remember a few things, remember these:
|
|
|
1748
2134
|
10. `createTestContext()` is caller-relative and not every test helper behaves the same way around `waitUntil()`
|
|
1749
2135
|
11. `devflare/test` plus unified `env` is a major part of the package’s value
|
|
1750
2136
|
12. use `ref()` for multi-worker composition instead of magic strings
|
|
1751
|
-
13.
|
|
2137
|
+
13. store R2 object keys as the durable identifier instead of storing full delivery URLs
|
|
2138
|
+
14. treat local preview or inspector URLs as dev conveniences, not as the production file-delivery contract
|
|
2139
|
+
15. when native config does not cover a Wrangler feature, use `wrangler.passthrough`
|
package/R2.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
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
|
+
Only connect to real remote buckets when you intentionally need integration testing, and prefer **separate dev/staging buckets** instead of production buckets.
|
|
125
|
+
|
|
126
|
+
Important remote-dev reality:
|
|
127
|
+
|
|
128
|
+
- remote bindings touch **real data**
|
|
129
|
+
- remote bindings incur **real costs**
|
|
130
|
+
- avoid pointing local development at production uploads unless absolutely necessary
|
|
131
|
+
|
|
132
|
+
Cloudflare docs:
|
|
133
|
+
|
|
134
|
+
- [Workers development & testing](https://developers.cloudflare.com/workers/development-testing/)
|
|
135
|
+
- [Remote bindings](https://developers.cloudflare.com/workers/development-testing/#remote-bindings)
|
|
136
|
+
|
|
137
|
+
### Production
|
|
138
|
+
|
|
139
|
+
For production:
|
|
140
|
+
|
|
141
|
+
- use a **custom domain**, not `r2.dev`
|
|
142
|
+
- choose public vs private intentionally per bucket or per content class
|
|
143
|
+
- keep sensitive content private behind a Worker, Access, or token validation
|
|
144
|
+
- configure **CORS** intentionally for browser upload/download flows
|
|
145
|
+
- use separate **dev**, **staging**, and **prod** buckets
|
|
146
|
+
|
|
147
|
+
Optional performance feature:
|
|
148
|
+
|
|
149
|
+
- if users upload from many regions, consider **Local Uploads** for better upload performance
|
|
150
|
+
|
|
151
|
+
Cloudflare docs:
|
|
152
|
+
|
|
153
|
+
- [Public buckets](https://developers.cloudflare.com/r2/buckets/public-buckets/)
|
|
154
|
+
- [Local uploads](https://developers.cloudflare.com/r2/buckets/local-uploads/)
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Recommended defaults
|
|
159
|
+
|
|
160
|
+
If you need a sane default architecture:
|
|
161
|
+
|
|
162
|
+
- **public assets** → public bucket + custom domain
|
|
163
|
+
- **user uploads** → presigned `PUT` upload + object key stored in DB
|
|
164
|
+
- **private assets** → private bucket + Worker-gated reads
|
|
165
|
+
- **internal assets** → custom domain + Cloudflare Access
|
|
166
|
+
- **custom-domain expiring links** → Worker token auth or WAF HMAC validation
|
|
167
|
+
|
|
168
|
+
If you only remember one rule, remember this:
|
|
169
|
+
|
|
170
|
+
> Use **presigned URLs** for short-lived direct R2 access, but use a **Worker/custom domain auth layer** for polished private media delivery.
|
package/dist/bridge/proxy.d.ts
CHANGED
|
@@ -20,14 +20,13 @@ export declare function createEnvProxy(options?: EnvProxyOptions & {
|
|
|
20
20
|
/**
|
|
21
21
|
* Get the global env proxy for bridge RPC
|
|
22
22
|
*
|
|
23
|
-
* Note: This is distinct from `
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* Note: This is distinct from the published `import { env } from 'devflare'`
|
|
24
|
+
* proxy, which provides unified request/test/bridge-aware access.
|
|
25
|
+
* Use `bridgeEnv` for standalone internal bridge usage and `env` from the
|
|
26
|
+
* main package within request handlers and normal test flows.
|
|
26
27
|
*
|
|
27
28
|
* @example
|
|
28
29
|
* ```ts
|
|
29
|
-
* import { bridgeEnv } from 'devflare'
|
|
30
|
-
*
|
|
31
30
|
* await bridgeEnv.MY_KV.get('key')
|
|
32
31
|
* await bridgeEnv.MY_DO.get(id).fetch(request)
|
|
33
32
|
* ```
|