@occultist/occultist 0.0.9 → 0.0.11
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/dist/actions/context.d.ts +10 -1
- package/dist/actions/context.js +29 -0
- package/dist/registry.d.ts +8 -1
- package/dist/registry.js +21 -0
- package/dist/types.d.ts +41 -1
- package/dist/types.js +1 -0
- package/lib/actions/context.ts +34 -1
- package/lib/registry.ts +28 -1
- package/lib/types.ts +52 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CacheOperation, HandlerDefinition } from "../mod.ts";
|
|
1
|
+
import type { CacheOperation, HandlerDefinition, StaticAsset } from "../mod.ts";
|
|
2
2
|
import type { Registry } from "../registry.ts";
|
|
3
3
|
import type { ActionPayload, ActionSpec, ContextState, ParsedIRIValues } from "./spec.ts";
|
|
4
4
|
import type { AuthState, ImplementedAction } from "./types.ts";
|
|
@@ -84,5 +84,14 @@ export declare class Context<State extends ContextState = ContextState, Auth ext
|
|
|
84
84
|
set status(status: number);
|
|
85
85
|
get body(): undefined | ResponseBody;
|
|
86
86
|
set body(body: ResponseBody);
|
|
87
|
+
/**
|
|
88
|
+
* Returns the public facing URL of a static asset using its
|
|
89
|
+
* static file alias.
|
|
90
|
+
*
|
|
91
|
+
* @param assetAlias The alias of the static asset.
|
|
92
|
+
* @param cspDirective A directive to add the asset to when generating CSP headers.
|
|
93
|
+
* @returns The public facing URL of the static asset.
|
|
94
|
+
*/
|
|
95
|
+
useAsset(assetAlias: string, cspDirective?: string): StaticAsset | undefined;
|
|
87
96
|
get [Symbol.toStringTag](): string;
|
|
88
97
|
}
|
package/dist/actions/context.js
CHANGED
|
@@ -3,6 +3,8 @@ class EditableContext {
|
|
|
3
3
|
etag;
|
|
4
4
|
status;
|
|
5
5
|
body;
|
|
6
|
+
staticAssets = new Map();
|
|
7
|
+
cspDirectives;
|
|
6
8
|
}
|
|
7
9
|
;
|
|
8
10
|
/**
|
|
@@ -121,6 +123,33 @@ export class Context {
|
|
|
121
123
|
set body(body) {
|
|
122
124
|
this.#editable.body = body;
|
|
123
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Returns the public facing URL of a static asset using its
|
|
128
|
+
* static file alias.
|
|
129
|
+
*
|
|
130
|
+
* @param assetAlias The alias of the static asset.
|
|
131
|
+
* @param cspDirective A directive to add the asset to when generating CSP headers.
|
|
132
|
+
* @returns The public facing URL of the static asset.
|
|
133
|
+
*/
|
|
134
|
+
useAsset(assetAlias, cspDirective) {
|
|
135
|
+
const staticAlias = assetAlias.split('/')[0];
|
|
136
|
+
const extension = this.registry.getStaticExtension(staticAlias);
|
|
137
|
+
if (extension == null)
|
|
138
|
+
return;
|
|
139
|
+
const asset = extension.getAsset(assetAlias);
|
|
140
|
+
if (asset == null)
|
|
141
|
+
return;
|
|
142
|
+
this.#editable.staticAssets.set(asset.alias, asset);
|
|
143
|
+
if (typeof cspDirective === 'string' && cspDirective != null) {
|
|
144
|
+
if (!this.#editable.cspDirectives.has(cspDirective)) {
|
|
145
|
+
this.#editable.cspDirectives.set(cspDirective, [asset.alias]);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
this.#editable.cspDirectives.get(cspDirective).push(asset.alias);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return asset;
|
|
152
|
+
}
|
|
124
153
|
get [Symbol.toStringTag]() {
|
|
125
154
|
return `action=${this.action.name} method=${this.method} contentType=${this.contentType}`;
|
|
126
155
|
}
|
package/dist/registry.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { IncomingMessage, type ServerResponse } from "node:http";
|
|
|
7
7
|
import type { Merge } from "./actions/spec.ts";
|
|
8
8
|
import type { ContextState, Middleware } from "./actions/spec.ts";
|
|
9
9
|
import { type CacheOperationResult } from "./mod.ts";
|
|
10
|
-
import type { Extension } from "./types.ts";
|
|
10
|
+
import type { Extension, StaticExtension } from "./types.ts";
|
|
11
11
|
export interface Callable<State extends ContextState = ContextState> {
|
|
12
12
|
method(method: string, name: string, path: string): ActionAuth<State>;
|
|
13
13
|
}
|
|
@@ -249,6 +249,13 @@ export declare class Registry<State extends ContextState = ContextState> impleme
|
|
|
249
249
|
* @returns A NodeJS server response instance.
|
|
250
250
|
*/
|
|
251
251
|
handleRequest(req: IncomingMessage, res: ServerResponse): Promise<ServerResponse>;
|
|
252
|
+
/**
|
|
253
|
+
* Retrieves a static extension by one of the static aliases it uses.
|
|
254
|
+
*
|
|
255
|
+
* @param staticAlias A static alias used to create paths to files served
|
|
256
|
+
* by the static extension.
|
|
257
|
+
*/
|
|
258
|
+
getStaticExtension(staticAlias: string): StaticExtension | undefined;
|
|
252
259
|
/**
|
|
253
260
|
* Registers an Occultist extension. This is usually done
|
|
254
261
|
* by extensions when they are created.
|
package/dist/registry.js
CHANGED
|
@@ -123,6 +123,7 @@ export class Registry {
|
|
|
123
123
|
#actions = null;
|
|
124
124
|
#handlers = null;
|
|
125
125
|
#extensions = [];
|
|
126
|
+
#staticExtensions = new Map();
|
|
126
127
|
constructor(args) {
|
|
127
128
|
const url = new URL(args.rootIRI);
|
|
128
129
|
this.#rootIRI = args.rootIRI;
|
|
@@ -500,6 +501,15 @@ export class Registry {
|
|
|
500
501
|
return res;
|
|
501
502
|
}
|
|
502
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* Retrieves a static extension by one of the static aliases it uses.
|
|
506
|
+
*
|
|
507
|
+
* @param staticAlias A static alias used to create paths to files served
|
|
508
|
+
* by the static extension.
|
|
509
|
+
*/
|
|
510
|
+
getStaticExtension(staticAlias) {
|
|
511
|
+
return this.#staticExtensions.get(staticAlias);
|
|
512
|
+
}
|
|
503
513
|
/**
|
|
504
514
|
* Registers an Occultist extension. This is usually done
|
|
505
515
|
* by extensions when they are created.
|
|
@@ -507,6 +517,17 @@ export class Registry {
|
|
|
507
517
|
* @param The Occultist extension to register.
|
|
508
518
|
*/
|
|
509
519
|
registerExtension(extension) {
|
|
520
|
+
let staticAlias;
|
|
521
|
+
if (typeof extension.getAsset === 'function' &&
|
|
522
|
+
Array.isArray(extension.staticAliases)) {
|
|
523
|
+
for (let i = 0; i < extension.staticAliases.length; i++) {
|
|
524
|
+
staticAlias = extension.staticAliases[i];
|
|
525
|
+
if (this.#staticExtensions.has(staticAlias)) {
|
|
526
|
+
throw new Error(`Static alias '${staticAlias}' already used by other extension`);
|
|
527
|
+
}
|
|
528
|
+
this.#staticExtensions.set(staticAlias, extension);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
510
531
|
this.#extensions.push(extension);
|
|
511
532
|
}
|
|
512
533
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,50 @@
|
|
|
1
|
+
export interface StaticAsset {
|
|
2
|
+
alias: string;
|
|
3
|
+
contentType: string;
|
|
4
|
+
url: string;
|
|
5
|
+
integrity?: string;
|
|
6
|
+
}
|
|
1
7
|
export interface StaticContext {
|
|
2
8
|
link(alias: string, as: string): string;
|
|
3
9
|
}
|
|
4
10
|
export interface Extension {
|
|
11
|
+
/**
|
|
12
|
+
* The name of the extension.
|
|
13
|
+
*/
|
|
5
14
|
name: string;
|
|
15
|
+
/**
|
|
16
|
+
* Setup method which can perform async setup tasks
|
|
17
|
+
* and report status via a readable stream.
|
|
18
|
+
*/
|
|
6
19
|
setup?(): ReadableStream;
|
|
7
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Retrieves a static assets from the extension.
|
|
22
|
+
*
|
|
23
|
+
* @param assetAlias The alias for the asset.
|
|
24
|
+
*/
|
|
25
|
+
getAsset?(assetAlias: string): StaticAsset | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Root level aliases the extension uses to identify
|
|
28
|
+
* the assets it manages.
|
|
29
|
+
*/
|
|
30
|
+
staticAliases?: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface StaticExtension {
|
|
33
|
+
/**
|
|
34
|
+
* The name of the extension.
|
|
35
|
+
*/
|
|
36
|
+
name: string;
|
|
37
|
+
/**
|
|
38
|
+
* Root level aliases the extension uses to identify
|
|
39
|
+
* assets it manages.
|
|
40
|
+
*/
|
|
41
|
+
staticAliases: string[];
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves a static assets from the extension.
|
|
44
|
+
*
|
|
45
|
+
* @param assetAlias The alias for the asset.
|
|
46
|
+
*/
|
|
47
|
+
getAsset(assetAlias: string): StaticAsset | undefined;
|
|
8
48
|
}
|
|
9
49
|
export type ProblemDetailsParam = {
|
|
10
50
|
name: string;
|
package/dist/types.js
CHANGED
package/lib/actions/context.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {CacheOperation, HandlerDefinition} from "../mod.ts";
|
|
1
|
+
import type {CacheOperation, HandlerDefinition, StaticAsset} from "../mod.ts";
|
|
2
2
|
import type {Registry} from "../registry.ts";
|
|
3
3
|
import type {ActionPayload, ActionSpec, ContextState, ParsedIRIValues} from "./spec.ts";
|
|
4
4
|
import type {AuthState, ImplementedAction} from "./types.ts";
|
|
@@ -10,6 +10,8 @@ class EditableContext {
|
|
|
10
10
|
etag?: string;
|
|
11
11
|
status?: number;
|
|
12
12
|
body?: ResponseBody;
|
|
13
|
+
staticAssets: Map<string, StaticAsset> = new Map();
|
|
14
|
+
cspDirectives: Map<string, string[]>;
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
export type CacheContextArgs<
|
|
@@ -187,6 +189,37 @@ export class Context<
|
|
|
187
189
|
this.#editable.body = body;
|
|
188
190
|
}
|
|
189
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Returns the public facing URL of a static asset using its
|
|
194
|
+
* static file alias.
|
|
195
|
+
*
|
|
196
|
+
* @param assetAlias The alias of the static asset.
|
|
197
|
+
* @param cspDirective A directive to add the asset to when generating CSP headers.
|
|
198
|
+
* @returns The public facing URL of the static asset.
|
|
199
|
+
*/
|
|
200
|
+
useAsset(assetAlias: string, cspDirective?: string): StaticAsset | undefined {
|
|
201
|
+
const staticAlias = assetAlias.split('/')[0];
|
|
202
|
+
const extension = this.registry.getStaticExtension(staticAlias);
|
|
203
|
+
|
|
204
|
+
if (extension == null) return;
|
|
205
|
+
|
|
206
|
+
const asset = extension.getAsset(assetAlias);
|
|
207
|
+
|
|
208
|
+
if (asset == null) return;
|
|
209
|
+
|
|
210
|
+
this.#editable.staticAssets.set(asset.alias, asset);
|
|
211
|
+
|
|
212
|
+
if (typeof cspDirective === 'string' && cspDirective != null) {
|
|
213
|
+
if (!this.#editable.cspDirectives.has(cspDirective)) {
|
|
214
|
+
this.#editable.cspDirectives.set(cspDirective, [asset.alias]);
|
|
215
|
+
} else {
|
|
216
|
+
this.#editable.cspDirectives.get(cspDirective).push(asset.alias);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return asset;
|
|
221
|
+
}
|
|
222
|
+
|
|
190
223
|
get [Symbol.toStringTag]() {
|
|
191
224
|
return `action=${this.action.name} method=${this.method} contentType=${this.contentType}`;
|
|
192
225
|
}
|
package/lib/registry.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { ContextState, Middleware } from "./actions/spec.ts";
|
|
|
11
11
|
import {ProblemDetailsError} from "./errors.ts"
|
|
12
12
|
import {WrappedRequest} from "./request.ts";
|
|
13
13
|
import {type CacheOperationResult} from "./mod.ts";
|
|
14
|
-
import type {Extension} from "./types.ts";
|
|
14
|
+
import type {Extension, StaticExtension} from "./types.ts";
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
export interface Callable<
|
|
@@ -189,6 +189,7 @@ export class Registry<
|
|
|
189
189
|
#actions: ImplementedAction[] | null = null;
|
|
190
190
|
#handlers: HandlerDefinition[] | null = null;
|
|
191
191
|
#extensions: Extension[] = [];
|
|
192
|
+
#staticExtensions: Map<string, StaticExtension> = new Map();
|
|
192
193
|
|
|
193
194
|
constructor(args: RegistryArgs) {
|
|
194
195
|
const url = new URL(args.rootIRI);
|
|
@@ -733,6 +734,16 @@ export class Registry<
|
|
|
733
734
|
}
|
|
734
735
|
}
|
|
735
736
|
|
|
737
|
+
/**
|
|
738
|
+
* Retrieves a static extension by one of the static aliases it uses.
|
|
739
|
+
*
|
|
740
|
+
* @param staticAlias A static alias used to create paths to files served
|
|
741
|
+
* by the static extension.
|
|
742
|
+
*/
|
|
743
|
+
getStaticExtension(staticAlias: string): StaticExtension | undefined {
|
|
744
|
+
return this.#staticExtensions.get(staticAlias);
|
|
745
|
+
}
|
|
746
|
+
|
|
736
747
|
/**
|
|
737
748
|
* Registers an Occultist extension. This is usually done
|
|
738
749
|
* by extensions when they are created.
|
|
@@ -740,6 +751,22 @@ export class Registry<
|
|
|
740
751
|
* @param The Occultist extension to register.
|
|
741
752
|
*/
|
|
742
753
|
registerExtension(extension: Extension): void {
|
|
754
|
+
let staticAlias: string;
|
|
755
|
+
if (
|
|
756
|
+
typeof extension.getAsset === 'function' &&
|
|
757
|
+
Array.isArray(extension.staticAliases)
|
|
758
|
+
) {
|
|
759
|
+
for (let i = 0; i < extension.staticAliases.length; i++) {
|
|
760
|
+
staticAlias = extension.staticAliases[i];
|
|
761
|
+
|
|
762
|
+
if (this.#staticExtensions.has(staticAlias)) {
|
|
763
|
+
throw new Error(`Static alias '${staticAlias}' already used by other extension`);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
this.#staticExtensions.set(staticAlias, extension as StaticExtension);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
743
770
|
this.#extensions.push(extension);
|
|
744
771
|
}
|
|
745
772
|
|
package/lib/types.ts
CHANGED
|
@@ -1,14 +1,65 @@
|
|
|
1
1
|
|
|
2
|
+
export interface StaticAsset {
|
|
3
|
+
alias: string;
|
|
4
|
+
contentType: string;
|
|
5
|
+
url: string;
|
|
6
|
+
integrity?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
2
9
|
export interface StaticContext {
|
|
3
10
|
link(alias: string, as: string): string;
|
|
4
11
|
}
|
|
5
12
|
|
|
6
13
|
export interface Extension {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The name of the extension.
|
|
17
|
+
*/
|
|
7
18
|
name: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Setup method which can perform async setup tasks
|
|
22
|
+
* and report status via a readable stream.
|
|
23
|
+
*/
|
|
8
24
|
setup?(): ReadableStream;
|
|
9
|
-
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Retrieves a static assets from the extension.
|
|
28
|
+
*
|
|
29
|
+
* @param assetAlias The alias for the asset.
|
|
30
|
+
*/
|
|
31
|
+
getAsset?(assetAlias: string): StaticAsset | undefined;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Root level aliases the extension uses to identify
|
|
35
|
+
* the assets it manages.
|
|
36
|
+
*/
|
|
37
|
+
staticAliases?: string[];
|
|
38
|
+
|
|
10
39
|
};
|
|
11
40
|
|
|
41
|
+
export interface StaticExtension {
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The name of the extension.
|
|
45
|
+
*/
|
|
46
|
+
name: string;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Root level aliases the extension uses to identify
|
|
50
|
+
* assets it manages.
|
|
51
|
+
*/
|
|
52
|
+
staticAliases: string[];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Retrieves a static assets from the extension.
|
|
56
|
+
*
|
|
57
|
+
* @param assetAlias The alias for the asset.
|
|
58
|
+
*/
|
|
59
|
+
getAsset(assetAlias: string): StaticAsset | undefined;
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
12
63
|
export type ProblemDetailsParam = {
|
|
13
64
|
name: string;
|
|
14
65
|
reason: string;
|