@twin.org/web 0.0.3-next.25 → 0.0.3-next.26
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/es/index.js +2 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/models/IHttpLinkHeader.js +2 -0
- package/dist/es/models/IHttpLinkHeader.js.map +1 -0
- package/dist/es/models/httpLinkRelType.js +130 -0
- package/dist/es/models/httpLinkRelType.js.map +1 -0
- package/dist/es/utils/headerHelper.js +77 -19
- package/dist/es/utils/headerHelper.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/models/IHttpLinkHeader.d.ts +26 -0
- package/dist/types/models/httpLinkRelType.d.ts +130 -0
- package/dist/types/utils/headerHelper.d.ts +22 -32
- package/docs/changelog.md +20 -0
- package/docs/reference/classes/HeaderHelper.md +67 -9
- package/docs/reference/index.md +3 -0
- package/docs/reference/interfaces/IHttpLinkHeader.md +43 -0
- package/docs/reference/type-aliases/HttpLinkRelType.md +5 -0
- package/docs/reference/variables/HttpLinkRelType.md +191 -0
- package/package.json +4 -4
package/dist/es/index.js
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
3
|
export * from "./errors/fetchError.js";
|
|
4
4
|
export * from "./models/headerTypes.js";
|
|
5
|
+
export * from "./models/httpLinkRelType.js";
|
|
5
6
|
export * from "./models/httpMethod.js";
|
|
6
7
|
export * from "./models/httpStatusCode.js";
|
|
7
8
|
export * from "./models/IFetchOptions.js";
|
|
8
9
|
export * from "./models/IHttpHeaders.js";
|
|
10
|
+
export * from "./models/IHttpLinkHeader.js";
|
|
9
11
|
export * from "./models/IJwk.js";
|
|
10
12
|
export * from "./models/IJwtHeader.js";
|
|
11
13
|
export * from "./models/IJwtPayload.js";
|
package/dist/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./errors/fetchError.js\";\nexport * from \"./models/headerTypes.js\";\nexport * from \"./models/httpMethod.js\";\nexport * from \"./models/httpStatusCode.js\";\nexport * from \"./models/IFetchOptions.js\";\nexport * from \"./models/IHttpHeaders.js\";\nexport * from \"./models/IJwk.js\";\nexport * from \"./models/IJwtHeader.js\";\nexport * from \"./models/IJwtPayload.js\";\nexport * from \"./models/jwkCryptoKey.js\";\nexport * from \"./models/mimeTypes.js\";\nexport * from \"./utils/cookieHelper.js\";\nexport * from \"./utils/fetchHelper.js\";\nexport * from \"./utils/headerHelper.js\";\nexport * from \"./utils/jwk.js\";\nexport * from \"./utils/jws.js\";\nexport * from \"./utils/jwt.js\";\nexport * from \"./utils/mimeTypeHelper.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./errors/fetchError.js\";\nexport * from \"./models/headerTypes.js\";\nexport * from \"./models/httpLinkRelType.js\";\nexport * from \"./models/httpMethod.js\";\nexport * from \"./models/httpStatusCode.js\";\nexport * from \"./models/IFetchOptions.js\";\nexport * from \"./models/IHttpHeaders.js\";\nexport * from \"./models/IHttpLinkHeader.js\";\nexport * from \"./models/IJwk.js\";\nexport * from \"./models/IJwtHeader.js\";\nexport * from \"./models/IJwtPayload.js\";\nexport * from \"./models/jwkCryptoKey.js\";\nexport * from \"./models/mimeTypes.js\";\nexport * from \"./utils/cookieHelper.js\";\nexport * from \"./utils/fetchHelper.js\";\nexport * from \"./utils/headerHelper.js\";\nexport * from \"./utils/jwk.js\";\nexport * from \"./utils/jws.js\";\nexport * from \"./utils/jwt.js\";\nexport * from \"./utils/mimeTypeHelper.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IHttpLinkHeader.js","sourceRoot":"","sources":["../../../src/models/IHttpLinkHeader.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { HttpLinkRelType } from \"./httpLinkRelType.js\";\n\n/**\n * Model used for Http link headers parameter.\n */\nexport interface IHttpLinkHeader {\n\t/**\n\t * The URL of the link.\n\t */\n\turl: string;\n\n\t/**\n\t * Optional query parameters for the URL.\n\t */\n\turlQueryParams?: { [id: string]: string };\n\n\t/**\n\t * The relation types of the link.\n\t */\n\trel: (string | HttpLinkRelType)[];\n\n\t/**\n\t * Optional additional parameters for the link.\n\t */\n\tparams?: { [id: string]: string };\n}\n"]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
/**
|
|
4
|
+
* Common HTML rel attribute values.
|
|
5
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel
|
|
6
|
+
*/
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
8
|
+
export const HttpLinkRelType = {
|
|
9
|
+
/**
|
|
10
|
+
* Alternate representation of the current document.
|
|
11
|
+
*/
|
|
12
|
+
alternate: "alternate",
|
|
13
|
+
/**
|
|
14
|
+
* Author of the current document or article.
|
|
15
|
+
*/
|
|
16
|
+
author: "author",
|
|
17
|
+
/**
|
|
18
|
+
* Permalink for the nearest ancestor section.
|
|
19
|
+
*/
|
|
20
|
+
bookmark: "bookmark",
|
|
21
|
+
/**
|
|
22
|
+
* Preferred URL for the current document.
|
|
23
|
+
*/
|
|
24
|
+
canonical: "canonical",
|
|
25
|
+
/**
|
|
26
|
+
* Compression dictionary for future downloads.
|
|
27
|
+
*/
|
|
28
|
+
compressionDictionary: "compression-dictionary",
|
|
29
|
+
/**
|
|
30
|
+
* Hint to perform DNS resolution in advance.
|
|
31
|
+
*/
|
|
32
|
+
dnsPrefetch: "dns-prefetch",
|
|
33
|
+
/**
|
|
34
|
+
* The referenced document is external to the current site.
|
|
35
|
+
*/
|
|
36
|
+
external: "external",
|
|
37
|
+
/**
|
|
38
|
+
* Allows render-blocking until essential parts are parsed.
|
|
39
|
+
*/
|
|
40
|
+
expect: "expect",
|
|
41
|
+
/**
|
|
42
|
+
* Link to context-sensitive help.
|
|
43
|
+
*/
|
|
44
|
+
help: "help",
|
|
45
|
+
/**
|
|
46
|
+
* Icon representing the current document.
|
|
47
|
+
*/
|
|
48
|
+
icon: "icon",
|
|
49
|
+
/**
|
|
50
|
+
* Licensing information for the current document.
|
|
51
|
+
*/
|
|
52
|
+
license: "license",
|
|
53
|
+
/**
|
|
54
|
+
* Web application manifest.
|
|
55
|
+
*/
|
|
56
|
+
manifest: "manifest",
|
|
57
|
+
/**
|
|
58
|
+
* Indicates the current document represents the linked identity.
|
|
59
|
+
*/
|
|
60
|
+
me: "me",
|
|
61
|
+
/**
|
|
62
|
+
* Pre-emptively fetch a module and optionally its dependencies.
|
|
63
|
+
*/
|
|
64
|
+
modulePreload: "modulepreload",
|
|
65
|
+
/**
|
|
66
|
+
* The next document in a series.
|
|
67
|
+
*/
|
|
68
|
+
next: "next",
|
|
69
|
+
/**
|
|
70
|
+
* The current document does not endorse the referenced document.
|
|
71
|
+
*/
|
|
72
|
+
nofollow: "nofollow",
|
|
73
|
+
/**
|
|
74
|
+
* Prevent access to the originating browsing context.
|
|
75
|
+
*/
|
|
76
|
+
noopener: "noopener",
|
|
77
|
+
/**
|
|
78
|
+
* Suppress the Referer header and implies noopener.
|
|
79
|
+
*/
|
|
80
|
+
noreferrer: "noreferrer",
|
|
81
|
+
/**
|
|
82
|
+
* Allow access to the originating browsing context.
|
|
83
|
+
*/
|
|
84
|
+
opener: "opener",
|
|
85
|
+
/**
|
|
86
|
+
* Address of the pingback server for the current document.
|
|
87
|
+
*/
|
|
88
|
+
pingback: "pingback",
|
|
89
|
+
/**
|
|
90
|
+
* Hint to connect to the target origin in advance.
|
|
91
|
+
*/
|
|
92
|
+
preconnect: "preconnect",
|
|
93
|
+
/**
|
|
94
|
+
* Hint to fetch and cache a likely next resource.
|
|
95
|
+
*/
|
|
96
|
+
prefetch: "prefetch",
|
|
97
|
+
/**
|
|
98
|
+
* Hint to fetch and cache a resource for the current navigation.
|
|
99
|
+
*/
|
|
100
|
+
preload: "preload",
|
|
101
|
+
/**
|
|
102
|
+
* Deprecated hint to fetch and process a target in advance.
|
|
103
|
+
*/
|
|
104
|
+
prerender: "prerender",
|
|
105
|
+
/**
|
|
106
|
+
* The previous document in a series.
|
|
107
|
+
*/
|
|
108
|
+
prev: "prev",
|
|
109
|
+
/**
|
|
110
|
+
* Privacy policy for the current document.
|
|
111
|
+
*/
|
|
112
|
+
privacyPolicy: "privacy-policy",
|
|
113
|
+
/**
|
|
114
|
+
* Search resource for the current document or related resources.
|
|
115
|
+
*/
|
|
116
|
+
search: "search",
|
|
117
|
+
/**
|
|
118
|
+
* External stylesheet for the current document.
|
|
119
|
+
*/
|
|
120
|
+
stylesheet: "stylesheet",
|
|
121
|
+
/**
|
|
122
|
+
* Tag applying to the current document.
|
|
123
|
+
*/
|
|
124
|
+
tag: "tag",
|
|
125
|
+
/**
|
|
126
|
+
* Terms of service for the current document.
|
|
127
|
+
*/
|
|
128
|
+
termsOfService: "terms-of-service"
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=httpLinkRelType.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpLinkRelType.js","sourceRoot":"","sources":["../../../src/models/httpLinkRelType.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AAEvC;;;GAGG;AACH,gEAAgE;AAChE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B;;OAEG;IACH,SAAS,EAAE,WAAW;IAEtB;;OAEG;IACH,MAAM,EAAE,QAAQ;IAEhB;;OAEG;IACH,QAAQ,EAAE,UAAU;IAEpB;;OAEG;IACH,SAAS,EAAE,WAAW;IAEtB;;OAEG;IACH,qBAAqB,EAAE,wBAAwB;IAE/C;;OAEG;IACH,WAAW,EAAE,cAAc;IAE3B;;OAEG;IACH,QAAQ,EAAE,UAAU;IAEpB;;OAEG;IACH,MAAM,EAAE,QAAQ;IAEhB;;OAEG;IACH,IAAI,EAAE,MAAM;IAEZ;;OAEG;IACH,IAAI,EAAE,MAAM;IAEZ;;OAEG;IACH,OAAO,EAAE,SAAS;IAElB;;OAEG;IACH,QAAQ,EAAE,UAAU;IAEpB;;OAEG;IACH,EAAE,EAAE,IAAI;IAER;;OAEG;IACH,aAAa,EAAE,eAAe;IAE9B;;OAEG;IACH,IAAI,EAAE,MAAM;IAEZ;;OAEG;IACH,QAAQ,EAAE,UAAU;IAEpB;;OAEG;IACH,QAAQ,EAAE,UAAU;IAEpB;;OAEG;IACH,UAAU,EAAE,YAAY;IAExB;;OAEG;IACH,MAAM,EAAE,QAAQ;IAEhB;;OAEG;IACH,QAAQ,EAAE,UAAU;IAEpB;;OAEG;IACH,UAAU,EAAE,YAAY;IAExB;;OAEG;IACH,QAAQ,EAAE,UAAU;IAEpB;;OAEG;IACH,OAAO,EAAE,SAAS;IAElB;;OAEG;IACH,SAAS,EAAE,WAAW;IAEtB;;OAEG;IACH,IAAI,EAAE,MAAM;IAEZ;;OAEG;IACH,aAAa,EAAE,gBAAgB;IAE/B;;OAEG;IACH,MAAM,EAAE,QAAQ;IAEhB;;OAEG;IACH,UAAU,EAAE,YAAY;IAExB;;OAEG;IACH,GAAG,EAAE,KAAK;IAEV;;OAEG;IACH,cAAc,EAAE,kBAAkB;CACzB,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Common HTML rel attribute values.\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const HttpLinkRelType = {\n\t/**\n\t * Alternate representation of the current document.\n\t */\n\talternate: \"alternate\",\n\n\t/**\n\t * Author of the current document or article.\n\t */\n\tauthor: \"author\",\n\n\t/**\n\t * Permalink for the nearest ancestor section.\n\t */\n\tbookmark: \"bookmark\",\n\n\t/**\n\t * Preferred URL for the current document.\n\t */\n\tcanonical: \"canonical\",\n\n\t/**\n\t * Compression dictionary for future downloads.\n\t */\n\tcompressionDictionary: \"compression-dictionary\",\n\n\t/**\n\t * Hint to perform DNS resolution in advance.\n\t */\n\tdnsPrefetch: \"dns-prefetch\",\n\n\t/**\n\t * The referenced document is external to the current site.\n\t */\n\texternal: \"external\",\n\n\t/**\n\t * Allows render-blocking until essential parts are parsed.\n\t */\n\texpect: \"expect\",\n\n\t/**\n\t * Link to context-sensitive help.\n\t */\n\thelp: \"help\",\n\n\t/**\n\t * Icon representing the current document.\n\t */\n\ticon: \"icon\",\n\n\t/**\n\t * Licensing information for the current document.\n\t */\n\tlicense: \"license\",\n\n\t/**\n\t * Web application manifest.\n\t */\n\tmanifest: \"manifest\",\n\n\t/**\n\t * Indicates the current document represents the linked identity.\n\t */\n\tme: \"me\",\n\n\t/**\n\t * Pre-emptively fetch a module and optionally its dependencies.\n\t */\n\tmodulePreload: \"modulepreload\",\n\n\t/**\n\t * The next document in a series.\n\t */\n\tnext: \"next\",\n\n\t/**\n\t * The current document does not endorse the referenced document.\n\t */\n\tnofollow: \"nofollow\",\n\n\t/**\n\t * Prevent access to the originating browsing context.\n\t */\n\tnoopener: \"noopener\",\n\n\t/**\n\t * Suppress the Referer header and implies noopener.\n\t */\n\tnoreferrer: \"noreferrer\",\n\n\t/**\n\t * Allow access to the originating browsing context.\n\t */\n\topener: \"opener\",\n\n\t/**\n\t * Address of the pingback server for the current document.\n\t */\n\tpingback: \"pingback\",\n\n\t/**\n\t * Hint to connect to the target origin in advance.\n\t */\n\tpreconnect: \"preconnect\",\n\n\t/**\n\t * Hint to fetch and cache a likely next resource.\n\t */\n\tprefetch: \"prefetch\",\n\n\t/**\n\t * Hint to fetch and cache a resource for the current navigation.\n\t */\n\tpreload: \"preload\",\n\n\t/**\n\t * Deprecated hint to fetch and process a target in advance.\n\t */\n\tprerender: \"prerender\",\n\n\t/**\n\t * The previous document in a series.\n\t */\n\tprev: \"prev\",\n\n\t/**\n\t * Privacy policy for the current document.\n\t */\n\tprivacyPolicy: \"privacy-policy\",\n\n\t/**\n\t * Search resource for the current document or related resources.\n\t */\n\tsearch: \"search\",\n\n\t/**\n\t * External stylesheet for the current document.\n\t */\n\tstylesheet: \"stylesheet\",\n\n\t/**\n\t * Tag applying to the current document.\n\t */\n\ttag: \"tag\",\n\n\t/**\n\t * Terms of service for the current document.\n\t */\n\ttermsOfService: \"terms-of-service\"\n} as const;\n\n/**\n * Common HTML rel attribute values.\n */\nexport type HttpLinkRelType = (typeof HttpLinkRelType)[keyof typeof HttpLinkRelType];\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright 2024 IOTA Stiftung.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
-
import { GeneralError, Guards, Is } from "@twin.org/core";
|
|
3
|
+
import { ArrayHelper, GeneralError, Guards, Is } from "@twin.org/core";
|
|
4
4
|
/**
|
|
5
5
|
* Class to helper with header operations.
|
|
6
6
|
*/
|
|
@@ -35,7 +35,7 @@ export class HeaderHelper {
|
|
|
35
35
|
return "";
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
* Extract the properties from a Link header for a specific relation type.
|
|
38
|
+
* Extract the first occurrence of properties from a Link header for a specific relation type.
|
|
39
39
|
* @param linkHeader The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
40
40
|
* @param relation The relation type to extract.
|
|
41
41
|
* @returns The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
@@ -44,7 +44,20 @@ export class HeaderHelper {
|
|
|
44
44
|
static extractLinkHeaderRelation(linkHeader, relation) {
|
|
45
45
|
const headers = HeaderHelper.extractLinkHeaders(linkHeader);
|
|
46
46
|
if (Is.arrayValue(headers)) {
|
|
47
|
-
return headers.find(h => h.rel
|
|
47
|
+
return headers.find(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extract multiple properties from a Link header for a specific relation type.
|
|
52
|
+
* @param linkHeader The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
53
|
+
* @param relation The relation type to extract.
|
|
54
|
+
* @returns The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
55
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
56
|
+
*/
|
|
57
|
+
static extractLinkHeaderRelations(linkHeader, relation) {
|
|
58
|
+
const headers = HeaderHelper.extractLinkHeaders(linkHeader);
|
|
59
|
+
if (Is.arrayValue(headers)) {
|
|
60
|
+
return headers.filter(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));
|
|
48
61
|
}
|
|
49
62
|
}
|
|
50
63
|
/**
|
|
@@ -54,22 +67,36 @@ export class HeaderHelper {
|
|
|
54
67
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
55
68
|
*/
|
|
56
69
|
static extractLinkHeaders(linkHeader) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return header ? [header] : [];
|
|
60
|
-
}
|
|
61
|
-
if (Is.arrayValue(linkHeader)) {
|
|
70
|
+
const linkHeaderArray = ArrayHelper.fromObjectOrArray(linkHeader);
|
|
71
|
+
if (Is.arrayValue(linkHeaderArray)) {
|
|
62
72
|
const results = [];
|
|
63
|
-
for (const singleLinkHeader of
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
results.push(header);
|
|
67
|
-
}
|
|
73
|
+
for (const singleLinkHeader of linkHeaderArray) {
|
|
74
|
+
const segments = HeaderHelper.extractLinkHeaderSegments(singleLinkHeader);
|
|
75
|
+
results.push(...segments.map(l => HeaderHelper.extractLinkHeader(l)).filter(h => !Is.empty(h)));
|
|
68
76
|
}
|
|
69
77
|
return results;
|
|
70
78
|
}
|
|
71
79
|
return undefined;
|
|
72
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Split a combined Link header value into individual link-value segments, comma separated.
|
|
83
|
+
* @param linkHeader Raw Link header string.
|
|
84
|
+
* @returns Array of individual link-value segments.
|
|
85
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
86
|
+
*/
|
|
87
|
+
static extractLinkHeaderSegments(linkHeader) {
|
|
88
|
+
if (!Is.stringValue(linkHeader)) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
const trimmed = linkHeader.trim();
|
|
92
|
+
if (Is.empty(trimmed)) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
return trimmed
|
|
96
|
+
.split(/,(?=\s*<)/)
|
|
97
|
+
.map(s => s.trim())
|
|
98
|
+
.filter(s => !Is.empty(s));
|
|
99
|
+
}
|
|
73
100
|
/**
|
|
74
101
|
* Extract the properties from a Link header.
|
|
75
102
|
* @param linkHeader The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
@@ -105,7 +132,7 @@ export class HeaderHelper {
|
|
|
105
132
|
for (let i = 1; i < parts.length; i++) {
|
|
106
133
|
const relMatch = /rel="([^"]+)"/.exec(parts[i].trim());
|
|
107
134
|
if (relMatch?.[1]) {
|
|
108
|
-
rel = relMatch[1];
|
|
135
|
+
rel = HeaderHelper.normalizeLinkHeaderRelations(relMatch[1]);
|
|
109
136
|
}
|
|
110
137
|
else {
|
|
111
138
|
const paramMatch = /([^=]+)="([^"]+)"/.exec(parts[i].trim());
|
|
@@ -114,7 +141,7 @@ export class HeaderHelper {
|
|
|
114
141
|
}
|
|
115
142
|
}
|
|
116
143
|
}
|
|
117
|
-
if (Is.stringValue(url) && Is.
|
|
144
|
+
if (Is.stringValue(url) && Is.arrayValue(rel)) {
|
|
118
145
|
return {
|
|
119
146
|
url,
|
|
120
147
|
urlQueryParams,
|
|
@@ -136,12 +163,18 @@ export class HeaderHelper {
|
|
|
136
163
|
*/
|
|
137
164
|
static createLinkHeader(url, urlQueryParams, rel, params) {
|
|
138
165
|
Guards.stringValue(HeaderHelper.CLASS_NAME, "url", url);
|
|
139
|
-
|
|
166
|
+
const relationValues = Is.string(rel)
|
|
167
|
+
? HeaderHelper.normalizeLinkHeaderRelations(rel)
|
|
168
|
+
: ArrayHelper.fromObjectOrArray(rel);
|
|
169
|
+
Guards.arrayValue(HeaderHelper.CLASS_NAME, "rel", relationValues);
|
|
140
170
|
if (url.includes(">")) {
|
|
141
171
|
throw new GeneralError(HeaderHelper.CLASS_NAME, "invalidLinkHeaderURL");
|
|
142
172
|
}
|
|
143
|
-
|
|
144
|
-
|
|
173
|
+
for (let i = 0; i < relationValues.length; i++) {
|
|
174
|
+
Guards.stringValue(HeaderHelper.CLASS_NAME, `${"rel"}.${i.toString()}`, relationValues[i]);
|
|
175
|
+
if (relationValues[i].includes('"') || relationValues[i].includes(" ")) {
|
|
176
|
+
throw new GeneralError(HeaderHelper.CLASS_NAME, "invalidLinkHeaderRel");
|
|
177
|
+
}
|
|
145
178
|
}
|
|
146
179
|
if (Is.objectValue(urlQueryParams)) {
|
|
147
180
|
const queryParamsString = Object.entries(urlQueryParams)
|
|
@@ -158,11 +191,36 @@ export class HeaderHelper {
|
|
|
158
191
|
url += `&${queryParamsString}`;
|
|
159
192
|
}
|
|
160
193
|
}
|
|
161
|
-
return `<${url}>; rel="${
|
|
194
|
+
return `<${url}>; rel="${relationValues.join(" ")}"${params
|
|
162
195
|
? Object.entries(params)
|
|
163
196
|
.map(([key, value]) => `; ${key}="${value}"`)
|
|
164
197
|
.join("")
|
|
165
198
|
: ""}`;
|
|
166
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Does the relation selector match any of the link header relations.
|
|
202
|
+
* @param relations The relations from the header.
|
|
203
|
+
* @param relation The relation selector to test.
|
|
204
|
+
* @returns True if the selector matches any relation.
|
|
205
|
+
* @internal
|
|
206
|
+
*/
|
|
207
|
+
static matchesLinkHeaderRelation(relations, relation) {
|
|
208
|
+
if (Is.string(relation)) {
|
|
209
|
+
return relations.includes(relation);
|
|
210
|
+
}
|
|
211
|
+
return relations.some(relValue => relation.test(relValue));
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Normalize a relation string into tokens.
|
|
215
|
+
* @param relation The relation string.
|
|
216
|
+
* @returns The relation tokens.
|
|
217
|
+
* @internal
|
|
218
|
+
*/
|
|
219
|
+
static normalizeLinkHeaderRelations(relation) {
|
|
220
|
+
return relation
|
|
221
|
+
.split(/\s+/)
|
|
222
|
+
.map(relValue => relValue.trim())
|
|
223
|
+
.filter(relValue => !Is.empty(relValue));
|
|
224
|
+
}
|
|
167
225
|
}
|
|
168
226
|
//# sourceMappingURL=headerHelper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headerHelper.js","sourceRoot":"","sources":["../../../src/utils/headerHelper.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAG1D;;GAEG;AACH,MAAM,OAAO,YAAY;IACxB;;OAEG;IACI,MAAM,CAAU,UAAU,kBAAkC;IAEnE;;;;OAIG;IACI,MAAM,CAAC,YAAY,CAAC,KAAc;QACxC,IAAI,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBACjC,OAAO,KAAK,CAAC;YACd,CAAC;YACD,OAAO,UAAU,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,aAAa,CAAC,MAAe;QAC1C,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,yBAAyB,CACtC,UAAmB,EACnB,QAAgB;QAShB,MAAM,OAAO,GAAG,YAAY,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAC5D,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,kBAAkB,CAAC,UAAmB;QAQnD,IAAI,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,YAAY,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAC1D,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,EAAE,CAAC,UAAU,CAAS,UAAU,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,EAAE,CAAC;YACnB,KAAK,MAAM,gBAAgB,IAAI,UAAU,EAAE,CAAC;gBAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;gBAChE,IAAI,MAAM,EAAE,CAAC;oBACZ,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtB,CAAC;YACF,CAAC;YACD,OAAO,OAAO,CAAC;QAChB,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,iBAAiB,CAAC,UAAkB;QAQjD,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEpC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC;YACR,IAAI,cAAoD,CAAC;YAEzD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnC,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAElB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACpC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;oBACvB,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;oBAClD,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAE9C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;wBACpC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBAC1C,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;4BAClD,cAAc,KAAK,EAAE,CAAC;4BACtB,cAAc,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;wBACjD,CAAC;oBACF,CAAC;gBACF,CAAC;YACF,CAAC;YAED,IAAI,GAAG,CAAC;YACR,MAAM,MAAM,GAA6B,EAAE,CAAC;YAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACvD,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnB,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACP,MAAM,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC7D,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACxC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;oBACvC,CAAC;gBACF,CAAC;YACF,CAAC;YAED,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChD,OAAO;oBACN,GAAG;oBACH,cAAc;oBACd,GAAG;oBACH,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;iBAC3D,CAAC;YACH,CAAC;QACF,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,gBAAgB,CAC7B,GAAW,EACX,cAAoD,EACpD,GAAW,EACX,MAAiC;QAEjC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,SAAe,GAAG,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,SAAe,GAAG,CAAC,CAAC;QAE9D,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,YAAY,CAAC,YAAY,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,YAAY,CAAC,YAAY,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,EAAE,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;YACpC,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;iBACtD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;iBAC5D,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;gBACvB,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAC;YAChC,CAAC;iBAAM,IAAI,UAAU,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1C,GAAG,IAAI,iBAAiB,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACP,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAC;YAChC,CAAC;QACF,CAAC;QAED,OAAO,IAAI,GAAG,WAAW,GAAG,IAC3B,MAAM;YACL,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;iBACrB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,KAAK,GAAG,CAAC;iBAC5C,IAAI,CAAC,EAAE,CAAC;YACX,CAAC,CAAC,EACJ,EAAE,CAAC;IACJ,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { GeneralError, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\n\n/**\n * Class to helper with header operations.\n */\nexport class HeaderHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<HeaderHelper>();\n\n\t/**\n\t * Create a bearer token header.\n\t * @param token The token to create the header for.\n\t * @returns The bearer token header.\n\t */\n\tpublic static createBearer(token: unknown): string {\n\t\tif (Is.stringValue(token)) {\n\t\t\tif (token.startsWith(\"Bearer \")) {\n\t\t\t\treturn token;\n\t\t\t}\n\t\t\treturn `Bearer ${token.trim()}`;\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract the bearer token from a header.\n\t * @param header The header value to extract the token from.\n\t * @returns The extracted token if it exists.\n\t */\n\tpublic static extractBearer(header: unknown): string {\n\t\tif (Is.stringValue(header) && header.startsWith(\"Bearer \")) {\n\t\t\treturn header.slice(7, header.length).trim();\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract the properties from a Link header for a specific relation type.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @param relation The relation type to extract.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderRelation(\n\t\tlinkHeader: unknown,\n\t\trelation: string\n\t):\n\t\t| {\n\t\t\t\turl: string;\n\t\t\t\turlQueryParams?: { [id: string]: string };\n\t\t\t\trel: string;\n\t\t\t\tparams?: { [id: string]: string };\n\t\t }\n\t\t| undefined {\n\t\tconst headers = HeaderHelper.extractLinkHeaders(linkHeader);\n\t\tif (Is.arrayValue(headers)) {\n\t\t\treturn headers.find(h => h.rel === relation);\n\t\t}\n\t}\n\n\t/**\n\t * Extract the link headers.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted possible array of URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaders(linkHeader: unknown):\n\t\t| {\n\t\t\t\turl: string;\n\t\t\t\turlQueryParams?: { [id: string]: string };\n\t\t\t\trel: string;\n\t\t\t\tparams?: { [id: string]: string };\n\t\t }[]\n\t\t| undefined {\n\t\tif (Is.stringValue(linkHeader)) {\n\t\t\tconst header = HeaderHelper.extractLinkHeader(linkHeader);\n\t\t\treturn header ? [header] : [];\n\t\t}\n\t\tif (Is.arrayValue<string>(linkHeader)) {\n\t\t\tconst results = [];\n\t\t\tfor (const singleLinkHeader of linkHeader) {\n\t\t\t\tconst header = HeaderHelper.extractLinkHeader(singleLinkHeader);\n\t\t\t\tif (header) {\n\t\t\t\t\tresults.push(header);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Extract the properties from a Link header.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeader(linkHeader: string):\n\t\t| {\n\t\t\t\turl: string;\n\t\t\t\turlQueryParams?: { [id: string]: string };\n\t\t\t\trel: string;\n\t\t\t\tparams?: { [id: string]: string };\n\t\t }\n\t\t| undefined {\n\t\tif (!Is.stringValue(linkHeader)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parts = linkHeader.split(\";\");\n\n\t\tif (parts.length >= 2) {\n\t\t\tlet url;\n\t\t\tlet urlQueryParams: { [id: string]: string } | undefined;\n\n\t\t\tconst urlMatch = /<([^>]+)>/.exec(parts[0]);\n\t\t\tif (Is.stringValue(urlMatch?.[1])) {\n\t\t\t\turl = urlMatch[1];\n\n\t\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\t\tif (queryIndex !== -1) {\n\t\t\t\t\tconst urlParamsString = url.slice(queryIndex + 1);\n\t\t\t\t\tconst queryParts = urlParamsString.split(\"&\");\n\n\t\t\t\t\tfor (const queryPart of queryParts) {\n\t\t\t\t\t\tconst [key, value] = queryPart.split(\"=\");\n\t\t\t\t\t\tif (Is.stringValue(key) && Is.stringValue(value)) {\n\t\t\t\t\t\t\turlQueryParams ??= {};\n\t\t\t\t\t\t\turlQueryParams[key] = decodeURIComponent(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet rel;\n\t\t\tconst params: { [id: string]: string } = {};\n\n\t\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\t\tconst relMatch = /rel=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\tif (relMatch?.[1]) {\n\t\t\t\t\trel = relMatch[1];\n\t\t\t\t} else {\n\t\t\t\t\tconst paramMatch = /([^=]+)=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\t\tif (paramMatch?.[1] && paramMatch?.[2]) {\n\t\t\t\t\t\tparams[paramMatch[1]] = paramMatch[2];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (Is.stringValue(url) && Is.stringValue(rel)) {\n\t\t\t\treturn {\n\t\t\t\t\turl,\n\t\t\t\t\turlQueryParams,\n\t\t\t\t\trel,\n\t\t\t\t\tparams: Object.keys(params).length > 0 ? params : undefined\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Create a compliant Link header.\n\t * @param url The URL to include in the Link header.\n\t * @param urlQueryParams Optional query parameters to include in the URL.\n\t * @param rel The relation type (e.g., \"next\", \"prev\", \"self\").\n\t * @returns The formatted Link header string.\n\t * @throws GeneralError if the URL or rel are invalid.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static createLinkHeader(\n\t\turl: string,\n\t\turlQueryParams: { [id: string]: string } | undefined,\n\t\trel: string,\n\t\tparams?: { [id: string]: string }\n\t): string {\n\t\tGuards.stringValue(HeaderHelper.CLASS_NAME, nameof(url), url);\n\t\tGuards.stringValue(HeaderHelper.CLASS_NAME, nameof(rel), rel);\n\n\t\tif (url.includes(\">\")) {\n\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderURL\");\n\t\t}\n\t\tif (rel.includes('\"')) {\n\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderRel\");\n\t\t}\n\n\t\tif (Is.objectValue(urlQueryParams)) {\n\t\t\tconst queryParamsString = Object.entries(urlQueryParams)\n\t\t\t\t.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n\t\t\t\t.join(\"&\");\n\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\tif (queryIndex === -1) {\n\t\t\t\turl += `?${queryParamsString}`;\n\t\t\t} else if (queryIndex === url.length - 1) {\n\t\t\t\turl += queryParamsString;\n\t\t\t} else {\n\t\t\t\turl += `&${queryParamsString}`;\n\t\t\t}\n\t\t}\n\n\t\treturn `<${url}>; rel=\"${rel}\"${\n\t\t\tparams\n\t\t\t\t? Object.entries(params)\n\t\t\t\t\t\t.map(([key, value]) => `; ${key}=\"${value}\"`)\n\t\t\t\t\t\t.join(\"\")\n\t\t\t\t: \"\"\n\t\t}`;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"headerHelper.js","sourceRoot":"","sources":["../../../src/utils/headerHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ArrayHelper, GeneralError, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport type { HttpLinkRelType } from \"../models/httpLinkRelType.js\";\nimport type { IHttpLinkHeader } from \"../models/IHttpLinkHeader.js\";\n\n/**\n * Class to helper with header operations.\n */\nexport class HeaderHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<HeaderHelper>();\n\n\t/**\n\t * Create a bearer token header.\n\t * @param token The token to create the header for.\n\t * @returns The bearer token header.\n\t */\n\tpublic static createBearer(token: unknown): string {\n\t\tif (Is.stringValue(token)) {\n\t\t\tif (token.startsWith(\"Bearer \")) {\n\t\t\t\treturn token;\n\t\t\t}\n\t\t\treturn `Bearer ${token.trim()}`;\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract the bearer token from a header.\n\t * @param header The header value to extract the token from.\n\t * @returns The extracted token if it exists.\n\t */\n\tpublic static extractBearer(header: unknown): string {\n\t\tif (Is.stringValue(header) && header.startsWith(\"Bearer \")) {\n\t\t\treturn header.slice(7, header.length).trim();\n\t\t}\n\t\treturn \"\";\n\t}\n\n\t/**\n\t * Extract the first occurrence of properties from a Link header for a specific relation type.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @param relation The relation type to extract.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderRelation(\n\t\tlinkHeader: unknown,\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): IHttpLinkHeader | undefined {\n\t\tconst headers = HeaderHelper.extractLinkHeaders(linkHeader);\n\t\tif (Is.arrayValue(headers)) {\n\t\t\treturn headers.find(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));\n\t\t}\n\t}\n\n\t/**\n\t * Extract multiple properties from a Link header for a specific relation type.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @param relation The relation type to extract.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderRelations(\n\t\tlinkHeader: unknown,\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): IHttpLinkHeader[] | undefined {\n\t\tconst headers = HeaderHelper.extractLinkHeaders(linkHeader);\n\t\tif (Is.arrayValue(headers)) {\n\t\t\treturn headers.filter(h => HeaderHelper.matchesLinkHeaderRelation(h.rel, relation));\n\t\t}\n\t}\n\n\t/**\n\t * Extract the link headers.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted possible array of URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaders(linkHeader: unknown): IHttpLinkHeader[] | undefined {\n\t\tconst linkHeaderArray = ArrayHelper.fromObjectOrArray<string>(linkHeader as string | string[]);\n\t\tif (Is.arrayValue<string>(linkHeaderArray)) {\n\t\t\tconst results = [];\n\t\t\tfor (const singleLinkHeader of linkHeaderArray) {\n\t\t\t\tconst segments = HeaderHelper.extractLinkHeaderSegments(singleLinkHeader);\n\t\t\t\tresults.push(\n\t\t\t\t\t...segments.map(l => HeaderHelper.extractLinkHeader(l)).filter(h => !Is.empty(h))\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Split a combined Link header value into individual link-value segments, comma separated.\n\t * @param linkHeader Raw Link header string.\n\t * @returns Array of individual link-value segments.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeaderSegments(linkHeader: string): string[] {\n\t\tif (!Is.stringValue(linkHeader)) {\n\t\t\treturn [];\n\t\t}\n\t\tconst trimmed = linkHeader.trim();\n\t\tif (Is.empty(trimmed)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn trimmed\n\t\t\t.split(/,(?=\\s*<)/)\n\t\t\t.map(s => s.trim())\n\t\t\t.filter(s => !Is.empty(s));\n\t}\n\n\t/**\n\t * Extract the properties from a Link header.\n\t * @param linkHeader The Link header value in format `<url>; rel=\"...\"; param1=\"\"; param2=\"\"`.\n\t * @returns The extracted URL, rel and optional params or undefined if invalid/missing.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static extractLinkHeader(linkHeader: string): IHttpLinkHeader | undefined {\n\t\tif (!Is.stringValue(linkHeader)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parts = linkHeader.split(\";\");\n\n\t\tif (parts.length >= 2) {\n\t\t\tlet url;\n\t\t\tlet urlQueryParams: { [id: string]: string } | undefined;\n\n\t\t\tconst urlMatch = /<([^>]+)>/.exec(parts[0]);\n\t\t\tif (Is.stringValue(urlMatch?.[1])) {\n\t\t\t\turl = urlMatch[1];\n\n\t\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\t\tif (queryIndex !== -1) {\n\t\t\t\t\tconst urlParamsString = url.slice(queryIndex + 1);\n\t\t\t\t\tconst queryParts = urlParamsString.split(\"&\");\n\n\t\t\t\t\tfor (const queryPart of queryParts) {\n\t\t\t\t\t\tconst [key, value] = queryPart.split(\"=\");\n\t\t\t\t\t\tif (Is.stringValue(key) && Is.stringValue(value)) {\n\t\t\t\t\t\t\turlQueryParams ??= {};\n\t\t\t\t\t\t\turlQueryParams[key] = decodeURIComponent(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet rel: string[] | undefined;\n\t\t\tconst params: { [id: string]: string } = {};\n\n\t\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\t\tconst relMatch = /rel=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\tif (relMatch?.[1]) {\n\t\t\t\t\trel = HeaderHelper.normalizeLinkHeaderRelations(relMatch[1]);\n\t\t\t\t} else {\n\t\t\t\t\tconst paramMatch = /([^=]+)=\"([^\"]+)\"/.exec(parts[i].trim());\n\t\t\t\t\tif (paramMatch?.[1] && paramMatch?.[2]) {\n\t\t\t\t\t\tparams[paramMatch[1]] = paramMatch[2];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (Is.stringValue(url) && Is.arrayValue(rel)) {\n\t\t\t\treturn {\n\t\t\t\t\turl,\n\t\t\t\t\turlQueryParams,\n\t\t\t\t\trel,\n\t\t\t\t\tparams: Object.keys(params).length > 0 ? params : undefined\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Create a compliant Link header.\n\t * @param url The URL to include in the Link header.\n\t * @param urlQueryParams Optional query parameters to include in the URL.\n\t * @param rel The relation type (e.g., \"next\", \"prev\", \"self\").\n\t * @returns The formatted Link header string.\n\t * @throws GeneralError if the URL or rel are invalid.\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link\n\t */\n\tpublic static createLinkHeader(\n\t\turl: string,\n\t\turlQueryParams: { [id: string]: string } | undefined,\n\t\trel: HttpLinkRelType | HttpLinkRelType[] | string | string[],\n\t\tparams?: { [id: string]: string }\n\t): string {\n\t\tGuards.stringValue(HeaderHelper.CLASS_NAME, nameof(url), url);\n\n\t\tconst relationValues = Is.string(rel)\n\t\t\t? HeaderHelper.normalizeLinkHeaderRelations(rel)\n\t\t\t: ArrayHelper.fromObjectOrArray(rel);\n\n\t\tGuards.arrayValue(HeaderHelper.CLASS_NAME, nameof(rel), relationValues);\n\n\t\tif (url.includes(\">\")) {\n\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderURL\");\n\t\t}\n\n\t\tfor (let i = 0; i < relationValues.length; i++) {\n\t\t\tGuards.stringValue(\n\t\t\t\tHeaderHelper.CLASS_NAME,\n\t\t\t\t`${nameof(rel)}.${i.toString()}`,\n\t\t\t\trelationValues[i]\n\t\t\t);\n\t\t\tif (relationValues[i].includes('\"') || relationValues[i].includes(\" \")) {\n\t\t\t\tthrow new GeneralError(HeaderHelper.CLASS_NAME, \"invalidLinkHeaderRel\");\n\t\t\t}\n\t\t}\n\n\t\tif (Is.objectValue(urlQueryParams)) {\n\t\t\tconst queryParamsString = Object.entries(urlQueryParams)\n\t\t\t\t.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n\t\t\t\t.join(\"&\");\n\t\t\tconst queryIndex = url.indexOf(\"?\");\n\t\t\tif (queryIndex === -1) {\n\t\t\t\turl += `?${queryParamsString}`;\n\t\t\t} else if (queryIndex === url.length - 1) {\n\t\t\t\turl += queryParamsString;\n\t\t\t} else {\n\t\t\t\turl += `&${queryParamsString}`;\n\t\t\t}\n\t\t}\n\n\t\treturn `<${url}>; rel=\"${relationValues.join(\" \")}\"${\n\t\t\tparams\n\t\t\t\t? Object.entries(params)\n\t\t\t\t\t\t.map(([key, value]) => `; ${key}=\"${value}\"`)\n\t\t\t\t\t\t.join(\"\")\n\t\t\t\t: \"\"\n\t\t}`;\n\t}\n\n\t/**\n\t * Does the relation selector match any of the link header relations.\n\t * @param relations The relations from the header.\n\t * @param relation The relation selector to test.\n\t * @returns True if the selector matches any relation.\n\t * @internal\n\t */\n\tprivate static matchesLinkHeaderRelation(\n\t\trelations: (HttpLinkRelType | string)[],\n\t\trelation: HttpLinkRelType | string | RegExp\n\t): boolean {\n\t\tif (Is.string(relation)) {\n\t\t\treturn relations.includes(relation);\n\t\t}\n\n\t\treturn relations.some(relValue => relation.test(relValue));\n\t}\n\n\t/**\n\t * Normalize a relation string into tokens.\n\t * @param relation The relation string.\n\t * @returns The relation tokens.\n\t * @internal\n\t */\n\tprivate static normalizeLinkHeaderRelations(relation: string): HttpLinkRelType[] {\n\t\treturn relation\n\t\t\t.split(/\\s+/)\n\t\t\t.map(relValue => relValue.trim())\n\t\t\t.filter(relValue => !Is.empty(relValue)) as HttpLinkRelType[];\n\t}\n}\n"]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from "./errors/fetchError.js";
|
|
2
2
|
export * from "./models/headerTypes.js";
|
|
3
|
+
export * from "./models/httpLinkRelType.js";
|
|
3
4
|
export * from "./models/httpMethod.js";
|
|
4
5
|
export * from "./models/httpStatusCode.js";
|
|
5
6
|
export * from "./models/IFetchOptions.js";
|
|
6
7
|
export * from "./models/IHttpHeaders.js";
|
|
8
|
+
export * from "./models/IHttpLinkHeader.js";
|
|
7
9
|
export * from "./models/IJwk.js";
|
|
8
10
|
export * from "./models/IJwtHeader.js";
|
|
9
11
|
export * from "./models/IJwtPayload.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HttpLinkRelType } from "./httpLinkRelType.js";
|
|
2
|
+
/**
|
|
3
|
+
* Model used for Http link headers parameter.
|
|
4
|
+
*/
|
|
5
|
+
export interface IHttpLinkHeader {
|
|
6
|
+
/**
|
|
7
|
+
* The URL of the link.
|
|
8
|
+
*/
|
|
9
|
+
url: string;
|
|
10
|
+
/**
|
|
11
|
+
* Optional query parameters for the URL.
|
|
12
|
+
*/
|
|
13
|
+
urlQueryParams?: {
|
|
14
|
+
[id: string]: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* The relation types of the link.
|
|
18
|
+
*/
|
|
19
|
+
rel: (string | HttpLinkRelType)[];
|
|
20
|
+
/**
|
|
21
|
+
* Optional additional parameters for the link.
|
|
22
|
+
*/
|
|
23
|
+
params?: {
|
|
24
|
+
[id: string]: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common HTML rel attribute values.
|
|
3
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel
|
|
4
|
+
*/
|
|
5
|
+
export declare const HttpLinkRelType: {
|
|
6
|
+
/**
|
|
7
|
+
* Alternate representation of the current document.
|
|
8
|
+
*/
|
|
9
|
+
readonly alternate: "alternate";
|
|
10
|
+
/**
|
|
11
|
+
* Author of the current document or article.
|
|
12
|
+
*/
|
|
13
|
+
readonly author: "author";
|
|
14
|
+
/**
|
|
15
|
+
* Permalink for the nearest ancestor section.
|
|
16
|
+
*/
|
|
17
|
+
readonly bookmark: "bookmark";
|
|
18
|
+
/**
|
|
19
|
+
* Preferred URL for the current document.
|
|
20
|
+
*/
|
|
21
|
+
readonly canonical: "canonical";
|
|
22
|
+
/**
|
|
23
|
+
* Compression dictionary for future downloads.
|
|
24
|
+
*/
|
|
25
|
+
readonly compressionDictionary: "compression-dictionary";
|
|
26
|
+
/**
|
|
27
|
+
* Hint to perform DNS resolution in advance.
|
|
28
|
+
*/
|
|
29
|
+
readonly dnsPrefetch: "dns-prefetch";
|
|
30
|
+
/**
|
|
31
|
+
* The referenced document is external to the current site.
|
|
32
|
+
*/
|
|
33
|
+
readonly external: "external";
|
|
34
|
+
/**
|
|
35
|
+
* Allows render-blocking until essential parts are parsed.
|
|
36
|
+
*/
|
|
37
|
+
readonly expect: "expect";
|
|
38
|
+
/**
|
|
39
|
+
* Link to context-sensitive help.
|
|
40
|
+
*/
|
|
41
|
+
readonly help: "help";
|
|
42
|
+
/**
|
|
43
|
+
* Icon representing the current document.
|
|
44
|
+
*/
|
|
45
|
+
readonly icon: "icon";
|
|
46
|
+
/**
|
|
47
|
+
* Licensing information for the current document.
|
|
48
|
+
*/
|
|
49
|
+
readonly license: "license";
|
|
50
|
+
/**
|
|
51
|
+
* Web application manifest.
|
|
52
|
+
*/
|
|
53
|
+
readonly manifest: "manifest";
|
|
54
|
+
/**
|
|
55
|
+
* Indicates the current document represents the linked identity.
|
|
56
|
+
*/
|
|
57
|
+
readonly me: "me";
|
|
58
|
+
/**
|
|
59
|
+
* Pre-emptively fetch a module and optionally its dependencies.
|
|
60
|
+
*/
|
|
61
|
+
readonly modulePreload: "modulepreload";
|
|
62
|
+
/**
|
|
63
|
+
* The next document in a series.
|
|
64
|
+
*/
|
|
65
|
+
readonly next: "next";
|
|
66
|
+
/**
|
|
67
|
+
* The current document does not endorse the referenced document.
|
|
68
|
+
*/
|
|
69
|
+
readonly nofollow: "nofollow";
|
|
70
|
+
/**
|
|
71
|
+
* Prevent access to the originating browsing context.
|
|
72
|
+
*/
|
|
73
|
+
readonly noopener: "noopener";
|
|
74
|
+
/**
|
|
75
|
+
* Suppress the Referer header and implies noopener.
|
|
76
|
+
*/
|
|
77
|
+
readonly noreferrer: "noreferrer";
|
|
78
|
+
/**
|
|
79
|
+
* Allow access to the originating browsing context.
|
|
80
|
+
*/
|
|
81
|
+
readonly opener: "opener";
|
|
82
|
+
/**
|
|
83
|
+
* Address of the pingback server for the current document.
|
|
84
|
+
*/
|
|
85
|
+
readonly pingback: "pingback";
|
|
86
|
+
/**
|
|
87
|
+
* Hint to connect to the target origin in advance.
|
|
88
|
+
*/
|
|
89
|
+
readonly preconnect: "preconnect";
|
|
90
|
+
/**
|
|
91
|
+
* Hint to fetch and cache a likely next resource.
|
|
92
|
+
*/
|
|
93
|
+
readonly prefetch: "prefetch";
|
|
94
|
+
/**
|
|
95
|
+
* Hint to fetch and cache a resource for the current navigation.
|
|
96
|
+
*/
|
|
97
|
+
readonly preload: "preload";
|
|
98
|
+
/**
|
|
99
|
+
* Deprecated hint to fetch and process a target in advance.
|
|
100
|
+
*/
|
|
101
|
+
readonly prerender: "prerender";
|
|
102
|
+
/**
|
|
103
|
+
* The previous document in a series.
|
|
104
|
+
*/
|
|
105
|
+
readonly prev: "prev";
|
|
106
|
+
/**
|
|
107
|
+
* Privacy policy for the current document.
|
|
108
|
+
*/
|
|
109
|
+
readonly privacyPolicy: "privacy-policy";
|
|
110
|
+
/**
|
|
111
|
+
* Search resource for the current document or related resources.
|
|
112
|
+
*/
|
|
113
|
+
readonly search: "search";
|
|
114
|
+
/**
|
|
115
|
+
* External stylesheet for the current document.
|
|
116
|
+
*/
|
|
117
|
+
readonly stylesheet: "stylesheet";
|
|
118
|
+
/**
|
|
119
|
+
* Tag applying to the current document.
|
|
120
|
+
*/
|
|
121
|
+
readonly tag: "tag";
|
|
122
|
+
/**
|
|
123
|
+
* Terms of service for the current document.
|
|
124
|
+
*/
|
|
125
|
+
readonly termsOfService: "terms-of-service";
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Common HTML rel attribute values.
|
|
129
|
+
*/
|
|
130
|
+
export type HttpLinkRelType = (typeof HttpLinkRelType)[keyof typeof HttpLinkRelType];
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { HttpLinkRelType } from "../models/httpLinkRelType.js";
|
|
2
|
+
import type { IHttpLinkHeader } from "../models/IHttpLinkHeader.js";
|
|
1
3
|
/**
|
|
2
4
|
* Class to helper with header operations.
|
|
3
5
|
*/
|
|
@@ -19,54 +21,42 @@ export declare class HeaderHelper {
|
|
|
19
21
|
*/
|
|
20
22
|
static extractBearer(header: unknown): string;
|
|
21
23
|
/**
|
|
22
|
-
* Extract the properties from a Link header for a specific relation type.
|
|
24
|
+
* Extract the first occurrence of properties from a Link header for a specific relation type.
|
|
23
25
|
* @param linkHeader The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
24
26
|
* @param relation The relation type to extract.
|
|
25
27
|
* @returns The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
26
28
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
27
29
|
*/
|
|
28
|
-
static extractLinkHeaderRelation(linkHeader: unknown, relation: string):
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} | undefined;
|
|
30
|
+
static extractLinkHeaderRelation(linkHeader: unknown, relation: HttpLinkRelType | string | RegExp): IHttpLinkHeader | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Extract multiple properties from a Link header for a specific relation type.
|
|
33
|
+
* @param linkHeader The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
34
|
+
* @param relation The relation type to extract.
|
|
35
|
+
* @returns The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
36
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
37
|
+
*/
|
|
38
|
+
static extractLinkHeaderRelations(linkHeader: unknown, relation: HttpLinkRelType | string | RegExp): IHttpLinkHeader[] | undefined;
|
|
38
39
|
/**
|
|
39
40
|
* Extract the link headers.
|
|
40
41
|
* @param linkHeader The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
41
42
|
* @returns The extracted possible array of URL, rel and optional params or undefined if invalid/missing.
|
|
42
43
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
43
44
|
*/
|
|
44
|
-
static extractLinkHeaders(linkHeader: unknown):
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
};
|
|
53
|
-
}[] | undefined;
|
|
45
|
+
static extractLinkHeaders(linkHeader: unknown): IHttpLinkHeader[] | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Split a combined Link header value into individual link-value segments, comma separated.
|
|
48
|
+
* @param linkHeader Raw Link header string.
|
|
49
|
+
* @returns Array of individual link-value segments.
|
|
50
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
51
|
+
*/
|
|
52
|
+
static extractLinkHeaderSegments(linkHeader: string): string[];
|
|
54
53
|
/**
|
|
55
54
|
* Extract the properties from a Link header.
|
|
56
55
|
* @param linkHeader The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
57
56
|
* @returns The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
58
57
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
59
58
|
*/
|
|
60
|
-
static extractLinkHeader(linkHeader: string):
|
|
61
|
-
url: string;
|
|
62
|
-
urlQueryParams?: {
|
|
63
|
-
[id: string]: string;
|
|
64
|
-
};
|
|
65
|
-
rel: string;
|
|
66
|
-
params?: {
|
|
67
|
-
[id: string]: string;
|
|
68
|
-
};
|
|
69
|
-
} | undefined;
|
|
59
|
+
static extractLinkHeader(linkHeader: string): IHttpLinkHeader | undefined;
|
|
70
60
|
/**
|
|
71
61
|
* Create a compliant Link header.
|
|
72
62
|
* @param url The URL to include in the Link header.
|
|
@@ -78,7 +68,7 @@ export declare class HeaderHelper {
|
|
|
78
68
|
*/
|
|
79
69
|
static createLinkHeader(url: string, urlQueryParams: {
|
|
80
70
|
[id: string]: string;
|
|
81
|
-
} | undefined, rel: string, params?: {
|
|
71
|
+
} | undefined, rel: HttpLinkRelType | HttpLinkRelType[] | string | string[], params?: {
|
|
82
72
|
[id: string]: string;
|
|
83
73
|
}): string;
|
|
84
74
|
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.26](https://github.com/twinfoundation/framework/compare/web-v0.0.3-next.25...web-v0.0.3-next.26) (2026-03-24)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* additional http link feature support ([b68b4cc](https://github.com/twinfoundation/framework/commit/b68b4cc6a6e3cf02f91e794353714e26a49fe66c))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/core bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
16
|
+
* @twin.org/crypto bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
17
|
+
* @twin.org/nameof bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
18
|
+
* devDependencies
|
|
19
|
+
* @twin.org/nameof-transformer bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
20
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
21
|
+
* @twin.org/validate-locales bumped from 0.0.3-next.25 to 0.0.3-next.26
|
|
22
|
+
|
|
3
23
|
## [0.0.3-next.25](https://github.com/twinfoundation/framework/compare/web-v0.0.3-next.24...web-v0.0.3-next.25) (2026-03-23)
|
|
4
24
|
|
|
5
25
|
|
|
@@ -68,9 +68,9 @@ The extracted token if it exists.
|
|
|
68
68
|
|
|
69
69
|
### extractLinkHeaderRelation() {#extractlinkheaderrelation}
|
|
70
70
|
|
|
71
|
-
> `static` **extractLinkHeaderRelation**(`linkHeader`, `relation`):
|
|
71
|
+
> `static` **extractLinkHeaderRelation**(`linkHeader`, `relation`): [`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md) \| `undefined`
|
|
72
72
|
|
|
73
|
-
Extract the properties from a Link header for a specific relation type.
|
|
73
|
+
Extract the first occurrence of properties from a Link header for a specific relation type.
|
|
74
74
|
|
|
75
75
|
#### Parameters
|
|
76
76
|
|
|
@@ -82,13 +82,45 @@ The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
|
82
82
|
|
|
83
83
|
##### relation
|
|
84
84
|
|
|
85
|
-
`string`
|
|
85
|
+
`string` \| `RegExp`
|
|
86
86
|
|
|
87
87
|
The relation type to extract.
|
|
88
88
|
|
|
89
89
|
#### Returns
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
[`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md) \| `undefined`
|
|
92
|
+
|
|
93
|
+
The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
94
|
+
|
|
95
|
+
#### See
|
|
96
|
+
|
|
97
|
+
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
98
|
+
|
|
99
|
+
***
|
|
100
|
+
|
|
101
|
+
### extractLinkHeaderRelations() {#extractlinkheaderrelations}
|
|
102
|
+
|
|
103
|
+
> `static` **extractLinkHeaderRelations**(`linkHeader`, `relation`): [`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md)[] \| `undefined`
|
|
104
|
+
|
|
105
|
+
Extract multiple properties from a Link header for a specific relation type.
|
|
106
|
+
|
|
107
|
+
#### Parameters
|
|
108
|
+
|
|
109
|
+
##### linkHeader
|
|
110
|
+
|
|
111
|
+
`unknown`
|
|
112
|
+
|
|
113
|
+
The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
114
|
+
|
|
115
|
+
##### relation
|
|
116
|
+
|
|
117
|
+
`string` \| `RegExp`
|
|
118
|
+
|
|
119
|
+
The relation type to extract.
|
|
120
|
+
|
|
121
|
+
#### Returns
|
|
122
|
+
|
|
123
|
+
[`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md)[] \| `undefined`
|
|
92
124
|
|
|
93
125
|
The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
94
126
|
|
|
@@ -100,7 +132,7 @@ https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
|
100
132
|
|
|
101
133
|
### extractLinkHeaders() {#extractlinkheaders}
|
|
102
134
|
|
|
103
|
-
> `static` **extractLinkHeaders**(`linkHeader`): `
|
|
135
|
+
> `static` **extractLinkHeaders**(`linkHeader`): [`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md)[] \| `undefined`
|
|
104
136
|
|
|
105
137
|
Extract the link headers.
|
|
106
138
|
|
|
@@ -114,7 +146,7 @@ The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
|
114
146
|
|
|
115
147
|
#### Returns
|
|
116
148
|
|
|
117
|
-
`
|
|
149
|
+
[`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md)[] \| `undefined`
|
|
118
150
|
|
|
119
151
|
The extracted possible array of URL, rel and optional params or undefined if invalid/missing.
|
|
120
152
|
|
|
@@ -124,9 +156,35 @@ https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
|
124
156
|
|
|
125
157
|
***
|
|
126
158
|
|
|
159
|
+
### extractLinkHeaderSegments() {#extractlinkheadersegments}
|
|
160
|
+
|
|
161
|
+
> `static` **extractLinkHeaderSegments**(`linkHeader`): `string`[]
|
|
162
|
+
|
|
163
|
+
Split a combined Link header value into individual link-value segments, comma separated.
|
|
164
|
+
|
|
165
|
+
#### Parameters
|
|
166
|
+
|
|
167
|
+
##### linkHeader
|
|
168
|
+
|
|
169
|
+
`string`
|
|
170
|
+
|
|
171
|
+
Raw Link header string.
|
|
172
|
+
|
|
173
|
+
#### Returns
|
|
174
|
+
|
|
175
|
+
`string`[]
|
|
176
|
+
|
|
177
|
+
Array of individual link-value segments.
|
|
178
|
+
|
|
179
|
+
#### See
|
|
180
|
+
|
|
181
|
+
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Link
|
|
182
|
+
|
|
183
|
+
***
|
|
184
|
+
|
|
127
185
|
### extractLinkHeader() {#extractlinkheader}
|
|
128
186
|
|
|
129
|
-
> `static` **extractLinkHeader**(`linkHeader`):
|
|
187
|
+
> `static` **extractLinkHeader**(`linkHeader`): [`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md) \| `undefined`
|
|
130
188
|
|
|
131
189
|
Extract the properties from a Link header.
|
|
132
190
|
|
|
@@ -140,7 +198,7 @@ The Link header value in format `<url>; rel="..."; param1=""; param2=""`.
|
|
|
140
198
|
|
|
141
199
|
#### Returns
|
|
142
200
|
|
|
143
|
-
|
|
201
|
+
[`IHttpLinkHeader`](../interfaces/IHttpLinkHeader.md) \| `undefined`
|
|
144
202
|
|
|
145
203
|
The extracted URL, rel and optional params or undefined if invalid/missing.
|
|
146
204
|
|
|
@@ -172,7 +230,7 @@ Optional query parameters to include in the URL.
|
|
|
172
230
|
|
|
173
231
|
##### rel
|
|
174
232
|
|
|
175
|
-
`string`
|
|
233
|
+
`string` \| `string`[] \| [`HttpLinkRelType`](../type-aliases/HttpLinkRelType.md)[]
|
|
176
234
|
|
|
177
235
|
The relation type (e.g., "next", "prev", "self").
|
|
178
236
|
|
package/docs/reference/index.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
- [IFetchOptions](interfaces/IFetchOptions.md)
|
|
17
17
|
- [IHttpHeaders](interfaces/IHttpHeaders.md)
|
|
18
|
+
- [IHttpLinkHeader](interfaces/IHttpLinkHeader.md)
|
|
18
19
|
|
|
19
20
|
## Type Aliases
|
|
20
21
|
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
- [IJwtHeader](type-aliases/IJwtHeader.md)
|
|
23
24
|
- [IJwtPayload](type-aliases/IJwtPayload.md)
|
|
24
25
|
- [HeaderTypes](type-aliases/HeaderTypes.md)
|
|
26
|
+
- [HttpLinkRelType](type-aliases/HttpLinkRelType.md)
|
|
25
27
|
- [HttpMethod](type-aliases/HttpMethod.md)
|
|
26
28
|
- [HttpStatusCode](type-aliases/HttpStatusCode.md)
|
|
27
29
|
- [JwkCryptoKey](type-aliases/JwkCryptoKey.md)
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
## Variables
|
|
31
33
|
|
|
32
34
|
- [HeaderTypes](variables/HeaderTypes.md)
|
|
35
|
+
- [HttpLinkRelType](variables/HttpLinkRelType.md)
|
|
33
36
|
- [HttpMethod](variables/HttpMethod.md)
|
|
34
37
|
- [HttpStatusCode](variables/HttpStatusCode.md)
|
|
35
38
|
- [MimeTypes](variables/MimeTypes.md)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Interface: IHttpLinkHeader
|
|
2
|
+
|
|
3
|
+
Model used for Http link headers parameter.
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
### url {#url}
|
|
8
|
+
|
|
9
|
+
> **url**: `string`
|
|
10
|
+
|
|
11
|
+
The URL of the link.
|
|
12
|
+
|
|
13
|
+
***
|
|
14
|
+
|
|
15
|
+
### urlQueryParams? {#urlqueryparams}
|
|
16
|
+
|
|
17
|
+
> `optional` **urlQueryParams?**: `object`
|
|
18
|
+
|
|
19
|
+
Optional query parameters for the URL.
|
|
20
|
+
|
|
21
|
+
#### Index Signature
|
|
22
|
+
|
|
23
|
+
\[`id`: `string`\]: `string`
|
|
24
|
+
|
|
25
|
+
***
|
|
26
|
+
|
|
27
|
+
### rel {#rel}
|
|
28
|
+
|
|
29
|
+
> **rel**: `string`[]
|
|
30
|
+
|
|
31
|
+
The relation types of the link.
|
|
32
|
+
|
|
33
|
+
***
|
|
34
|
+
|
|
35
|
+
### params? {#params}
|
|
36
|
+
|
|
37
|
+
> `optional` **params?**: `object`
|
|
38
|
+
|
|
39
|
+
Optional additional parameters for the link.
|
|
40
|
+
|
|
41
|
+
#### Index Signature
|
|
42
|
+
|
|
43
|
+
\[`id`: `string`\]: `string`
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Variable: HttpLinkRelType
|
|
2
|
+
|
|
3
|
+
> `const` **HttpLinkRelType**: `object`
|
|
4
|
+
|
|
5
|
+
Common HTML rel attribute values.
|
|
6
|
+
|
|
7
|
+
## Type Declaration
|
|
8
|
+
|
|
9
|
+
### alternate {#alternate}
|
|
10
|
+
|
|
11
|
+
> `readonly` **alternate**: `"alternate"` = `"alternate"`
|
|
12
|
+
|
|
13
|
+
Alternate representation of the current document.
|
|
14
|
+
|
|
15
|
+
### author {#author}
|
|
16
|
+
|
|
17
|
+
> `readonly` **author**: `"author"` = `"author"`
|
|
18
|
+
|
|
19
|
+
Author of the current document or article.
|
|
20
|
+
|
|
21
|
+
### bookmark {#bookmark}
|
|
22
|
+
|
|
23
|
+
> `readonly` **bookmark**: `"bookmark"` = `"bookmark"`
|
|
24
|
+
|
|
25
|
+
Permalink for the nearest ancestor section.
|
|
26
|
+
|
|
27
|
+
### canonical {#canonical}
|
|
28
|
+
|
|
29
|
+
> `readonly` **canonical**: `"canonical"` = `"canonical"`
|
|
30
|
+
|
|
31
|
+
Preferred URL for the current document.
|
|
32
|
+
|
|
33
|
+
### compressionDictionary {#compressiondictionary}
|
|
34
|
+
|
|
35
|
+
> `readonly` **compressionDictionary**: `"compression-dictionary"` = `"compression-dictionary"`
|
|
36
|
+
|
|
37
|
+
Compression dictionary for future downloads.
|
|
38
|
+
|
|
39
|
+
### dnsPrefetch {#dnsprefetch}
|
|
40
|
+
|
|
41
|
+
> `readonly` **dnsPrefetch**: `"dns-prefetch"` = `"dns-prefetch"`
|
|
42
|
+
|
|
43
|
+
Hint to perform DNS resolution in advance.
|
|
44
|
+
|
|
45
|
+
### external {#external}
|
|
46
|
+
|
|
47
|
+
> `readonly` **external**: `"external"` = `"external"`
|
|
48
|
+
|
|
49
|
+
The referenced document is external to the current site.
|
|
50
|
+
|
|
51
|
+
### expect {#expect}
|
|
52
|
+
|
|
53
|
+
> `readonly` **expect**: `"expect"` = `"expect"`
|
|
54
|
+
|
|
55
|
+
Allows render-blocking until essential parts are parsed.
|
|
56
|
+
|
|
57
|
+
### help {#help}
|
|
58
|
+
|
|
59
|
+
> `readonly` **help**: `"help"` = `"help"`
|
|
60
|
+
|
|
61
|
+
Link to context-sensitive help.
|
|
62
|
+
|
|
63
|
+
### icon {#icon}
|
|
64
|
+
|
|
65
|
+
> `readonly` **icon**: `"icon"` = `"icon"`
|
|
66
|
+
|
|
67
|
+
Icon representing the current document.
|
|
68
|
+
|
|
69
|
+
### license {#license}
|
|
70
|
+
|
|
71
|
+
> `readonly` **license**: `"license"` = `"license"`
|
|
72
|
+
|
|
73
|
+
Licensing information for the current document.
|
|
74
|
+
|
|
75
|
+
### manifest {#manifest}
|
|
76
|
+
|
|
77
|
+
> `readonly` **manifest**: `"manifest"` = `"manifest"`
|
|
78
|
+
|
|
79
|
+
Web application manifest.
|
|
80
|
+
|
|
81
|
+
### me {#me}
|
|
82
|
+
|
|
83
|
+
> `readonly` **me**: `"me"` = `"me"`
|
|
84
|
+
|
|
85
|
+
Indicates the current document represents the linked identity.
|
|
86
|
+
|
|
87
|
+
### modulePreload {#modulepreload}
|
|
88
|
+
|
|
89
|
+
> `readonly` **modulePreload**: `"modulepreload"` = `"modulepreload"`
|
|
90
|
+
|
|
91
|
+
Preemptively fetch a module and optionally its dependencies.
|
|
92
|
+
|
|
93
|
+
### next {#next}
|
|
94
|
+
|
|
95
|
+
> `readonly` **next**: `"next"` = `"next"`
|
|
96
|
+
|
|
97
|
+
The next document in a series.
|
|
98
|
+
|
|
99
|
+
### nofollow {#nofollow}
|
|
100
|
+
|
|
101
|
+
> `readonly` **nofollow**: `"nofollow"` = `"nofollow"`
|
|
102
|
+
|
|
103
|
+
The current document does not endorse the referenced document.
|
|
104
|
+
|
|
105
|
+
### noopener {#noopener}
|
|
106
|
+
|
|
107
|
+
> `readonly` **noopener**: `"noopener"` = `"noopener"`
|
|
108
|
+
|
|
109
|
+
Prevent access to the originating browsing context.
|
|
110
|
+
|
|
111
|
+
### noreferrer {#noreferrer}
|
|
112
|
+
|
|
113
|
+
> `readonly` **noreferrer**: `"noreferrer"` = `"noreferrer"`
|
|
114
|
+
|
|
115
|
+
Suppress the Referer header and implies noopener.
|
|
116
|
+
|
|
117
|
+
### opener {#opener}
|
|
118
|
+
|
|
119
|
+
> `readonly` **opener**: `"opener"` = `"opener"`
|
|
120
|
+
|
|
121
|
+
Allow access to the originating browsing context.
|
|
122
|
+
|
|
123
|
+
### pingback {#pingback}
|
|
124
|
+
|
|
125
|
+
> `readonly` **pingback**: `"pingback"` = `"pingback"`
|
|
126
|
+
|
|
127
|
+
Address of the pingback server for the current document.
|
|
128
|
+
|
|
129
|
+
### preconnect {#preconnect}
|
|
130
|
+
|
|
131
|
+
> `readonly` **preconnect**: `"preconnect"` = `"preconnect"`
|
|
132
|
+
|
|
133
|
+
Hint to connect to the target origin in advance.
|
|
134
|
+
|
|
135
|
+
### prefetch {#prefetch}
|
|
136
|
+
|
|
137
|
+
> `readonly` **prefetch**: `"prefetch"` = `"prefetch"`
|
|
138
|
+
|
|
139
|
+
Hint to fetch and cache a likely next resource.
|
|
140
|
+
|
|
141
|
+
### preload {#preload}
|
|
142
|
+
|
|
143
|
+
> `readonly` **preload**: `"preload"` = `"preload"`
|
|
144
|
+
|
|
145
|
+
Hint to fetch and cache a resource for the current navigation.
|
|
146
|
+
|
|
147
|
+
### prerender {#prerender}
|
|
148
|
+
|
|
149
|
+
> `readonly` **prerender**: `"prerender"` = `"prerender"`
|
|
150
|
+
|
|
151
|
+
Deprecated hint to fetch and process a target in advance.
|
|
152
|
+
|
|
153
|
+
### prev {#prev}
|
|
154
|
+
|
|
155
|
+
> `readonly` **prev**: `"prev"` = `"prev"`
|
|
156
|
+
|
|
157
|
+
The previous document in a series.
|
|
158
|
+
|
|
159
|
+
### privacyPolicy {#privacypolicy}
|
|
160
|
+
|
|
161
|
+
> `readonly` **privacyPolicy**: `"privacy-policy"` = `"privacy-policy"`
|
|
162
|
+
|
|
163
|
+
Privacy policy for the current document.
|
|
164
|
+
|
|
165
|
+
### search {#search}
|
|
166
|
+
|
|
167
|
+
> `readonly` **search**: `"search"` = `"search"`
|
|
168
|
+
|
|
169
|
+
Search resource for the current document or related resources.
|
|
170
|
+
|
|
171
|
+
### stylesheet {#stylesheet}
|
|
172
|
+
|
|
173
|
+
> `readonly` **stylesheet**: `"stylesheet"` = `"stylesheet"`
|
|
174
|
+
|
|
175
|
+
External stylesheet for the current document.
|
|
176
|
+
|
|
177
|
+
### tag {#tag}
|
|
178
|
+
|
|
179
|
+
> `readonly` **tag**: `"tag"` = `"tag"`
|
|
180
|
+
|
|
181
|
+
Tag applying to the current document.
|
|
182
|
+
|
|
183
|
+
### termsOfService {#termsofservice}
|
|
184
|
+
|
|
185
|
+
> `readonly` **termsOfService**: `"terms-of-service"` = `"terms-of-service"`
|
|
186
|
+
|
|
187
|
+
Terms of service for the current document.
|
|
188
|
+
|
|
189
|
+
## See
|
|
190
|
+
|
|
191
|
+
https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/web",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.26",
|
|
4
4
|
"description": "Classes for use with web operations",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"node": ">=20.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/core": "0.0.3-next.
|
|
18
|
-
"@twin.org/crypto": "0.0.3-next.
|
|
19
|
-
"@twin.org/nameof": "0.0.3-next.
|
|
17
|
+
"@twin.org/core": "0.0.3-next.26",
|
|
18
|
+
"@twin.org/crypto": "0.0.3-next.26",
|
|
19
|
+
"@twin.org/nameof": "0.0.3-next.26",
|
|
20
20
|
"jose": "6.2.2"
|
|
21
21
|
},
|
|
22
22
|
"main": "./dist/es/index.js",
|