@toa.io/extensions.exposition 0.24.0-alpha.22 → 0.24.0-alpha.23

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.
Files changed (62) hide show
  1. package/components/context.toa.yaml +1 -1
  2. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
  3. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
  4. package/components/octets.storage/manifest.toa.yaml +1 -0
  5. package/components/octets.storage/operations/store.js +2 -2
  6. package/documentation/octets.md +89 -37
  7. package/features/octets.entries.feature +121 -0
  8. package/features/octets.feature +1 -27
  9. package/features/octets.meta.feature +65 -0
  10. package/features/octets.workflows.feature +105 -4
  11. package/features/steps/Captures.ts +3 -2
  12. package/features/steps/HTTP.ts +1 -1
  13. package/features/steps/Parameters.ts +1 -1
  14. package/features/steps/components/octets.tester/manifest.toa.yaml +1 -0
  15. package/features/steps/components/octets.tester/operations/echo.js +7 -0
  16. package/features/steps/tsconfig.json +1 -1
  17. package/package.json +8 -8
  18. package/schemas/octets/delete.cos.yaml +2 -1
  19. package/schemas/octets/list.cos.yaml +2 -1
  20. package/source/HTTP/Server.ts +18 -4
  21. package/source/HTTP/messages.ts +1 -0
  22. package/source/directives/octets/Delete.ts +45 -6
  23. package/source/directives/octets/Fetch.ts +17 -18
  24. package/source/directives/octets/List.ts +36 -6
  25. package/source/directives/octets/Permute.ts +2 -2
  26. package/source/directives/octets/Store.ts +36 -94
  27. package/source/directives/octets/schemas.ts +11 -6
  28. package/source/directives/octets/workflow/Execution.ts +77 -0
  29. package/source/directives/octets/workflow/Workflow.ts +28 -0
  30. package/source/directives/octets/workflow/index.ts +1 -0
  31. package/source/schemas.ts +7 -3
  32. package/transpiled/HTTP/Server.js +13 -3
  33. package/transpiled/HTTP/Server.js.map +1 -1
  34. package/transpiled/HTTP/messages.d.ts +1 -0
  35. package/transpiled/directives/octets/Delete.d.ts +9 -1
  36. package/transpiled/directives/octets/Delete.js +30 -6
  37. package/transpiled/directives/octets/Delete.js.map +1 -1
  38. package/transpiled/directives/octets/Fetch.d.ts +4 -5
  39. package/transpiled/directives/octets/Fetch.js +11 -12
  40. package/transpiled/directives/octets/Fetch.js.map +1 -1
  41. package/transpiled/directives/octets/List.d.ts +6 -1
  42. package/transpiled/directives/octets/List.js +22 -4
  43. package/transpiled/directives/octets/List.js.map +1 -1
  44. package/transpiled/directives/octets/Permute.js +2 -2
  45. package/transpiled/directives/octets/Permute.js.map +1 -1
  46. package/transpiled/directives/octets/Store.d.ts +7 -19
  47. package/transpiled/directives/octets/Store.js +21 -66
  48. package/transpiled/directives/octets/Store.js.map +1 -1
  49. package/transpiled/directives/octets/schemas.d.ts +11 -6
  50. package/transpiled/directives/octets/schemas.js.map +1 -1
  51. package/transpiled/directives/octets/workflow/Execution.d.ts +24 -0
  52. package/transpiled/directives/octets/workflow/Execution.js +55 -0
  53. package/transpiled/directives/octets/workflow/Execution.js.map +1 -0
  54. package/transpiled/directives/octets/workflow/Workflow.d.ts +11 -0
  55. package/transpiled/directives/octets/workflow/Workflow.js +21 -0
  56. package/transpiled/directives/octets/workflow/Workflow.js.map +1 -0
  57. package/transpiled/directives/octets/workflow/index.d.ts +1 -0
  58. package/transpiled/directives/octets/workflow/index.js +6 -0
  59. package/transpiled/directives/octets/workflow/index.js.map +1 -0
  60. package/transpiled/schemas.d.ts +7 -3
  61. package/transpiled/schemas.js.map +1 -1
  62. package/transpiled/tsconfig.tsbuildinfo +1 -1
@@ -1,10 +1,9 @@
1
- import { Readable } from 'node:stream'
2
- import { posix } from 'node:path'
3
1
  import { match } from 'matchacho'
4
- import { promex } from '@toa.io/generic'
5
2
  import { BadRequest, UnsupportedMediaType } from '../../HTTP'
