@owlmeans/storage-resource 0.1.18-rc.0 → 0.1.18-rc.10
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/README.md +7 -3
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/storage-resource/SKILL.md +39 -14
- package/build/helper.d.ts.map +1 -1
- package/build/resource.d.ts.map +1 -1
- package/build/resource.js +1 -0
- package/build/resource.js.map +1 -1
- package/build/types.d.ts +7 -2
- package/build/types.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/resource.ts +4 -5
- package/src/types.ts +7 -2
package/README.md
CHANGED
|
@@ -6,7 +6,9 @@ S3-compatible object storage resource for OwlMeans server applications.
|
|
|
6
6
|
|
|
7
7
|
- `createStorageResource(alias?, configKey?)` — creates an S3-backed storage resource
|
|
8
8
|
- `appendStorageResource(ctx, alias?, configKey?)` — registers the resource in the context
|
|
9
|
-
- `StorageResource` —
|
|
9
|
+
- `StorageResource` — an upload and nothing else: `Pick<Resource<StoredRecord>, 'create'>` plus
|
|
10
|
+
`BasicResource`. The bucket takes a stream and hands back a URL; there is no record store behind
|
|
11
|
+
it to read, list or delete against
|
|
10
12
|
- `StoredConfigAppend` — config mixin type for storage bucket credentials
|
|
11
13
|
|
|
12
14
|
## Installation
|
|
@@ -51,19 +53,21 @@ Upload a file:
|
|
|
51
53
|
|
|
52
54
|
```typescript
|
|
53
55
|
const storage = context.resource<StorageResource>('images')
|
|
54
|
-
await storage.
|
|
56
|
+
const stored = await storage.create({
|
|
55
57
|
id: fileId,
|
|
56
58
|
prefix: 'uploads',
|
|
57
59
|
stream: readableStream,
|
|
58
60
|
type: 'image/jpeg'
|
|
59
61
|
})
|
|
62
|
+
// stored.url — where the object now lives
|
|
60
63
|
```
|
|
61
64
|
|
|
62
65
|
## API
|
|
63
66
|
|
|
64
67
|
### `createStorageResource(alias?, configKey?): StorageResource`
|
|
65
68
|
|
|
66
|
-
Creates an S3 storage resource. `alias` defaults to `DEFAULT_ALIAS` (`'s3-storage'`).
|
|
69
|
+
Creates an S3 storage resource. `alias` defaults to `DEFAULT_ALIAS` (`'s3-storage'`). The only data
|
|
70
|
+
method is `create(record)`, which uploads the stream and answers the record with its `url` filled in.
|
|
67
71
|
|
|
68
72
|
### `appendStorageResource<C, T>(ctx, alias?, configKey?): T`
|
|
69
73
|
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/storage-resource",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.10",
|
|
5
|
+
"generatedAt": "2026-09-01T16:28:56.982Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: storage-resource
|
|
3
|
-
description: How to use @owlmeans/storage-resource — S3-compatible object storage
|
|
3
|
+
description: How to use @owlmeans/storage-resource — the upload-only S3-compatible object storage resource, with mime sniffing on the way in. Auto-invoked when uploading files to a bucket or wiring cfg.storageBuckets.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,31 +8,56 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/storage-resource
|
|
9
9
|
|
|
10
10
|
**Layer:** Infra
|
|
11
|
-
**Install:** `"@owlmeans/storage-resource": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/storage-resource": "^0.1.18-rc.10"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
## Key Exports
|
|
14
14
|
|
|
15
15
|
| Export | Description |
|
|
16
16
|
|--------|-------------|
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
|
|
|
20
|
-
|
|
|
17
|
+
| `appendStorageResource(context, alias?, configKey?)` | Register the upload resource on a server context |
|
|
18
|
+
| `createStorageResource(alias?, configKey?)` | The bare resource, when you register it yourself |
|
|
19
|
+
| `StorageResource` | `Pick<Resource<StoredRecord>, 'create'>` — **an upload and nothing else** |
|
|
20
|
+
| `StoredRecord`, `StorageConfig`, `StoredConfigAppend` | The uploaded object, one bucket's config, and the `cfg.storageBuckets` shape |
|
|
21
|
+
| `stripData` | Drop the inline payload from a `StoredFileWithData` before it goes on the wire |
|
|
22
|
+
| `supportedMimeTypes`, `DEFAULT_ALIAS` (`s3-storage`) | Constants |
|
|
21
23
|
|
|
22
24
|
## Usage
|
|
23
25
|
|
|
24
26
|
```typescript
|
|
25
|
-
import {
|
|
27
|
+
import { appendStorageResource } from '@owlmeans/storage-resource'
|
|
26
28
|
|
|
27
|
-
context
|
|
28
|
-
alias: 'uploads',
|
|
29
|
-
bucket: WL_BUCKET,
|
|
30
|
-
}))
|
|
29
|
+
appendStorageResource(context, 'uploads', WL_BUCKET)
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
const uploads = context.resource<StorageResource>('uploads')
|
|
32
|
+
const stored = await uploads.create({ stream, size, type: 'image/png', prefix: `${entityId}/${id}` })
|
|
33
|
+
stored.url // the public URL the bucket answers on
|
|
33
34
|
```
|
|
34
35
|
|
|
36
|
+
`configKey` selects the entry in `cfg.storageBuckets` (defaulting to the alias):
|
|
37
|
+
`{ url, apiKey, basePrefix }`, where `apiKey` is `"<keyId>:<keySecret>"` and the object lands at
|
|
38
|
+
`<basePrefix>/<record.prefix>`.
|
|
39
|
+
|
|
40
|
+
## A bucket is not a record store
|
|
41
|
+
|
|
42
|
+
The type names the one method that works. There is no index behind a bucket to read, list or
|
|
43
|
+
delete against, so `StorageResource` exposes `create` alone rather than promising a full
|
|
44
|
+
`Resource<T>` whose rest would only throw. Keep the *record* — its url, size, mime type and
|
|
45
|
+
owner — in a mongo or postgres resource, and let this one carry the bytes; that record is what
|
|
46
|
+
answers criteria, sorting and paging.
|
|
47
|
+
|
|
48
|
+
`create` refuses anything it cannot vouch for: no `stream` raises `FileStreamError`, a missing
|
|
49
|
+
`size` `FilePropertyError`, and a body whose sniffed mime type disagrees with the declared `type`
|
|
50
|
+
raises `FileTypeError('mime-mismatch')` — a caller's claim about a file is checked against its
|
|
51
|
+
bytes, never taken. Bucket failures surface as `StorageApiError`. `opts.ttl` has nothing to act on
|
|
52
|
+
here: a bucket object never expires on its own.
|
|
53
|
+
|
|
35
54
|
## Depends On
|
|
36
55
|
|
|
37
|
-
- `@owlmeans/storage-common`, `@owlmeans/resource`, `@owlmeans/server-context
|
|
38
|
-
|
|
56
|
+
- `@owlmeans/storage-common`, `@owlmeans/resource`, `@owlmeans/context`, `@owlmeans/server-context`,
|
|
57
|
+
`@owlmeans/error`
|
|
58
|
+
- `@aws-sdk/client-s3`, `file-type` (runtime)
|
|
59
|
+
|
|
60
|
+
## Related
|
|
61
|
+
|
|
62
|
+
- [[storage-common]] — the shared file types, schemas and errors
|
|
63
|
+
- [[image-resource]] — the image-shaped specialization of those types
|
package/build/helper.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAE9E,eAAO,MAAM,SAAS,GACpB,KAAK,SAAS,kBAAkB,EAChC,MAAM,SAAS,UAAU,
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAE9E,eAAO,MAAM,SAAS,GACpB,KAAK,SAAS,kBAAkB,EAChC,MAAM,SAAS,UAAU,EACzB,MAAM,KAAK,KAAG,MAgBf,CAAA"}
|
package/build/resource.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAgB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAgB,MAAM,YAAY,CAAA;AAOhF,eAAO,MAAM,qBAAqB,GAAI,QAAO,MAAsB,EAAE,YAAY,MAAM,oBAwEtF,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EAC1E,KAAK,CAAC,EAAE,QAAO,MAAsB,EAAE,YAAY,MAAM,KACxD,CAMF,CAAA"}
|
package/build/resource.js
CHANGED
|
@@ -7,6 +7,7 @@ import { fileTypeFromBuffer } from 'file-type';
|
|
|
7
7
|
export const createStorageResource = (alias = DEFAULT_ALIAS, configKey) => {
|
|
8
8
|
configKey ??= alias;
|
|
9
9
|
const resource = appendContextual(alias, {
|
|
10
|
+
/** A bucket object never expires on its own, so `opts.ttl` has nothing to act on here. */
|
|
10
11
|
create: async (record, _opts) => {
|
|
11
12
|
if (record.stream == null) {
|
|
12
13
|
throw new FileStreamError('no');
|
package/build/resource.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG3C,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC7G,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
|
package/build/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BasicResource } from '@owlmeans/context';
|
|
1
2
|
import type { Resource, ResourceRecord } from '@owlmeans/resource';
|
|
2
3
|
import type { StoredFileFormat } from '@owlmeans/storage-common';
|
|
3
4
|
import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
|
|
@@ -22,8 +23,12 @@ export interface StorageConfig {
|
|
|
22
23
|
apiKey: string;
|
|
23
24
|
basePrefix: string;
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* An upload and nothing else. The bucket takes a stream and hands back a URL; there is no record
|
|
28
|
+
* store behind it to read, list or delete against, so the type names the one method that works
|
|
29
|
+
* rather than promising a full {@link Resource} whose rest would only throw.
|
|
30
|
+
*/
|
|
31
|
+
export type StorageResource = Pick<Resource<StoredRecord>, 'create'> & BasicResource;
|
|
27
32
|
export interface Config extends ServerConfig, StoredConfigAppend {
|
|
28
33
|
}
|
|
29
34
|
export interface Context<C extends Config = Config> extends ServerContext<C> {
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEtC,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,QAAQ,CAAA;IACjB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;KAAE,CAAA;CACjD;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEtC,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,QAAQ,CAAA;IACjB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;KAAE,CAAA;CACjD;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,GAAG,aAAa,CAAA;AAEpF,MAAM,WAAW,MAAO,SAAQ,YAAY,EAAE,kBAAkB;CAAI;AACpE,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/storage-resource",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@aws-sdk/client-s3": "^3.701.0",
|
|
28
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
29
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
30
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
31
|
-
"@owlmeans/server-context": "^0.1.18-rc.
|
|
32
|
-
"@owlmeans/storage-common": "^0.1.18-rc.
|
|
28
|
+
"@owlmeans/context": "^0.1.18-rc.7",
|
|
29
|
+
"@owlmeans/error": "^0.1.18-rc.7",
|
|
30
|
+
"@owlmeans/resource": "^0.1.18-rc.8",
|
|
31
|
+
"@owlmeans/server-context": "^0.1.18-rc.10",
|
|
32
|
+
"@owlmeans/storage-common": "^0.1.18-rc.8",
|
|
33
33
|
"file-type": "^22.0.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
package/src/resource.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { appendContextual } from '@owlmeans/context'
|
|
2
2
|
import { DEFAULT_ALIAS } from './consts.js'
|
|
3
3
|
import type { Config, Context, StorageResource, StoredRecord } from './types.js'
|
|
4
|
-
import type {
|
|
4
|
+
import type { WriteOptions } from '@owlmeans/resource'
|
|
5
5
|
import { FilePropertyError, FileStreamError, FileTypeError, StorageApiError } from '@owlmeans/storage-common'
|
|
6
6
|
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
|
|
7
7
|
import { ResilientError } from '@owlmeans/error'
|
|
8
8
|
import { fileTypeFromBuffer } from 'file-type'
|
|
9
9
|
|
|
10
|
-
type Getter = string | GetterOptions
|
|
11
|
-
|
|
12
10
|
export const createStorageResource = (alias: string = DEFAULT_ALIAS, configKey?: string) => {
|
|
13
11
|
configKey ??= alias
|
|
14
12
|
|
|
15
13
|
const resource = appendContextual<StorageResource>(alias, {
|
|
16
|
-
|
|
14
|
+
/** A bucket object never expires on its own, so `opts.ttl` has nothing to act on here. */
|
|
15
|
+
create: async (record: Partial<StoredRecord>, _opts?: WriteOptions) => {
|
|
17
16
|
if (record.stream == null) {
|
|
18
17
|
throw new FileStreamError('no')
|
|
19
18
|
}
|
|
@@ -75,7 +74,7 @@ export const createStorageResource = (alias: string = DEFAULT_ALIAS, configKey?:
|
|
|
75
74
|
throw new StorageApiError()
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
return record as
|
|
77
|
+
return record as StoredRecord
|
|
79
78
|
}
|
|
80
79
|
})
|
|
81
80
|
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BasicResource } from '@owlmeans/context'
|
|
1
2
|
import type { Resource, ResourceRecord } from '@owlmeans/resource'
|
|
2
3
|
import type { StoredFileFormat } from '@owlmeans/storage-common'
|
|
3
4
|
import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
|
|
@@ -24,8 +25,12 @@ export interface StorageConfig {
|
|
|
24
25
|
basePrefix: string
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* An upload and nothing else. The bucket takes a stream and hands back a URL; there is no record
|
|
30
|
+
* store behind it to read, list or delete against, so the type names the one method that works
|
|
31
|
+
* rather than promising a full {@link Resource} whose rest would only throw.
|
|
32
|
+
*/
|
|
33
|
+
export type StorageResource = Pick<Resource<StoredRecord>, 'create'> & BasicResource
|
|
29
34
|
|
|
30
35
|
export interface Config extends ServerConfig, StoredConfigAppend { }
|
|
31
36
|
export interface Context<C extends Config = Config> extends ServerContext<C> { }
|