request-iframe 0.0.6 → 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 +53 -6
- package/README.md +63 -10
- 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 +30 -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 +3 -3
- package/react/package.json +24 -2
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import "core-js/modules/es.array.includes.js";
|
|
2
|
+
import "core-js/modules/es.array.iterator.js";
|
|
3
|
+
import "core-js/modules/es.promise.js";
|
|
4
|
+
import "core-js/modules/es.regexp.to-string.js";
|
|
5
|
+
import "core-js/modules/es.string.includes.js";
|
|
6
|
+
import "core-js/modules/web.dom-collections.iterator.js";
|
|
7
|
+
import "core-js/modules/web.url.js";
|
|
8
|
+
import "core-js/modules/web.url.to-json.js";
|
|
9
|
+
import "core-js/modules/web.url-search-params.js";
|
|
10
|
+
/**
|
|
11
|
+
* Generate unique request ID
|
|
12
|
+
*/
|
|
13
|
+
export function generateRequestId() {
|
|
14
|
+
return `req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generate unique instance ID
|
|
19
|
+
*/
|
|
20
|
+
export function generateInstanceId() {
|
|
21
|
+
return `inst_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Derive targetOrigin from iframe.src
|
|
26
|
+
*/
|
|
27
|
+
export function getIframeTargetOrigin(iframe) {
|
|
28
|
+
if (!iframe.src) {
|
|
29
|
+
return '*';
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return new URL(iframe.src).origin;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return '*';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function isPromise(value) {
|
|
38
|
+
return value !== null && typeof value === 'object' && 'then' in value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Check if target window is still available (not closed/removed)
|
|
43
|
+
* @param targetWindow Target window to check
|
|
44
|
+
* @returns true if window is available, false otherwise
|
|
45
|
+
*/
|
|
46
|
+
export function isWindowAvailable(targetWindow) {
|
|
47
|
+
if (!targetWindow) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
// Must have postMessage to be a usable target
|
|
52
|
+
if (typeof targetWindow.postMessage !== 'function') {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// For windows opened via window.open(), check closed property
|
|
57
|
+
if ('closed' in targetWindow && targetWindow.closed === true) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Avoid touching cross-origin properties (like document) which may throw.
|
|
62
|
+
// If closed is not true and postMessage exists, treat as available.
|
|
63
|
+
return true;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
// If accessing window properties throws an error, window is likely closed
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Export protocol-related functions
|
|
70
|
+
export { createPostMessage, isValidPostMessage, validatePostMessage, validateProtocolVersion, isRequestIframeMessage, getProtocolVersion, isCompatibleVersion } from './protocol';
|
|
71
|
+
|
|
72
|
+
// Export cache-related functions
|
|
73
|
+
export * from './cache';
|
|
74
|
+
|
|
75
|
+
// Export path matching functions
|
|
76
|
+
export * from './path-match';
|
|
77
|
+
|
|
78
|
+
// Export origin matching functions
|
|
79
|
+
export * from './origin';
|
|
80
|
+
|
|
81
|
+
// ackMeta is a reserved protocol field (internal). Do not export helpers publicly.
|
|
82
|
+
|
|
83
|
+
// Export Cookie-related functions
|
|
84
|
+
export * from './cookie';
|
|
85
|
+
|
|
86
|
+
// Export Error class
|
|
87
|
+
export { RequestIframeError } from './error';
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Detect Content-Type based on data type
|
|
91
|
+
* @param data The data to detect Content-Type for
|
|
92
|
+
* @param options Options for detection
|
|
93
|
+
* @param options.checkStream Whether to check for IframeWritableStream (default: false)
|
|
94
|
+
* @param options.isIframeWritableStream Optional function to check if data is a stream (required if checkStream is true)
|
|
95
|
+
* @returns The detected Content-Type, or null if Content-Type should not be auto-set
|
|
96
|
+
*/
|
|
97
|
+
export function detectContentType(data, options) {
|
|
98
|
+
if (data === null || data === undefined) return null;
|
|
99
|
+
var _ref = options || {},
|
|
100
|
+
_ref$checkStream = _ref.checkStream,
|
|
101
|
+
checkStream = _ref$checkStream === void 0 ? false : _ref$checkStream,
|
|
102
|
+
isIframeWritableStream = _ref.isIframeWritableStream;
|
|
103
|
+
|
|
104
|
+
// Stream - handled separately (only for response)
|
|
105
|
+
if (checkStream && isIframeWritableStream) {
|
|
106
|
+
if (isIframeWritableStream(data)) {
|
|
107
|
+
return null; // Stream will be handled by sendStream
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// File
|
|
112
|
+
if (typeof File !== 'undefined' && data instanceof File) {
|
|
113
|
+
return data.type || 'application/octet-stream';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Blob
|
|
117
|
+
if (typeof Blob !== 'undefined' && data instanceof Blob) {
|
|
118
|
+
return data.type || 'application/octet-stream';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ArrayBuffer
|
|
122
|
+
if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) {
|
|
123
|
+
return 'application/octet-stream';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// FormData
|
|
127
|
+
if (typeof FormData !== 'undefined' && data instanceof FormData) {
|
|
128
|
+
// FormData typically doesn't need Content-Type header (browser sets it with boundary)
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// URLSearchParams
|
|
133
|
+
if (typeof URLSearchParams !== 'undefined' && data instanceof URLSearchParams) {
|
|
134
|
+
return 'application/x-www-form-urlencoded';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// String - check if it's JSON string
|
|
138
|
+
if (typeof data === 'string') {
|
|
139
|
+
// Try to parse as JSON, if successful, treat as JSON
|
|
140
|
+
try {
|
|
141
|
+
JSON.parse(data);
|
|
142
|
+
return 'application/json';
|
|
143
|
+
} catch (_unused) {
|
|
144
|
+
return 'text/plain; charset=utf-8';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Number, boolean - treat as JSON
|
|
149
|
+
if (typeof data === 'number' || typeof data === 'boolean') {
|
|
150
|
+
return 'application/json';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Plain object or array - treat as JSON
|
|
154
|
+
if (typeof data === 'object') {
|
|
155
|
+
// Exclude common binary/file types (already checked above, but double-check for safety)
|
|
156
|
+
if (typeof Blob !== 'undefined' && data instanceof Blob) return null;
|
|
157
|
+
if (typeof File !== 'undefined' && data instanceof File) return null;
|
|
158
|
+
if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return null;
|
|
159
|
+
if (typeof FormData !== 'undefined' && data instanceof FormData) return null;
|
|
160
|
+
if (typeof URLSearchParams !== 'undefined' && data instanceof URLSearchParams) return null;
|
|
161
|
+
return 'application/json';
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Convert Blob to base64 string */
|
|
167
|
+
export function blobToBase64(blob) {
|
|
168
|
+
return new Promise((resolve, reject) => {
|
|
169
|
+
var reader = new FileReader();
|
|
170
|
+
reader.onloadend = () => {
|
|
171
|
+
var result = reader.result;
|
|
172
|
+
var base64 = result.includes(',') ? result.split(',')[1] : result;
|
|
173
|
+
resolve(base64);
|
|
174
|
+
};
|
|
175
|
+
reader.onerror = reject;
|
|
176
|
+
reader.readAsDataURL(blob);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import "core-js/modules/es.regexp.constructor.js";
|
|
2
|
+
import "core-js/modules/es.regexp.exec.js";
|
|
3
|
+
import "core-js/modules/es.regexp.to-string.js";
|
|
4
|
+
/**
|
|
5
|
+
* Origin matcher type (supports string, RegExp, Array)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Match origin by matcher.
|
|
10
|
+
*
|
|
11
|
+
* Notes:
|
|
12
|
+
* - string: exact match. Special case: '*' means allow all.
|
|
13
|
+
* - RegExp: test against origin string.
|
|
14
|
+
* - Array: any item matches.
|
|
15
|
+
*/
|
|
16
|
+
export function matchOrigin(origin, matcher) {
|
|
17
|
+
if (matcher === '*') return true;
|
|
18
|
+
if (typeof matcher === 'string') {
|
|
19
|
+
return origin === matcher;
|
|
20
|
+
}
|
|
21
|
+
if (matcher instanceof RegExp) {
|
|
22
|
+
return matcher.test(origin);
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(matcher)) {
|
|
25
|
+
return matcher.some(m => matchOrigin(origin, m));
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import "core-js/modules/es.array.includes.js";
|
|
2
|
+
import "core-js/modules/es.regexp.constructor.js";
|
|
3
|
+
import "core-js/modules/es.regexp.exec.js";
|
|
4
|
+
import "core-js/modules/es.regexp.to-string.js";
|
|
5
|
+
import "core-js/modules/es.string.ends-with.js";
|
|
6
|
+
import "core-js/modules/es.string.includes.js";
|
|
7
|
+
import "core-js/modules/es.string.match.js";
|
|
8
|
+
import "core-js/modules/es.string.replace.js";
|
|
9
|
+
import "core-js/modules/es.string.starts-with.js";
|
|
10
|
+
/**
|
|
11
|
+
* Path matcher type
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Path pattern (supports wildcards)
|
|
16
|
+
* Example: '/api/*' matches all paths starting with '/api/'
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Check if path matches the given matcher
|
|
21
|
+
* @param path request path
|
|
22
|
+
* @param matcher path matcher (string, RegExp, PathPattern, or array)
|
|
23
|
+
* @returns whether matches
|
|
24
|
+
*/
|
|
25
|
+
export function matchPath(path, matcher) {
|
|
26
|
+
// Normalize path (ensure starts with /)
|
|
27
|
+
var normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
28
|
+
|
|
29
|
+
// If array, match if any one matches
|
|
30
|
+
if (Array.isArray(matcher)) {
|
|
31
|
+
return matcher.some(m => matchPath(normalizedPath, m));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// If RegExp
|
|
35
|
+
if (matcher instanceof RegExp) {
|
|
36
|
+
return matcher.test(normalizedPath);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// If string
|
|
40
|
+
if (typeof matcher === 'string') {
|
|
41
|
+
// Exact match
|
|
42
|
+
if (normalizedPath === matcher) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Normalize matcher (ensure starts with /)
|
|
47
|
+
var normalizedMatcher = matcher.startsWith('/') ? matcher : `/${matcher}`;
|
|
48
|
+
|
|
49
|
+
// Prefix match
|
|
50
|
+
if (normalizedPath.startsWith(normalizedMatcher)) {
|
|
51
|
+
// If matcher is '/api', path is '/api', match
|
|
52
|
+
// If matcher is '/api', path is '/api/users', match
|
|
53
|
+
// If matcher is '/api/', path is '/api/users', match
|
|
54
|
+
// If matcher is '/api', path is '/api2', no match
|
|
55
|
+
if (normalizedMatcher.endsWith('/')) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// If matcher doesn't end with /, ensure path has / or ends after matcher
|
|
59
|
+
var nextChar = normalizedPath[normalizedMatcher.length];
|
|
60
|
+
return nextChar === undefined || nextChar === '/';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Support wildcard patterns (e.g., '/api/*')
|
|
64
|
+
if (matcher.includes('*')) {
|
|
65
|
+
return matchPattern(normalizedPath, normalizedMatcher);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Support parameter patterns (e.g., '/api/users/:id')
|
|
69
|
+
if (matcher.includes(':')) {
|
|
70
|
+
return matchPathWithParams(normalizedPath, normalizedMatcher).match;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Match path pattern (supports wildcards)
|
|
79
|
+
* @param path request path
|
|
80
|
+
* @param pattern path pattern (e.g., '/api/*')
|
|
81
|
+
*/
|
|
82
|
+
function matchPattern(path, pattern) {
|
|
83
|
+
// Convert pattern to regex
|
|
84
|
+
// '/api/*' -> '^/api/.*$'
|
|
85
|
+
// '/api/*/users' -> '^/api/.*/users$'
|
|
86
|
+
var regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special characters
|
|
87
|
+
.replace(/\*/g, '.*'); // Replace * with .*
|
|
88
|
+
var regex = new RegExp(`^${regexPattern}$`);
|
|
89
|
+
return regex.test(path);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Path match result with extracted parameters
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Match path with parameter extraction (supports :param syntax like Express)
|
|
98
|
+
* @param path request path
|
|
99
|
+
* @param pattern path pattern with parameters (e.g., '/api/users/:id')
|
|
100
|
+
* @returns match result with extracted parameters
|
|
101
|
+
*/
|
|
102
|
+
export function matchPathWithParams(path, pattern) {
|
|
103
|
+
// Normalize paths
|
|
104
|
+
var normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
105
|
+
var normalizedPattern = pattern.startsWith('/') ? pattern : `/${pattern}`;
|
|
106
|
+
|
|
107
|
+
// Check if pattern contains parameters (:param)
|
|
108
|
+
if (!normalizedPattern.includes(':')) {
|
|
109
|
+
// No parameters, use exact match
|
|
110
|
+
return {
|
|
111
|
+
match: normalizedPath === normalizedPattern,
|
|
112
|
+
params: {}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Extract parameter names from pattern
|
|
117
|
+
var paramNames = [];
|
|
118
|
+
var paramRegex = /:([^/]+)/g;
|
|
119
|
+
var match;
|
|
120
|
+
while ((match = paramRegex.exec(normalizedPattern)) !== null) {
|
|
121
|
+
paramNames.push(match[1]);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Convert pattern to regex, replacing :param with capture groups
|
|
125
|
+
// '/api/users/:id' -> '^/api/users/([^/]+)$'
|
|
126
|
+
// '/api/users/:id/posts/:postId' -> '^/api/users/([^/]+)/posts/([^/]+)$'
|
|
127
|
+
var regexPattern = normalizedPattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special characters
|
|
128
|
+
.replace(/:[^/]+/g, '([^/]+)'); // Replace :param with capture group
|
|
129
|
+
|
|
130
|
+
var regex = new RegExp(`^${regexPattern}$`);
|
|
131
|
+
var regexMatch = regex.exec(normalizedPath);
|
|
132
|
+
if (!regexMatch) {
|
|
133
|
+
return {
|
|
134
|
+
match: false,
|
|
135
|
+
params: {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Extract parameter values from match groups
|
|
140
|
+
var params = {};
|
|
141
|
+
for (var i = 0; i < paramNames.length; i++) {
|
|
142
|
+
params[paramNames[i]] = regexMatch[i + 1];
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
match: true,
|
|
146
|
+
params
|
|
147
|
+
};
|
|
148
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import "core-js/modules/es.array.filter.js";
|
|
2
|
+
import "core-js/modules/es.object.get-own-property-descriptors.js";
|
|
3
|
+
import "core-js/modules/web.dom-collections.for-each.js";
|
|
4
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
5
|
+
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; }
|
|
6
|
+
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; }
|
|
7
|
+
import { ProtocolVersion, Messages, formatMessage } from '../constants';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Validate protocol version
|
|
11
|
+
*
|
|
12
|
+
* Only checks minimum supported version, not maximum version
|
|
13
|
+
* Because new versions usually maintain backward compatibility with older message formats
|
|
14
|
+
*
|
|
15
|
+
* @param version protocol version number
|
|
16
|
+
* @returns validation result
|
|
17
|
+
*/
|
|
18
|
+
export function validateProtocolVersion(version) {
|
|
19
|
+
if (typeof version !== 'number' || !Number.isInteger(version)) {
|
|
20
|
+
return {
|
|
21
|
+
valid: false,
|
|
22
|
+
error: Messages.INVALID_PROTOCOL_VERSION_FORMAT,
|
|
23
|
+
errorCode: 'INVALID_FORMAT'
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (version < ProtocolVersion.MIN_SUPPORTED) {
|
|
27
|
+
return {
|
|
28
|
+
valid: false,
|
|
29
|
+
version,
|
|
30
|
+
error: formatMessage(Messages.PROTOCOL_VERSION_TOO_LOW, version, ProtocolVersion.MIN_SUPPORTED),
|
|
31
|
+
errorCode: 'VERSION_TOO_LOW'
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Don't check maximum version, new versions usually maintain backward compatibility
|
|
36
|
+
return {
|
|
37
|
+
valid: true,
|
|
38
|
+
version
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Validate PostMessage data format (full validation)
|
|
44
|
+
* @param data data to validate
|
|
45
|
+
* @returns validation result, including protocol version info
|
|
46
|
+
*/
|
|
47
|
+
export function validatePostMessage(data) {
|
|
48
|
+
// Basic format validation
|
|
49
|
+
if (!data || typeof data !== 'object') {
|
|
50
|
+
return {
|
|
51
|
+
valid: false,
|
|
52
|
+
error: Messages.INVALID_MESSAGE_FORMAT_NOT_OBJECT,
|
|
53
|
+
errorCode: 'INVALID_FORMAT'
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Protocol identifier validation
|
|
58
|
+
if (data.__requestIframe__ === undefined) {
|
|
59
|
+
return {
|
|
60
|
+
valid: false,
|
|
61
|
+
error: Messages.INVALID_MESSAGE_FORMAT_MISSING_PROTOCOL,
|
|
62
|
+
errorCode: 'INVALID_FORMAT'
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Protocol version validation
|
|
67
|
+
var versionResult = validateProtocolVersion(data.__requestIframe__);
|
|
68
|
+
if (!versionResult.valid) {
|
|
69
|
+
return versionResult;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Required field validation
|
|
73
|
+
if (typeof data.type !== 'string') {
|
|
74
|
+
return {
|
|
75
|
+
valid: false,
|
|
76
|
+
version: versionResult.version,
|
|
77
|
+
error: Messages.INVALID_MESSAGE_FORMAT_MISSING_TYPE,
|
|
78
|
+
errorCode: 'INVALID_FORMAT'
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (typeof data.requestId !== 'string') {
|
|
82
|
+
return {
|
|
83
|
+
valid: false,
|
|
84
|
+
version: versionResult.version,
|
|
85
|
+
error: Messages.INVALID_MESSAGE_FORMAT_MISSING_REQUEST_ID,
|
|
86
|
+
errorCode: 'INVALID_FORMAT'
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
valid: true,
|
|
91
|
+
version: versionResult.version,
|
|
92
|
+
data: data
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check if data is a request-iframe framework message (only checks basic format, doesn't validate version compatibility)
|
|
98
|
+
* @param data data to check
|
|
99
|
+
* @returns whether it's a request-iframe message
|
|
100
|
+
*/
|
|
101
|
+
export function isRequestIframeMessage(data) {
|
|
102
|
+
return !!(data && typeof data === 'object' && typeof data.__requestIframe__ === 'number' && typeof data.type === 'string' && typeof data.requestId === 'string');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Create PostMessage data
|
|
107
|
+
* @param type message type
|
|
108
|
+
* @param requestId request ID
|
|
109
|
+
* @param data additional data
|
|
110
|
+
* @returns PostMessageData
|
|
111
|
+
*/
|
|
112
|
+
export function createPostMessage(type, requestId, data) {
|
|
113
|
+
return _objectSpread({
|
|
114
|
+
__requestIframe__: ProtocolVersion.CURRENT,
|
|
115
|
+
timestamp: Date.now(),
|
|
116
|
+
type,
|
|
117
|
+
requestId
|
|
118
|
+
}, data);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Validate PostMessage data format (only checks basic format, doesn't validate version compatibility)
|
|
123
|
+
* Used for quick determination of whether it's a request-iframe framework message
|
|
124
|
+
*
|
|
125
|
+
* Note: This method doesn't check protocol version compatibility, use isCompatibleVersion for version compatibility check
|
|
126
|
+
*
|
|
127
|
+
* @param data data to validate
|
|
128
|
+
* @returns whether it's a valid PostMessageData
|
|
129
|
+
*/
|
|
130
|
+
export function isValidPostMessage(data) {
|
|
131
|
+
return !!(data && typeof data === 'object' && typeof data.__requestIframe__ === 'number' && typeof data.type === 'string' && typeof data.requestId === 'string');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get protocol version from message
|
|
136
|
+
* @param data PostMessageData
|
|
137
|
+
* @returns protocol version number, undefined if invalid
|
|
138
|
+
*/
|
|
139
|
+
export function getProtocolVersion(data) {
|
|
140
|
+
if (data && typeof data === 'object' && typeof data.__requestIframe__ === 'number') {
|
|
141
|
+
return data.__requestIframe__;
|
|
142
|
+
}
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Check if protocol version is compatible
|
|
148
|
+
*
|
|
149
|
+
* Only checks minimum supported version, not maximum version
|
|
150
|
+
* Because new versions usually maintain backward compatibility with older message formats
|
|
151
|
+
*
|
|
152
|
+
* @param version protocol version number
|
|
153
|
+
* @returns whether compatible
|
|
154
|
+
*/
|
|
155
|
+
export function isCompatibleVersion(version) {
|
|
156
|
+
return version >= ProtocolVersion.MIN_SUPPORTED;
|
|
157
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAO1F;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,GAAG,MAAM,EAClC,OAAO,CAAC,EAAE,0BAA0B,GACnC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAO1F;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,GAAG,MAAM,EAClC,OAAO,CAAC,EAAE,0BAA0B,GACnC,mBAAmB,CAuDrB;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAKtE"}
|
package/library/api/client.js
CHANGED
|
@@ -36,6 +36,11 @@ function requestIframeClient(target, options) {
|
|
|
36
36
|
targetOrigin = '*';
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
// Allow user to override targetOrigin explicitly
|
|
40
|
+
if (options !== null && options !== void 0 && options.targetOrigin) {
|
|
41
|
+
targetOrigin = options.targetOrigin;
|
|
42
|
+
}
|
|
43
|
+
|
|
39
44
|
// Determine secretKey
|
|
40
45
|
var secretKey = options === null || options === void 0 ? void 0 : options.secretKey;
|
|
41
46
|
|
|
@@ -56,7 +61,9 @@ function requestIframeClient(target, options) {
|
|
|
56
61
|
timeout: options === null || options === void 0 ? void 0 : options.timeout,
|
|
57
62
|
asyncTimeout: options === null || options === void 0 ? void 0 : options.asyncTimeout,
|
|
58
63
|
returnData: options === null || options === void 0 ? void 0 : options.returnData,
|
|
59
|
-
headers: options === null || options === void 0 ? void 0 : options.headers
|
|
64
|
+
headers: options === null || options === void 0 ? void 0 : options.headers,
|
|
65
|
+
allowedOrigins: options === null || options === void 0 ? void 0 : options.allowedOrigins,
|
|
66
|
+
validateOrigin: options === null || options === void 0 ? void 0 : options.validateOrigin
|
|
60
67
|
}, instanceId);
|
|
61
68
|
|
|
62
69
|
// If trace mode is enabled, register debug interceptors
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAK3E;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,CAAC,EAAE,0BAA0B,GACnC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAK3E;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,CAAC,EAAE,0BAA0B,GACnC,mBAAmB,CAmCrB;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAKtE"}
|
package/library/api/server.js
CHANGED
|
@@ -35,7 +35,10 @@ function requestIframeServer(options) {
|
|
|
35
35
|
secretKey,
|
|
36
36
|
id,
|
|
37
37
|
ackTimeout: options === null || options === void 0 ? void 0 : options.ackTimeout,
|
|
38
|
-
autoOpen: options === null || options === void 0 ? void 0 : options.autoOpen
|
|
38
|
+
autoOpen: options === null || options === void 0 ? void 0 : options.autoOpen,
|
|
39
|
+
allowedOrigins: options === null || options === void 0 ? void 0 : options.allowedOrigins,
|
|
40
|
+
validateOrigin: options === null || options === void 0 ? void 0 : options.validateOrigin,
|
|
41
|
+
maxConcurrentRequestsPerClient: options === null || options === void 0 ? void 0 : options.maxConcurrentRequestsPerClient
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
// If trace mode is enabled, register debug listeners
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const ProtocolVersion: {
|
|
11
11
|
/** Current protocol version */
|
|
12
|
-
readonly CURRENT:
|
|
12
|
+
readonly CURRENT: 2;
|
|
13
13
|
/** Minimum supported protocol version (messages below this version will be rejected) */
|
|
14
14
|
readonly MIN_SUPPORTED: 1;
|
|
15
15
|
};
|
|
@@ -41,6 +41,8 @@ export declare const HttpStatus: {
|
|
|
41
41
|
readonly UNAUTHORIZED: 401;
|
|
42
42
|
readonly FORBIDDEN: 403;
|
|
43
43
|
readonly NOT_FOUND: 404;
|
|
44
|
+
readonly REQUEST_TIMEOUT: 408;
|
|
45
|
+
readonly TOO_MANY_REQUESTS: 429;
|
|
44
46
|
readonly INTERNAL_SERVER_ERROR: 500;
|
|
45
47
|
readonly BAD_GATEWAY: 502;
|
|
46
48
|
readonly SERVICE_UNAVAILABLE: 503;
|
|
@@ -81,6 +83,10 @@ export declare const ErrorCode: {
|
|
|
81
83
|
readonly STREAM_NOT_BOUND: "STREAM_NOT_BOUND";
|
|
82
84
|
/** Target window closed */
|
|
83
85
|
readonly TARGET_WINDOW_CLOSED: "TARGET_WINDOW_CLOSED";
|
|
86
|
+
/** Too many concurrent requests (rate limiting) */
|
|
87
|
+
readonly TOO_MANY_REQUESTS: "TOO_MANY_REQUESTS";
|
|
88
|
+
/** Stream start not received in time */
|
|
89
|
+
readonly STREAM_START_TIMEOUT: "STREAM_START_TIMEOUT";
|
|
84
90
|
};
|
|
85
91
|
/**
|
|
86
92
|
* Message type constants
|
|
@@ -112,6 +118,10 @@ export declare const MessageType: {
|
|
|
112
118
|
readonly STREAM_ERROR: "stream_error";
|
|
113
119
|
/** Stream cancel */
|
|
114
120
|
readonly STREAM_CANCEL: "stream_cancel";
|
|
121
|
+
/** Stream pull (receiver requests next chunks) */
|
|
122
|
+
readonly STREAM_PULL: "stream_pull";
|
|
123
|
+
/** Stream ack (receiver acknowledges a chunk) */
|
|
124
|
+
readonly STREAM_ACK: "stream_ack";
|
|
115
125
|
};
|
|
116
126
|
export declare const MessageRole: {
|
|
117
127
|
/** Server role */
|
|
@@ -172,6 +182,16 @@ export declare const StreamType: {
|
|
|
172
182
|
/** File stream */
|
|
173
183
|
readonly FILE: "file";
|
|
174
184
|
};
|
|
185
|
+
/**
|
|
186
|
+
* Stream mode constants
|
|
187
|
+
* - PULL: receiver pulls next chunks (backpressure)
|
|
188
|
+
* - PUSH: producer pushes via write()
|
|
189
|
+
*/
|
|
190
|
+
export declare const StreamMode: {
|
|
191
|
+
readonly PULL: "pull";
|
|
192
|
+
readonly PUSH: "push";
|
|
193
|
+
};
|
|
194
|
+
export type StreamModeValue = typeof StreamMode[keyof typeof StreamMode];
|
|
175
195
|
/**
|
|
176
196
|
* Stream internal message type constants (for stream internal message handling)
|
|
177
197
|
* Note: These are MessageType.STREAM_* values with the stream_ prefix removed
|
|
@@ -185,6 +205,10 @@ export declare const StreamInternalMessageType: {
|
|
|
185
205
|
readonly ERROR: "error";
|
|
186
206
|
/** Cancel message */
|
|
187
207
|
readonly CANCEL: "cancel";
|
|
208
|
+
/** Pull message */
|
|
209
|
+
readonly PULL: "pull";
|
|
210
|
+
/** Ack message */
|
|
211
|
+
readonly ACK: "ack";
|
|
188
212
|
};
|
|
189
213
|
/**
|
|
190
214
|
* Stream internal message type value type
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;IAC1B,+BAA+B;;IAE/B,wFAAwF;;CAEhF,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,eAAe,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAExF;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,oBAAoB;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,SAAS,CAAC,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;CAClD;AAED;;GAEG;AACH,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"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"}
|