3
+ import { cors } from '../cors'
6
4
  import * as schemas from './schemas'
7
- import type { Maybe } from '@toa.io/types'
5
+ import { Workflow } from './workflow'
6
+ import type { Unit } from './workflow'
8
7
  import type { Entry } from '@toa.io/extensions.storages'
9
8
  import type { Remotes } from '../../Remotes'
10
9
  import type { ErrorType } from 'error-value'
@@ -15,11 +14,9 @@ import type { Directive, Input } from './types'
15
14
  export class Store implements Directive {
16
15
  public readonly targeted = false
17
16
 
18
- private readonly accept: string | undefined
19
- private readonly workflow: Workflow | undefined
17
+ private readonly accept?: string
18
+ private readonly workflow?: Workflow
20
19
  private readonly discovery: Record<string, Promise<Component>> = {}
21
- private readonly remotes: Remotes
22
- private readonly components: Record<string, Component> = {}
23
20
  private storage: Component | null = null
24
21
 
25
22
  public constructor
@@ -31,19 +28,26 @@ export class Store implements Directive {
31
28
  Array, (types: string[]) => types.join(','),
32
29
  undefined)
33
30
 
34
- this.workflow = match(options?.workflow,
35
- Array, (units: Unit[]) => units,
36
- Object, (unit: Unit) => [unit],
37
- undefined)
31
+ if (options?.workflow !== undefined)
32
+ this.workflow = new Workflow(options.workflow, remotes)
38
33
 
39
34
  this.discovery.storage = discovery
40
- this.remotes = remotes
35
+
36
+ cors.allowHeader('content-meta')
41
37
  }
42
38
 
