1 |
|
2 | import { notAcceptable, unsupportedMediaType } from "@worker-tools/response-creators";
|
3 | import negotiated from 'negotiated';
|
4 | const weightSortFn = (a, b) => a.weight >= b.weight ? a : b;
|
5 | const ACCEPT = 'Accept';
|
6 | const ACCEPT_ENCODING = 'Accept-Encoding';
|
7 | const ACCEPT_LANGUAGE = 'Accept-Language';
|
8 | const CONTENT_TYPE = 'Content-Type';
|
9 | const CONTENT_LANGUAGE = 'Content-Language';
|
10 | const CONTENT_ENCODING = 'Content-Encoding';
|
11 | const VARY = 'Vary';
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | export function contentTypes(types) {
|
17 | return async (ax) => {
|
18 | const ctx = await ax;
|
19 | const { headers } = ctx.request;
|
20 | const type = [...negotiated.mediaTypes(headers.get(ACCEPT))]
|
21 | .filter(t => !types || types.includes(t.type))
|
22 | .reduce(weightSortFn, { weight: -1 }).type;
|
23 | if (headers.has(ACCEPT) && types && !type)
|
24 | throw notAcceptable();
|
25 | ctx.effects.push(response => {
|
26 | var _a;
|
27 | if (!response.headers.has(CONTENT_TYPE))
|
28 | response.headers.set(CONTENT_TYPE, type);
|
29 |
|
30 | if (((_a = types === null || types === void 0 ? void 0 : types.length) !== null && _a !== void 0 ? _a : 0) > 1)
|
31 | response.headers.append(VARY, ACCEPT);
|
32 | return response;
|
33 | });
|
34 | return Object.assign(ctx, { type });
|
35 | };
|
36 | }
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | export function contentLanguages(languages) {
|
42 | return async (ax) => {
|
43 | const ctx = await ax;
|
44 | const { headers } = ctx.request;
|
45 | const language = [...negotiated.languages(headers.get(ACCEPT_LANGUAGE))]
|
46 | .filter(l => !languages || languages.includes(l.language))
|
47 | .reduce(weightSortFn, { weight: -1 }).language;
|
48 | if (headers.has(ACCEPT_LANGUAGE) && languages && !language)
|
49 | throw notAcceptable();
|
50 | ctx.effects.push(response => {
|
51 | var _a;
|
52 | if (!response.headers.has(CONTENT_LANGUAGE))
|
53 | response.headers.set(CONTENT_LANGUAGE, language);
|
54 |
|
55 | if (((_a = languages === null || languages === void 0 ? void 0 : languages.length) !== null && _a !== void 0 ? _a : 0) > 1)
|
56 | response.headers.append(VARY, ACCEPT_LANGUAGE);
|
57 | return response;
|
58 | });
|
59 | return Object.assign(ctx, { language });
|
60 | };
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 |
|
66 | export function contentEncodings(encodings) {
|
67 | return async (ax) => {
|
68 | const ctx = await ax;
|
69 | const { headers } = ctx.request;
|
70 | const encoding = [...negotiated.encodings(headers.get(ACCEPT_ENCODING))]
|
71 | .filter(e => !encodings || encodings.includes(e.encoding))
|
72 | .reduce(weightSortFn, { weight: -1 }).encoding;
|
73 |
|
74 | if (headers.has(ACCEPT_ENCODING) && encodings && !encoding)
|
75 | throw notAcceptable();
|
76 | ctx.effects.push(response => {
|
77 | var _a;
|
78 | if (!response.headers.has(CONTENT_ENCODING))
|
79 | response.headers.set(CONTENT_ENCODING, encoding);
|
80 |
|
81 | if (((_a = encodings === null || encodings === void 0 ? void 0 : encodings.length) !== null && _a !== void 0 ? _a : 0) > 1)
|
82 | response.headers.append(VARY, ACCEPT_ENCODING);
|
83 | return response;
|
84 | });
|
85 | return Object.assign(ctx, { encoding });
|
86 | };
|
87 | }
|
88 | export { contentTypes as provides, contentLanguages as providesLanguages, contentEncodings as providesEncodings, };
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | export function accepts(types) {
|
94 | return async (ax) => {
|
95 | var _a;
|
96 | const ctx = await ax;
|
97 | const { headers } = ctx.request;
|
98 | const accepted = (_a = [...negotiated.mediaTypes(headers.get(CONTENT_TYPE))][0]) === null || _a === void 0 ? void 0 : _a.type;
|
99 | if ((types === null || types === void 0 ? void 0 : types.length) && !types.includes(accepted))
|
100 | throw unsupportedMediaType();
|
101 | return Object.assign(ctx, { accepted });
|
102 | };
|
103 | }
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | export function acceptsLanguages(languages) {
|
109 | return async (ax) => {
|
110 | var _a;
|
111 | const ctx = await ax;
|
112 | const { headers } = ctx.request;
|
113 | const acceptedLanguage = (_a = [...negotiated.languages(headers.get(CONTENT_LANGUAGE))][0]) === null || _a === void 0 ? void 0 : _a.language;
|
114 | if ((languages === null || languages === void 0 ? void 0 : languages.length) && !languages.includes(acceptedLanguage))
|
115 | throw notAcceptable();
|
116 | return Object.assign(ctx, { acceptedLanguage });
|
117 | };
|
118 | }
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | export function acceptsEncodings(encodings) {
|
124 | return async (ax) => {
|
125 | var _a;
|
126 | const ctx = await ax;
|
127 | const { headers } = ctx.request;
|
128 | const acceptedEncoding = (_a = [...negotiated.encodings(headers.get(CONTENT_ENCODING))][0]) === null || _a === void 0 ? void 0 : _a.encoding;
|
129 | if ((encodings === null || encodings === void 0 ? void 0 : encodings.length) && !encodings.includes(acceptedEncoding))
|
130 | throw notAcceptable();
|
131 | return Object.assign(ctx, { acceptedEncoding });
|
132 | };
|
133 | }
|
134 |
|
\ | No newline at end of file |