request-iframe 0.0.5 → 0.1.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/README.CN.md +54 -7
- package/README.md +64 -11
- package/esm/api/client.js +79 -0
- package/esm/api/server.js +59 -0
- package/esm/constants/index.js +257 -0
- package/esm/constants/messages.js +155 -0
- package/esm/core/client-server.js +329 -0
- package/esm/core/client.js +873 -0
- package/esm/core/request.js +27 -0
- package/esm/core/response.js +451 -0
- package/esm/core/server.js +767 -0
- package/esm/index.js +21 -0
- package/esm/interceptors/index.js +122 -0
- package/esm/message/channel.js +181 -0
- package/esm/message/dispatcher.js +380 -0
- package/esm/message/index.js +2 -0
- package/esm/stream/file-stream.js +289 -0
- package/esm/stream/index.js +44 -0
- package/esm/stream/readable-stream.js +500 -0
- package/esm/stream/stream-core.js +91 -0
- package/esm/stream/types.js +1 -0
- package/esm/stream/writable-stream.js +582 -0
- package/esm/types/index.js +1 -0
- package/esm/utils/ack-meta.js +53 -0
- package/esm/utils/cache.js +147 -0
- package/esm/utils/cookie.js +352 -0
- package/esm/utils/debug.js +521 -0
- package/esm/utils/error.js +27 -0
- package/esm/utils/index.js +178 -0
- package/esm/utils/origin.js +28 -0
- package/esm/utils/path-match.js +148 -0
- package/esm/utils/protocol.js +157 -0
- package/library/api/client.d.ts.map +1 -1
- package/library/api/client.js +8 -1
- package/library/api/server.d.ts.map +1 -1
- package/library/api/server.js +4 -1
- package/library/constants/index.d.ts +25 -1
- package/library/constants/index.d.ts.map +1 -1
- package/library/constants/index.js +30 -5
- package/library/constants/messages.d.ts +5 -0
- package/library/constants/messages.d.ts.map +1 -1
- package/library/constants/messages.js +5 -0
- package/library/core/client-server.d.ts +3 -2
- package/library/core/client-server.d.ts.map +1 -1
- package/library/core/client-server.js +51 -4
- package/library/core/client.d.ts +4 -1
- package/library/core/client.d.ts.map +1 -1
- package/library/core/client.js +74 -31
- package/library/core/response.d.ts +21 -3
- package/library/core/response.d.ts.map +1 -1
- package/library/core/response.js +46 -6
- package/library/core/server.d.ts +28 -1
- package/library/core/server.d.ts.map +1 -1
- package/library/core/server.js +180 -19
- package/library/message/channel.d.ts +6 -0
- package/library/message/channel.d.ts.map +1 -1
- package/library/message/dispatcher.d.ts +22 -0
- package/library/message/dispatcher.d.ts.map +1 -1
- package/library/message/dispatcher.js +92 -0
- package/library/stream/file-stream.d.ts +4 -0
- package/library/stream/file-stream.d.ts.map +1 -1
- package/library/stream/file-stream.js +61 -33
- package/library/stream/index.d.ts.map +1 -1
- package/library/stream/index.js +2 -0
- package/library/stream/readable-stream.d.ts +30 -11
- package/library/stream/readable-stream.d.ts.map +1 -1
- package/library/stream/readable-stream.js +329 -73
- package/library/stream/stream-core.d.ts +44 -0
- package/library/stream/stream-core.d.ts.map +1 -0
- package/library/stream/stream-core.js +98 -0
- package/library/stream/types.d.ts +90 -3
- package/library/stream/types.d.ts.map +1 -1
- package/library/stream/writable-stream.d.ts +40 -12
- package/library/stream/writable-stream.d.ts.map +1 -1
- package/library/stream/writable-stream.js +391 -195
- package/library/types/index.d.ts +70 -3
- package/library/types/index.d.ts.map +1 -1
- package/library/utils/ack-meta.d.ts +2 -0
- package/library/utils/ack-meta.d.ts.map +1 -0
- package/library/utils/ack-meta.js +59 -0
- package/library/utils/index.d.ts +1 -0
- package/library/utils/index.d.ts.map +1 -1
- package/library/utils/index.js +16 -0
- package/library/utils/origin.d.ts +14 -0
- package/library/utils/origin.d.ts.map +1 -0
- package/library/utils/origin.js +34 -0
- package/package.json +31 -7
- package/react/README.md +16 -0
- package/react/esm/index.js +284 -0
- package/react/library/index.d.ts +1 -1
- package/react/library/index.d.ts.map +1 -1
- package/react/library/index.js +7 -4
- package/react/package.json +24 -2
- package/library/__tests__/channel.test.ts +0 -432
- package/library/__tests__/coverage-branches.test.ts +0 -356
- package/library/__tests__/debug.test.ts +0 -610
- package/library/__tests__/dispatcher.test.ts +0 -485
- package/library/__tests__/interceptors.test.ts +0 -146
- package/library/__tests__/requestIframe.test.ts +0 -5590
- package/library/__tests__/server.test.ts +0 -738
- package/library/__tests__/stream.test.ts +0 -726
- package/library/__tests__/utils.test.ts +0 -473
- package/library/api/client.d.js +0 -5
- package/library/api/server.d.js +0 -5
- package/library/constants/index.d.js +0 -36
- package/library/constants/messages.d.js +0 -5
- package/library/core/client.d.js +0 -5
- package/library/core/message-handler.d.ts +0 -110
- package/library/core/message-handler.d.ts.map +0 -1
- package/library/core/message-handler.js +0 -320
- package/library/core/request-response.d.ts +0 -59
- package/library/core/request-response.d.ts.map +0 -1
- package/library/core/request-response.js +0 -337
- package/library/core/request.d.js +0 -5
- package/library/core/response.d.js +0 -5
- package/library/core/server-base.d.ts +0 -86
- package/library/core/server-base.d.ts.map +0 -1
- package/library/core/server-base.js +0 -257
- package/library/core/server-client.d.js +0 -5
- package/library/core/server-client.d.ts +0 -101
- package/library/core/server-client.d.ts.map +0 -1
- package/library/core/server-client.js +0 -266
- package/library/core/server.d.js +0 -5
- package/library/interceptors/index.d.js +0 -5
- package/library/message/channel.d.js +0 -5
- package/library/message/dispatcher.d.js +0 -5
- package/library/message/index.d.js +0 -25
- package/library/stream/file-stream.d.js +0 -4
- package/library/stream/index.d.js +0 -58
- package/library/stream/readable-stream.d.js +0 -5
- package/library/stream/types.d.js +0 -5
- package/library/stream/writable-stream.d.js +0 -5
- package/library/types/index.d.js +0 -5
- package/library/utils/cache.d.js +0 -5
- package/library/utils/cookie.d.js +0 -5
- package/library/utils/debug.d.js +0 -5
- package/library/utils/index.d.js +0 -94
- package/library/utils/path-match.d.js +0 -5
- package/library/utils/protocol.d.js +0 -5
- package/react/library/__tests__/index.test.d.ts +0 -2
- package/react/library/__tests__/index.test.d.ts.map +0 -1
- package/react/library/__tests__/index.test.tsx +0 -792
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import "core-js/modules/es.array.iterator.js";
|
|
2
|
+
import "core-js/modules/es.map.js";
|
|
3
|
+
import "core-js/modules/web.dom-collections.for-each.js";
|
|
4
|
+
import "core-js/modules/web.dom-collections.iterator.js";
|
|
5
|
+
import { MessageChannel, ChannelType } from '../message';
|
|
6
|
+
/**
|
|
7
|
+
* Global cache Symbol (used to store MessageChannel instance cache on window)
|
|
8
|
+
* Using Symbol.for() ensures multiple library copies share the same cache, avoiding multiple instance creation
|
|
9
|
+
*/
|
|
10
|
+
var MESSAGE_CHANNEL_CACHE_SYMBOL = Symbol.for('__requestIframeMessageChannelCache__');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Global cache Symbol for server instances
|
|
14
|
+
* Using Symbol.for() ensures multiple library copies share the same cache
|
|
15
|
+
*/
|
|
16
|
+
var SERVER_CACHE_SYMBOL = Symbol.for('__requestIframeServerCache__');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get the MessageChannel cache from window
|
|
20
|
+
*/
|
|
21
|
+
function getChannelCacheForWindow(win) {
|
|
22
|
+
if (!(MESSAGE_CHANNEL_CACHE_SYMBOL in win)) {
|
|
23
|
+
win[MESSAGE_CHANNEL_CACHE_SYMBOL] = new Map();
|
|
24
|
+
}
|
|
25
|
+
return win[MESSAGE_CHANNEL_CACHE_SYMBOL];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generate cache key
|
|
30
|
+
* Cache key format: "type:secretKey" or "type:" when no secretKey
|
|
31
|
+
* Different channel types use separate cache entries
|
|
32
|
+
*/
|
|
33
|
+
function getCacheKey(type, secretKey) {
|
|
34
|
+
return `${type}:${secretKey !== null && secretKey !== void 0 ? secretKey : ''}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get or create MessageChannel instance
|
|
39
|
+
* - Within the same window, only one channel is created per type + secretKey combination
|
|
40
|
+
* - Uses reference counting to manage lifecycle
|
|
41
|
+
* @param secretKey secret key for message isolation
|
|
42
|
+
* @param type channel type (defaults to postMessage)
|
|
43
|
+
*/
|
|
44
|
+
export function getOrCreateMessageChannel(secretKey, type = ChannelType.POST_MESSAGE) {
|
|
45
|
+
var cache = getChannelCacheForWindow(window);
|
|
46
|
+
var key = getCacheKey(type, secretKey);
|
|
47
|
+
var channel = cache.get(key);
|
|
48
|
+
if (!channel) {
|
|
49
|
+
channel = new MessageChannel(secretKey, type);
|
|
50
|
+
cache.set(key, channel);
|
|
51
|
+
}
|
|
52
|
+
channel.addRef();
|
|
53
|
+
return channel;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Release MessageChannel reference
|
|
58
|
+
* - When reference count reaches 0, destroy channel and remove from cache
|
|
59
|
+
*/
|
|
60
|
+
export function releaseMessageChannel(channel) {
|
|
61
|
+
var refCount = channel.release();
|
|
62
|
+
if (refCount <= 0) {
|
|
63
|
+
var cache = getChannelCacheForWindow(window);
|
|
64
|
+
var key = getCacheKey(channel.type, channel.secretKey);
|
|
65
|
+
if (cache.get(key) === channel) {
|
|
66
|
+
cache.delete(key);
|
|
67
|
+
channel.destroy();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Clear all MessageChannel cache (mainly for testing)
|
|
74
|
+
*/
|
|
75
|
+
export function clearMessageChannelCache() {
|
|
76
|
+
var cache = getChannelCacheForWindow(window);
|
|
77
|
+
cache.forEach(channel => {
|
|
78
|
+
channel.destroy();
|
|
79
|
+
});
|
|
80
|
+
cache.clear();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get the server cache from window
|
|
85
|
+
*/
|
|
86
|
+
function getServerCacheForWindow(win) {
|
|
87
|
+
if (!(SERVER_CACHE_SYMBOL in win)) {
|
|
88
|
+
win[SERVER_CACHE_SYMBOL] = new Map();
|
|
89
|
+
}
|
|
90
|
+
return win[SERVER_CACHE_SYMBOL];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Generate server cache key
|
|
95
|
+
* Cache key format: "secretKey:id" or "secretKey:" when no id
|
|
96
|
+
*/
|
|
97
|
+
function getServerCacheKey(secretKey, id) {
|
|
98
|
+
return `${secretKey !== null && secretKey !== void 0 ? secretKey : ''}:${id !== null && id !== void 0 ? id : ''}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get cached server instance or null
|
|
103
|
+
* @param secretKey secret key for message isolation
|
|
104
|
+
* @param id server instance ID
|
|
105
|
+
*/
|
|
106
|
+
export function getCachedServer(secretKey, id) {
|
|
107
|
+
if (!id) return null;
|
|
108
|
+
var cache = getServerCacheForWindow(window);
|
|
109
|
+
var key = getServerCacheKey(secretKey, id);
|
|
110
|
+
return cache.get(key) || null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Cache server instance
|
|
115
|
+
* @param server server instance
|
|
116
|
+
* @param secretKey secret key for message isolation
|
|
117
|
+
* @param id server instance ID
|
|
118
|
+
*/
|
|
119
|
+
export function cacheServer(server, secretKey, id) {
|
|
120
|
+
if (!id) return;
|
|
121
|
+
var cache = getServerCacheForWindow(window);
|
|
122
|
+
var key = getServerCacheKey(secretKey, id);
|
|
123
|
+
cache.set(key, server);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Remove server from cache
|
|
128
|
+
* @param secretKey secret key for message isolation
|
|
129
|
+
* @param id server instance ID
|
|
130
|
+
*/
|
|
131
|
+
export function removeCachedServer(secretKey, id) {
|
|
132
|
+
if (!id) return;
|
|
133
|
+
var cache = getServerCacheForWindow(window);
|
|
134
|
+
var key = getServerCacheKey(secretKey, id);
|
|
135
|
+
cache.delete(key);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Clear all server cache (mainly for testing)
|
|
140
|
+
*/
|
|
141
|
+
export function clearServerCache() {
|
|
142
|
+
var cache = getServerCacheForWindow(window);
|
|
143
|
+
cache.forEach(server => {
|
|
144
|
+
server.destroy();
|
|
145
|
+
});
|
|
146
|
+
cache.clear();
|
|
147
|
+
}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
5
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
6
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
7
|
+
import "core-js/modules/es.symbol.description.js";
|
|
8
|
+
import "core-js/modules/es.array.filter.js";
|
|
9
|
+
import "core-js/modules/es.array.from.js";
|
|
10
|
+
import "core-js/modules/es.array.index-of.js";
|
|
11
|
+
import "core-js/modules/es.array.iterator.js";
|
|
12
|
+
import "core-js/modules/es.array.map.js";
|
|
13
|
+
import "core-js/modules/es.array.slice.js";
|
|
14
|
+
import "core-js/modules/es.map.js";
|
|
15
|
+
import "core-js/modules/es.object.get-own-property-descriptors.js";
|
|
16
|
+
import "core-js/modules/es.regexp.exec.js";
|
|
17
|
+
import "core-js/modules/es.regexp.to-string.js";
|
|
18
|
+
import "core-js/modules/es.string.ends-with.js";
|
|
19
|
+
import "core-js/modules/es.string.starts-with.js";
|
|
20
|
+
import "core-js/modules/es.string.trim.js";
|
|
21
|
+
import "core-js/modules/web.dom-collections.for-each.js";
|
|
22
|
+
import "core-js/modules/web.dom-collections.iterator.js";
|
|
23
|
+
/**
|
|
24
|
+
* Cookie management utilities
|
|
25
|
+
* Implements browser-like Cookie mechanism
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Cookie storage item
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Cookie options (for res.cookie)
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Parse Set-Cookie string to CookieItem
|
|
38
|
+
* @param setCookieStr Set-Cookie string, e.g., "token=abc; Path=/; HttpOnly"
|
|
39
|
+
*/
|
|
40
|
+
export function parseSetCookie(setCookieStr) {
|
|
41
|
+
if (!setCookieStr) return null;
|
|
42
|
+
var parts = setCookieStr.split(';').map(p => p.trim());
|
|
43
|
+
if (parts.length === 0) return null;
|
|
44
|
+
|
|
45
|
+
// First part is name=value
|
|
46
|
+
var firstPart = parts[0];
|
|
47
|
+
var eqIndex = firstPart.indexOf('=');
|
|
48
|
+
if (eqIndex === -1) return null;
|
|
49
|
+
var name = firstPart.substring(0, eqIndex).trim();
|
|
50
|
+
var value = firstPart.substring(eqIndex + 1).trim();
|
|
51
|
+
if (!name) return null;
|
|
52
|
+
var cookie = {
|
|
53
|
+
name,
|
|
54
|
+
value,
|
|
55
|
+
path: '/' // Default path
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Parse other attributes
|
|
59
|
+
for (var i = 1; i < parts.length; i++) {
|
|
60
|
+
var part = parts[i];
|
|
61
|
+
var attrEqIndex = part.indexOf('=');
|
|
62
|
+
if (attrEqIndex === -1) {
|
|
63
|
+
// Attribute without value
|
|
64
|
+
var attrName = part.toLowerCase();
|
|
65
|
+
if (attrName === 'httponly') {
|
|
66
|
+
cookie.httpOnly = true;
|
|
67
|
+
} else if (attrName === 'secure') {
|
|
68
|
+
cookie.secure = true;
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
// Attribute with value
|
|
72
|
+
var _attrName = part.substring(0, attrEqIndex).trim().toLowerCase();
|
|
73
|
+
var attrValue = part.substring(attrEqIndex + 1).trim();
|
|
74
|
+
if (_attrName === 'path') {
|
|
75
|
+
cookie.path = attrValue || '/';
|
|
76
|
+
} else if (_attrName === 'expires') {
|
|
77
|
+
var date = new Date(attrValue);
|
|
78
|
+
if (!isNaN(date.getTime())) {
|
|
79
|
+
cookie.expires = date.getTime();
|
|
80
|
+
}
|
|
81
|
+
} else if (_attrName === 'max-age') {
|
|
82
|
+
var maxAge = parseInt(attrValue, 10);
|
|
83
|
+
if (!isNaN(maxAge)) {
|
|
84
|
+
cookie.expires = Date.now() + maxAge * 1000;
|
|
85
|
+
}
|
|
86
|
+
} else if (_attrName === 'samesite') {
|
|
87
|
+
var sameSite = attrValue.charAt(0).toUpperCase() + attrValue.slice(1).toLowerCase();
|
|
88
|
+
if (sameSite === 'Strict' || sameSite === 'Lax' || sameSite === 'None') {
|
|
89
|
+
cookie.sameSite = sameSite;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return cookie;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Serialize CookieItem to Set-Cookie string
|
|
99
|
+
*/
|
|
100
|
+
export function serializeSetCookie(cookie) {
|
|
101
|
+
var str = `${cookie.name}=${cookie.value}`;
|
|
102
|
+
if (cookie.path) {
|
|
103
|
+
str += `; Path=${cookie.path}`;
|
|
104
|
+
}
|
|
105
|
+
if (cookie.expires !== undefined) {
|
|
106
|
+
str += `; Expires=${new Date(cookie.expires).toUTCString()}`;
|
|
107
|
+
}
|
|
108
|
+
if (cookie.httpOnly) {
|
|
109
|
+
str += '; HttpOnly';
|
|
110
|
+
}
|
|
111
|
+
if (cookie.secure) {
|
|
112
|
+
str += '; Secure';
|
|
113
|
+
}
|
|
114
|
+
if (cookie.sameSite) {
|
|
115
|
+
str += `; SameSite=${cookie.sameSite}`;
|
|
116
|
+
}
|
|
117
|
+
return str;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Create Set-Cookie string from CookieOptions
|
|
122
|
+
*/
|
|
123
|
+
export function createSetCookie(name, value, options) {
|
|
124
|
+
var _options$path;
|
|
125
|
+
var str = `${name}=${value}`;
|
|
126
|
+
var path = (_options$path = options === null || options === void 0 ? void 0 : options.path) !== null && _options$path !== void 0 ? _options$path : '/';
|
|
127
|
+
str += `; Path=${path}`;
|
|
128
|
+
if (options !== null && options !== void 0 && options.expires) {
|
|
129
|
+
str += `; Expires=${options.expires.toUTCString()}`;
|
|
130
|
+
} else if ((options === null || options === void 0 ? void 0 : options.maxAge) !== undefined) {
|
|
131
|
+
var expires = new Date(Date.now() + options.maxAge * 1000);
|
|
132
|
+
str += `; Expires=${expires.toUTCString()}`;
|
|
133
|
+
str += `; Max-Age=${options.maxAge}`;
|
|
134
|
+
}
|
|
135
|
+
if (options !== null && options !== void 0 && options.httpOnly) {
|
|
136
|
+
str += '; HttpOnly';
|
|
137
|
+
}
|
|
138
|
+
if (options !== null && options !== void 0 && options.secure) {
|
|
139
|
+
str += '; Secure';
|
|
140
|
+
}
|
|
141
|
+
if (options !== null && options !== void 0 && options.sameSite) {
|
|
142
|
+
str += `; SameSite=${options.sameSite}`;
|
|
143
|
+
}
|
|
144
|
+
return str;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Create Set-Cookie string to delete Cookie
|
|
149
|
+
*/
|
|
150
|
+
export function createClearCookie(name, options) {
|
|
151
|
+
var _options$path2;
|
|
152
|
+
var path = (_options$path2 = options === null || options === void 0 ? void 0 : options.path) !== null && _options$path2 !== void 0 ? _options$path2 : '/';
|
|
153
|
+
// Set expiration time to past to delete cookie
|
|
154
|
+
return `${name}=; Path=${path}; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Check if request path matches Cookie's path attribute
|
|
159
|
+
* Implements RFC 6265 path matching algorithm
|
|
160
|
+
* @param requestPath request path, e.g., "/api/users"
|
|
161
|
+
* @param cookiePath Cookie's path attribute, e.g., "/api"
|
|
162
|
+
*/
|
|
163
|
+
export function matchCookiePath(requestPath, cookiePath) {
|
|
164
|
+
// Normalize paths
|
|
165
|
+
var reqPath = normalizePath(requestPath);
|
|
166
|
+
var cPath = normalizePath(cookiePath);
|
|
167
|
+
|
|
168
|
+
// Exact match
|
|
169
|
+
if (reqPath === cPath) {
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Cookie path is prefix of request path
|
|
174
|
+
if (reqPath.startsWith(cPath)) {
|
|
175
|
+
// Cookie path ends with / or request path has / after cookie path
|
|
176
|
+
if (cPath.endsWith('/') || reqPath.charAt(cPath.length) === '/') {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Normalize path
|
|
185
|
+
*/
|
|
186
|
+
function normalizePath(path) {
|
|
187
|
+
if (!path || path === '') return '/';
|
|
188
|
+
// Ensure starts with /
|
|
189
|
+
if (!path.startsWith('/')) {
|
|
190
|
+
path = '/' + path;
|
|
191
|
+
}
|
|
192
|
+
// Remove trailing / (unless root path)
|
|
193
|
+
if (path.length > 1 && path.endsWith('/')) {
|
|
194
|
+
path = path.slice(0, -1);
|
|
195
|
+
}
|
|
196
|
+
return path;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Cookie storage manager
|
|
201
|
+
*/
|
|
202
|
+
export class CookieStore {
|
|
203
|
+
constructor() {
|
|
204
|
+
_defineProperty(this, "cookies", new Map());
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Generate unique key for Cookie
|
|
208
|
+
*/
|
|
209
|
+
getKey(name, path) {
|
|
210
|
+
return `${name}|${path}`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Set Cookie
|
|
215
|
+
*/
|
|
216
|
+
set(cookie) {
|
|
217
|
+
var key = this.getKey(cookie.name, cookie.path);
|
|
218
|
+
this.cookies.set(key, cookie);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Set Cookie from Set-Cookie string
|
|
223
|
+
*/
|
|
224
|
+
setFromSetCookie(setCookieStr) {
|
|
225
|
+
var cookie = parseSetCookie(setCookieStr);
|
|
226
|
+
if (cookie) {
|
|
227
|
+
// Check if this is a delete operation (expiration in the past)
|
|
228
|
+
if (cookie.expires !== undefined && cookie.expires <= Date.now()) {
|
|
229
|
+
this.remove(cookie.name, cookie.path);
|
|
230
|
+
} else {
|
|
231
|
+
this.set(cookie);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Remove Cookie
|
|
238
|
+
*/
|
|
239
|
+
remove(name, path = '/') {
|
|
240
|
+
var key = this.getKey(name, path);
|
|
241
|
+
this.cookies.delete(key);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Get all Cookies matching specified path
|
|
246
|
+
* @param requestPath request path
|
|
247
|
+
* @returns matching cookies, format: Record<string, string>
|
|
248
|
+
*/
|
|
249
|
+
getForPath(requestPath) {
|
|
250
|
+
var result = {};
|
|
251
|
+
var now = Date.now();
|
|
252
|
+
this.cookies.forEach(cookie => {
|
|
253
|
+
// Check if expired
|
|
254
|
+
if (cookie.expires !== undefined && cookie.expires <= now) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Check if path matches
|
|
259
|
+
if (matchCookiePath(requestPath, cookie.path)) {
|
|
260
|
+
// If same-name cookie already exists, use the one with longer (more specific) path
|
|
261
|
+
if (result[cookie.name] === undefined) {
|
|
262
|
+
result[cookie.name] = cookie.value;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Get Cookie value by name
|
|
271
|
+
* @param name Cookie name
|
|
272
|
+
* @param path path (optional, returns first match if not specified)
|
|
273
|
+
*/
|
|
274
|
+
get(name, path) {
|
|
275
|
+
if (path) {
|
|
276
|
+
var key = this.getKey(name, path);
|
|
277
|
+
var cookie = this.cookies.get(key);
|
|
278
|
+
if (cookie && (!cookie.expires || cookie.expires > Date.now())) {
|
|
279
|
+
return cookie.value;
|
|
280
|
+
}
|
|
281
|
+
return undefined;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// If path not specified, find all cookies with same name
|
|
285
|
+
var _iterator = _createForOfIteratorHelper(this.cookies.values()),
|
|
286
|
+
_step;
|
|
287
|
+
try {
|
|
288
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
289
|
+
var _cookie = _step.value;
|
|
290
|
+
if (_cookie.name === name) {
|
|
291
|
+
if (!_cookie.expires || _cookie.expires > Date.now()) {
|
|
292
|
+
return _cookie.value;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} catch (err) {
|
|
297
|
+
_iterator.e(err);
|
|
298
|
+
} finally {
|
|
299
|
+
_iterator.f();
|
|
300
|
+
}
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get all Cookies (with full info)
|
|
306
|
+
*/
|
|
307
|
+
getAll() {
|
|
308
|
+
var now = Date.now();
|
|
309
|
+
var result = [];
|
|
310
|
+
this.cookies.forEach(cookie => {
|
|
311
|
+
if (!cookie.expires || cookie.expires > now) {
|
|
312
|
+
result.push(_objectSpread({}, cookie));
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
return result;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Get all Cookies (simple format)
|
|
320
|
+
*/
|
|
321
|
+
getAllSimple() {
|
|
322
|
+
var result = {};
|
|
323
|
+
var now = Date.now();
|
|
324
|
+
this.cookies.forEach(cookie => {
|
|
325
|
+
if (!cookie.expires || cookie.expires > now) {
|
|
326
|
+
result[cookie.name] = cookie.value;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Clear all Cookies
|
|
334
|
+
*/
|
|
335
|
+
clear() {
|
|
336
|
+
this.cookies.clear();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Cleanup expired Cookies
|
|
341
|
+
*/
|
|
342
|
+
cleanup() {
|
|
343
|
+
var now = Date.now();
|
|
344
|
+
var keysToDelete = [];
|
|
345
|
+
this.cookies.forEach((cookie, key) => {
|
|
346
|
+
if (cookie.expires !== undefined && cookie.expires <= now) {
|
|
347
|
+
keysToDelete.push(key);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
keysToDelete.forEach(key => this.cookies.delete(key));
|
|
351
|
+
}
|
|
352
|
+
}
|