43
39
  public async apply (storage: string, request: Input): Promise<Output> {
44
40
  this.storage ??= await this.discovery.storage
45
41
 
46
- const input = { storage, request, accept: this.accept }
42
+ const input: StoreInput = { storage, request }
43
+ const meta = request.headers['content-meta']
44
+
45
+ if (this.accept !== undefined)
46
+ input.accept = this.accept
47
+
48
+ if (meta !== undefined)
49
+ input.meta = this.parseMeta(meta)
50
+
47
51
  const entry = await this.storage.invoke<Entry>('store', { input })
48
52
 
49
53
  return match<Output>(entry,
@@ -54,7 +58,7 @@ export class Store implements Directive {
54
58
  private reply (request: Input, storage: string, entry: Entry): Output {
55
59
  const body = this.workflow === undefined
56
60
  ? entry
57
- : Readable.from(this.execute(request, storage, entry))
61
+ : this.workflow.execute(request, storage, entry)
58
62
 
59
63
  return { body }
60
64
  }
@@ -66,93 +70,31 @@ export class Store implements Directive {
66
70
  error)
67
71
  }
68
72
 
69
- /* eslint-disable no-useless-return, max-depth */
70
-
71
- /**
72
- * Execute workflow units sequentially, steps within a unit in parallel.
73
- * Yield results as soon as they come.
74
- *
75
- * If you need to change this, it may take a while.
76
- */
77
- private async * execute (request: Input, storage: string, entry: Entry): AsyncGenerator {
78
- yield entry
79
-
80
- const path = posix.join(request.path, entry.id)
81
- let interrupted = false
82
-
83
- for (const unit of this.workflow!) {
84
- if (interrupted)
85
- break
86
-
87
- const steps = Object.keys(unit)
88
-
89
- // unit result promises queue
90
- const results = Array.from(steps, promex<unknown>)
91
- let next = 0
92
-
93
- // execute steps in parallel
94
- for (const step of steps)
95
- // these promises are indirectly awaited in the yield loop
96
- void (async () => {
97
- const endpoint = unit[step]
98
- const context: Context = { storage, path, entry }
99
- const result = await this.call(endpoint, context)
100
-
101
- if (interrupted)
102
- return
103
-
104
- // as a result is received, resolve the next promise from the queue
105
- const promise = results[next++]
106
-
107
- if (result instanceof Error) {
108
- interrupted = true
109
- promise.resolve({ error: { step, ...result } })
110
-
111
- // cancel pending promises
112
- results[next].resolve(null)
113
- } else
114
- promise.resolve({ [step]: result ?? null })
115
- })().catch((e) => results[next].reject(e))
116
-
117
- // yield results from the queue as they come
118
- for (const promise of results) {
119
- const result = await promise
120
-
121
- if (result === null) // canceled promise
122
- break
123
- else
124
- yield result
125
- }
126
- }
127
- }
128
-
129
- private async call (endpoint: string, context: Context): Promise<Maybe<unknown>> {
130
- const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
131
- const key = `${namespace}.${component}`
73
+ private parseMeta (value: string | string[]): Record<string, string> {
74
+ if (Array.isArray(value))
75
+ value = value.join(',')
132
76
 
133
- this.components[key] ??= await this.discover(key, namespace, component)
77
+ const meta: Record<string, string> = {}
134
78
 
135
- return await this.components[key].invoke(operation, { input: context })
136
- }
79
+ for (const pair of value.split(',')) {
80
+ const eq = pair.indexOf('=')
81
+ const key = (eq === -1 ? pair : pair.slice(0, eq)).trim()
137
82
 
138
- private async discover (key: string, namespace: string, component: string): Promise<Component> {
139
- if (this.discovery[key] === undefined)
140
- this.discovery[key] = this.remotes.discover(namespace, component)
83
+ meta[key] = eq === -1 ? 'true' : pair.slice(eq + 1).trim()
84
+ }
141
85
 
142
- return await this.discovery[key]
86
+ return meta
143
87
  }
144
88
  }
145
89
 
146
- type Unit = Record<string, string>
147
- type Workflow = Unit[]
148
-
149
- interface Options {
150
- accept: string | string[]
151
- workflow: Workflow | Unit
90
+ export interface Options {
91
+ accept?: string | string[]
92
+ workflow?: Unit[] | Unit
152
93
  }
153
94
 
154
- interface Context {
95
+ interface StoreInput {
155
96
  storage: string
156
- path: string
157
- entry: Entry
97
+ request: Input
98
+ accept?: string
99
+ meta?: Record<string, string>
158
100
  }
@@ -1,12 +1,17 @@
1
1
  import { resolve } from 'node:path'
2
2
  import schemas from '@toa.io/schemas'
3
+ import type { Permissions as FetchPermissions } from './Fetch'
4
+ import type { Permissions as ListPermissions } from './List'
5
+ import type { Options as StoreOptions } from './Store'
6
+ import type { Options as DeleteOptions } from './Delete'
7
+ import type { Schema } from '@toa.io/schemas'
3
8
 
4
9
  const path = resolve(__dirname, '../../../schemas/octets')
5
10
  const namespace = schemas.namespace(path)
6
11
 
7
- export const context = namespace.schema('context')
8
- export const store = namespace.schema('store')
9
- export const fetch = namespace.schema('fetch')
10
- export const remove = namespace.schema('delete')
11
- export const list = namespace.schema('list')
12
- export const permute = namespace.schema('permute')
12
+ export const context: Schema<string> = namespace.schema('context')
13
+ export const store: Schema<StoreOptions | null> = namespace.schema('store')
14
+ export const fetch: Schema<FetchPermissions | null> = namespace.schema('fetch')
15
+ export const remove: Schema<DeleteOptions | null> = namespace.schema('delete')
16
+ export const list: Schema<ListPermissions | null> = namespace.schema('list')
17
+ export const permute: Schema<null> = namespace.schema('permute')
@@ -0,0 +1,77 @@
1
+ import { Readable } from 'stream'
2
+ import type { Unit } from './Workflow'
3
+ import type { Remotes } from '../../../Remotes'
4
+ import type { Component } from '@toa.io/core'
5
+ import type { Maybe } from '@toa.io/types'
6
+ import type { Entry } from '@toa.io/extensions.storages'
7
+
8
+ export class Execution extends Readable {
9
+ private readonly units: Unit[]
10
+ private readonly remotes: Remotes
11
+ private readonly context: Context
12
+ private readonly components: Record<string, Component> = {}
13
+ private readonly discovery: Record<string, Promise<Component>> = {}
14
+ private interrupted = false
15
+
16
+ public constructor (context: Context, units: Unit[], remotes: Remotes) {
17
+ super({ objectMode: true })
18
+
19
+ this.context = context
20
+ this.units = units
21
+ this.remotes = remotes
22
+
23
+ void this.run()
24
+ }
25
+
26
+ public override _read (): void {
27
+ }
28
+
29
+ private async run (): Promise<void> {
30
+ this.push(this.context.entry)
31
+
32
+ for (const unit of this.units) {
33
+ await this.execute(unit)
34
+
35
+ if (this.interrupted)
36
+ break
37
+ }
38
+
39
+ this.push(null)
40
+ }
41
+
42
+ private async execute (unit: Unit): Promise<void> {
43
+ const promises = Object.entries(unit).map(async ([step, endpoint]) => {
44
+ const result = await this.call(endpoint)
45
+
46
+ if (result instanceof Error) {
47
+ this.push({ error: { step, ...result } })
48
+ this.interrupted = true
49
+ } else
50
+ this.push({ [step]: result ?? null })
51
+ })
52
+
53
+ await Promise.all(promises)
54
+ }
55
+
56
+ private async call (endpoint: string): Promise<Maybe<unknown>> {
57
+ const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
58
+ const key = `${namespace}.${component}`
59
+
60
+ this.components[key] ??= await this.discover(key, namespace, component)
61
+
62
+ return await this.components[key].invoke(operation, { input: this.context })
63
+ }
64
+
65
+ private async discover (key: string, namespace: string, component: string): Promise<Component> {
66
+ if (this.discovery[key] === undefined)
67
+ this.discovery[key] = this.remotes.discover(namespace, component)
68
+
69
+ return await this.discovery[key]
70
+ }
71
+ }
72
+
73
+ export interface Context {
74
+ storage: string
75
+ path: string
76
+ entry: Entry
77
+ }
@@ -0,0 +1,28 @@
1
+ import { posix } from 'node:path'
2
+ import { match } from 'matchacho'
3
+ import { Execution } from './Execution'
4
+ import type { Input } from '../types'
5
+ import type { Entry } from '@toa.io/extensions.storages'
6
+ import type { Remotes } from '../../../Remotes'
7
+
8
+ export class Workflow {
9
+ private readonly units: Unit[]
10
+ private readonly remotes: Remotes
11
+
12
+ public constructor (units: Unit[] | Unit, remotes: Remotes) {
13
+ this.units = match<Unit[]>(units,
14
+ Array, (units: Unit[]) => units,
15
+ Object, (unit: Unit) => [unit])
16
+
17
+ this.remotes = remotes
18
+ }
19
+
20
+ public execute (request: Input, storage: string, entry: Entry): Execution {
21
+ const path = posix.join(request.path, entry.id)
22
+ const context = { storage, path, entry }
23
+
24
+ return new Execution(context, this.units, this.remotes)
25
+ }
26
+ }
27
+
28
+ export type Unit = Record<string, string>
@@ -0,0 +1 @@
1
+ export { Workflow, type Unit } from './Workflow'
package/source/schemas.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  import { resolve } from 'node:path'
2
2
  import schemas from '@toa.io/schemas'
3
+ import type { Query } from './HTTP'
4
+ import type { Node } from './RTD'
5
+ import type { Schema } from '@toa.io/schemas'
6
+ import type { Annotation } from './Annotation'
3
7
 
4
8
  const path = resolve(__dirname, '../schemas')
5
9
  const namespace = schemas.namespace(path)
6
10
 
7
- export const querystring = namespace.schema('querystring')
8
- export const annotaion = namespace.schema('annotation')
9
- export const node = namespace.schema('node')
11
+ export const querystring: Schema<Query> = namespace.schema('querystring')
12
+ export const annotaion: Schema<Annotation> = namespace.schema('annotation')
13
+ export const node: Schema<Node> = namespace.schema('node')
@@ -64,7 +64,7 @@ class Server extends core_1.Connector {
64
64
  }
65
65
  extend(request) {
66
66
  const message = request;
67
- message.encoder = negotiate(request);
67
+ negotiate(request, message);
68
68
  message.pipelines = { body: [], response: [] };
69
69
  message.parse = async () => {
70
70
  const value = await (0, messages_1.read)(request);
@@ -117,10 +117,19 @@ function supportedMethods(methods) {
117
117
  res.sendStatus(501);
118
118
  };
119
119
  }
120
- function negotiate(request) {
120
+ function negotiate(request, message) {
121
+ if (request.headers.accept !== undefined) {
122
+ const match = SUBTYPE.exec(request.headers.accept);
123
+ if (match !== null) {
124
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
125
+ const { type, subtype, suffix } = match.groups;
126
+ request.headers.accept = `${type}/${suffix}`;
127
+ message.subtype = subtype;
128
+ }
129
+ }
121
130
  const negotiator = new negotiator_1.default(request);
122
131
  const mediaType = negotiator.mediaType(formats_1.types);
123
- return mediaType === undefined ? null : formats_1.formats[mediaType];
132
+ message.encoder = mediaType === undefined ? null : formats_1.formats[mediaType];
124
133
  }
125
134
  // https://github.com/whatwg/fetch/issues/1254
126
135
  async function adam(request) {
@@ -136,4 +145,5 @@ const DEFAULTS = {
136
145
  debug: false,
137
146
  port: 8000
138
147
  };
148
+ const SUBTYPE = /^(?<type>\w{1,32})\/(vnd\.toa\.(?<subtype>\S{1,32})\+)(?<suffix>\S{1,32})$/;
139
149
  //# sourceMappingURL=Server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Server.js","sourceRoot":"","sources":["../../source/HTTP/Server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Server.js","sourceRoot":"","sources":["../../source/HTTP/Server.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ export interface IncomingMessage extends Request {
13
13
  query: Query;
14
14
  parse: <T>() => Promise<T>;
15
15
  encoder: Format | null;
16
+ subtype: string | null;
16
17
  pipelines: {
17
18
  body: Array<(input: unknown) => unknown>;
18
19
  response: Array<(output: OutgoingMessage) => void>;
@@ -1,10 +1,18 @@
1
+ import type { Unit } from './workflow';
1
2
  import type { Component } from '@toa.io/core';
2
3
  import type { Output } from '../../io';
3
4
  import type { Directive, Input } from './types';
5
+ import type { Remotes } from '../../Remotes';
4
6
  export declare class Delete implements Directive {
5
7
  readonly targeted = true;
8
+ private readonly workflow?;
6
9
  private readonly discovery;
7
10
  private storage;
8
- constructor(value: null, discovery: Promise<Component>);
11
+ constructor(options: Options | null, discovery: Promise<Component>, remotes: Remotes);
9
12
  apply(storage: string, request: Input): Promise<Output>;
13
+ private delete;
14
+ private execute;
15
+ }
16
+ export interface Options {
17
+ workflow?: Unit[] | Unit;
10
18
  }
@@ -24,23 +24,47 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Delete = void 0;
27
+ const stream_1 = require("stream");
27
28
  const HTTP_1 = require("../../HTTP");
28
29
  const schemas = __importStar(require("./schemas"));
30
+ const workflow_1 = require("./workflow");
29
31
  class Delete {
30
32
  targeted = true;
33
+ workflow;
31
34
  discovery;
32
35
  storage = null;
33
- constructor(value, discovery) {
34
- schemas.remove.validate(value);
36
+ constructor(options, discovery, remotes) {
37
+ schemas.remove.validate(options);
38
+ if (options?.workflow !== undefined)
39
+ this.workflow = new workflow_1.Workflow(options.workflow, remotes);
35
40
  this.discovery = discovery;
36
41
  }
37
42
  async apply(storage, request) {
38
43
  this.storage ??= await this.discovery;
39
- const input = { storage, path: request.path };
40
- const error = await this.storage.invoke('delete', { input });
41
- if (error instanceof Error)
44
+ const entry = await this.storage.invoke('get', { input: { storage, path: request.url } });
45
+ if (entry instanceof Error)
42
46
  throw new HTTP_1.NotFound();
43
- return {};
47
+ const output = {};
48
+ if (this.workflow !== undefined) {
49
+ output.status = 202;
50
+ output.body = stream_1.Readable.from(this.execute(request, storage, entry));
51
+ }
52
+ else
53
+ await this.delete(storage, request);
54
+ return output;
55
+ }
56
+ async delete(storage, request) {
57
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
58
+ await this.storage.invoke('delete', { input: { storage, path: request.url } });
59
+ }
60
+ async *execute(request, storage, entry) {
61
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
62
+ for await (const chunk of this.workflow.execute(request, storage, entry)) {
63
+ yield chunk;
64
+ if (typeof chunk === 'object' && chunk !== null && 'error' in chunk)
65
+ return;
66
+ }
67
+ await this.delete(storage, request);
44
68
  }
45
69
  }
46
70
  exports.Delete = Delete;
@@ -1 +1 @@
1
- {"version":3,"file":"Delete.js","sourceRoot":"","sources":["../../../source/directives/octets/Delete.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAqC;AACrC,mDAAoC;AAMpC,MAAa,MAAM;IACD,QAAQ,GAAG,IAAI,CAAA;IAEd,SAAS,CAAoB;IACtC,OAAO,GAAqB,IAAI,CAAA;IAExC,YAAoB,KAAW,EAAE,SAA6B;QAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAE9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QACjD,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,CAAA;QAErC,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAA;QAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAiB,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAE5E,IAAI,KAAK,YAAY,KAAK;YACxB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,OAAO,EAAE,CAAA;IACX,CAAC;CACF;AAvBD,wBAuBC"}
1
+ {"version":3,"file":"Delete.js","sourceRoot":"","sources":["../../../source/directives/octets/Delete.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mCAAiC;AACjC,qCAAqC;AACrC,mDAAoC;AACpC,yCAAqC;AASrC,MAAa,MAAM;IACD,QAAQ,GAAG,IAAI,CAAA;IAEd,QAAQ,CAAW;IACnB,SAAS,CAAoB;IACtC,OAAO,GAAqB,IAAI,CAAA;IAExC,YAAoB,OAAuB,EAAE,SAA6B,EAAE,OAAgB;QAC1F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAEhC,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS;YACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAEzD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QACjD,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,CAAA;QAErC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAe,KAAK,EACzD,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QAE5C,IAAI,KAAK,YAAY,KAAK;YACxB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,MAAM,MAAM,GAAW,EAAE,CAAA;QAEzB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAA;YACnB,MAAM,CAAC,IAAI,GAAG,iBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;QACpE,CAAC;;YACC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAErC,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,KAAK,CAAC,MAAM,CAAE,OAAe,EAAE,OAAc;QACnD,oEAAoE;QACpE,MAAM,IAAI,CAAC,OAAQ,CAAC,MAAM,CAAC,QAAQ,EACjC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC9C,CAAC;IAEO,KAAK,CAAC,CAAE,OAAO,CAAE,OAAc,EAAE,OAAe,EAAE,KAAY;QACpE,oEAAoE;QACpE,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,QAAS,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YAC1E,MAAM,KAAK,CAAA;YAEX,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK;gBACjE,OAAM;QACV,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,CAAC;CACF;AArDD,wBAqDC"}
@@ -6,13 +6,12 @@ export declare class Fetch implements Directive {
6
6
  private readonly permissions;
7
7
  private readonly discovery;
8
8
  private storage;
9
- constructor(permissions: Partial<Permissions> | null, discovery: Promise<Component>);
9
+ constructor(permissions: Permissions | null, discovery: Promise<Component>);
10
10
  apply(storage: string, request: Input): Promise<Output>;
11
11
  private fetch;
12
12
  private get;
13
13
  }
14
- interface Permissions {
15
- blob: boolean;
16
- meta: boolean;
14
+ export interface Permissions {
15
+ blob?: boolean;
16
+ meta?: boolean;
17
17
  }
18
- export {};
@@ -39,16 +39,18 @@ class Fetch {
39
39
  }
40
40
  async apply(storage, request) {
41
41
  this.storage ??= await this.discovery;
42
- if (request.url.slice(-5) === ':meta')
43
- return await this.get(storage, request);
44
- else
45
- return await this.fetch(storage, request);
46
- }
47
- async fetch(storage, request) {
48
- const filename = node_path_1.posix.basename(request.url);
49
- const variant = filename.includes('.');
42
+ const variant = node_path_1.posix.basename(request.url).includes('.');
43
+ const metadata = request.subtype === 'octets.entry';
44
+ if (!variant && metadata)
45
+ if (this.permissions.meta)
46
+ return this.get(storage, request);
47
+ else
48
+ throw new HTTP_1.Forbidden('Metadata is not accessible.');
50
49
  if (!variant && !this.permissions.blob)
51
50
  throw new HTTP_1.Forbidden('BLOB variant must be specified.');
51
+ return await this.fetch(storage, request);
52
+ }
53
+ async fetch(storage, request) {
52
54
  if ('if-none-match' in request.headers)
53
55
  return { status: 304 };
54
56
  const input = { storage, path: request.url };
@@ -63,10 +65,7 @@ class Fetch {
63
65
  return { headers, body: result.stream };
64
66
  }
65
67
  async get(storage, request) {
66
- if (!this.permissions.meta)
67
- throw new HTTP_1.Forbidden('Metadata is not accessible.');
68
- const path = request.url.slice(0, -5);
69
- const input = { storage, path };
68
+ const input = { storage, path: request.url };
70
69
  const entry = await this.storage.invoke('get', { input });
71
70
  if (entry instanceof Error)
72
71
  throw new HTTP_1.NotFound();
@@ -1 +1 @@
1
- {"version":3,"file":"Fetch.js","sourceRoot":"","sources":["../../../source/directives/octets/Fetch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAiC;AACjC,qCAAgD;AAChD,mDAAoC;AASpC,MAAa,KAAK;IACA,QAAQ,GAAG,IAAI,CAAA;IAEd,WAAW,GAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IACtD,SAAS,CAAoB;IACtC,OAAO,GAAc,IAA4B,CAAA;IAEzD,YAAoB,WAAwC,EAAE,SAA6B;QACzF,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QAEnC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QAC5C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QACjD,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,CAAA;QAErC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO;YACnC,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;;YAEvC,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;IAEO,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QAClD,MAAM,QAAQ,GAAG,iBAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QAEtC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI;YACpC,MAAM,IAAI,gBAAS,CAAC,iCAAiC,CAAC,CAAA;QAExD,IAAI,eAAe,IAAI,OAAO,CAAC,OAAO;YACpC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;QAExB,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAA;QAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAqB,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAEhF,IAAI,MAAM,YAAY,KAAK;YACzB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;YAC1B,cAAc,EAAE,MAAM,CAAC,IAAI;YAC3B,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;YACxC,IAAI,EAAE,MAAM,CAAC,QAAQ;SACtB,CAAC,CAAA;QAEF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;IACzC,CAAC;IAEO,KAAK,CAAC,GAAG,CAAE,OAAe,EAAE,OAAc;QAChD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI;YACxB,MAAM,IAAI,gBAAS,CAAC,6BAA6B,CAAC,CAAA;QAEpD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAe,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAEvE,IAAI,KAAK,YAAY,KAAK;YACxB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IACxB,CAAC;CACF;AA7DD,sBA6DC"}
1
+ {"version":3,"file":"Fetch.js","sourceRoot":"","sources":["../../../source/directives/octets/Fetch.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAiC;AACjC,qCAAgD;AAChD,mDAAoC;AASpC,MAAa,KAAK;IACA,QAAQ,GAAG,IAAI,CAAA;IAEd,WAAW,GAA0B,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IAChE,SAAS,CAAoB;IACtC,OAAO,GAAc,IAA4B,CAAA;IAEzD,YAAoB,WAA+B,EAAE,SAA6B;QAChF,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QAEnC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QAC5C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QACjD,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,CAAA;QAErC,MAAM,OAAO,GAAG,iBAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,KAAK,cAAc,CAAA;QAEnD,IAAI,CAAC,OAAO,IAAI,QAAQ;YACtB,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI;gBACvB,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;;gBAEjC,MAAM,IAAI,gBAAS,CAAC,6BAA6B,CAAC,CAAA;QAEtD,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI;YACpC,MAAM,IAAI,gBAAS,CAAC,iCAAiC,CAAC,CAAA;QAExD,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;IAEO,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QAClD,IAAI,eAAe,IAAI,OAAO,CAAC,OAAO;YACpC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;QAExB,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAA;QAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAqB,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAEhF,IAAI,MAAM,YAAY,KAAK;YACzB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;YAC1B,cAAc,EAAE,MAAM,CAAC,IAAI;YAC3B,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;YACxC,IAAI,EAAE,MAAM,CAAC,QAAQ;SACtB,CAAC,CAAA;QAEF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;IACzC,CAAC;IAEO,KAAK,CAAC,GAAG,CAAE,OAAe,EAAE,OAAc;QAChD,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAA;QAC5C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAe,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAEvE,IAAI,KAAK,YAAY,KAAK;YACxB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IACxB,CAAC;CACF;AA5DD,sBA4DC"}
@@ -3,8 +3,13 @@ import type { Output } from '../../io';
3
3
  import type { Directive, Input } from './types';
4
4
  export declare class List implements Directive {
5
5
  readonly targeted = false;
6
+ private readonly permissions;
6
7
  private readonly discovery;
7
8
  private storage;
8
- constructor(value: null, discovery: Promise<Component>);
9
+ constructor(permissions: Permissions | null, discovery: Promise<Component>);
9
10
  apply(storage: string, request: Input): Promise<Output>;
11
+ private expand;
12
+ }
13
+ export interface Permissions {
14
+ meta?: boolean;
10
15
  }
@@ -24,23 +24,41 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.List = void 0;
27
+ const node_path_1 = require("node:path");
27
28
  const HTTP_1 = require("../../HTTP");
28
29
  const schemas = __importStar(require("./schemas"));
29
30
  class List {
30
31
  targeted = false;
32
+ permissions = { meta: false };
31
33
  discovery;
32
34
  storage = null;
33
- constructor(value, discovery) {
34
- schemas.remove.validate(value);
35
+ constructor(permissions, discovery) {
36
+ schemas.list.validate(permissions);
37
+ Object.assign(this.permissions, permissions);
35
38
  this.discovery = discovery;
36
39
  }
37
40
  async apply(storage, request) {
38
41
  this.storage ??= await this.discovery;
39
- const input = { storage, path: request.path };
42
+ const metadata = request.subtype === 'octets.entries';
43
+ if (metadata && !this.permissions.meta)
44
+ throw new HTTP_1.Forbidden('Metadata is not accessible.');
45
+ const input = { storage, path: request.url };
40
46
  const list = await this.storage.invoke('list', { input });
41
47
  if (list instanceof Error)
42
48
  throw new HTTP_1.NotFound();
43
- return { body: list };
49
+ const body = metadata
50
+ ? await this.expand(storage, request.url, list)
51
+ : list;
52
+ return { body };
53
+ }
54
+ async expand(storage, prefix, list) {
55
+ const promises = list.map(async (id) => {
56
+ const path = node_path_1.posix.join(prefix, id);
57
+ const input = { storage, path };
58
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- ensured in `apply`
59
+ return this.storage.invoke('get', { input });
60
+ });
61
+ return await Promise.all(promises);
44
62
  }
45
63
  }
46
64
  exports.List = List;
@@ -1 +1 @@
1
- {"version":3,"file":"List.js","sourceRoot":"","sources":["../../../source/directives/octets/List.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAqC;AACrC,mDAAoC;AAOpC,MAAa,IAAI;IACC,QAAQ,GAAG,KAAK,CAAA;IAEf,SAAS,CAAoB;IACtC,OAAO,GAAqB,IAAI,CAAA;IAExC,YAAoB,KAAW,EAAE,SAA6B;QAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAE9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QACjD,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,CAAA;QAErC,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAA;QAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAiB,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAEzE,IAAI,IAAI,YAAY,KAAK;YACvB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IACvB,CAAC;CACF;AAvBD,oBAuBC"}
1
+ {"version":3,"file":"List.js","sourceRoot":"","sources":["../../../source/directives/octets/List.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAiC;AACjC,qCAAgD;AAChD,mDAAoC;AAQpC,MAAa,IAAI;IACC,QAAQ,GAAG,KAAK,CAAA;IAEf,WAAW,GAA0B,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IACpD,SAAS,CAAoB;IACtC,OAAO,GAAqB,IAAI,CAAA;IAExC,YAAoB,WAA+B,EAAE,SAA6B;QAChF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QAElC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QAC5C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,OAAe,EAAE,OAAc;QACjD,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,CAAA;QAErC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,KAAK,gBAAgB,CAAA;QAErD,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI;YACpC,MAAM,IAAI,gBAAS,CAAC,6BAA6B,CAAC,CAAA;QAEpD,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAA;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAkB,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAE1E,IAAI,IAAI,YAAY,KAAK;YACvB,MAAM,IAAI,eAAQ,EAAE,CAAA;QAEtB,MAAM,IAAI,GAAG,QAAQ;YACnB,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC;YAC/C,CAAC,CAAC,IAAI,CAAA;QAER,OAAO,EAAE,IAAI,EAAE,CAAA;IACjB,CAAC;IAEO,KAAK,CAAC,MAAM,CAAE,OAAe,EAAE,MAAc,EAAE,IAAc;QAEnE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,iBAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;YACnC,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;YAE/B,0FAA0F;YAC1F,OAAO,IAAI,CAAC,OAAQ,CAAC,MAAM,CAAe,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAC7D,CAAC,CAAC,CAAA;QAEF,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACpC,CAAC;CACF;AA/CD,oBA+CC"}
@@ -31,14 +31,14 @@ class Permute {
31
31
  discovery;
32
32
  storage = null;
33
33
  constructor(value, discovery) {
34
- schemas.remove.validate(value);
34
+ schemas.permute.validate(value);
35
35
  this.discovery = discovery;
36
36
  }
37
37
  async apply(storage, request) {
38
38
  this.storage ??= await this.discovery;
39
39
  if (request.encoder === null)
40
40
  throw new HTTP_1.NotAcceptable();
41
- const path = request.path;
41
+ const path = request.url;
42
42
  const list = await request.parse();
43
43
  const input = { storage, path, list };
44
44
  const error = await this.storage.invoke('permute', { input });