@occultist/occultist 0.0.1
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/LICENSE +21 -0
- package/README.md +144 -0
- package/dist/accept.d.ts +41 -0
- package/dist/accept.js +110 -0
- package/dist/accept.test.d.ts +1 -0
- package/dist/accept.test.js +44 -0
- package/dist/action.test.d.ts +1 -0
- package/dist/action.test.js +1 -0
- package/dist/actions/actionSets.d.ts +23 -0
- package/dist/actions/actionSets.js +49 -0
- package/dist/actions/actions.d.ts +163 -0
- package/dist/actions/actions.js +436 -0
- package/dist/actions/context.d.ts +78 -0
- package/dist/actions/context.js +112 -0
- package/dist/actions/meta.d.ts +49 -0
- package/dist/actions/meta.js +177 -0
- package/dist/actions/path.d.ts +21 -0
- package/dist/actions/path.js +83 -0
- package/dist/actions/path.test.d.ts +1 -0
- package/dist/actions/path.test.js +9 -0
- package/dist/actions/spec.d.ts +214 -0
- package/dist/actions/spec.js +1 -0
- package/dist/actions/types.d.ts +112 -0
- package/dist/actions/types.js +2 -0
- package/dist/actions/writer.d.ts +27 -0
- package/dist/actions/writer.js +140 -0
- package/dist/actions/writer.test.d.ts +1 -0
- package/dist/actions/writer.test.js +42 -0
- package/dist/auth/types.d.ts +14 -0
- package/dist/auth/types.js +1 -0
- package/dist/cache/cache.d.ts +30 -0
- package/dist/cache/cache.js +220 -0
- package/dist/cache/etag.d.ts +17 -0
- package/dist/cache/etag.js +83 -0
- package/dist/cache/etag.test.d.ts +1 -0
- package/dist/cache/etag.test.js +91 -0
- package/dist/cache/memory.d.ts +12 -0
- package/dist/cache/memory.js +36 -0
- package/dist/cache/types.d.ts +175 -0
- package/dist/cache/types.js +4 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +54 -0
- package/dist/jsonld.d.ts +43 -0
- package/dist/jsonld.js +1 -0
- package/dist/makeTypeDefs.d.ts +27 -0
- package/dist/makeTypeDefs.js +70 -0
- package/dist/merge.d.ts +61 -0
- package/dist/merge.js +1 -0
- package/dist/mod.d.ts +14 -0
- package/dist/mod.js +14 -0
- package/dist/processAction.d.ts +15 -0
- package/dist/processAction.js +512 -0
- package/dist/registry.d.ts +88 -0
- package/dist/registry.js +314 -0
- package/dist/registry.test.d.ts +1 -0
- package/dist/registry.test.js +133 -0
- package/dist/request.d.ts +29 -0
- package/dist/request.js +118 -0
- package/dist/scopes.d.ts +35 -0
- package/dist/scopes.js +121 -0
- package/dist/scopes.test.d.ts +1 -0
- package/dist/scopes.test.js +55 -0
- package/dist/transformers/fileTransformer.d.ts +1 -0
- package/dist/transformers/fileTransformer.js +8 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.js +1 -0
- package/dist/utils/alwaysArray.d.ts +1 -0
- package/dist/utils/alwaysArray.js +9 -0
- package/dist/utils/contextBuilder.d.ts +9 -0
- package/dist/utils/contextBuilder.js +82 -0
- package/dist/utils/getActionContext.d.ts +7 -0
- package/dist/utils/getActionContext.js +48 -0
- package/dist/utils/getInternalName.d.ts +6 -0
- package/dist/utils/getInternalName.js +7 -0
- package/dist/utils/getParamLocation.d.ts +2 -0
- package/dist/utils/getParamLocation.js +6 -0
- package/dist/utils/getPropertyValueSpecifications.d.ts +2 -0
- package/dist/utils/getPropertyValueSpecifications.js +49 -0
- package/dist/utils/getRequestBodyValues.d.ts +11 -0
- package/dist/utils/getRequestBodyValues.js +122 -0
- package/dist/utils/getRequestIRIValues.d.ts +14 -0
- package/dist/utils/getRequestIRIValues.js +133 -0
- package/dist/utils/isBodyInit.d.ts +1 -0
- package/dist/utils/isBodyInit.js +21 -0
- package/dist/utils/isNil.d.ts +1 -0
- package/dist/utils/isNil.js +4 -0
- package/dist/utils/isObject.d.ts +6 -0
- package/dist/utils/isObject.js +6 -0
- package/dist/utils/isPopulatedObject.d.ts +5 -0
- package/dist/utils/isPopulatedObject.js +8 -0
- package/dist/utils/isPopulatedString.d.ts +1 -0
- package/dist/utils/isPopulatedString.js +4 -0
- package/dist/utils/joinPaths.d.ts +1 -0
- package/dist/utils/joinPaths.js +31 -0
- package/dist/utils/makeAppendProblemDetails.d.ts +14 -0
- package/dist/utils/makeAppendProblemDetails.js +26 -0
- package/dist/utils/makeURLPattern.d.ts +5 -0
- package/dist/utils/makeURLPattern.js +12 -0
- package/dist/utils/normalizeURL.d.ts +4 -0
- package/dist/utils/normalizeURL.js +11 -0
- package/dist/utils/parseSearchParams.d.ts +3 -0
- package/dist/utils/parseSearchParams.js +24 -0
- package/dist/utils/preferredMediaTypes.d.ts +42 -0
- package/dist/utils/preferredMediaTypes.js +149 -0
- package/dist/utils/urlToIRI.d.ts +1 -0
- package/dist/utils/urlToIRI.js +8 -0
- package/dist/utils/validateSpecValue.d.ts +1 -0
- package/dist/utils/validateSpecValue.js +1 -0
- package/dist/validators.d.ts +16 -0
- package/dist/validators.js +134 -0
- package/lib/accept.test.ts +55 -0
- package/lib/accept.ts +147 -0
- package/lib/action.test.ts +2 -0
- package/lib/actions/actionSets.ts +88 -0
- package/lib/actions/actions.ts +795 -0
- package/lib/actions/context.ts +170 -0
- package/lib/actions/meta.ts +251 -0
- package/lib/actions/path.test.ts +15 -0
- package/lib/actions/path.ts +99 -0
- package/lib/actions/spec.ts +545 -0
- package/lib/actions/types.ts +146 -0
- package/lib/actions/writer.test.ts +57 -0
- package/lib/actions/writer.ts +176 -0
- package/lib/auth/types.ts +22 -0
- package/lib/cache/cache.ts +291 -0
- package/lib/cache/etag.test.ts +122 -0
- package/lib/cache/etag.ts +106 -0
- package/lib/cache/memory.ts +52 -0
- package/lib/cache/types.ts +240 -0
- package/lib/errors.ts +66 -0
- package/lib/jsonld.ts +67 -0
- package/lib/makeTypeDefs.ts +138 -0
- package/lib/merge.ts +86 -0
- package/lib/mod.ts +14 -0
- package/lib/processAction.ts +690 -0
- package/lib/registry.test.ts +174 -0
- package/lib/registry.ts +455 -0
- package/lib/request.ts +153 -0
- package/lib/scopes.test.ts +70 -0
- package/lib/scopes.ts +178 -0
- package/lib/transformers/fileTransformer.ts +10 -0
- package/lib/types.ts +13 -0
- package/lib/utils/alwaysArray.ts +10 -0
- package/lib/utils/contextBuilder.ts +111 -0
- package/lib/utils/getActionContext.ts +76 -0
- package/lib/utils/getInternalName.ts +15 -0
- package/lib/utils/getParamLocation.ts +14 -0
- package/lib/utils/getPropertyValueSpecifications.ts +76 -0
- package/lib/utils/getRequestBodyValues.ts +155 -0
- package/lib/utils/getRequestIRIValues.ts +201 -0
- package/lib/utils/isBodyInit.ts +22 -0
- package/lib/utils/isNil.ts +4 -0
- package/lib/utils/isObject.ts +8 -0
- package/lib/utils/isPopulatedObject.ts +9 -0
- package/lib/utils/isPopulatedString.ts +4 -0
- package/lib/utils/joinPaths.ts +36 -0
- package/lib/utils/makeAppendProblemDetails.ts +57 -0
- package/lib/utils/makeURLPattern.ts +18 -0
- package/lib/utils/normalizeURL.ts +15 -0
- package/lib/utils/parseSearchParams.ts +36 -0
- package/lib/utils/preferredMediaTypes.ts +220 -0
- package/lib/utils/urlToIRI.ts +11 -0
- package/lib/utils/validateSpecValue.ts +0 -0
- package/lib/validators.ts +186 -0
- package/package.json +41 -0
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
import {CacheInstanceArgs} from '../cache/types.js';
|
|
2
|
+
import type {JSONLDContext, JSONObject, TypeDef} from "../jsonld.js";
|
|
3
|
+
import type {Registry} from '../registry.js';
|
|
4
|
+
import type {Scope} from "../scopes.js";
|
|
5
|
+
import {getActionContext} from "../utils/getActionContext.js";
|
|
6
|
+
import {getPropertyValueSpecifications} from "../utils/getPropertyValueSpecifications.js";
|
|
7
|
+
import {isPopulatedObject} from '../utils/isPopulatedObject.js';
|
|
8
|
+
import {joinPaths} from "../utils/joinPaths.js";
|
|
9
|
+
import {AfterDefinition, BeforeDefinition, type ActionMeta} from "./meta.js";
|
|
10
|
+
import type {ActionSpec, ContextState} from "./spec.js";
|
|
11
|
+
import type {HandlerArgs, HandleRequestArgs, HandlerFn, HandlerMeta, HandlerObj, HandlerValue, HintArgs, ImplementedAction} from './types.js';
|
|
12
|
+
import {ResponseTypes} from './writer.js';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export type DefineArgs<
|
|
16
|
+
Term extends string = string,
|
|
17
|
+
Spec extends ActionSpec = ActionSpec,
|
|
18
|
+
> = {
|
|
19
|
+
typeDef?: TypeDef<Term>
|
|
20
|
+
spec?: Spec;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
function isHandlerObj<
|
|
25
|
+
State extends ContextState = ContextState,
|
|
26
|
+
Spec extends ActionSpec = ActionSpec
|
|
27
|
+
>(handler: unknown): handler is HandlerObj<State, Spec> {
|
|
28
|
+
return isPopulatedObject(handler);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A handler definition which can be pulled from a registry, scope or action
|
|
33
|
+
* after an action is defined.
|
|
34
|
+
*/
|
|
35
|
+
export class HandlerDefinition<
|
|
36
|
+
State extends ContextState = ContextState,
|
|
37
|
+
Spec extends ActionSpec = ActionSpec,
|
|
38
|
+
> {
|
|
39
|
+
name: string;
|
|
40
|
+
contentType: string;
|
|
41
|
+
handler: HandlerFn | HandlerValue;
|
|
42
|
+
meta: HandlerMeta;
|
|
43
|
+
action: ImplementedAction<State, Spec>;
|
|
44
|
+
cache: ReadonlyArray<CacheInstanceArgs>;
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
name: string,
|
|
48
|
+
contentType: string,
|
|
49
|
+
handler: HandlerFn | HandlerValue,
|
|
50
|
+
meta: HandlerMeta,
|
|
51
|
+
action: ImplementedAction<State, Spec>,
|
|
52
|
+
actionMeta: ActionMeta,
|
|
53
|
+
) {
|
|
54
|
+
this.name = name;
|
|
55
|
+
this.contentType = contentType;
|
|
56
|
+
this.handler = handler;
|
|
57
|
+
this.action = action;
|
|
58
|
+
this.meta = Object.freeze({ ...meta ?? {} });
|
|
59
|
+
|
|
60
|
+
const cache: CacheInstanceArgs[] = [];
|
|
61
|
+
|
|
62
|
+
for (let i = 0; i < actionMeta.cache.length; i++) {
|
|
63
|
+
cache.push(Object.freeze({ ...actionMeta.cache[i] }));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.cache = Object.freeze(cache);
|
|
67
|
+
|
|
68
|
+
Object.freeze(this);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get [Symbol.toStringTag]() {
|
|
72
|
+
return `name=${this.name} contentType=${this.contentType}`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface Handleable<
|
|
77
|
+
State extends ContextState = ContextState,
|
|
78
|
+
Spec extends ActionSpec = ActionSpec,
|
|
79
|
+
> {
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Defines the final handler for this content type.
|
|
83
|
+
*
|
|
84
|
+
* An action can have multiple handlers defined
|
|
85
|
+
* each for a different set of content types.
|
|
86
|
+
*/
|
|
87
|
+
handle(
|
|
88
|
+
contentType: string | string[],
|
|
89
|
+
handler: HandlerValue | HandlerFn<State, Spec>,
|
|
90
|
+
): FinalizedAction<State, Spec>;
|
|
91
|
+
|
|
92
|
+
handle(
|
|
93
|
+
args: HandlerObj<State, Spec>,
|
|
94
|
+
): FinalizedAction<State, Spec>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export class FinalizedAction<
|
|
98
|
+
State extends ContextState = ContextState,
|
|
99
|
+
Spec extends ActionSpec = ActionSpec,
|
|
100
|
+
> implements
|
|
101
|
+
Handleable<State, Spec>,
|
|
102
|
+
ImplementedAction<State, Spec>
|
|
103
|
+
{
|
|
104
|
+
#spec: Spec;
|
|
105
|
+
#meta: ActionMeta<State, Spec>;
|
|
106
|
+
#typeDef?: TypeDef;
|
|
107
|
+
#handlers: Map<string, HandlerDefinition<State, Spec>>;
|
|
108
|
+
|
|
109
|
+
constructor(
|
|
110
|
+
typeDef: TypeDef | undefined,
|
|
111
|
+
spec: Spec,
|
|
112
|
+
meta: ActionMeta<State, Spec>,
|
|
113
|
+
handlerArgs: HandlerObj<State, Spec>,
|
|
114
|
+
) {
|
|
115
|
+
this.#typeDef = typeDef;
|
|
116
|
+
this.#spec = spec ?? {} as Spec;
|
|
117
|
+
this.#meta = meta;
|
|
118
|
+
|
|
119
|
+
this.#meta.action = this as unknown as ImplementedAction<State, Spec>;
|
|
120
|
+
|
|
121
|
+
const handlers: Map<string, HandlerDefinition<State, Spec>> = new Map();
|
|
122
|
+
|
|
123
|
+
if (typeof handlerArgs.contentType === 'string') {
|
|
124
|
+
handlers.set(handlerArgs.contentType, new HandlerDefinition(
|
|
125
|
+
this.name,
|
|
126
|
+
handlerArgs.contentType,
|
|
127
|
+
handlerArgs.handler,
|
|
128
|
+
handlerArgs.meta,
|
|
129
|
+
this as unknown as ImplementedAction<State, Spec>,
|
|
130
|
+
this.#meta,
|
|
131
|
+
));
|
|
132
|
+
} else if (isPopulatedObject(handlerArgs)) {
|
|
133
|
+
for (let i = 0; i < handlerArgs.contentType.length; i++) {
|
|
134
|
+
handlers.set(handlerArgs.contentType[i], new HandlerDefinition(
|
|
135
|
+
this.name,
|
|
136
|
+
handlerArgs.contentType[i],
|
|
137
|
+
handlerArgs.handler,
|
|
138
|
+
handlerArgs.meta,
|
|
139
|
+
this as unknown as ImplementedAction<State, Spec>,
|
|
140
|
+
this.#meta,
|
|
141
|
+
));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this.#handlers = handlers;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
static fromHandlers<
|
|
149
|
+
State extends ContextState = ContextState,
|
|
150
|
+
Spec extends ActionSpec = ActionSpec,
|
|
151
|
+
>(
|
|
152
|
+
typeDef: TypeDef | undefined,
|
|
153
|
+
spec: Spec,
|
|
154
|
+
meta: ActionMeta<State, Spec>,
|
|
155
|
+
contextType: string | string[],
|
|
156
|
+
handler: HandlerValue | HandlerFn<State, Spec>,
|
|
157
|
+
): FinalizedAction<State, Spec>;
|
|
158
|
+
|
|
159
|
+
static fromHandlers<
|
|
160
|
+
State extends ContextState = ContextState,
|
|
161
|
+
Spec extends ActionSpec = ActionSpec,
|
|
162
|
+
>(
|
|
163
|
+
typeDef: TypeDef | undefined,
|
|
164
|
+
spec: Spec,
|
|
165
|
+
meta: ActionMeta<State, Spec>,
|
|
166
|
+
handlerArgs: HandlerObj<State, Spec>,
|
|
167
|
+
): FinalizedAction<State, Spec>;
|
|
168
|
+
|
|
169
|
+
static fromHandlers<
|
|
170
|
+
State extends ContextState = ContextState,
|
|
171
|
+
Spec extends ActionSpec = ActionSpec,
|
|
172
|
+
>(
|
|
173
|
+
typeDef: TypeDef | undefined,
|
|
174
|
+
spec: Spec,
|
|
175
|
+
meta: ActionMeta<State, Spec>,
|
|
176
|
+
arg3: string | string[] | HandlerObj<State, Spec>,
|
|
177
|
+
arg4?: HandlerValue | HandlerFn<State, Spec>,
|
|
178
|
+
): FinalizedAction<State, Spec> {
|
|
179
|
+
if (Array.isArray(arg3) || typeof arg3 === 'string') {
|
|
180
|
+
return new FinalizedAction<State, Spec>(typeDef, spec, meta, {
|
|
181
|
+
contentType: arg3,
|
|
182
|
+
handler: arg4,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return new FinalizedAction(typeDef, spec, meta, arg3);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
static async toJSONLD(
|
|
190
|
+
action: ImplementedAction,
|
|
191
|
+
scope: Scope,
|
|
192
|
+
): Promise<JSONObject | null> {
|
|
193
|
+
if (scope == null || action.typeDef == null) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const apiSpec = await getPropertyValueSpecifications(action.spec);
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
'@context': action.context,
|
|
201
|
+
'@id': joinPaths(action.registry.rootIRI, scope.path, action.name),
|
|
202
|
+
'@type': action.term,
|
|
203
|
+
target: {
|
|
204
|
+
'@type': 'https://schema.org/EntryPoint',
|
|
205
|
+
httpMethod: action.method,
|
|
206
|
+
urlTemplate: action.template,
|
|
207
|
+
contentType: 'application/ld+json',
|
|
208
|
+
},
|
|
209
|
+
...apiSpec,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
get public(): boolean {
|
|
214
|
+
return this.#meta.public;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
get method(): string {
|
|
218
|
+
return this.#meta.method;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
get term(): string | undefined {
|
|
222
|
+
return this.#typeDef?.term;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
get type(): string | undefined {
|
|
226
|
+
return this.#typeDef?.type;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
get typeDef(): TypeDef | undefined {
|
|
230
|
+
return this.#typeDef;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
get name(): string {
|
|
234
|
+
return this.#meta.name;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
get template(): string {
|
|
238
|
+
return this.#meta.uriTemplate;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
get pattern(): URLPattern {
|
|
242
|
+
return this.#meta.path.pattern;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
get spec(): Spec {
|
|
246
|
+
return this.#spec;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
get scope(): Scope | undefined {
|
|
250
|
+
return this.#meta.scope
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
get registry(): Registry {
|
|
254
|
+
return this.#meta.registry;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
get handlers(): HandlerDefinition<State, Spec>[] {
|
|
258
|
+
return Array.from(this.#handlers.values());
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
get contentTypes(): string[] {
|
|
262
|
+
return Array.from(this.#handlers.keys());
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
get context(): JSONObject {
|
|
266
|
+
return getActionContext({
|
|
267
|
+
spec: this.#spec,
|
|
268
|
+
//vocab: this.#vocab,
|
|
269
|
+
//aliases: this.#aliases,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
url(): string {
|
|
274
|
+
return joinPaths(this.#meta.registry.rootIRI, this.#meta.path.normalized);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
jsonld(): Promise<JSONObject | null> {
|
|
278
|
+
const scope = this.#meta.scope;
|
|
279
|
+
|
|
280
|
+
return FinalizedAction.toJSONLD(
|
|
281
|
+
this as unknown as ImplementedAction,
|
|
282
|
+
scope
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
jsonldPartial(): { '@type': string, '@id': string } | null {
|
|
287
|
+
const scope = this.#meta.scope;
|
|
288
|
+
const typeDef = this.#typeDef;
|
|
289
|
+
|
|
290
|
+
if (scope == null || typeDef == null) {
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
'@type': typeDef.type,
|
|
296
|
+
'@id': joinPaths(scope.url(), this.#meta.name),
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
handle(
|
|
301
|
+
contentType: string | string[],
|
|
302
|
+
handler: HandlerFn<State, Spec> | HandlerValue,
|
|
303
|
+
): FinalizedAction<State, Spec>;
|
|
304
|
+
|
|
305
|
+
handle(
|
|
306
|
+
args: HandlerObj<State, Spec>,
|
|
307
|
+
): FinalizedAction<State, Spec>;
|
|
308
|
+
|
|
309
|
+
handle(
|
|
310
|
+
arg1: string | string[] | HandlerObj<State, Spec>,
|
|
311
|
+
arg2?: HandlerFn<State, Spec>,
|
|
312
|
+
): FinalizedAction<State, Spec> {
|
|
313
|
+
let contentType: string | string[];
|
|
314
|
+
let handler: HandlerFn<State, Spec> | HandlerValue;
|
|
315
|
+
let meta: HandlerMeta;
|
|
316
|
+
|
|
317
|
+
if (isHandlerObj(arg1)) {
|
|
318
|
+
contentType = arg1.contentType;
|
|
319
|
+
handler = arg1.handler;
|
|
320
|
+
meta = Object.assign(Object.create(null), arg1.meta);
|
|
321
|
+
|
|
322
|
+
if (arg1.meta != null) {
|
|
323
|
+
for (const sym of Object.getOwnPropertySymbols(arg1.meta)) {
|
|
324
|
+
meta[sym] = arg1.meta[sym];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
} else {
|
|
328
|
+
contentType = arg1;
|
|
329
|
+
handler = arg2;
|
|
330
|
+
meta = Object.create(null);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (!Array.isArray(contentType)) {
|
|
334
|
+
this.#handlers.set(contentType, new HandlerDefinition(
|
|
335
|
+
this.#meta.name,
|
|
336
|
+
contentType,
|
|
337
|
+
handler,
|
|
338
|
+
meta,
|
|
339
|
+
this as unknown as ImplementedAction<State, Spec>,
|
|
340
|
+
this.#meta,
|
|
341
|
+
));
|
|
342
|
+
} else {
|
|
343
|
+
for (let i = 0; i < contentType.length; i++) {
|
|
344
|
+
this.#handlers.set(contentType[i], new HandlerDefinition(
|
|
345
|
+
this.#meta.name,
|
|
346
|
+
contentType[i],
|
|
347
|
+
handler,
|
|
348
|
+
meta,
|
|
349
|
+
this as unknown as ImplementedAction<State, Spec>,
|
|
350
|
+
this.#meta,
|
|
351
|
+
));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return this;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async handleRequest(args: HandleRequestArgs): Promise<ResponseTypes> {
|
|
359
|
+
const handler = this.#handlers.get(args.contentType as string);
|
|
360
|
+
|
|
361
|
+
return this.#meta.handleRequest({
|
|
362
|
+
...args,
|
|
363
|
+
spec: this.#spec,
|
|
364
|
+
handler,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export interface Applicable<ActionType> {
|
|
370
|
+
use(): ActionType;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export class DefinedAction<
|
|
374
|
+
State extends ContextState = ContextState,
|
|
375
|
+
Term extends string = string,
|
|
376
|
+
Spec extends ActionSpec = ActionSpec,
|
|
377
|
+
> implements
|
|
378
|
+
Applicable<DefinedAction<State, Term, Spec>>,
|
|
379
|
+
Handleable<State, Spec>,
|
|
380
|
+
ImplementedAction<State, Spec>
|
|
381
|
+
{
|
|
382
|
+
#spec: Spec;
|
|
383
|
+
#meta: ActionMeta<State, Spec>;
|
|
384
|
+
#typeDef?: TypeDef;
|
|
385
|
+
|
|
386
|
+
constructor(
|
|
387
|
+
typeDef: TypeDef | undefined,
|
|
388
|
+
spec: Spec,
|
|
389
|
+
meta: ActionMeta<State, Spec>,
|
|
390
|
+
) {
|
|
391
|
+
this.#spec = spec ?? {} as Spec;
|
|
392
|
+
this.#meta = meta;
|
|
393
|
+
this.#typeDef = typeDef;
|
|
394
|
+
|
|
395
|
+
this.#meta.action = this as unknown as ImplementedAction<State, Spec>;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
get public(): boolean {
|
|
399
|
+
return this.#meta.public;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
get method(): string {
|
|
403
|
+
return this.#meta.method;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
get term(): string | undefined {
|
|
407
|
+
return this.#typeDef?.term;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
get type(): string | undefined {
|
|
411
|
+
return this.#typeDef?.type;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
get typeDef(): TypeDef | undefined {
|
|
415
|
+
return this.#typeDef;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
get name(): string {
|
|
419
|
+
return this.#meta.name;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
get template(): string {
|
|
423
|
+
return this.#meta.uriTemplate;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
get pattern(): URLPattern {
|
|
427
|
+
return this.#meta.path.pattern;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
get path(): string {
|
|
431
|
+
return this.#meta.path.normalized;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
get spec(): Spec {
|
|
435
|
+
return this.#spec;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
get scope(): Scope | undefined {
|
|
439
|
+
return this.#meta.scope;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
get registry(): Registry {
|
|
443
|
+
return this.#meta.registry;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
get handlers(): HandlerDefinition<State, Spec>[] {
|
|
447
|
+
return [];
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
get contentTypes(): string[] {
|
|
451
|
+
return [];
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
url(): string {
|
|
455
|
+
return '';
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
get context(): JSONLDContext {
|
|
459
|
+
return getActionContext({
|
|
460
|
+
spec: this.#spec,
|
|
461
|
+
// vocab: this.#vocab,
|
|
462
|
+
// aliases: this.#aliases,
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
jsonld(): Promise<JSONObject | null> {
|
|
467
|
+
const scope = this.#meta.scope;
|
|
468
|
+
|
|
469
|
+
return FinalizedAction.toJSONLD(
|
|
470
|
+
this as unknown as ImplementedAction,
|
|
471
|
+
scope
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
jsonldPartial(): { '@type': string, '@id': string } | null {
|
|
476
|
+
const scope = this.#meta.scope;
|
|
477
|
+
const typeDef = this.#typeDef;
|
|
478
|
+
|
|
479
|
+
if (scope == null || typeDef == null) {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return {
|
|
484
|
+
'@type': typeDef.type,
|
|
485
|
+
'@id': joinPaths(scope.url(), this.#meta.name),
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Defines a cache handling rule for this action.
|
|
491
|
+
*
|
|
492
|
+
* Defining caching rules after the `action.define()` method is safer
|
|
493
|
+
* if validating and transforming the action payload might cause
|
|
494
|
+
* auth sensitive checks to be run which might reject the request.
|
|
495
|
+
*/
|
|
496
|
+
cache(args: CacheInstanceArgs): DefinedAction<State, string, Spec> {
|
|
497
|
+
if (this.#meta.cache.length !== 0 &&
|
|
498
|
+
this.#meta.cacheOccurance === BeforeDefinition) {
|
|
499
|
+
throw new Error(
|
|
500
|
+
'Action cache may be defined either before or after ' +
|
|
501
|
+
'the definition method is called, but not both.');
|
|
502
|
+
} else if (this.#meta.cacheOccurance === BeforeDefinition) {
|
|
503
|
+
this.#meta.cacheOccurance = AfterDefinition;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
this.#meta.cache.push(args);
|
|
507
|
+
|
|
508
|
+
return this;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
meta(): DefinedAction<State, string, Spec> {
|
|
512
|
+
return this;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
use(): DefinedAction<State, string, Spec> {
|
|
516
|
+
return this;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
handle(contentType: string | string[], handler: HandlerValue | HandlerFn<State, Spec>): FinalizedAction<State, Spec>;
|
|
520
|
+
handle(args: HandlerObj<State, Spec>): FinalizedAction<State, Spec>;
|
|
521
|
+
handle(arg1: unknown, arg2?: unknown): FinalizedAction<State, Spec> {
|
|
522
|
+
return FinalizedAction.fromHandlers(
|
|
523
|
+
this.#typeDef,
|
|
524
|
+
this.#spec,
|
|
525
|
+
this.#meta,
|
|
526
|
+
arg1 as string | string[],
|
|
527
|
+
arg2 as HandlerFn<State, Spec>,
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
async handleRequest(args: HandleRequestArgs): Promise<ResponseTypes> {
|
|
532
|
+
return this.#meta.handleRequest({
|
|
533
|
+
...args,
|
|
534
|
+
spec: this.#spec,
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export class Action<
|
|
541
|
+
State extends ContextState = ContextState,
|
|
542
|
+
> implements
|
|
543
|
+
Applicable<Action>,
|
|
544
|
+
Handleable<State>,
|
|
545
|
+
ImplementedAction<State>
|
|
546
|
+
{
|
|
547
|
+
#spec: ActionSpec = {};
|
|
548
|
+
#meta: ActionMeta<State>;
|
|
549
|
+
|
|
550
|
+
constructor(
|
|
551
|
+
meta: ActionMeta<State>,
|
|
552
|
+
) {
|
|
553
|
+
this.#meta = meta;
|
|
554
|
+
this.#meta.action = this as ImplementedAction<State, {}>;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
get public(): boolean {
|
|
558
|
+
return this.#meta.public;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
get method(): string {
|
|
562
|
+
return this.#meta.method;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
get term(): string | undefined {
|
|
566
|
+
return undefined;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
get type(): string | undefined {
|
|
570
|
+
return undefined;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
get typeDef(): TypeDef | undefined {
|
|
574
|
+
return undefined;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
get name(): string {
|
|
578
|
+
return this.#meta.name;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
get template(): string {
|
|
582
|
+
return this.#meta.uriTemplate;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
get pattern(): URLPattern {
|
|
586
|
+
return this.#meta.path.pattern;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
get path(): string {
|
|
591
|
+
return this.#meta.path.normalized;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
get spec(): ActionSpec {
|
|
595
|
+
return this.#spec;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
get scope(): Scope | undefined {
|
|
599
|
+
return this.#meta.scope;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
get registry(): Registry {
|
|
603
|
+
return this.#meta.registry;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
get handlers(): HandlerDefinition[] {
|
|
607
|
+
return [];
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
get contentTypes(): string[] {
|
|
611
|
+
return [];
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
get context(): JSONObject {
|
|
615
|
+
return getActionContext({
|
|
616
|
+
spec: this.#spec,
|
|
617
|
+
//vocab: this.#vocab,
|
|
618
|
+
//aliases: this.#aliases,
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
url(): string {
|
|
623
|
+
return '';
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
jsonld(): Promise<null> {
|
|
627
|
+
return Promise.resolve(null);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
jsonldPartial(): { '@type': string, '@id': string } | null {
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
use(): Action<State> {
|
|
635
|
+
return this;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
define<
|
|
639
|
+
Term extends string = string,
|
|
640
|
+
Spec extends ActionSpec = ActionSpec,
|
|
641
|
+
>(args: DefineArgs<Term, Spec>): DefinedAction<State, Term, Spec> {
|
|
642
|
+
return new DefinedAction<State, Term, Spec>(
|
|
643
|
+
args.typeDef,
|
|
644
|
+
args.spec ?? {} as Spec,
|
|
645
|
+
this.#meta as unknown as ActionMeta<State, Spec>,
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
handle(contentType: string | string[], handler: HandlerValue | HandlerFn<State>): FinalizedAction<State>;
|
|
650
|
+
handle(args: HandlerObj<State>): FinalizedAction<State>;
|
|
651
|
+
handle(arg1: unknown, arg2?: unknown): FinalizedAction<State> {
|
|
652
|
+
return FinalizedAction.fromHandlers(
|
|
653
|
+
null,
|
|
654
|
+
this.#spec,
|
|
655
|
+
this.#meta,
|
|
656
|
+
arg1 as string | string[],
|
|
657
|
+
arg2 as HandlerFn<State>,
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
async handleRequest(args: HandleRequestArgs): Promise<ResponseTypes> {
|
|
662
|
+
return this.#meta.handleRequest({
|
|
663
|
+
...args,
|
|
664
|
+
spec: this.#spec,
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export class PreAction<
|
|
671
|
+
State extends ContextState = ContextState,
|
|
672
|
+
> implements
|
|
673
|
+
Applicable<Action>,
|
|
674
|
+
Handleable<State>
|
|
675
|
+
{
|
|
676
|
+
#meta: ActionMeta<State>;
|
|
677
|
+
|
|
678
|
+
constructor(
|
|
679
|
+
meta: ActionMeta<State>,
|
|
680
|
+
) {
|
|
681
|
+
this.#meta = meta;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
use() {
|
|
685
|
+
return new Action(
|
|
686
|
+
this.#meta,
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
define<
|
|
691
|
+
Term extends string = string,
|
|
692
|
+
Spec extends ActionSpec = ActionSpec,
|
|
693
|
+
>(args: DefineArgs<Term, Spec>): DefinedAction<State, Term, Spec> {
|
|
694
|
+
return new DefinedAction<State, Term, Spec>(
|
|
695
|
+
args.typeDef,
|
|
696
|
+
args.spec,
|
|
697
|
+
this.#meta as unknown as ActionMeta<State, Spec>,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
handle(contentType: string | string[], handler: HandlerValue | HandlerFn<State>): FinalizedAction<State>;
|
|
702
|
+
handle(args: HandlerObj<State>): FinalizedAction<State>;
|
|
703
|
+
handle(arg1: unknown, arg2?: unknown): FinalizedAction<State> {
|
|
704
|
+
return FinalizedAction.fromHandlers(
|
|
705
|
+
null,
|
|
706
|
+
{},
|
|
707
|
+
this.#meta,
|
|
708
|
+
arg1 as string | string[],
|
|
709
|
+
arg2 as HandlerFn<State>,
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
export class Endpoint<
|
|
715
|
+
State extends ContextState = ContextState,
|
|
716
|
+
> implements
|
|
717
|
+
Applicable<Action>,
|
|
718
|
+
Handleable<State>
|
|
719
|
+
{
|
|
720
|
+
#meta: ActionMeta<State>;
|
|
721
|
+
|
|
722
|
+
constructor(
|
|
723
|
+
meta: ActionMeta<State>,
|
|
724
|
+
) {
|
|
725
|
+
this.#meta = meta;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
hint(hints: HintArgs): Endpoint<State> {
|
|
729
|
+
this.#meta.hints.push(hints);
|
|
730
|
+
|
|
731
|
+
return this;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
compress(): Endpoint<State> {
|
|
735
|
+
return this;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
cache(args: CacheInstanceArgs) {
|
|
739
|
+
this.#meta.cache.push(args);
|
|
740
|
+
|
|
741
|
+
return this;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
etag() {
|
|
745
|
+
return this;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
use(): Action<State> {
|
|
749
|
+
return new Action<State>(this.#meta);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
define<
|
|
753
|
+
Term extends string = string,
|
|
754
|
+
Spec extends ActionSpec = ActionSpec,
|
|
755
|
+
>(args: DefineArgs<Term, Spec>): DefinedAction<State, Term, Spec> {
|
|
756
|
+
return new DefinedAction<State, Term, Spec>(
|
|
757
|
+
args.typeDef,
|
|
758
|
+
args.spec,
|
|
759
|
+
this.#meta as ActionMeta<State, Spec>,
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
handle(contentType: string | string[], handler: HandlerValue | HandlerFn<State>): FinalizedAction<State>;
|
|
764
|
+
handle(args: HandlerObj<State>): FinalizedAction<State>;
|
|
765
|
+
handle(arg1: unknown, arg2?: unknown): FinalizedAction<State> {
|
|
766
|
+
return FinalizedAction.fromHandlers(
|
|
767
|
+
undefined,
|
|
768
|
+
{},
|
|
769
|
+
this.#meta,
|
|
770
|
+
arg1 as string | string[],
|
|
771
|
+
arg2 as HandlerFn<State>,
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
export class ActionAuth<
|
|
777
|
+
State extends ContextState = ContextState,
|
|
778
|
+
> {
|
|
779
|
+
#meta: ActionMeta<State>;
|
|
780
|
+
|
|
781
|
+
constructor(meta: ActionMeta<State>) {
|
|
782
|
+
this.#meta = meta;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
public(): Endpoint<State> {
|
|
786
|
+
this.#meta.public = true;
|
|
787
|
+
|
|
788
|
+
return new Endpoint(this.#meta);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
private(): Endpoint<State> {
|
|
792
|
+
return new Endpoint(this.#meta);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|