@duplojs/http 0.9.5 → 0.10.0
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/plugins/cookie/hooks/cookieHooks.cjs +15 -0
- package/dist/plugins/cookie/hooks/cookieHooks.d.ts +11 -0
- package/dist/plugins/cookie/hooks/cookieHooks.mjs +13 -0
- package/dist/plugins/cookie/hooks/index.cjs +11 -0
- package/dist/plugins/cookie/hooks/index.d.ts +3 -0
- package/dist/plugins/cookie/hooks/index.mjs +3 -0
- package/dist/plugins/cookie/hooks/parseRequestCookie.cjs +20 -0
- package/dist/plugins/cookie/hooks/parseRequestCookie.d.ts +8 -0
- package/dist/plugins/cookie/hooks/parseRequestCookie.mjs +18 -0
- package/dist/plugins/cookie/hooks/serializeResponseCookie.cjs +17 -0
- package/dist/plugins/cookie/hooks/serializeResponseCookie.d.ts +7 -0
- package/dist/plugins/cookie/hooks/serializeResponseCookie.mjs +15 -0
- package/dist/plugins/cookie/index.cjs +25 -0
- package/dist/plugins/cookie/index.d.ts +6 -0
- package/dist/plugins/cookie/index.mjs +9 -0
- package/dist/plugins/cookie/kind.cjs +9 -0
- package/dist/plugins/cookie/kind.d.ts +6 -0
- package/dist/plugins/cookie/kind.mjs +7 -0
- package/dist/plugins/cookie/metadata.cjs +8 -0
- package/dist/plugins/cookie/metadata.d.ts +1 -0
- package/dist/plugins/cookie/metadata.mjs +6 -0
- package/dist/plugins/cookie/override.cjs +30 -0
- package/dist/plugins/cookie/override.d.ts +16 -0
- package/dist/plugins/cookie/override.mjs +28 -0
- package/dist/plugins/cookie/parser.cjs +84 -0
- package/dist/plugins/cookie/parser.d.ts +2 -0
- package/dist/plugins/cookie/parser.mjs +79 -0
- package/dist/plugins/cookie/plugin.cjs +30 -0
- package/dist/plugins/cookie/plugin.d.ts +8 -0
- package/dist/plugins/cookie/plugin.mjs +28 -0
- package/dist/plugins/cookie/serialize.cjs +84 -0
- package/dist/plugins/cookie/serialize.d.ts +29 -0
- package/dist/plugins/cookie/serialize.mjs +81 -0
- package/package.json +8 -3
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var parser = require('../parser.cjs');
|
|
4
|
+
var serialize = require('../serialize.cjs');
|
|
5
|
+
var parseRequestCookie = require('./parseRequestCookie.cjs');
|
|
6
|
+
var serializeResponseCookie = require('./serializeResponseCookie.cjs');
|
|
7
|
+
|
|
8
|
+
function cookieHooks({ parser: parser$1 = parser.defaultParser, serializer = serialize.defaultSerializer, } = {}) {
|
|
9
|
+
return {
|
|
10
|
+
...parseRequestCookie.parseRequestCookieHook({ parser: parser$1 }),
|
|
11
|
+
...serializeResponseCookie.serializeResponseCookieHook({ serializer }),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
exports.cookieHooks = cookieHooks;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Parser } from "../parser";
|
|
2
|
+
import { type Serializer } from "../serialize";
|
|
3
|
+
interface CookieHooksParams {
|
|
4
|
+
parser?: Parser;
|
|
5
|
+
serializer?: Serializer;
|
|
6
|
+
}
|
|
7
|
+
export declare function cookieHooks({ parser, serializer, }?: CookieHooksParams): {
|
|
8
|
+
beforeSendResponse: ({ currentResponse, next }: import("../../../core/route").RouteHookParamsAfter) => import("../../../core/route").RouteHookNext;
|
|
9
|
+
beforeRouteExecution: ({ request, next }: import("../../../core/route").RouteHookParams) => import("../../../core/route").RouteHookNext;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defaultParser } from '../parser.mjs';
|
|
2
|
+
import { defaultSerializer } from '../serialize.mjs';
|
|
3
|
+
import { parseRequestCookieHook } from './parseRequestCookie.mjs';
|
|
4
|
+
import { serializeResponseCookieHook } from './serializeResponseCookie.mjs';
|
|
5
|
+
|
|
6
|
+
function cookieHooks({ parser = defaultParser, serializer = defaultSerializer, } = {}) {
|
|
7
|
+
return {
|
|
8
|
+
...parseRequestCookieHook({ parser }),
|
|
9
|
+
...serializeResponseCookieHook({ serializer }),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { cookieHooks };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var parseRequestCookie = require('./parseRequestCookie.cjs');
|
|
4
|
+
var serializeResponseCookie = require('./serializeResponseCookie.cjs');
|
|
5
|
+
var cookieHooks = require('./cookieHooks.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.parseRequestCookieHook = parseRequestCookie.parseRequestCookieHook;
|
|
10
|
+
exports.serializeResponseCookieHook = serializeResponseCookie.serializeResponseCookieHook;
|
|
11
|
+
exports.cookieHooks = cookieHooks.cookieHooks;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('../../../core/route/index.cjs');
|
|
4
|
+
var hooks = require('../../../core/route/hooks.cjs');
|
|
5
|
+
|
|
6
|
+
function parseRequestCookieHook(params) {
|
|
7
|
+
return hooks.createHookRouteLifeCycle({
|
|
8
|
+
beforeRouteExecution: ({ request, next }) => {
|
|
9
|
+
if (request.headers.cookie) {
|
|
10
|
+
const cookieValue = Array.isArray(request.headers.cookie)
|
|
11
|
+
? request.headers.cookie.join("; ")
|
|
12
|
+
: request.headers.cookie;
|
|
13
|
+
request.cookies = params.parser(cookieValue);
|
|
14
|
+
}
|
|
15
|
+
return next();
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.parseRequestCookieHook = parseRequestCookieHook;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Parser } from "../parser";
|
|
2
|
+
interface ParseRequestCookieHookParams {
|
|
3
|
+
parser: Parser;
|
|
4
|
+
}
|
|
5
|
+
export declare function parseRequestCookieHook(params: ParseRequestCookieHookParams): {
|
|
6
|
+
readonly beforeRouteExecution: ({ request, next }: import("../../../core/route").RouteHookParams) => import("../../../core/route").RouteHookNext;
|
|
7
|
+
};
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import '../../../core/route/index.mjs';
|
|
2
|
+
import { createHookRouteLifeCycle } from '../../../core/route/hooks.mjs';
|
|
3
|
+
|
|
4
|
+
function parseRequestCookieHook(params) {
|
|
5
|
+
return createHookRouteLifeCycle({
|
|
6
|
+
beforeRouteExecution: ({ request, next }) => {
|
|
7
|
+
if (request.headers.cookie) {
|
|
8
|
+
const cookieValue = Array.isArray(request.headers.cookie)
|
|
9
|
+
? request.headers.cookie.join("; ")
|
|
10
|
+
: request.headers.cookie;
|
|
11
|
+
request.cookies = params.parser(cookieValue);
|
|
12
|
+
}
|
|
13
|
+
return next();
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { parseRequestCookieHook };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('../../../core/route/index.cjs');
|
|
4
|
+
var hooks = require('../../../core/route/hooks.cjs');
|
|
5
|
+
|
|
6
|
+
function serializeResponseCookieHook(params) {
|
|
7
|
+
return hooks.createHookRouteLifeCycle({
|
|
8
|
+
beforeSendResponse: ({ currentResponse, next }) => {
|
|
9
|
+
if (currentResponse.cookie !== undefined && Object.keys(currentResponse.cookie).length !== 0) {
|
|
10
|
+
currentResponse.setHeader("set-cookie", Object.entries(currentResponse.cookie).map(([name, content]) => params.serializer(name, content.value, content.params)));
|
|
11
|
+
}
|
|
12
|
+
return next();
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exports.serializeResponseCookieHook = serializeResponseCookieHook;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Serializer } from "../serialize";
|
|
2
|
+
export interface SerializeResponseCookieHookParams {
|
|
3
|
+
serializer: Serializer;
|
|
4
|
+
}
|
|
5
|
+
export declare function serializeResponseCookieHook(params: SerializeResponseCookieHookParams): {
|
|
6
|
+
readonly beforeSendResponse: ({ currentResponse, next }: import("../../../core/route").RouteHookParamsAfter) => import("../../../core/route").RouteHookNext;
|
|
7
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import '../../../core/route/index.mjs';
|
|
2
|
+
import { createHookRouteLifeCycle } from '../../../core/route/hooks.mjs';
|
|
3
|
+
|
|
4
|
+
function serializeResponseCookieHook(params) {
|
|
5
|
+
return createHookRouteLifeCycle({
|
|
6
|
+
beforeSendResponse: ({ currentResponse, next }) => {
|
|
7
|
+
if (currentResponse.cookie !== undefined && Object.keys(currentResponse.cookie).length !== 0) {
|
|
8
|
+
currentResponse.setHeader("set-cookie", Object.entries(currentResponse.cookie).map(([name, content]) => params.serializer(name, content.value, content.params)));
|
|
9
|
+
}
|
|
10
|
+
return next();
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { serializeResponseCookieHook };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var parser = require('./parser.cjs');
|
|
4
|
+
var serialize = require('./serialize.cjs');
|
|
5
|
+
require('./override.cjs');
|
|
6
|
+
var metadata = require('./metadata.cjs');
|
|
7
|
+
require('./hooks/index.cjs');
|
|
8
|
+
var plugin = require('./plugin.cjs');
|
|
9
|
+
var parseRequestCookie = require('./hooks/parseRequestCookie.cjs');
|
|
10
|
+
var serializeResponseCookie = require('./hooks/serializeResponseCookie.cjs');
|
|
11
|
+
var cookieHooks = require('./hooks/cookieHooks.cjs');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
exports.decode = parser.decode;
|
|
16
|
+
exports.defaultParser = parser.defaultParser;
|
|
17
|
+
exports.findPairEndIndex = parser.findPairEndIndex;
|
|
18
|
+
exports.sliceAndTrimOws = parser.sliceAndTrimOws;
|
|
19
|
+
exports.SerializeCookieError = serialize.SerializeCookieError;
|
|
20
|
+
exports.defaultSerializer = serialize.defaultSerializer;
|
|
21
|
+
exports.IgnoreRouteCookieMetadata = metadata.IgnoreRouteCookieMetadata;
|
|
22
|
+
exports.cookiePlugin = plugin.cookiePlugin;
|
|
23
|
+
exports.parseRequestCookieHook = parseRequestCookie.parseRequestCookieHook;
|
|
24
|
+
exports.serializeResponseCookieHook = serializeResponseCookie.serializeResponseCookieHook;
|
|
25
|
+
exports.cookieHooks = cookieHooks.cookieHooks;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { decode, defaultParser, findPairEndIndex, sliceAndTrimOws } from './parser.mjs';
|
|
2
|
+
export { SerializeCookieError, defaultSerializer } from './serialize.mjs';
|
|
3
|
+
import './override.mjs';
|
|
4
|
+
export { IgnoreRouteCookieMetadata } from './metadata.mjs';
|
|
5
|
+
import './hooks/index.mjs';
|
|
6
|
+
export { cookiePlugin } from './plugin.mjs';
|
|
7
|
+
export { parseRequestCookieHook } from './hooks/parseRequestCookie.mjs';
|
|
8
|
+
export { serializeResponseCookieHook } from './hooks/serializeResponseCookie.mjs';
|
|
9
|
+
export { cookieHooks } from './hooks/cookieHooks.mjs';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare module "@duplojs/utils" {
|
|
2
|
+
interface ReservedKindNamespace {
|
|
3
|
+
DuplojsCookiePlugin: true;
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export declare const createCookiePluginKind: <GenericName extends string, GenericKindValue extends unknown = unknown>(name: GenericName & import("@duplojs/utils/string").ForbiddenString<GenericName, "@" | "/">) => import("@duplojs/utils").KindHandler<import("@duplojs/utils").KindDefinition<`@DuplojsCookiePlugin/${GenericName}`, GenericKindValue>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const IgnoreRouteCookieMetadata: import("../../core/metadata").MetadataHandler<"ignore-by-cookie", unknown>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('../../core/request/index.cjs');
|
|
4
|
+
require('../../core/response/index.cjs');
|
|
5
|
+
var base = require('../../core/response/base.cjs');
|
|
6
|
+
|
|
7
|
+
index.Request.prototype.cookies = undefined;
|
|
8
|
+
base.Response.prototype.cookie = undefined;
|
|
9
|
+
base.Response.prototype.setCookie = function (name, value, params) {
|
|
10
|
+
if (!this.cookie) {
|
|
11
|
+
this.cookie = {};
|
|
12
|
+
}
|
|
13
|
+
this.cookie[name] = {
|
|
14
|
+
value,
|
|
15
|
+
params,
|
|
16
|
+
};
|
|
17
|
+
return this;
|
|
18
|
+
};
|
|
19
|
+
base.Response.prototype.dropCookie = function (name) {
|
|
20
|
+
if (!this.cookie) {
|
|
21
|
+
this.cookie = {};
|
|
22
|
+
}
|
|
23
|
+
this.cookie[name] = {
|
|
24
|
+
value: "",
|
|
25
|
+
params: {
|
|
26
|
+
maxAge: 0,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
return this;
|
|
30
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SerializerParams } from "./serialize";
|
|
2
|
+
declare module "../../core/request" {
|
|
3
|
+
interface Request {
|
|
4
|
+
cookies?: Partial<Record<string, string>>;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
declare module "../../core/response" {
|
|
8
|
+
interface Response<GenericCode, GenericInformation, GenericBody> {
|
|
9
|
+
cookie?: Record<string, {
|
|
10
|
+
value: string;
|
|
11
|
+
params?: SerializerParams;
|
|
12
|
+
}>;
|
|
13
|
+
setCookie(name: string, value: string, params?: SerializerParams): this;
|
|
14
|
+
dropCookie(name: string): this;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Request } from '../../core/request/index.mjs';
|
|
2
|
+
import '../../core/response/index.mjs';
|
|
3
|
+
import { Response } from '../../core/response/base.mjs';
|
|
4
|
+
|
|
5
|
+
Request.prototype.cookies = undefined;
|
|
6
|
+
Response.prototype.cookie = undefined;
|
|
7
|
+
Response.prototype.setCookie = function (name, value, params) {
|
|
8
|
+
if (!this.cookie) {
|
|
9
|
+
this.cookie = {};
|
|
10
|
+
}
|
|
11
|
+
this.cookie[name] = {
|
|
12
|
+
value,
|
|
13
|
+
params,
|
|
14
|
+
};
|
|
15
|
+
return this;
|
|
16
|
+
};
|
|
17
|
+
Response.prototype.dropCookie = function (name) {
|
|
18
|
+
if (!this.cookie) {
|
|
19
|
+
this.cookie = {};
|
|
20
|
+
}
|
|
21
|
+
this.cookie[name] = {
|
|
22
|
+
value: "",
|
|
23
|
+
params: {
|
|
24
|
+
maxAge: 0,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
return this;
|
|
28
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
function findPairEndIndex(value, start, len) {
|
|
7
|
+
const index = value.indexOf(";", start);
|
|
8
|
+
return index === -1 ? len : index;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
function sliceAndTrimOws(value, min, max) {
|
|
14
|
+
if (min === max) {
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
let start = min;
|
|
18
|
+
let end = max;
|
|
19
|
+
do {
|
|
20
|
+
const code = value.charCodeAt(start);
|
|
21
|
+
if (code !== 32 /* */ && code !== 9 /* \t */) {
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
} while (++start < end);
|
|
25
|
+
while (end > start) {
|
|
26
|
+
const code = value.charCodeAt(end - 1);
|
|
27
|
+
if (code !== 32 /* */ && code !== 9 /* \t */) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
end--;
|
|
31
|
+
}
|
|
32
|
+
return value.slice(start, end);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
function decode(value) {
|
|
38
|
+
if (!value.includes("%")) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return decodeURIComponent(value);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function defaultParser(value) {
|
|
49
|
+
const result = {};
|
|
50
|
+
const valueLength = value.length;
|
|
51
|
+
if (valueLength < 2) {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
let index = 0;
|
|
55
|
+
do {
|
|
56
|
+
const equalCharIndex = value.indexOf("=", index);
|
|
57
|
+
if (equalCharIndex === -1) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
const pairEndIndex = findPairEndIndex(value, index, valueLength);
|
|
61
|
+
if (equalCharIndex > pairEndIndex) {
|
|
62
|
+
index = value.lastIndexOf(";", equalCharIndex - 1) + 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const key = sliceAndTrimOws(value, index, equalCharIndex);
|
|
66
|
+
if (key === ""
|
|
67
|
+
|| key === "__proto__"
|
|
68
|
+
|| key === "constructor"
|
|
69
|
+
|| key === "prototype") {
|
|
70
|
+
index = pairEndIndex + 1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (result[key] === undefined) {
|
|
74
|
+
result[key] = decode(sliceAndTrimOws(value, equalCharIndex + 1, pairEndIndex));
|
|
75
|
+
}
|
|
76
|
+
index = pairEndIndex + 1;
|
|
77
|
+
} while (index < valueLength);
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
exports.decode = decode;
|
|
82
|
+
exports.defaultParser = defaultParser;
|
|
83
|
+
exports.findPairEndIndex = findPairEndIndex;
|
|
84
|
+
exports.sliceAndTrimOws = sliceAndTrimOws;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
4
|
+
function findPairEndIndex(value, start, len) {
|
|
5
|
+
const index = value.indexOf(";", start);
|
|
6
|
+
return index === -1 ? len : index;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
function sliceAndTrimOws(value, min, max) {
|
|
12
|
+
if (min === max) {
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
let start = min;
|
|
16
|
+
let end = max;
|
|
17
|
+
do {
|
|
18
|
+
const code = value.charCodeAt(start);
|
|
19
|
+
if (code !== 32 /* */ && code !== 9 /* \t */) {
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
} while (++start < end);
|
|
23
|
+
while (end > start) {
|
|
24
|
+
const code = value.charCodeAt(end - 1);
|
|
25
|
+
if (code !== 32 /* */ && code !== 9 /* \t */) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
end--;
|
|
29
|
+
}
|
|
30
|
+
return value.slice(start, end);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
function decode(value) {
|
|
36
|
+
if (!value.includes("%")) {
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return decodeURIComponent(value);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function defaultParser(value) {
|
|
47
|
+
const result = {};
|
|
48
|
+
const valueLength = value.length;
|
|
49
|
+
if (valueLength < 2) {
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
let index = 0;
|
|
53
|
+
do {
|
|
54
|
+
const equalCharIndex = value.indexOf("=", index);
|
|
55
|
+
if (equalCharIndex === -1) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
const pairEndIndex = findPairEndIndex(value, index, valueLength);
|
|
59
|
+
if (equalCharIndex > pairEndIndex) {
|
|
60
|
+
index = value.lastIndexOf(";", equalCharIndex - 1) + 1;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const key = sliceAndTrimOws(value, index, equalCharIndex);
|
|
64
|
+
if (key === ""
|
|
65
|
+
|| key === "__proto__"
|
|
66
|
+
|| key === "constructor"
|
|
67
|
+
|| key === "prototype") {
|
|
68
|
+
index = pairEndIndex + 1;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (result[key] === undefined) {
|
|
72
|
+
result[key] = decode(sliceAndTrimOws(value, equalCharIndex + 1, pairEndIndex));
|
|
73
|
+
}
|
|
74
|
+
index = pairEndIndex + 1;
|
|
75
|
+
} while (index < valueLength);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { decode, defaultParser, findPairEndIndex, sliceAndTrimOws };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('@duplojs/utils');
|
|
4
|
+
require('./hooks/index.cjs');
|
|
5
|
+
var metadata = require('./metadata.cjs');
|
|
6
|
+
var cookieHooks = require('./hooks/cookieHooks.cjs');
|
|
7
|
+
|
|
8
|
+
function cookiePlugin(params) {
|
|
9
|
+
return () => ({
|
|
10
|
+
name: "cookie-plugin",
|
|
11
|
+
hooksHubLifeCycle: [
|
|
12
|
+
{
|
|
13
|
+
beforeBuildRoute: (route) => {
|
|
14
|
+
if (utils.A.some(route.definition.metadata, metadata.IgnoreRouteCookieMetadata.is)) {
|
|
15
|
+
return route;
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
...route,
|
|
19
|
+
definition: {
|
|
20
|
+
...route.definition,
|
|
21
|
+
hooks: [...route.definition.hooks, cookieHooks.cookieHooks(params)],
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.cookiePlugin = cookiePlugin;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HubPlugin } from "../../core/hub";
|
|
2
|
+
import type { Parser } from "./parser";
|
|
3
|
+
import type { Serializer } from "./serialize";
|
|
4
|
+
export interface CookiePluginParams {
|
|
5
|
+
parser?: Parser;
|
|
6
|
+
serializer?: Serializer;
|
|
7
|
+
}
|
|
8
|
+
export declare function cookiePlugin(params?: CookiePluginParams): () => HubPlugin;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { A } from '@duplojs/utils';
|
|
2
|
+
import './hooks/index.mjs';
|
|
3
|
+
import { IgnoreRouteCookieMetadata } from './metadata.mjs';
|
|
4
|
+
import { cookieHooks } from './hooks/cookieHooks.mjs';
|
|
5
|
+
|
|
6
|
+
function cookiePlugin(params) {
|
|
7
|
+
return () => ({
|
|
8
|
+
name: "cookie-plugin",
|
|
9
|
+
hooksHubLifeCycle: [
|
|
10
|
+
{
|
|
11
|
+
beforeBuildRoute: (route) => {
|
|
12
|
+
if (A.some(route.definition.metadata, IgnoreRouteCookieMetadata.is)) {
|
|
13
|
+
return route;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
...route,
|
|
17
|
+
definition: {
|
|
18
|
+
...route.definition,
|
|
19
|
+
hooks: [...route.definition.hooks, cookieHooks(params)],
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { cookiePlugin };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('@duplojs/utils');
|
|
4
|
+
var kind = require('./kind.cjs');
|
|
5
|
+
|
|
6
|
+
const nameRegex = /^[!#$%&'*+\-.^_`|~A-Za-z0-9]+$/;
|
|
7
|
+
const domainValueRegex = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
|
|
8
|
+
const pathValueRegex = /^[\u0020-\u003A\u003C-\u007E]*$/;
|
|
9
|
+
class SerializeCookieError extends utils.kindHeritage("serialize-cookie-error", kind.createCookiePluginKind("serialize-cookie-error"), Error) {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super({}, [message]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function defaultSerializer(name, value, params) {
|
|
15
|
+
if (!nameRegex.test(name)) {
|
|
16
|
+
throw new SerializeCookieError(`argument name is invalid: ${name}`);
|
|
17
|
+
}
|
|
18
|
+
let encodedValue = "";
|
|
19
|
+
try {
|
|
20
|
+
encodedValue = encodeURIComponent(value);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new SerializeCookieError(`argument value is invalid: ${value}`);
|
|
24
|
+
}
|
|
25
|
+
let setCookie = `${name}=${encodedValue}`;
|
|
26
|
+
if (params?.maxAge !== undefined) {
|
|
27
|
+
if (!Number.isInteger(params.maxAge)) {
|
|
28
|
+
throw new SerializeCookieError(`param maxAge is invalid: ${params.maxAge}`);
|
|
29
|
+
}
|
|
30
|
+
setCookie += `; Max-Age=${params.maxAge}`;
|
|
31
|
+
}
|
|
32
|
+
if (params?.domain) {
|
|
33
|
+
if (!domainValueRegex.test(params.domain)) {
|
|
34
|
+
throw new SerializeCookieError(`param domain is invalid: ${params.domain}`);
|
|
35
|
+
}
|
|
36
|
+
setCookie += `; Domain=${params.domain}`;
|
|
37
|
+
}
|
|
38
|
+
if (params?.path) {
|
|
39
|
+
if (!pathValueRegex.test(params.path)) {
|
|
40
|
+
throw new SerializeCookieError(`param path is invalid: ${params.path}`);
|
|
41
|
+
}
|
|
42
|
+
setCookie += `; Path=${params.path}`;
|
|
43
|
+
}
|
|
44
|
+
if (params?.expires && params?.expireIn) {
|
|
45
|
+
throw new SerializeCookieError("params expires and expireIn are mutually exclusive");
|
|
46
|
+
}
|
|
47
|
+
if (params?.expires) {
|
|
48
|
+
setCookie += `; Expires=${params.expires.toUTCString()}`;
|
|
49
|
+
}
|
|
50
|
+
if (params?.expireIn !== undefined) {
|
|
51
|
+
setCookie += `; Expires=${utils.D.addTime(utils.D.now(), params.expireIn).toUTCString()}`;
|
|
52
|
+
}
|
|
53
|
+
if (params?.httpOnly) {
|
|
54
|
+
setCookie += "; HttpOnly";
|
|
55
|
+
}
|
|
56
|
+
if (params?.secure) {
|
|
57
|
+
setCookie += "; Secure";
|
|
58
|
+
}
|
|
59
|
+
if (params?.partitioned) {
|
|
60
|
+
setCookie += "; Partitioned";
|
|
61
|
+
}
|
|
62
|
+
if (params?.priority === "high") {
|
|
63
|
+
setCookie += "; Priority=High";
|
|
64
|
+
}
|
|
65
|
+
else if (params?.priority === "low") {
|
|
66
|
+
setCookie += "; Priority=Low";
|
|
67
|
+
}
|
|
68
|
+
else if (params?.priority === "medium") {
|
|
69
|
+
setCookie += "; Priority=Medium";
|
|
70
|
+
}
|
|
71
|
+
if (params?.sameSite === "strict") {
|
|
72
|
+
setCookie += "; SameSite=Strict";
|
|
73
|
+
}
|
|
74
|
+
else if (params?.sameSite === "lax") {
|
|
75
|
+
setCookie += "; SameSite=Lax";
|
|
76
|
+
}
|
|
77
|
+
else if (params?.sameSite === "none") {
|
|
78
|
+
setCookie += "; SameSite=None";
|
|
79
|
+
}
|
|
80
|
+
return setCookie;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
exports.SerializeCookieError = SerializeCookieError;
|
|
84
|
+
exports.defaultSerializer = defaultSerializer;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { D } from "@duplojs/utils";
|
|
2
|
+
declare const SerializeCookieError_base: new (params: {
|
|
3
|
+
"@DuplojsCookiePlugin/serialize-cookie-error"?: unknown;
|
|
4
|
+
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsCookiePlugin/serialize-cookie-error", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"serialize-cookie-error", unknown>, unknown> & Error;
|
|
5
|
+
export declare class SerializeCookieError extends SerializeCookieError_base {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
interface SerializerParamsBase {
|
|
9
|
+
maxAge?: number;
|
|
10
|
+
domain?: string;
|
|
11
|
+
path?: string;
|
|
12
|
+
httpOnly?: boolean;
|
|
13
|
+
secure?: boolean;
|
|
14
|
+
partitioned?: boolean;
|
|
15
|
+
priority?: "low" | "medium" | "high";
|
|
16
|
+
sameSite?: "lax" | "strict" | "none";
|
|
17
|
+
}
|
|
18
|
+
export interface SerializerParamsWithExpires extends SerializerParamsBase {
|
|
19
|
+
expires?: D.TheDate;
|
|
20
|
+
expireIn?: undefined;
|
|
21
|
+
}
|
|
22
|
+
export interface SerializerParamsWithExpireIn extends SerializerParamsBase {
|
|
23
|
+
expires?: undefined;
|
|
24
|
+
expireIn?: D.TheTime;
|
|
25
|
+
}
|
|
26
|
+
export type SerializerParams = SerializerParamsWithExpires | SerializerParamsWithExpireIn;
|
|
27
|
+
export declare function defaultSerializer(name: string, value: string, params?: SerializerParams): string;
|
|
28
|
+
export type Serializer = typeof defaultSerializer;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { kindHeritage, D } from '@duplojs/utils';
|
|
2
|
+
import { createCookiePluginKind } from './kind.mjs';
|
|
3
|
+
|
|
4
|
+
const nameRegex = /^[!#$%&'*+\-.^_`|~A-Za-z0-9]+$/;
|
|
5
|
+
const domainValueRegex = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
|
|
6
|
+
const pathValueRegex = /^[\u0020-\u003A\u003C-\u007E]*$/;
|
|
7
|
+
class SerializeCookieError extends kindHeritage("serialize-cookie-error", createCookiePluginKind("serialize-cookie-error"), Error) {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super({}, [message]);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function defaultSerializer(name, value, params) {
|
|
13
|
+
if (!nameRegex.test(name)) {
|
|
14
|
+
throw new SerializeCookieError(`argument name is invalid: ${name}`);
|
|
15
|
+
}
|
|
16
|
+
let encodedValue = "";
|
|
17
|
+
try {
|
|
18
|
+
encodedValue = encodeURIComponent(value);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new SerializeCookieError(`argument value is invalid: ${value}`);
|
|
22
|
+
}
|
|
23
|
+
let setCookie = `${name}=${encodedValue}`;
|
|
24
|
+
if (params?.maxAge !== undefined) {
|
|
25
|
+
if (!Number.isInteger(params.maxAge)) {
|
|
26
|
+
throw new SerializeCookieError(`param maxAge is invalid: ${params.maxAge}`);
|
|
27
|
+
}
|
|
28
|
+
setCookie += `; Max-Age=${params.maxAge}`;
|
|
29
|
+
}
|
|
30
|
+
if (params?.domain) {
|
|
31
|
+
if (!domainValueRegex.test(params.domain)) {
|
|
32
|
+
throw new SerializeCookieError(`param domain is invalid: ${params.domain}`);
|
|
33
|
+
}
|
|
34
|
+
setCookie += `; Domain=${params.domain}`;
|
|
35
|
+
}
|
|
36
|
+
if (params?.path) {
|
|
37
|
+
if (!pathValueRegex.test(params.path)) {
|
|
38
|
+
throw new SerializeCookieError(`param path is invalid: ${params.path}`);
|
|
39
|
+
}
|
|
40
|
+
setCookie += `; Path=${params.path}`;
|
|
41
|
+
}
|
|
42
|
+
if (params?.expires && params?.expireIn) {
|
|
43
|
+
throw new SerializeCookieError("params expires and expireIn are mutually exclusive");
|
|
44
|
+
}
|
|
45
|
+
if (params?.expires) {
|
|
46
|
+
setCookie += `; Expires=${params.expires.toUTCString()}`;
|
|
47
|
+
}
|
|
48
|
+
if (params?.expireIn !== undefined) {
|
|
49
|
+
setCookie += `; Expires=${D.addTime(D.now(), params.expireIn).toUTCString()}`;
|
|
50
|
+
}
|
|
51
|
+
if (params?.httpOnly) {
|
|
52
|
+
setCookie += "; HttpOnly";
|
|
53
|
+
}
|
|
54
|
+
if (params?.secure) {
|
|
55
|
+
setCookie += "; Secure";
|
|
56
|
+
}
|
|
57
|
+
if (params?.partitioned) {
|
|
58
|
+
setCookie += "; Partitioned";
|
|
59
|
+
}
|
|
60
|
+
if (params?.priority === "high") {
|
|
61
|
+
setCookie += "; Priority=High";
|
|
62
|
+
}
|
|
63
|
+
else if (params?.priority === "low") {
|
|
64
|
+
setCookie += "; Priority=Low";
|
|
65
|
+
}
|
|
66
|
+
else if (params?.priority === "medium") {
|
|
67
|
+
setCookie += "; Priority=Medium";
|
|
68
|
+
}
|
|
69
|
+
if (params?.sameSite === "strict") {
|
|
70
|
+
setCookie += "; SameSite=Strict";
|
|
71
|
+
}
|
|
72
|
+
else if (params?.sameSite === "lax") {
|
|
73
|
+
setCookie += "; SameSite=Lax";
|
|
74
|
+
}
|
|
75
|
+
else if (params?.sameSite === "none") {
|
|
76
|
+
setCookie += "; SameSite=None";
|
|
77
|
+
}
|
|
78
|
+
return setCookie;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { SerializeCookieError, defaultSerializer };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duplojs/http",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "mathcovax",
|
|
6
6
|
"url": "https://github.com/mathcovax"
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"test:tu:watch": "vitest --coverage --watch",
|
|
22
22
|
"test:tu:update": "vitest --coverage --update",
|
|
23
23
|
"test:types": "./.commands/test-types.sh",
|
|
24
|
-
"test:lint": "./.commands/test-
|
|
25
|
-
"test:lint:fix": "./.commands/test-
|
|
24
|
+
"test:lint": "./.commands/test-lint.sh",
|
|
25
|
+
"test:lint:fix": "./.commands/test-lint.sh --fix",
|
|
26
26
|
"prepare": "husky"
|
|
27
27
|
},
|
|
28
28
|
"types": "./dist/core/index.d.ts",
|
|
@@ -67,6 +67,11 @@
|
|
|
67
67
|
"require": "./dist/plugins/cacheController/index.cjs",
|
|
68
68
|
"types": "./dist/plugins/cacheController/index.d.ts"
|
|
69
69
|
},
|
|
70
|
+
"./cookie": {
|
|
71
|
+
"import": "./dist/plugins/cookie/index.mjs",
|
|
72
|
+
"require": "./dist/plugins/cookie/index.cjs",
|
|
73
|
+
"types": "./dist/plugins/cookie/index.d.ts"
|
|
74
|
+
},
|
|
70
75
|
"./static": {
|
|
71
76
|
"import": "./dist/plugins/static/index.mjs",
|
|
72
77
|
"require": "./dist/plugins/static/index.cjs",
|