@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 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` — extends `Resource<StoredRecord>` for uploading and retrieving files
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.save({
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
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/storage-resource",
4
- "version": "0.1.18-rc.0",
5
- "generatedAt": "2026-08-16T22:20:50.499Z",
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 Resource with file-type detection. Auto-invoked when defining a resource backed by S3/MinIO.
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.0"` in `dependencies`
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
- | `makeStorageResource(options)` | Factory for an S3-compatible storage Resource |
18
- | `StorageResource` types | Resource interface (put/get/delete/list) |
19
- | Helpers | File type detection, content-type sniffing |
20
- | Constants | Default chunk size, max body size |
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 { makeStorageResource } from '@owlmeans/storage-resource'
27
+ import { appendStorageResource } from '@owlmeans/storage-resource'
26
28
 
27
- context.registerResource(makeStorageResource({
28
- alias: 'uploads',
29
- bucket: WL_BUCKET,
30
- }))
29
+ appendStorageResource(context, 'uploads', WL_BUCKET)
31
30
 
32
- // Bucket config from cfg.storageBuckets[WL_BUCKET]
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
- - `@aws-sdk/client-s3` or compatible (runtime)
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
@@ -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,QACnB,KAAK,KAAG,MAgBf,CAAA"}
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"}
@@ -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;AAShF,eAAO,MAAM,qBAAqB,WAAW,MAAM,cAA8B,MAAM,oBAuEtF,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OACrE,CAAC,UAAS,MAAM,cAA8B,MAAM,KACxD,CAMF,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');
@@ -1 +1 @@
1
- {"version":3,"file":"resource.js","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
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
- export interface StorageResource extends Resource<StoredRecord> {
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> {
@@ -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,WAAW,eAAgB,SAAQ,QAAQ,CAAC,YAAY,CAAC;CAC9D;AAED,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"}
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.0",
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.0",
29
- "@owlmeans/error": "^0.1.18-rc.0",
30
- "@owlmeans/resource": "^0.1.18-rc.0",
31
- "@owlmeans/server-context": "^0.1.18-rc.0",
32
- "@owlmeans/storage-common": "^0.1.18-rc.0",
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 { GetterOptions } from '@owlmeans/resource'
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
- create: async <Type extends StoredRecord>(record: Partial<Type>, _opts?: Getter) => {
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 Type
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
- export interface StorageResource extends Resource<StoredRecord> {
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> { }