@toa.io/extensions.exposition 1.0.0-alpha.286 → 1.0.0-alpha.288
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/CHANGELOG.md +16 -0
- package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
- package/components/identity.clients/tsconfig.tsbuildinfo +1 -1
- package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
- package/components/identity.grants/tsconfig.tsbuildinfo +1 -1
- package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/manifest.toa.yaml +2 -1
- package/components/identity.passkeys/source/errors.test.ts +34 -0
- package/components/identity.passkeys/source/webauthn.test.ts +26 -0
- package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/types/toa.d.ts +1 -1
- package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
- package/documentation/access.md +22 -4
- package/documentation/discovery.md +81 -0
- package/documentation/help.md +109 -0
- package/documentation/introspection.md +34 -9
- package/documentation/mcp.md +13 -16
- package/features/cors.feature +31 -1
- package/features/dev.feature +2 -0
- package/features/discovery.feature +211 -0
- package/features/discovery.ui.feature +197 -0
- package/features/help.feature +466 -0
- package/features/introspection.feature +94 -8
- package/features/map.feature +1 -0
- package/features/mcp.feature +74 -12
- package/features/methods.feature +2 -1
- package/features/oauth.grants.feature +3 -1
- package/features/octets.download.feature +1 -0
- package/features/octets.meta.feature +1 -0
- package/features/site/_app/immutable/asset.js +1 -0
- package/features/site/favicon.ico +0 -0
- package/features/site/index.html +10 -0
- package/features/steps/Parameters.ts +12 -0
- package/package.json +6 -4
- package/readme.md +3 -0
- package/source/Directive.ts +4 -0
- package/source/Discovery/Explorer.ts +34 -0
- package/source/Discovery/Site.test.ts +147 -0
- package/source/Discovery/Site.ts +202 -0
- package/source/Discovery/index.ts +3 -0
- package/source/Discovery/tree.test.ts +175 -0
- package/source/Discovery/tree.ts +77 -0
- package/source/Discovery/trunk.ts +23 -0
- package/source/Endpoint.ts +4 -0
- package/source/Gateway.ts +34 -4
- package/source/HTTP/Context.ts +7 -0
- package/source/Introspection.ts +33 -10
- package/source/MCP/schema.ts +16 -5
- package/source/MCP/tools.ts +14 -32
- package/source/Mapping.ts +5 -0
- package/source/Query.ts +17 -2
- package/source/RTD/Directives.ts +10 -0
- package/source/RTD/Endpoint.ts +8 -1
- package/source/RTD/Node.ts +20 -6
- package/source/RTD/Tree.ts +19 -9
- package/source/RTD/factory.ts +37 -1
- package/source/RTD/segment.ts +21 -0
- package/source/const.ts +8 -0
- package/source/directives/auth/Anonymous.test.ts +31 -5
- package/source/directives/auth/Anonymous.ts +5 -3
- package/source/directives/auth/Anyone.ts +6 -0
- package/source/directives/auth/Assert.ts +5 -0
- package/source/directives/auth/Delegate.ts +5 -2
- package/source/directives/auth/Federation.ts +11 -0
- package/source/directives/auth/Id.ts +15 -0
- package/source/directives/auth/Input.ts +5 -0
- package/source/directives/auth/Role.ts +17 -0
- package/source/directives/cors/CORS.test.ts +75 -0
- package/source/directives/cors/CORS.ts +10 -3
- package/source/directives/help/Family.ts +118 -0
- package/source/directives/help/Help.test.ts +227 -0
- package/source/directives/help/Help.ts +26 -0
- package/source/directives/help/Parameters.ts +47 -0
- package/source/directives/help/described.ts +57 -0
- package/source/directives/help/index.ts +45 -0
- package/source/directives/index.ts +8 -1
- package/source/directives/map/Headers.ts +6 -6
- package/source/directives/mcp/MCP.ts +12 -21
- package/source/directives/mcp/Tool.test.ts +22 -68
- package/source/directives/mcp/Tool.ts +14 -41
- package/transpiled/Directive.d.ts +1 -0
- package/transpiled/Directive.js +3 -0
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Discovery/Explorer.d.ts +11 -0
- package/transpiled/Discovery/Explorer.js +29 -0
- package/transpiled/Discovery/Explorer.js.map +1 -0
- package/transpiled/Discovery/Site.d.ts +43 -0
- package/transpiled/Discovery/Site.js +171 -0
- package/transpiled/Discovery/Site.js.map +1 -0
- package/transpiled/Discovery/index.d.ts +3 -0
- package/transpiled/Discovery/index.js +4 -0
- package/transpiled/Discovery/index.js.map +1 -0
- package/transpiled/Discovery/tree.d.ts +26 -0
- package/transpiled/Discovery/tree.js +50 -0
- package/transpiled/Discovery/tree.js.map +1 -0
- package/transpiled/Discovery/trunk.d.ts +10 -0
- package/transpiled/Discovery/trunk.js +21 -0
- package/transpiled/Discovery/trunk.js.map +1 -0
- package/transpiled/Endpoint.d.ts +2 -1
- package/transpiled/Endpoint.js +3 -0
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Gateway.d.ts +4 -0
- package/transpiled/Gateway.js +29 -4
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +6 -0
- package/transpiled/HTTP/Context.js +6 -0
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/Introspection.d.ts +18 -7
- package/transpiled/Introspection.js +16 -1
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/schema.d.ts +2 -2
- package/transpiled/MCP/schema.js +11 -5
- package/transpiled/MCP/schema.js.map +1 -1
- package/transpiled/MCP/tools.d.ts +1 -1
- package/transpiled/MCP/tools.js +12 -28
- package/transpiled/MCP/tools.js.map +1 -1
- package/transpiled/Mapping.d.ts +2 -0
- package/transpiled/Mapping.js +4 -0
- package/transpiled/Mapping.js.map +1 -1
- package/transpiled/Query.d.ts +12 -0
- package/transpiled/Query.js +16 -2
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RTD/Directives.d.ts +8 -0
- package/transpiled/RTD/Endpoint.d.ts +7 -1
- package/transpiled/RTD/Node.d.ts +11 -2
- package/transpiled/RTD/Node.js +12 -2
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Tree.js +15 -8
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/RTD/factory.js +27 -1
- package/transpiled/RTD/factory.js.map +1 -1
- package/transpiled/RTD/segment.d.ts +7 -0
- package/transpiled/RTD/segment.js +17 -0
- package/transpiled/RTD/segment.js.map +1 -1
- package/transpiled/const.d.ts +7 -0
- package/transpiled/const.js +7 -0
- package/transpiled/const.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.d.ts +4 -2
- package/transpiled/directives/auth/Anonymous.js +5 -3
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Anyone.d.ts +3 -0
- package/transpiled/directives/auth/Anyone.js +4 -0
- package/transpiled/directives/auth/Anyone.js.map +1 -1
- package/transpiled/directives/auth/Assert.d.ts +2 -0
- package/transpiled/directives/auth/Assert.js +4 -0
- package/transpiled/directives/auth/Assert.js.map +1 -1
- package/transpiled/directives/auth/Delegate.d.ts +4 -1
- package/transpiled/directives/auth/Delegate.js +5 -2
- package/transpiled/directives/auth/Delegate.js.map +1 -1
- package/transpiled/directives/auth/Federation.d.ts +5 -0
- package/transpiled/directives/auth/Federation.js +8 -0
- package/transpiled/directives/auth/Federation.js.map +1 -1
- package/transpiled/directives/auth/Id.d.ts +9 -0
- package/transpiled/directives/auth/Id.js +12 -0
- package/transpiled/directives/auth/Id.js.map +1 -1
- package/transpiled/directives/auth/Input.d.ts +2 -0
- package/transpiled/directives/auth/Input.js +4 -0
- package/transpiled/directives/auth/Input.js.map +1 -1
- package/transpiled/directives/auth/Role.d.ts +7 -0
- package/transpiled/directives/auth/Role.js +11 -0
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/cors/CORS.js +9 -2
- package/transpiled/directives/cors/CORS.js.map +1 -1
- package/transpiled/directives/help/Family.d.ts +28 -0
- package/transpiled/directives/help/Family.js +79 -0
- package/transpiled/directives/help/Family.js.map +1 -0
- package/transpiled/directives/help/Help.d.ts +16 -0
- package/transpiled/directives/help/Help.js +22 -0
- package/transpiled/directives/help/Help.js.map +1 -0
- package/transpiled/directives/help/Parameters.d.ts +18 -0
- package/transpiled/directives/help/Parameters.js +34 -0
- package/transpiled/directives/help/Parameters.js.map +1 -0
- package/transpiled/directives/help/described.d.ts +16 -0
- package/transpiled/directives/help/described.js +23 -0
- package/transpiled/directives/help/described.js.map +1 -0
- package/transpiled/directives/help/index.d.ts +22 -0
- package/transpiled/directives/help/index.js +34 -0
- package/transpiled/directives/help/index.js.map +1 -0
- package/transpiled/directives/index.d.ts +4 -0
- package/transpiled/directives/index.js +8 -1
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/map/Headers.d.ts +5 -0
- package/transpiled/directives/map/Headers.js +7 -5
- package/transpiled/directives/map/Headers.js.map +1 -1
- package/transpiled/directives/mcp/MCP.d.ts +8 -5
- package/transpiled/directives/mcp/MCP.js +9 -13
- package/transpiled/directives/mcp/MCP.js.map +1 -1
- package/transpiled/directives/mcp/Tool.d.ts +6 -12
- package/transpiled/directives/mcp/Tool.js +10 -23
- package/transpiled/directives/mcp/Tool.js.map +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/ui/dist/_app/env.js +1 -0
- package/ui/dist/_app/immutable/assets/0.BcIGtTfw.css +2 -0
- package/ui/dist/_app/immutable/assets/2.BC0-Jhqu.css +1 -0
- package/ui/dist/_app/immutable/assets/inter-cyrillic-ext-wght-normal.BOeWTOD4.woff2 +0 -0
- package/ui/dist/_app/immutable/assets/inter-cyrillic-wght-normal.DqGufNeO.woff2 +0 -0
- package/ui/dist/_app/immutable/assets/inter-greek-ext-wght-normal.DlzME5K_.woff2 +0 -0
- package/ui/dist/_app/immutable/assets/inter-greek-wght-normal.CkhJZR-_.woff2 +0 -0
- package/ui/dist/_app/immutable/assets/inter-latin-ext-wght-normal.DO1Apj_S.woff2 +0 -0
- package/ui/dist/_app/immutable/assets/inter-latin-wght-normal.Dx4kXJAl.woff2 +0 -0
- package/ui/dist/_app/immutable/assets/inter-vietnamese-wght-normal.CBcvBZtf.woff2 +0 -0
- package/ui/dist/_app/immutable/chunks/BgTrzN6u.js +1 -0
- package/ui/dist/_app/immutable/chunks/Bjy-W4x2.js +81 -0
- package/ui/dist/_app/immutable/chunks/CWJaG9mK.js +6 -0
- package/ui/dist/_app/immutable/chunks/DjIYL2zC.js +3 -0
- package/ui/dist/_app/immutable/chunks/xihTtKlq.js +1 -0
- package/ui/dist/_app/immutable/chunks/yDQhitF9.js +1 -0
- package/ui/dist/_app/immutable/entry/app.WZSMBcGf.js +2 -0
- package/ui/dist/_app/immutable/entry/start._LkoC6Lz.js +1 -0
- package/ui/dist/_app/immutable/nodes/0.Dl2DqINo.js +1 -0
- package/ui/dist/_app/immutable/nodes/1.CSSnGhVD.js +1 -0
- package/ui/dist/_app/immutable/nodes/2.DmolQyNG.js +14 -0
- package/ui/dist/_app/version.json +1 -0
- package/ui/dist/apple-touch-icon.png +0 -0
- package/ui/dist/favicon-96x96.png +0 -0
- package/ui/dist/favicon.ico +0 -0
- package/ui/dist/index.html +66 -0
|
@@ -5,6 +5,14 @@ export class Federation {
|
|
|
5
5
|
this.matchers = Object.entries(options).map(([key, value]) => [key, toMatcher(value)]);
|
|
6
6
|
assert.ok(this.matchers.length > 0, '`auth:claims` requires at least one property defined');
|
|
7
7
|
}
|
|
8
|
+
/** Which claims it takes needs the request; that it takes an identity does not. */
|
|
9
|
+
admits(identity) {
|
|
10
|
+
return identity === null ? false : undefined;
|
|
11
|
+
}
|
|
12
|
+
/** Which claims is the application's business; that it takes an identity is the caller's. */
|
|
13
|
+
describe(introspection) {
|
|
14
|
+
return { ...introspection, authenticated: true };
|
|
15
|
+
}
|
|
8
16
|
authorize(identity, context, parameters) {
|
|
9
17
|
if (identity === null || !('claims' in identity))
|
|
10
18
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Federation.js","sourceRoot":"","sources":["../../../source/directives/auth/Federation.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"Federation.js","sourceRoot":"","sources":["../../../source/directives/auth/Federation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { type Parameter } from '../../RTD/index.js';
|
|
2
2
|
import { type Directive, type Identity } from './types.js';
|
|
3
|
+
import type { Introspection } from '../../Introspection.js';
|
|
3
4
|
export declare class Id implements Directive {
|
|
4
5
|
private readonly parameter;
|
|
5
6
|
constructor(parameter: string);
|
|
7
|
+
/**
|
|
8
|
+
* Whether it is *this* identity's cannot be told from a description, which has no route
|
|
9
|
+
* variable to read — but that there must be an identity at all can, and a caller with
|
|
10
|
+
* none is refused whatever the value would have been.
|
|
11
|
+
*/
|
|
12
|
+
admits(identity: Identity | null): boolean | undefined;
|
|
13
|
+
/** Reaching it is being the identity it is about, which is what `private` says. */
|
|
14
|
+
describe(introspection: Introspection): Introspection;
|
|
6
15
|
authorize(identity: Identity | null, _: unknown, parameters: Parameter[]): boolean;
|
|
7
16
|
}
|
|
@@ -3,6 +3,18 @@ export class Id {
|
|
|
3
3
|
constructor(parameter) {
|
|
4
4
|
this.parameter = parameter;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Whether it is *this* identity's cannot be told from a description, which has no route
|
|
8
|
+
* variable to read — but that there must be an identity at all can, and a caller with
|
|
9
|
+
* none is refused whatever the value would have been.
|
|
10
|
+
*/
|
|
11
|
+
admits(identity) {
|
|
12
|
+
return identity === null ? false : undefined;
|
|
13
|
+
}
|
|
14
|
+
/** Reaching it is being the identity it is about, which is what `private` says. */
|
|
15
|
+
describe(introspection) {
|
|
16
|
+
return { ...introspection, private: true };
|
|
17
|
+
}
|
|
6
18
|
authorize(identity, _, parameters) {
|
|
7
19
|
if (identity === null)
|
|
8
20
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Id.js","sourceRoot":"","sources":["../../../source/directives/auth/Id.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Id.js","sourceRoot":"","sources":["../../../source/directives/auth/Id.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,EAAE;IACI,SAAS,CAAQ;IAElC,YAAmB,SAAiB;QAClC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,QAAyB;QACrC,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9C,CAAC;IAED,mFAAmF;IAC5E,QAAQ,CAAC,aAA4B;QAC1C,OAAO,EAAE,GAAG,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC5C,CAAC;IAEM,SAAS,CACd,QAAyB,EACzB,CAAU,EACV,UAAuB;QAEvB,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAA;QAEnC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,CAAA;QAEnF,OAAO,SAAS,EAAE,KAAK,KAAK,QAAQ,CAAC,EAAE,CAAA;IACzC,CAAC;CACF"}
|
|
@@ -4,6 +4,8 @@ export declare class Input implements Directive {
|
|
|
4
4
|
priority: number;
|
|
5
5
|
private readonly statements;
|
|
6
6
|
constructor(declarations: Declaration[], create: Create);
|
|
7
|
+
/** It admits nobody: it says what a body may carry, not who may send one. */
|
|
8
|
+
admits(): boolean;
|
|
7
9
|
authorize(identity: Identity | null, context: Context, parameters: Parameter[]): Promise<boolean>;
|
|
8
10
|
private check;
|
|
9
11
|
}
|
|
@@ -5,6 +5,10 @@ export class Input {
|
|
|
5
5
|
constructor(declarations, create) {
|
|
6
6
|
this.statements = declarations.map((declaration) => new Statement(declaration, create));
|
|
7
7
|
}
|
|
8
|
+
/** It admits nobody: it says what a body may carry, not who may send one. */
|
|
9
|
+
admits() {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
8
12
|
async authorize(identity, context, parameters) {
|
|
9
13
|
context.pipelines.body.push(async (body) => this.check(identity, context, parameters, body));
|
|
10
14
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../source/directives/auth/Input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAI/C,MAAM,OAAO,KAAK;IACT,QAAQ,GAAG,CAAC,CAAA;IACF,UAAU,GAAgB,EAAE,CAAA;IAE7C,YAAmB,YAA2B,EAAE,MAAc;QAC5D,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,GAAG,CAChC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,MAAM,CAAC,CACpD,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,SAAS,CACpB,QAAyB,EACzB,OAAgB,EAChB,UAAuB;QAEvB,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CACzC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,CAChD,CAAA;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,sCAAsC;IAC9B,KAAK,CAAC,KAAK,CACjB,QAAyB,EACzB,OAAgB,EAChB,UAAuB,EACvB,IAAa;QAEb,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM;YAAE,OAAO,IAAI,CAAA;QAEnF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CACtC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAY,CAAC,CAC7D,CACF,CAAA;QAED,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,MAAM,CAAC,MAAM,CAAA;QAEnF,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAED,MAAM,SAAS;IACI,UAAU,CAAU;IACpB,UAAU,GAAgB,EAAE,CAAA;IAE7C,YAAmB,EAAE,IAAI,EAAE,GAAG,UAAU,EAAe,EAAE,MAAc;QACrE,IAAI,CAAC,UAAU,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAE1D,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAErC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAED,sCAAsC;IAC/B,KAAK,CAAC,KAAK,CAChB,QAAyB,EACzB,OAAgB,EAChB,UAAuB,EACvB,IAAU;QAEV,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAA;QAElE,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;YAE3E,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;QAC1E,CAAC;IACH,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../source/directives/auth/Input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAI/C,MAAM,OAAO,KAAK;IACT,QAAQ,GAAG,CAAC,CAAA;IACF,UAAU,GAAgB,EAAE,CAAA;IAE7C,YAAmB,YAA2B,EAAE,MAAc;QAC5D,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,GAAG,CAChC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,MAAM,CAAC,CACpD,CAAA;IACH,CAAC;IAED,6EAA6E;IACtE,MAAM;QACX,OAAO,KAAK,CAAA;IACd,CAAC;IAEM,KAAK,CAAC,SAAS,CACpB,QAAyB,EACzB,OAAgB,EAChB,UAAuB;QAEvB,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CACzC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,CAChD,CAAA;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAED,sCAAsC;IAC9B,KAAK,CAAC,KAAK,CACjB,QAAyB,EACzB,OAAgB,EAChB,UAAuB,EACvB,IAAa;QAEb,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM;YAAE,OAAO,IAAI,CAAA;QAEnF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CACtC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAY,CAAC,CAC7D,CACF,CAAA;QAED,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,MAAM,CAAC,MAAM,CAAA;QAEnF,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAED,MAAM,SAAS;IACI,UAAU,CAAU;IACpB,UAAU,GAAgB,EAAE,CAAA;IAE7C,YAAmB,EAAE,IAAI,EAAE,GAAG,UAAU,EAAe,EAAE,MAAc;QACrE,IAAI,CAAC,UAAU,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAE1D,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAErC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAED,sCAAsC;IAC/B,KAAK,CAAC,KAAK,CAChB,QAAyB,EACzB,OAAgB,EAChB,UAAuB,EACvB,IAAU;QAEV,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAA;QAElE,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;YAE3E,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;QAC1E,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Component } from '@toa.io/core';
|
|
2
2
|
import { type Directive, type Identity } from './types.js';
|
|
3
3
|
import type { Parameter } from '../../RTD/index.js';
|
|
4
|
+
import type { Introspection } from '../../Introspection.js';
|
|
4
5
|
export declare class Role implements Directive {
|
|
5
6
|
static remote: Component | null;
|
|
6
7
|
private readonly roles;
|
|
@@ -8,6 +9,12 @@ export declare class Role implements Directive {
|
|
|
8
9
|
private readonly dynamic;
|
|
9
10
|
constructor(roles: string | string[], discovery: Promise<Component>);
|
|
10
11
|
static get(identity: Identity, discovery: Promise<Component>): Promise<string[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Reaching it takes a role, which is what `protected` says. A role of the `system` scope
|
|
14
|
+
* says so besides: what it guards is the machinery an application runs on rather than
|
|
15
|
+
* anything it serves, and a reader has no business being offered it as one.
|
|
16
|
+
*/
|
|
17
|
+
describe(introspection: Introspection): Introspection;
|
|
11
18
|
authorize(identity: Identity | null, _: unknown, parameters: Parameter[]): Promise<boolean>;
|
|
12
19
|
/** A role naming a route variable cannot be told from a description, which has no values. */
|
|
13
20
|
admits(identity: Identity | null): Promise<boolean | undefined>;
|
|
@@ -18,6 +18,15 @@ export class Role {
|
|
|
18
18
|
};
|
|
19
19
|
return await this.remote.invoke('list', { query });
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Reaching it takes a role, which is what `protected` says. A role of the `system` scope
|
|
23
|
+
* says so besides: what it guards is the machinery an application runs on rather than
|
|
24
|
+
* anything it serves, and a reader has no business being offered it as one.
|
|
25
|
+
*/
|
|
26
|
+
describe(introspection) {
|
|
27
|
+
const system = this.roles.some((role) => role === SYSTEM || role.startsWith(SYSTEM + ':'));
|
|
28
|
+
return { ...introspection, protected: true, ...(system ? { system: true } : {}) };
|
|
29
|
+
}
|
|
21
30
|
async authorize(identity, _, parameters) {
|
|
22
31
|
if (identity === null)
|
|
23
32
|
return false;
|
|
@@ -50,4 +59,6 @@ export class Role {
|
|
|
50
59
|
}));
|
|
51
60
|
}
|
|
52
61
|
}
|
|
62
|
+
/** The scope of what an application runs on, as opposed to what it serves. */
|
|
63
|
+
const SYSTEM = 'system';
|
|
53
64
|
//# sourceMappingURL=Role.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Role.js","sourceRoot":"","sources":["../../../source/directives/auth/Role.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"Role.js","sourceRoot":"","sources":["../../../source/directives/auth/Role.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAOvC,MAAM,OAAO,IAAI;IACR,MAAM,CAAC,MAAM,GAAqB,IAAI,CAAA;IAC5B,KAAK,CAAU;IACf,SAAS,CAAoB;IAC7B,OAAO,CAAS;IAEjC,YAAmB,KAAwB,EAAE,SAA6B;QACxE,IAAI,CAAC,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QACxD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9D,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,GAAG,CACrB,QAAkB,EAClB,SAA6B;QAE7B,IAAI,CAAC,MAAM,KAAK,MAAM,SAAS,CAAA;QAE/B,MAAM,KAAK,GAAU;YACnB,QAAQ,EAAE,aAAa,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YAC3C,KAAK,EAAE,IAAI;SACZ,CAAA;QAED,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IACpD,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAC,aAA4B;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAC5B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,CAC3D,CAAA;QAED,OAAO,EAAE,GAAG,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;IACnF,CAAC;IAEM,KAAK,CAAC,SAAS,CACpB,QAAyB,EACzB,CAAU,EACV,UAAuB;QAEvB,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAA;QAEnC,QAAQ,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QAE3D,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IAC/C,CAAC;IAED,6FAA6F;IACtF,KAAK,CAAC,MAAM,CAAC,QAAyB;QAC3C,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAA;QAElC,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAA;QAEnC,QAAQ,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QAE3D,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACvC,CAAC;IAEO,KAAK,CAAC,KAAe,EAAE,UAAuB;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAA;QAExE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CACtB,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,CACnE,CAAA;YAED,IAAI,EAAE;gBAAE,OAAO,IAAI,CAAA;QACrB,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,UAAU,CAAC,UAAuB;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC7B,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,CAAA;YAE3E,MAAM,CAAC,EAAE,CAAC,KAAK,KAAK,SAAS,EAAE,SAAS,IAAI,eAAe,GAAG,mBAAmB,CAAC,CAAA;YAElF,OAAO,KAAK,CAAA;QACd,CAAC,CAAC,CACH,CAAA;IACH,CAAC;;AAGH,8EAA8E;AAC9E,MAAM,MAAM,GAAG,QAAQ,CAAA"}
|
|
@@ -10,7 +10,7 @@ export class CORS {
|
|
|
10
10
|
name = 'cors';
|
|
11
11
|
requestHeaders = new Set(REQUEST_HEADERS);
|
|
12
12
|
headers = new Headers({
|
|
13
|
-
'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE, LOCK, UNLOCK',
|
|
13
|
+
'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE, LOCK, UNLOCK, OPTIONS',
|
|
14
14
|
'access-control-allow-credentials': 'true',
|
|
15
15
|
'access-control-allow-headers': this.allowedHeaders(),
|
|
16
16
|
'access-control-max-age': '3600',
|
|
@@ -19,7 +19,14 @@ export class CORS {
|
|
|
19
19
|
});
|
|
20
20
|
intercept(input) {
|
|
21
21
|
const origin = input.request.headers.origin;
|
|
22
|
-
|
|
22
|
+
const requested = input.request.headers['access-control-request-method'];
|
|
23
|
+
/*
|
|
24
|
+
* A preflight is `OPTIONS` carrying `Access-Control-Request-Method`, and only that. A
|
|
25
|
+
* browser puts `Origin` on every request whose method is not `GET` or `HEAD` — its own
|
|
26
|
+
* `OPTIONS` included, same-origin or not — so answering that one here would put
|
|
27
|
+
* introspection out of reach of any page.
|
|
28
|
+
*/
|
|
29
|
+
if (origin !== undefined && requested !== undefined && input.request.method === 'OPTIONS')
|
|
23
30
|
return this.preflightResponse(origin);
|
|
24
31
|
input.pipelines.response.push((output) => {
|
|
25
32
|
output.headers ??= new Headers();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CORS.js","sourceRoot":"","sources":["../../../source/directives/cors/CORS.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,MAAM,eAAe,GAAG;IACtB,QAAQ;IACR,eAAe;IACf,cAAc;IACd,UAAU;IACV,eAAe;CAChB,CAAA;AAED,MAAM,OAAO,IAAI;IACC,IAAI,GAAG,MAAM,CAAA;IAErB,cAAc,GAAG,IAAI,GAAG,CAAS,eAAe,CAAC,CAAA;IAExC,OAAO,GAAG,IAAI,OAAO,CAAC;QACrC,8BAA8B,EAAE,
|
|
1
|
+
{"version":3,"file":"CORS.js","sourceRoot":"","sources":["../../../source/directives/cors/CORS.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,MAAM,eAAe,GAAG;IACtB,QAAQ;IACR,eAAe;IACf,cAAc;IACd,UAAU;IACV,eAAe;CAChB,CAAA;AAED,MAAM,OAAO,IAAI;IACC,IAAI,GAAG,MAAM,CAAA;IAErB,cAAc,GAAG,IAAI,GAAG,CAAS,eAAe,CAAC,CAAA;IAExC,OAAO,GAAG,IAAI,OAAO,CAAC;QACrC,8BAA8B,EAAE,sDAAsD;QACtF,kCAAkC,EAAE,MAAM;QAC1C,8BAA8B,EAAE,IAAI,CAAC,cAAc,EAAE;QACrD,wBAAwB,EAAE,MAAM;QAChC,eAAe,EAAE,cAAc;QAC/B,IAAI,EAAE,QAAQ;KACf,CAAC,CAAA;IAEK,SAAS,CAAC,KAAY;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAA;QAC3C,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAA;QAExE;;;;;WAKG;QACH,IAAI,MAAM,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS;YACvF,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAA;QAEvC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACvC,MAAM,CAAC,OAAO,KAAK,IAAI,OAAO,EAAE,CAAA;YAEhC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAA;gBACzD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,MAAM,CAAC,CAAA;gBAC9D,MAAM,CAAC,OAAO,CAAC,GAAG,CAChB,+BAA+B,EAC/B,wEAAwE,CACzE,CAAA;YACH,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAA;YAEnC,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,SAAS;gBAC/D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC3C,CAAC,CAAC,CAAA;QAEF,OAAO,IAAI,CAAA;IACb,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAA;QAC9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAA;IACzE,CAAC;IAEM,KAAK,CAAC,MAAc;QACzB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAA;IACzE,CAAC;IAED;;;;OAIG;IACK,cAAc;QACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1D,CAAC;IAEO,iBAAiB,CAAC,MAAc;QACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAA;QAEvD,OAAO;YACL,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Help } from './Help.js';
|
|
2
|
+
import { Parameters } from './Parameters.js';
|
|
3
|
+
import type { Introspection } from '../../Introspection.js';
|
|
4
|
+
import type { Described } from './described.js';
|
|
5
|
+
import type { Context } from '../../HTTP/index.js';
|
|
6
|
+
import type { DirectiveFamily } from '../../RTD/index.js';
|
|
7
|
+
/** The name the family is declared under, and what a consumer of one asks a method for. */
|
|
8
|
+
export declare const FAMILY = "help";
|
|
9
|
+
export type Directive = Help | Parameters;
|
|
10
|
+
export declare class Family implements DirectiveFamily<Directive> {
|
|
11
|
+
readonly name = "help";
|
|
12
|
+
readonly mandatory = false;
|
|
13
|
+
/**
|
|
14
|
+
* What a node says of itself is not said of what is under it: inherited, `help:node`
|
|
15
|
+
* would describe every resource below as the one it was written for. The rest go with
|
|
16
|
+
* it — a sentence about one method is not true of the next, and a route variable a
|
|
17
|
+
* template does not have is not one at all.
|
|
18
|
+
*/
|
|
19
|
+
readonly inherited = false;
|
|
20
|
+
/** What the nearest declaration says of the method, or nothing where none does. */
|
|
21
|
+
static method(directives: Directive[] | undefined): Help | null;
|
|
22
|
+
/** And the same of the resource the method is on. */
|
|
23
|
+
static node(directives: Directive[] | undefined): Help | null;
|
|
24
|
+
create(name: string, value: unknown, _: unknown, route: string): Directive;
|
|
25
|
+
/** What the route states this method and its parameters are. */
|
|
26
|
+
explain(directives: Directive[], _: Context, introspection: Introspection): Introspection;
|
|
27
|
+
}
|
|
28
|
+
export type { Described };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { Help } from './Help.js';
|
|
3
|
+
import { Parameters } from './Parameters.js';
|
|
4
|
+
/** The name the family is declared under, and what a consumer of one asks a method for. */
|
|
5
|
+
export const FAMILY = 'help';
|
|
6
|
+
export class Family {
|
|
7
|
+
name = FAMILY;
|
|
8
|
+
mandatory = false;
|
|
9
|
+
/**
|
|
10
|
+
* What a node says of itself is not said of what is under it: inherited, `help:node`
|
|
11
|
+
* would describe every resource below as the one it was written for. The rest go with
|
|
12
|
+
* it — a sentence about one method is not true of the next, and a route variable a
|
|
13
|
+
* template does not have is not one at all.
|
|
14
|
+
*/
|
|
15
|
+
inherited = false;
|
|
16
|
+
/** What the nearest declaration says of the method, or nothing where none does. */
|
|
17
|
+
static method(directives) {
|
|
18
|
+
return stated(directives, 'method');
|
|
19
|
+
}
|
|
20
|
+
/** And the same of the resource the method is on. */
|
|
21
|
+
static node(directives) {
|
|
22
|
+
return stated(directives, 'node');
|
|
23
|
+
}
|
|
24
|
+
// eslint-disable-next-line max-params
|
|
25
|
+
create(name, value, _, route) {
|
|
26
|
+
if (name === 'node' || name === 'method')
|
|
27
|
+
return new Help(name, value);
|
|
28
|
+
assert.ok(name === 'route' || name === 'query', `Unknown directive: help:${name}`);
|
|
29
|
+
return new Parameters(name, value, route);
|
|
30
|
+
}
|
|
31
|
+
/** What the route states this method and its parameters are. */
|
|
32
|
+
explain(directives, _, introspection) {
|
|
33
|
+
const help = Family.method(directives);
|
|
34
|
+
const described = {
|
|
35
|
+
...introspection,
|
|
36
|
+
...(help?.title === undefined ? {} : { title: help.title }),
|
|
37
|
+
...(help?.description === undefined ? {} : { description: help.description })
|
|
38
|
+
};
|
|
39
|
+
// a schema says `title` and `description` of what it describes, which is where these go
|
|
40
|
+
for (const subject of PARAMETERS) {
|
|
41
|
+
const declaration = declared(directives, subject);
|
|
42
|
+
if (declaration === null)
|
|
43
|
+
continue;
|
|
44
|
+
const parameters = declaration.parameters;
|
|
45
|
+
for (const [name, stated] of Object.entries(parameters)) {
|
|
46
|
+
const schema = described[subject]?.[name];
|
|
47
|
+
/*
|
|
48
|
+
* A route variable is one because the template names it, whether or not the
|
|
49
|
+
* operation declares it as input — and only then is it answered. `:id` on an
|
|
50
|
+
* observation is the ordinary case: it is taken by the query, so nothing describes
|
|
51
|
+
* it and the caller is not told it is a path parameter at all.
|
|
52
|
+
*
|
|
53
|
+
* Anything else is described only where it is already answered: a querystring
|
|
54
|
+
* parameter is one only where the mapping takes it, and a segment `map:segments`
|
|
55
|
+
* renames is answered under the property it fills.
|
|
56
|
+
*/
|
|
57
|
+
if (schema === undefined && !declaration.variables.includes(name))
|
|
58
|
+
continue;
|
|
59
|
+
// written where the shape states it, whatever the schema already said
|
|
60
|
+
const merged = { ...schema };
|
|
61
|
+
delete merged.title;
|
|
62
|
+
delete merged.description;
|
|
63
|
+
described[subject] ??= {};
|
|
64
|
+
described[subject][name] = Object.assign(merged, stated);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return described;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const PARAMETERS = ['route', 'query'];
|
|
71
|
+
function stated(directives, subject) {
|
|
72
|
+
const help = directives?.find((directive) => directive instanceof Help && directive.subject === subject);
|
|
73
|
+
return help ?? null;
|
|
74
|
+
}
|
|
75
|
+
function declared(directives, subject) {
|
|
76
|
+
const found = directives?.find((directive) => directive instanceof Parameters && directive.subject === subject);
|
|
77
|
+
return found ?? null;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=Family.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Family.js","sourceRoot":"","sources":["../../../source/directives/help/Family.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a resource or a method is, in the words an application chooses for it — read by
|
|
3
|
+
* everything that describes one: `OPTIONS`, discovery, and the tools MCP publishes.
|
|
4
|
+
*
|
|
5
|
+
* The operation states what it is too, and that is not this. An operation is written
|
|
6
|
+
* without knowledge of any route, and a method is an operation and a route together — the
|
|
7
|
+
* same operation mounted twice is two methods, and one sentence is not true of both.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Help {
|
|
10
|
+
/** `node` says what the resource is; `method` what one of its methods is. */
|
|
11
|
+
readonly subject: Subject;
|
|
12
|
+
readonly title: string | undefined;
|
|
13
|
+
readonly description: string | undefined;
|
|
14
|
+
constructor(subject: Subject, value: unknown);
|
|
15
|
+
}
|
|
16
|
+
export type Subject = 'node' | 'method';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { described } from './described.js';
|
|
2
|
+
/**
|
|
3
|
+
* What a resource or a method is, in the words an application chooses for it — read by
|
|
4
|
+
* everything that describes one: `OPTIONS`, discovery, and the tools MCP publishes.
|
|
5
|
+
*
|
|
6
|
+
* The operation states what it is too, and that is not this. An operation is written
|
|
7
|
+
* without knowledge of any route, and a method is an operation and a route together — the
|
|
8
|
+
* same operation mounted twice is two methods, and one sentence is not true of both.
|
|
9
|
+
*/
|
|
10
|
+
export class Help {
|
|
11
|
+
/** `node` says what the resource is; `method` what one of its methods is. */
|
|
12
|
+
subject;
|
|
13
|
+
title;
|
|
14
|
+
description;
|
|
15
|
+
constructor(subject, value) {
|
|
16
|
+
const stated = described(`help:${subject}`, value);
|
|
17
|
+
this.subject = subject;
|
|
18
|
+
this.title = stated.title;
|
|
19
|
+
this.description = stated.description;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=Help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Help.js","sourceRoot":"","sources":["../../../source/directives/help/Help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAA;AAE1D;;;;;;;GAOG;AACH,MAAM,OAAO,IAAI;IACf,6EAA6E;IAC7D,OAAO,CAAS;IAChB,KAAK,CAAoB;IACzB,WAAW,CAAoB;IAE/C,YAAmB,OAAgB,EAAE,KAAc;QACjD,MAAM,MAAM,GAAc,SAAS,CAAC,QAAQ,OAAO,EAAE,EAAE,KAAK,CAAC,CAAA;QAE7D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;QACzB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAA;IACvC,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Described } from './described.js';
|
|
2
|
+
/**
|
|
3
|
+
* What the parameters of a method are, by name: a route variable, or one of the
|
|
4
|
+
* querystring. Written where the method is, because what a variable means is what the
|
|
5
|
+
* route it is in makes of it.
|
|
6
|
+
*
|
|
7
|
+
* A name is not checked against the template, because the template is not what says them
|
|
8
|
+
* all: `map:segments` answers a variable under the property it fills instead, and that
|
|
9
|
+
* name is nowhere here. What matches nothing is not answered.
|
|
10
|
+
*/
|
|
11
|
+
export declare class Parameters {
|
|
12
|
+
readonly subject: Subject;
|
|
13
|
+
readonly parameters: Record<string, Described>;
|
|
14
|
+
/** What the route template names, which is a parameter whether an operation takes it or not. */
|
|
15
|
+
readonly variables: string[];
|
|
16
|
+
constructor(subject: Subject, value: unknown, route: string);
|
|
17
|
+
}
|
|
18
|
+
export type Subject = 'route' | 'query';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { segment } from '../../RTD/segment.js';
|
|
3
|
+
import { described } from './described.js';
|
|
4
|
+
/**
|
|
5
|
+
* What the parameters of a method are, by name: a route variable, or one of the
|
|
6
|
+
* querystring. Written where the method is, because what a variable means is what the
|
|
7
|
+
* route it is in makes of it.
|
|
8
|
+
*
|
|
9
|
+
* A name is not checked against the template, because the template is not what says them
|
|
10
|
+
* all: `map:segments` answers a variable under the property it fills instead, and that
|
|
11
|
+
* name is nowhere here. What matches nothing is not answered.
|
|
12
|
+
*/
|
|
13
|
+
export class Parameters {
|
|
14
|
+
subject;
|
|
15
|
+
parameters;
|
|
16
|
+
/** What the route template names, which is a parameter whether an operation takes it or not. */
|
|
17
|
+
variables;
|
|
18
|
+
constructor(subject, value, route) {
|
|
19
|
+
assert.ok(typeof value === 'object' && value !== null && !Array.isArray(value), `Directive help:${subject}: the value names each parameter it describes`);
|
|
20
|
+
const parameters = {};
|
|
21
|
+
for (const [name, stated] of Object.entries(value))
|
|
22
|
+
parameters[name] = described(`help:${subject}.${name}`, stated);
|
|
23
|
+
this.subject = subject;
|
|
24
|
+
this.parameters = parameters;
|
|
25
|
+
this.variables = subject === 'route' ? names(route) : [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** The variables the template names, which are what a route parameter may be called. */
|
|
29
|
+
function names(route) {
|
|
30
|
+
return segment(route)
|
|
31
|
+
.map((part) => part.fragment !== null ? null : part.wildcard === true ? '**' : part.placeholder)
|
|
32
|
+
.filter((name) => name !== null);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=Parameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Parameters.js","sourceRoot":"","sources":["../../../source/directives/help/Parameters.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAA;AAE1D;;;;;;;;GAQG;AACH,MAAM,OAAO,UAAU;IACL,OAAO,CAAS;IAChB,UAAU,CAA2B;IAErD,gGAAgG;IAChF,SAAS,CAAU;IAEnC,YAAmB,OAAgB,EAAE,KAAc,EAAE,KAAa;QAChE,MAAM,CAAC,EAAE,CACP,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EACpE,kBAAkB,OAAO,+CAA+C,CACzE,CAAA;QAED,MAAM,UAAU,GAA8B,EAAE,CAAA;QAEhD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAChD,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,OAAO,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,CAAA;QAEjE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC1D,CAAC;CACF;AAED,wFAAwF;AACxF,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,OAAO,CAAC,KAAK,CAAC;SAClB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CACjF;SACA,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AACpD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** What a resource, a method or a parameter says of itself, in the order it is written. */
|
|
2
|
+
export interface Described {
|
|
3
|
+
title?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
/** what its methods are guarded by; see `guarded` */
|
|
6
|
+
authenticated?: boolean;
|
|
7
|
+
private?: boolean;
|
|
8
|
+
protected?: boolean;
|
|
9
|
+
system?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A bare value is the title: it is the short thing, and the one a client has somewhere to
|
|
13
|
+
* put — a name is an address and reads as one. A sentence is written as a mapping, beside
|
|
14
|
+
* the title it explains, and either may stand alone.
|
|
15
|
+
*/
|
|
16
|
+
export declare function described(subject: string, value: unknown): Described;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
/**
|
|
3
|
+
* A bare value is the title: it is the short thing, and the one a client has somewhere to
|
|
4
|
+
* put — a name is an address and reads as one. A sentence is written as a mapping, beside
|
|
5
|
+
* the title it explains, and either may stand alone.
|
|
6
|
+
*/
|
|
7
|
+
export function described(subject, value) {
|
|
8
|
+
const stated = typeof value === 'string' ? { title: value } : value;
|
|
9
|
+
assert.ok(typeof stated === 'object' && stated !== null && !Array.isArray(stated), `Directive ${subject}: the value is a title, or a \`title\` and a \`description\``);
|
|
10
|
+
const { title, description, ...rest } = stated;
|
|
11
|
+
assert.ok(Object.keys(rest).length === 0, `Directive ${subject}: unknown ${Object.keys(rest)
|
|
12
|
+
.map((key) => `'${key}'`)
|
|
13
|
+
.join(', ')}`);
|
|
14
|
+
assert.ok(title === undefined || (typeof title === 'string' && title.trim().length > 0), `Directive ${subject}: a title cannot be empty`);
|
|
15
|
+
assert.ok(description === undefined ||
|
|
16
|
+
(typeof description === 'string' && description.trim().length > 0), `Directive ${subject}: a description cannot be empty`);
|
|
17
|
+
assert.ok(title !== undefined || description !== undefined, `Directive ${subject}: says nothing`);
|
|
18
|
+
return {
|
|
19
|
+
...(title === undefined ? {} : { title: title }),
|
|
20
|
+
...(description === undefined ? {} : { description: description })
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=described.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"described.js","sourceRoot":"","sources":["../../../source/directives/help/described.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAchC;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,KAAc;IACvD,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;IAEnE,MAAM,CAAC,EAAE,CACP,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACvE,aAAa,OAAO,8DAA8D,CACnF,CAAA;IAED,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,MAAiC,CAAA;IAEzE,MAAM,CAAC,EAAE,CACP,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAC9B,aAAa,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;SAC/C,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAA;IAED,MAAM,CAAC,EAAE,CACP,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAC7E,aAAa,OAAO,2BAA2B,CAChD,CAAA;IAED,MAAM,CAAC,EAAE,CACP,WAAW,KAAK,SAAS;QACvB,CAAC,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EACpE,aAAa,OAAO,iCAAiC,CACtD,CAAA;IAED,MAAM,CAAC,EAAE,CACP,KAAK,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,EAChD,aAAa,OAAO,gBAAgB,CACrC,CAAA;IAED,OAAO;QACL,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAe,EAAE,CAAC;QAC1D,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,WAAqB,EAAE,CAAC;KAC7E,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Family } from './Family.js';
|
|
2
|
+
import type { Described } from './described.js';
|
|
3
|
+
import type { Directives } from '../../RTD/index.js';
|
|
4
|
+
import type { Introspection } from '../../Introspection.js';
|
|
5
|
+
export declare const help: Family;
|
|
6
|
+
/**
|
|
7
|
+
* What the resource a method is on says of itself, or nothing where it says nothing. Read
|
|
8
|
+
* from the method because that is what carries a route's directives; every method of one
|
|
9
|
+
* node carries the same declaration.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resource(directives: Directives): Described | null;
|
|
12
|
+
/**
|
|
13
|
+
* What a resource is, taken from what its methods are: the flags are a method's, and a
|
|
14
|
+
* resource carries whichever of them any of its methods does — which is what a reader picks
|
|
15
|
+
* one icon by.
|
|
16
|
+
*/
|
|
17
|
+
export declare function guarded(methods: Record<string, Introspection>): Described;
|
|
18
|
+
export { FAMILY, Family } from './Family.js';
|
|
19
|
+
export { Help } from './Help.js';
|
|
20
|
+
export { Parameters } from './Parameters.js';
|
|
21
|
+
export type { Directive } from './Family.js';
|
|
22
|
+
export type { Described } from './described.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Family, FAMILY } from './Family.js';
|
|
2
|
+
export const help = new Family();
|
|
3
|
+
/**
|
|
4
|
+
* What the resource a method is on says of itself, or nothing where it says nothing. Read
|
|
5
|
+
* from the method because that is what carries a route's directives; every method of one
|
|
6
|
+
* node carries the same declaration.
|
|
7
|
+
*/
|
|
8
|
+
export function resource(directives) {
|
|
9
|
+
const stated = Family.node(directives.declared(FAMILY));
|
|
10
|
+
if (stated === null)
|
|
11
|
+
return null;
|
|
12
|
+
return {
|
|
13
|
+
...(stated.title === undefined ? {} : { title: stated.title }),
|
|
14
|
+
...(stated.description === undefined ? {} : { description: stated.description })
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* What a resource is, taken from what its methods are: the flags are a method's, and a
|
|
19
|
+
* resource carries whichever of them any of its methods does — which is what a reader picks
|
|
20
|
+
* one icon by.
|
|
21
|
+
*/
|
|
22
|
+
export function guarded(methods) {
|
|
23
|
+
const described = {};
|
|
24
|
+
for (const introspection of Object.values(methods))
|
|
25
|
+
for (const flag of FLAGS)
|
|
26
|
+
if (introspection[flag] === true)
|
|
27
|
+
described[flag] = true;
|
|
28
|
+
return described;
|
|
29
|
+
}
|
|
30
|
+
const FLAGS = ['authenticated', 'private', 'protected', 'system'];
|
|
31
|
+
export { FAMILY, Family } from './Family.js';
|
|
32
|
+
export { Help } from './Help.js';
|
|
33
|
+
export { Parameters } from './Parameters.js';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../source/directives/help/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAM5C,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE,CAAA;AAEhC;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,UAAsB;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAY,MAAM,CAAC,CAAC,CAAA;IAElE,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAEhC,OAAO;QACL,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;KACjF,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,OAAsC;IAC5D,MAAM,SAAS,GAAc,EAAE,CAAA;IAE/B,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,IAAI;gBAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAEpF,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAU,CAAA;AAE1E,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { DirectiveFamily } from '../RTD/index.js';
|
|
2
2
|
import type { Interceptor } from '../Interception.js';
|
|
3
3
|
export declare const families: DirectiveFamily[];
|
|
4
|
+
/**
|
|
5
|
+
* `cors` first, so a preflight is answered before anything reads the request; the page is
|
|
6
|
+
* last, and claims its own prefix.
|
|
7
|
+
*/
|
|
4
8
|
export declare const interceptors: Interceptor[];
|
|
@@ -8,17 +8,24 @@ import { map } from './map/index.js';
|
|
|
8
8
|
import { mcp } from './mcp/index.js';
|
|
9
9
|
import { req } from './require/index.js';
|
|
10
10
|
import { flow } from './flow/index.js';
|
|
11
|
+
import { help } from './help/index.js';
|
|
11
12
|
import { discovery } from './oauth/index.js';
|
|
13
|
+
import { Site } from '../Discovery/index.js';
|
|
12
14
|
export const families = [
|
|
13
15
|
authorization,
|
|
14
16
|
io,
|
|
15
17
|
cache,
|
|
16
18
|
map,
|
|
17
19
|
mcp,
|
|
20
|
+
help,
|
|
18
21
|
req,
|
|
19
22
|
flow,
|
|
20
23
|
octets,
|
|
21
24
|
dev
|
|
22
25
|
];
|
|
23
|
-
|
|
26
|
+
/**
|
|
27
|
+
* `cors` first, so a preflight is answered before anything reads the request; the page is
|
|
28
|
+
* last, and claims its own prefix.
|
|
29
|
+
*/
|
|
30
|
+
export const interceptors = [cors, discovery, new Site()];
|
|
24
31
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/directives/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAI5C,MAAM,CAAC,MAAM,QAAQ,GAAsB;IACzC,aAAa;IACb,EAAE;IACF,KAAK;IACL,GAAG;IACH,GAAG;IACH,GAAG;IACH,IAAI;IACJ,MAAM;IACN,GAAG;CACJ,CAAA;AACD,MAAM,CAAC,MAAM,YAAY,GAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/directives/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAI5C,MAAM,CAAC,MAAM,QAAQ,GAAsB;IACzC,aAAa;IACb,EAAE;IACF,KAAK;IACL,GAAG;IACH,GAAG;IACH,IAAI;IACJ,GAAG;IACH,IAAI;IACJ,MAAM;IACN,GAAG;CACJ,CAAA;AACD;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA"}
|
|
@@ -4,6 +4,11 @@ import type { Introspection } from '../../Introspection.js';
|
|
|
4
4
|
export declare class Headers extends Mapping<Record<string, string>> {
|
|
5
5
|
private readonly headers;
|
|
6
6
|
constructor(map: Record<string, string>);
|
|
7
|
+
/**
|
|
8
|
+
* The property is filled from a request header, so it is not the body's to send. Which
|
|
9
|
+
* header, and that there is one at all, is not answered: what an application reads off a
|
|
10
|
+
* request is its own, and a caller has nowhere to put one anyway.
|
|
11
|
+
*/
|
|
7
12
|
explain(introspection: Introspection): void;
|
|
8
13
|
properties(context: Input): Record<string, string>;
|
|
9
14
|
}
|
|
@@ -17,12 +17,14 @@ export class Headers extends Mapping {
|
|
|
17
17
|
this.headers = Object.values(map).filter((header) => !FORBIDDEN.has(header));
|
|
18
18
|
this.headers.forEach((header) => cors.allow(header));
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* The property is filled from a request header, so it is not the body's to send. Which
|
|
22
|
+
* header, and that there is one at all, is not answered: what an application reads off a
|
|
23
|
+
* request is its own, and a caller has nowhere to put one anyway.
|
|
24
|
+
*/
|
|
20
25
|
explain(introspection) {
|
|
21
|
-
for (const
|
|
22
|
-
|
|
23
|
-
introspection.headers ??= {};
|
|
24
|
-
introspection.headers[property] = { ...schema, header };
|
|
25
|
-
}
|
|
26
|
+
for (const property of Object.keys(this.value))
|
|
27
|
+
take(introspection, property);
|
|
26
28
|
}
|
|
27
29
|
properties(context) {
|
|
28
30
|
context.pipelines.response.push((response) => {
|