Skip to content

Commit 1c98fd7

Browse files
committed
docs: update blob + miscellanous
1 parent e7ffed1 commit 1c98fd7

File tree

7 files changed

+227
-4
lines changed

7 files changed

+227
-4
lines changed

docs/content/2.usage/1.database.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ NuxtHub Database is a layer to [Cloudflare D1](https://developers.cloudflare.com
77

88
<!-- TODO: config, binding ? -->
99

10-
Once properly configured, NuxtHub module exposes a server composable to your application.
10+
Once properly configured, NuxtHub module exposes a server composable to the application.
1111

12-
## `useDB()`
12+
## `useDatabase()`
13+
14+
Server composable that returns a set of methods from [D1Database](https://developers.cloudflare.com/d1/build-databases/query-databases/).
15+
16+
### `exec()`
17+
18+
### `dump()`
19+
20+
### `prepare()`
21+
22+
### `batch()`

docs/content/2.usage/2.kv.md

+8
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,11 @@ description: How to use key-value data storage with NuxtHub.
44
---
55

66
NuxtHub KV is a layer to [Cloudflare Workers KV](https://developers.cloudflare.com/kv), a global, low-latency, key-value data storage.
7+
8+
<!-- TODO: config, binding ? -->
9+
10+
Once properly configured, NuxtHub module exposes a server composable to the application.
11+
12+
## `useKV()`
13+
14+
Server composable that returns a [Storage](https://unstorage.unjs.io/getting-started/usage#interface).

docs/content/2.usage/3.blob.md

+172
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,175 @@ description: How to store objects with NuxtHub.
44
---
55

66
NuxtHub Blob is a layer to [Cloudflare R2](https://developers.cloudflare.com/r2), allowing to store large amounts of unstructured data.
7+
8+
<!-- TODO: config, binding ? -->
9+
10+
Once properly configured, NuxtHub module exposes a server composable to the application.
11+
12+
## `useBlob()`
13+
14+
Server composable that returns a set of methods to manipulate the blob storage.
15+
16+
### `list()`
17+
18+
Returns a paginated list of blobs.
19+
20+
```ts[/api/blob/index.get.ts]
21+
export default eventHandler(async () => {
22+
return useBlob().list()
23+
})
24+
```
25+
26+
#### Params
27+
28+
- `options`: [`BlobListOptions`](#bloblistoptions)
29+
30+
#### Return
31+
32+
Returns an array of [`BlobObject`](#blobobject).
33+
34+
### `serve()`
35+
36+
Returns a blob's data.
37+
38+
```ts[/api/blob/[...pathname\\].get.ts]
39+
export default eventHandler(async (event) => {
40+
const { pathname } = getRouterParams(event)
41+
42+
return useBlob().serve(event, pathname)
43+
})
44+
```
45+
46+
#### Params
47+
48+
- `event`: [`H3Event`](https://github.com/unjs/h3)
49+
- `pathname`: `string`
50+
51+
#### Return
52+
53+
Returns the blob's raw data and sets `Content-Type` and `Content-Length` headers.
54+
55+
::callout{icon="i-heroicons-information-circle"}
56+
If you are fetching an image with a server route similar to the one above, you might simply want to use it this way:
57+
<br>
58+
```vue
59+
<img :src="`/api/blob/${file.pathname}`">
60+
```
61+
::
62+
63+
### `head()`
64+
65+
Returns a blob's metadata.
66+
67+
```ts[/api/blob/[...pathname\\].head.ts]
68+
export default eventHandler(async (event) => {
69+
const { pathname } = getRouterParams(event)
70+
71+
const blob = await useBlob().head(pathname)
72+
73+
setHeader(event, 'x-blob', JSON.stringify(blob))
74+
75+
return sendNoContent(event)
76+
})
77+
```
78+
79+
#### Params
80+
81+
- `pathname`: `string`
82+
83+
#### Return
84+
85+
Returns a [`BlobObject`](#blobobject).
86+
87+
### `put()`
88+
89+
Uploads a blob.
90+
91+
```ts[/api/blob/[...pathname\\].put.ts]
92+
export default eventHandler(async (event) => {
93+
const { pathname } = getRouterParams(event)
94+
const form = await readFormData(event)
95+
const file = form.get('file') as Blob
96+
97+
if (!file || !file.size) {
98+
throw createError({ statusCode: 400, message: 'No file provided' })
99+
}
100+
101+
ensureBlob(file, { maxSize: '1MB', types: ['image' ]})
102+
103+
return useBlob().put(`images/${file.name}`, file, { addRandomSuffix: false })
104+
})
105+
```
106+
107+
#### Params
108+
109+
- `pathname`: `string`
110+
- `body`: `string` | `ReadableStream<any>` | `ArrayBuffer` | `ArrayBufferView` | `Blob`
111+
- `options`: [`BlobPutOptions`](#blobputoptions)
112+
#### Return
113+
114+
Returns a [`BlobObject`](#blobobject).
115+
116+
::callout{icon="i-heroicons-light-bulb"}
117+
Take a look at all the [validation](/recipes/validation) utils like [`ensureBlob`](/recipes/validation#ensureblob)
118+
::
119+
120+
### `delete()`
121+
122+
Deletes a blob.
123+
124+
```ts[/api/blob/[...pathname\\].delete.ts]
125+
export default eventHandler(async (event) => {
126+
const { pathname } = getRouterParams(event)
127+
128+
await useBlob().delete(pathname)
129+
130+
return sendNoContent(event)
131+
})
132+
```
133+
134+
#### Params
135+
136+
- `pathname`: `string`
137+
138+
#### Return
139+
140+
Returns nothing.
141+
142+
## Types
143+
144+
### `BlobListOptions`
145+
146+
```ts
147+
interface BlobListOptions {
148+
/**
149+
* The maximum number of blobs to return per request.
150+
* @default 1000
151+
*/
152+
limit?: number
153+
prefix?: string
154+
cursor?: string
155+
}
156+
```
157+
158+
### `BlobPutOptions`
159+
160+
```ts
161+
interface BlobPutOptions {
162+
contentType?: string,
163+
contentLength?: string,
164+
addRandomSuffix?: boolean,
165+
[key: string]: any
166+
}
167+
```
168+
169+
### `BlobObject`
170+
171+
```ts
172+
interface BlobObject {
173+
pathname: string
174+
contentType: string | undefined
175+
size: number
176+
uploadedAt: Date
177+
}
178+
```

docs/content/2.usage/4.analytics.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@ description: How to track events with NuxtHub.
44
---
55

66
NuxtHub Analytics is a layer to [Cloudflare Workers Analytics Engine](https://developers.cloudflare.com/analytics/analytics-engine/), allowing to get analytics about anything.
7+
8+
<!-- TODO: config, binding ? -->
9+
10+
Once properly configured, NuxtHub module exposes a server composable to the application.
11+
12+
## `useAnalytics()`
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: Validation
3+
description:
4+
---
5+
6+
## Blob
7+
8+
### `ensureBlob()`
9+
10+
<!-- TODO -->

docs/content/3.recipes/2.hooks.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: Hooks
3+
description:
4+
---
5+
6+
## Hooks
7+
8+
### `onHubReady`
9+
10+
<!-- TODO -->

src/runtime/server/utils/blob.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ export interface BlobListOptions {
2828
cursor?: string
2929
}
3030

31+
export interface BlobPutOptions {
32+
contentType?: string,
33+
contentLength?: string,
34+
addRandomSuffix?: boolean,
35+
[key: string]: any
36+
}
37+
3138
const _r2_buckets: Record<string, R2Bucket> = {}
3239

3340
function _useBucket() {
@@ -89,7 +96,7 @@ export function useBlob() {
8996

9097
return object.body
9198
},
92-
async put(pathname: string, body: string | ReadableStream<any> | ArrayBuffer | ArrayBufferView | Blob, options: { contentType?: string, contentLength?: string, addRandomSuffix?: boolean, [key: string]: any } = { addRandomSuffix: true }) {
99+
async put(pathname: string, body: string | ReadableStream<any> | ArrayBuffer | ArrayBufferView | Blob, options: BlobPutOptions = { addRandomSuffix: true }) {
93100
pathname = decodeURI(pathname)
94101
const { contentType: optionsContentType, contentLength, addRandomSuffix, ...customMetadata } = options
95102
const contentType = optionsContentType || (body as Blob).type || getContentType(pathname)
@@ -145,7 +152,7 @@ export function useProxyBlob(projectUrl: string, secretKey?: string) {
145152
method: 'GET'
146153
})
147154
},
148-
async put(pathname: string, body: string | ReadableStream<any> | ArrayBuffer | ArrayBufferView | Blob, options: { contentType?: string, contentLength?: string, addRandomSuffix?: boolean, [key: string]: any } = { addRandomSuffix: true }) {
155+
async put(pathname: string, body: string | ReadableStream<any> | ArrayBuffer | ArrayBufferView | Blob, options: BlobPutOptions = { addRandomSuffix: true }) {
149156
const { contentType, contentLength, ...query } = options
150157
const headers: Record<string, string> = {}
151158
if (contentType) { headers['content-type'] = contentType }

0 commit comments

Comments
 (0)