@outfoxx/sunday 2.0.0-beta.2 → 2.0.0-beta.21

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.
Files changed (141) hide show
  1. package/README.md +346 -4
  2. package/build/authentication-adapter.d.ts +21 -0
  3. package/build/authentication-adapter.js +74 -0
  4. package/build/authentication-adapter.js.map +1 -0
  5. package/build/bearer-token-rejection-adapter.d.ts +6 -0
  6. package/build/bearer-token-rejection-adapter.js +25 -0
  7. package/build/bearer-token-rejection-adapter.js.map +1 -0
  8. package/build/client-settings.d.ts +22 -0
  9. package/build/client-settings.js +180 -0
  10. package/build/client-settings.js.map +1 -0
  11. package/build/credentials.d.ts +58 -0
  12. package/build/credentials.js +51 -0
  13. package/build/credentials.js.map +1 -0
  14. package/build/event-parser.d.ts +23 -8
  15. package/build/event-parser.js +93 -121
  16. package/build/event-parser.js.map +1 -1
  17. package/build/fetch-copy.d.ts +15 -0
  18. package/build/fetch-copy.js +71 -0
  19. package/build/fetch-copy.js.map +1 -0
  20. package/build/fetch-event-source.d.ts +18 -8
  21. package/build/fetch-event-source.js +241 -144
  22. package/build/fetch-event-source.js.map +1 -1
  23. package/build/fetch-oauth-token-provider.d.ts +28 -0
  24. package/build/fetch-oauth-token-provider.js +213 -0
  25. package/build/fetch-oauth-token-provider.js.map +1 -0
  26. package/build/fetch-transport.d.ts +15 -1
  27. package/build/fetch-transport.js +142 -132
  28. package/build/fetch-transport.js.map +1 -1
  29. package/build/fetch.js +24 -10
  30. package/build/fetch.js.map +1 -1
  31. package/build/header-token-adapters.d.ts +28 -0
  32. package/build/header-token-adapters.js +121 -0
  33. package/build/header-token-adapters.js.map +1 -0
  34. package/build/index.d.ts +23 -1
  35. package/build/index.js +22 -1
  36. package/build/index.js.map +1 -1
  37. package/build/media-type-codecs/binary-decoder.d.ts +1 -0
  38. package/build/media-type-codecs/binary-decoder.js +4 -11
  39. package/build/media-type-codecs/binary-decoder.js.map +1 -1
  40. package/build/media-type-codecs/cbor-encoder.d.ts +2 -2
  41. package/build/media-type-codecs/cbor-encoder.js +2 -2
  42. package/build/media-type-codecs/cbor-encoder.js.map +1 -1
  43. package/build/media-type-codecs/json-encoder.d.ts +3 -3
  44. package/build/media-type-codecs/json-encoder.js +4 -4
  45. package/build/media-type-codecs/json-encoder.js.map +1 -1
  46. package/build/media-type-codecs/media-type-encoder.d.ts +3 -3
  47. package/build/media-type-codecs/media-type-encoder.js.map +1 -1
  48. package/build/media-type-codecs/www-form-url-encoder.d.ts +2 -2
  49. package/build/media-type-codecs/www-form-url-encoder.js +2 -2
  50. package/build/media-type-codecs/www-form-url-encoder.js.map +1 -1
  51. package/build/model-construction.d.ts +5 -0
  52. package/build/model-construction.js +40 -0
  53. package/build/model-construction.js.map +1 -0
  54. package/build/model-schema.d.ts +9 -0
  55. package/build/model-schema.js +131 -0
  56. package/build/model-schema.js.map +1 -0
  57. package/build/oauth-wire.d.ts +33 -0
  58. package/build/oauth-wire.js +143 -0
  59. package/build/oauth-wire.js.map +1 -0
  60. package/build/operation.d.ts +3 -1
  61. package/build/problem.d.ts +39 -16
  62. package/build/problem.js +88 -32
  63. package/build/problem.js.map +1 -1
  64. package/build/request-adapter.d.ts +8 -0
  65. package/build/request-adapter.js +15 -0
  66. package/build/request-adapter.js.map +1 -0
  67. package/build/request-adapters-compat.d.ts +6 -0
  68. package/build/request-adapters-compat.js +19 -0
  69. package/build/request-adapters-compat.js.map +1 -0
  70. package/build/request-adapters.d.ts +13 -23
  71. package/build/request-adapters.js +40 -31
  72. package/build/request-adapters.js.map +1 -1
  73. package/build/request-body.d.ts +24 -0
  74. package/build/request-body.js +104 -0
  75. package/build/request-body.js.map +1 -0
  76. package/build/request-cancellation-error.d.ts +13 -0
  77. package/build/request-cancellation-error.js +43 -0
  78. package/build/request-cancellation-error.js.map +1 -0
  79. package/build/request-context.d.ts +4 -0
  80. package/build/request-context.js +29 -0
  81. package/build/request-context.js.map +1 -0
  82. package/build/request-execution.d.ts +13 -0
  83. package/build/request-execution.js +80 -0
  84. package/build/request-execution.js.map +1 -0
  85. package/build/request-security-bindings.d.ts +5 -0
  86. package/build/request-security-bindings.js +30 -0
  87. package/build/request-security-bindings.js.map +1 -0
  88. package/build/request-security.d.ts +20 -0
  89. package/build/request-security.js +223 -0
  90. package/build/request-security.js.map +1 -0
  91. package/build/request-validation-error.d.ts +4 -0
  92. package/build/request-validation-error.js +21 -0
  93. package/build/request-validation-error.js.map +1 -0
  94. package/build/response-adapter.d.ts +10 -0
  95. package/build/response-adapter.js +15 -0
  96. package/build/response-adapter.js.map +1 -0
  97. package/build/response-adapters.d.ts +13 -0
  98. package/build/response-adapters.js +75 -0
  99. package/build/response-adapters.js.map +1 -0
  100. package/build/schema-builtins.js +11 -21
  101. package/build/schema-builtins.js.map +1 -1
  102. package/build/schema-runtime.d.ts +8 -1
  103. package/build/schema-runtime.js +12 -3
  104. package/build/schema-runtime.js.map +1 -1
  105. package/build/security-binding.d.ts +22 -0
  106. package/build/security-binding.js +15 -0
  107. package/build/security-binding.js.map +1 -0
  108. package/build/standard-authentication-adapter.d.ts +18 -0
  109. package/build/standard-authentication-adapter.js +58 -0
  110. package/build/standard-authentication-adapter.js.map +1 -0
  111. package/build/token-manager.d.ts +42 -0
  112. package/build/token-manager.js +276 -0
  113. package/build/token-manager.js.map +1 -0
  114. package/build/token-provider.d.ts +52 -0
  115. package/build/token-provider.js +102 -0
  116. package/build/token-provider.js.map +1 -0
  117. package/build/transport.d.ts +10 -3
  118. package/build/unknown-variant.d.ts +12 -0
  119. package/build/unknown-variant.js +45 -0
  120. package/build/unknown-variant.js.map +1 -0
  121. package/build/url-template.d.ts +3 -0
  122. package/build/url-template.js +30 -2
  123. package/build/url-template.js.map +1 -1
  124. package/build/util/abort.d.ts +3 -0
  125. package/build/util/abort.js +42 -0
  126. package/build/util/abort.js.map +1 -0
  127. package/build/util/base64.d.ts +4 -0
  128. package/build/util/base64.js +46 -0
  129. package/build/util/base64.js.map +1 -0
  130. package/build/util/native-fetch.d.ts +2 -0
  131. package/build/util/native-fetch.js +39 -0
  132. package/build/util/native-fetch.js.map +1 -0
  133. package/build/util/nullify.js +12 -5
  134. package/build/util/nullify.js.map +1 -1
  135. package/build/util/owned-body.d.ts +12 -0
  136. package/build/util/owned-body.js +243 -0
  137. package/build/util/owned-body.js.map +1 -0
  138. package/build/util/status-title.d.ts +2 -0
  139. package/build/util/status-title.js +83 -0
  140. package/build/util/status-title.js.map +1 -0
  141. package/package.json +18 -6
@@ -0,0 +1,180 @@
1
+ // Copyright 2020 Outfox, Inc.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { validateCredentials } from './credentials.js';
15
+ /** Resolved, transport-independent inputs supplied to an application's transport factory. */
16
+ export class ClientSettings {
17
+ baseUrl;
18
+ /** Providers shared by this configuration's operations; caching requires an explicit TokenManager. */
19
+ tokenProviders;
20
+ bindings;
21
+ #credentials;
22
+ /** Snapshots operation bindings and credentials without acquiring tokens or making requests. */
23
+ constructor(baseUrl, bindings = {}, credentials = {}) {
24
+ const url = new URL(baseUrl);
25
+ if (!['https:', 'http:'].includes(url.protocol) ||
26
+ url.username ||
27
+ url.password ||
28
+ url.href.includes('?') ||
29
+ url.href.includes('#'))
30
+ throw new TypeError('Client endpoint must be HTTP or HTTPS');
31
+ this.baseUrl = url.href;
32
+ this.bindings = Object.freeze(Object.fromEntries(Object.entries(bindings).map(([operation, values]) => [
33
+ operation,
34
+ Object.freeze(values.map((value) => Object.freeze({
35
+ ...value,
36
+ ...Object.fromEntries([
37
+ 'discoveryUrl',
38
+ 'authorizationUrl',
39
+ 'tokenUrl',
40
+ 'refreshUrl',
41
+ ].flatMap((key) => {
42
+ const endpoint = value[key];
43
+ if (typeof endpoint !== 'string')
44
+ return [];
45
+ if (/[{}]/.test(endpoint))
46
+ throw new TypeError('Security endpoint URLs do not support server variables');
47
+ return [[key, new URL(endpoint, baseUrl).href]];
48
+ })),
49
+ scopes: Object.freeze([...value.scopes]),
50
+ transport: Object.freeze({ ...value.transport }),
51
+ }))),
52
+ ])));
53
+ this.#credentials = new Map(Object.entries(credentials).map(([scheme, value]) => [
54
+ scheme,
55
+ Object.freeze({
56
+ ...value,
57
+ ...(value.kind === 'oauth' && value.endpoints
58
+ ? {
59
+ endpoints: Object.freeze(Object.fromEntries(Object.entries(value.endpoints).map(([key, endpoint]) => {
60
+ if (endpoint === undefined)
61
+ return [key, undefined];
62
+ if (/[{}]/.test(endpoint))
63
+ throw new TypeError('Security endpoint URLs do not support server variables');
64
+ return [key, new URL(endpoint, baseUrl).href];
65
+ }))),
66
+ }
67
+ : {}),
68
+ }),
69
+ ]));
70
+ for (const binding of Object.values(this.bindings).flat()) {
71
+ const credential = this.#credentials.get(binding.scheme);
72
+ if (!credential)
73
+ throw new TypeError(`Missing credentials for scheme '${binding.scheme}'`);
74
+ validateCredentials(credential, binding);
75
+ }
76
+ this.tokenProviders = this.prepareTokenProviders();
77
+ Object.freeze(this);
78
+ }
79
+ /** Expands server variables once and resolves relative servers against their document location. */
80
+ static serverUrl(template, variables, documentBaseUrl) {
81
+ const expanded = template.replace(/\{([^{}]+)\}/g, (_match, name) => {
82
+ if (!Object.hasOwn(variables, name))
83
+ throw new TypeError(`Missing server variable '${name}'`);
84
+ return variables[name];
85
+ });
86
+ const url = new URL(expanded, documentBaseUrl);
87
+ if (!['http:', 'https:'].includes(url.protocol) ||
88
+ url.username ||
89
+ url.password ||
90
+ url.search ||
91
+ url.hash) {
92
+ throw new TypeError('Invalid HTTP server endpoint');
93
+ }
94
+ return url.href;
95
+ }
96
+ /**
97
+ * Chooses one complete alternative per operation using credentials and optional explicit scheme sets.
98
+ * `alternativeSelection` selects a zero-based candidate index, including its scopes and endpoint metadata.
99
+ */
100
+ static resolve(baseUrl, alternatives, credentials, selection = {}, alternativeSelection = {}) {
101
+ if ([...Object.keys(selection), ...Object.keys(alternativeSelection)].some((operation) => !Object.hasOwn(alternatives, operation))) {
102
+ throw new TypeError('Unknown operation selection');
103
+ }
104
+ const bindings = Object.create(null);
105
+ for (const [operation, candidates] of Object.entries(alternatives)) {
106
+ const selected = Object.hasOwn(selection, operation)
107
+ ? selection[operation]
108
+ : undefined;
109
+ const selectedIndex = Object.hasOwn(alternativeSelection, operation)
110
+ ? alternativeSelection[operation]
111
+ : undefined;
112
+ const usable = candidates.filter((candidate, index) => {
113
+ if (selectedIndex !== undefined && selectedIndex !== index)
114
+ return false;
115
+ if (selected &&
116
+ (selected.length !== candidate.length ||
117
+ candidate.some((binding) => !selected.includes(binding.scheme))))
118
+ return false;
119
+ return candidate.every((binding) => {
120
+ const credential = Object.hasOwn(credentials, binding.scheme)
121
+ ? credentials[binding.scheme]
122
+ : undefined;
123
+ if (!credential)
124
+ return false;
125
+ try {
126
+ validateCredentials(credential, binding);
127
+ return true;
128
+ }
129
+ catch {
130
+ return false;
131
+ }
132
+ });
133
+ });
134
+ if (usable.length !== 1)
135
+ throw new TypeError(`Operation '${operation}' requires one complete security alternative`);
136
+ bindings[operation] = usable[0];
137
+ }
138
+ return new ClientSettings(baseUrl, bindings, credentials);
139
+ }
140
+ prepareTokenProviders() {
141
+ const providers = new Map();
142
+ const owners = new Map();
143
+ for (const binding of Object.values(this.bindings).flat()) {
144
+ const previous = owners.get(binding.provider);
145
+ if (previous !== undefined && previous !== binding.scheme) {
146
+ throw new TypeError('Distinct credential schemes require distinct provider bindings');
147
+ }
148
+ if (previous !== undefined)
149
+ continue;
150
+ owners.set(binding.provider, binding.scheme);
151
+ providers.set(binding.provider, this.prepareProvider(this.#credentials.get(binding.scheme)));
152
+ }
153
+ return Object.freeze(Object.fromEntries(providers));
154
+ }
155
+ prepareProvider(credentials) {
156
+ if (credentials.kind === 'provider')
157
+ return credentials.provider;
158
+ if (credentials.kind === 'oauth')
159
+ return credentials.providerFactory(credentials);
160
+ const identity = crypto.randomUUID();
161
+ let token;
162
+ switch (credentials.kind) {
163
+ case 'bearer':
164
+ token = credentials.token;
165
+ break;
166
+ case 'apiKey':
167
+ token = credentials.key;
168
+ break;
169
+ case 'basic':
170
+ token = btoa(Array.from(new TextEncoder().encode(`${credentials.username}:${credentials.password}`), (byte) => String.fromCodePoint(byte)).join(''));
171
+ break;
172
+ }
173
+ return {
174
+ identity,
175
+ configure: () => ({ clientIdentity: identity }),
176
+ acquire: () => Promise.resolve({ accessToken: token }),
177
+ };
178
+ }
179
+ }
180
+ //# sourceMappingURL=client-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-settings.js","sourceRoot":"","sources":["../src/client-settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { SecurityBinding, SecurityEndpoints } from './security-binding.js';
2
+ import type { TokenProvider, TokenRequest } from './token-provider.js';
3
+ /** Fresh application-authorized PKCE result; interactive authorization remains application-owned. */
4
+ export interface AuthorizationGrant {
5
+ readonly code: string;
6
+ readonly redirectUri: string;
7
+ readonly codeVerifier: string;
8
+ }
9
+ /** Transport-independent OAuth client configuration. */
10
+ export interface OAuthCredentialOptions {
11
+ readonly identity: string;
12
+ readonly clientId: string;
13
+ readonly clientSecret?: string;
14
+ readonly authentication?: 'none' | 'client_secret_basic' | 'client_secret_post';
15
+ readonly grantIdentity?: string;
16
+ readonly authorization?: (request: TokenRequest, signal: AbortSignal) => Promise<AuthorizationGrant>;
17
+ readonly endpoints?: SecurityEndpoints;
18
+ readonly issuer?: string;
19
+ }
20
+ /** Application-supplied bearer token, without its wire prefix. */
21
+ export interface BearerCredentials {
22
+ readonly kind: 'bearer';
23
+ readonly token: string;
24
+ }
25
+ /** Application-supplied API key; the contract determines its wire location. */
26
+ export interface ApiKeyCredentials {
27
+ readonly kind: 'apiKey';
28
+ readonly key: string;
29
+ }
30
+ /** Basic authentication inputs; the runtime supplies the wire encoding. */
31
+ export interface BasicCredentials {
32
+ readonly kind: 'basic';
33
+ readonly username: string;
34
+ readonly password: string;
35
+ }
36
+ /** OAuth inputs narrowed to the selected acquisition flow. */
37
+ export type OAuthCredentials = {
38
+ /** Builds the installed module's provider without acquiring tokens. */
39
+ readonly providerFactory: (credentials: OAuthCredentials) => TokenProvider;
40
+ } & ((OAuthCredentialOptions & {
41
+ readonly kind: 'oauth';
42
+ readonly flow: 'clientCredentials';
43
+ }) | (OAuthCredentialOptions & {
44
+ readonly kind: 'oauth';
45
+ readonly flow: 'authorizationCode';
46
+ readonly grantIdentity: string;
47
+ readonly authorization: NonNullable<OAuthCredentialOptions['authorization']>;
48
+ }));
49
+ /** Escape hatch for application-owned acquisition and unsupported OAuth flows. */
50
+ export interface ProviderCredentials {
51
+ readonly kind: 'provider';
52
+ readonly provider: TokenProvider;
53
+ readonly flow?: SecurityBinding['flow'];
54
+ }
55
+ /** Shared credential family; generated code narrows this union for each declared scheme. */
56
+ export type Credentials = BearerCredentials | ApiKeyCredentials | BasicCredentials | OAuthCredentials | ProviderCredentials;
57
+ /** Reject incompatible inputs before constructing a transport or acquiring a token. */
58
+ export declare function validateCredentials(credentials: Credentials, binding: SecurityBinding): void;
@@ -0,0 +1,51 @@
1
+ // Copyright 2020 Outfox, Inc.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ /** Reject incompatible inputs before constructing a transport or acquiring a token. */
15
+ export function validateCredentials(credentials, binding) {
16
+ if (credentials.kind === 'provider') {
17
+ if (credentials.flow !== undefined && credentials.flow !== binding.flow)
18
+ throw new TypeError('Provider flow does not match');
19
+ return;
20
+ }
21
+ const prefix = binding.transport.prefix?.toLowerCase();
22
+ if (credentials.kind === 'oauth') {
23
+ validateOAuthCredentials(credentials, binding);
24
+ return;
25
+ }
26
+ if (binding.flow !== 'static' && binding.flow !== 'external') {
27
+ throw new TypeError('Static credentials cannot satisfy an OAuth acquisition binding');
28
+ }
29
+ if (credentials.kind === 'bearer' && (prefix !== 'bearer' || !credentials.token)) {
30
+ throw new TypeError('Bearer credentials do not match the selected security binding');
31
+ }
32
+ if (credentials.kind === 'apiKey' && (prefix !== undefined || !credentials.key)) {
33
+ throw new TypeError('API key credentials do not match the selected security binding');
34
+ }
35
+ if (credentials.kind === 'basic' && (prefix !== 'basic' || credentials.username.includes(':'))) {
36
+ throw new TypeError('Basic credentials do not match the selected security binding');
37
+ }
38
+ }
39
+ function validateOAuthCredentials(credentials, binding) {
40
+ const prefix = binding.transport.prefix?.toLowerCase();
41
+ if (prefix !== 'bearer' || credentials.flow !== binding.flow || !credentials.identity.trim() || !credentials.clientId.trim()) {
42
+ throw new TypeError('OAuth credentials do not match the selected security binding');
43
+ }
44
+ const authentication = credentials.authentication ?? 'none';
45
+ if (!['none', 'client_secret_basic', 'client_secret_post'].includes(authentication) || (authentication === 'none') !== (credentials.clientSecret === undefined) || credentials.clientSecret === '' ||
46
+ (credentials.flow === 'clientCredentials' && authentication === 'none') ||
47
+ (credentials.flow === 'authorizationCode' && (!credentials.grantIdentity.trim() || !credentials.authorization))) {
48
+ throw new TypeError('Invalid OAuth credential configuration');
49
+ }
50
+ }
51
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAiEjC,uFAAuF;AACvF,MAAM,UAAU,mBAAmB,CAAC,WAAwB,EAAE,OAAwB;IACpF,IAAI,WAAW,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACpC,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI;YAAE,MAAM,IAAI,SAAS,CAAC,8BAA8B,CAAC,CAAC;QAC7H,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IACvD,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACjC,wBAAwB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC7D,MAAM,IAAI,SAAS,CAAC,gEAAgE,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,SAAS,CAAC,+DAA+D,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QAChF,MAAM,IAAI,SAAS,CAAC,gEAAgE,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,SAAS,CAAC,8DAA8D,CAAC,CAAC;IACtF,CAAC;AACH,CAAC;AAGD,SAAS,wBAAwB,CAAC,WAA6B,EAAE,OAAwB;IACvF,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IACvD,IAAI,MAAM,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7H,MAAM,IAAI,SAAS,CAAC,8DAA8D,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,cAAc,GAAG,WAAW,CAAC,cAAc,IAAI,MAAM,CAAC;IAC5D,IAAI,CAAC,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,KAAK,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,SAAS,CAAC,IAAI,WAAW,CAAC,YAAY,KAAK,EAAE;QAChM,CAAC,WAAW,CAAC,IAAI,KAAK,mBAAmB,IAAI,cAAc,KAAK,MAAM,CAAC;QACvE,CAAC,WAAW,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;QAClH,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
@@ -1,17 +1,32 @@
1
+ /** Message fields dispatched at a blank line; ID-only frames update the reconnect cursor. */
1
2
  export interface EventInfo {
3
+ /** Last valid ID in this frame; NUL-containing fields are ignored. */
2
4
  id?: string;
3
5
  event?: string;
4
6
  data?: string;
7
+ }
8
+ /** Connection controls reported immediately, independently of message boundaries. */
9
+ export interface EventControl {
10
+ /** A valid non-negative safe integer, retaining its wire representation. */
5
11
  retry?: string;
12
+ keepalive?: string;
13
+ 'retry-max'?: string;
6
14
  }
15
+ /** Incremental UTF-8 SSE parser. Create one instance per connection; incomplete events end with it. */
7
16
  export declare class EventParser {
17
+ private readonly control;
8
18
  private readonly decoder;
9
- private unprocessedBuffer?;
10
- process(buffer: ArrayBuffer, dispatcher: (eventInfo: EventInfo) => void): void;
11
- private buildAvailableBuffer;
12
- private extractEventStringsFromBuffer;
13
- private static findEventSeparator;
14
- private static parseAndDispatchEvents;
15
- private static parseEvent;
16
- private static trimFieldValue;
19
+ private atStart;
20
+ private readonly lineParts;
21
+ private event;
22
+ private readonly data;
23
+ private skipLF;
24
+ /** Receives each completed control line, even when EOF discards the unfinished message. */
25
+ constructor(control?: (control: EventControl) => void);
26
+ /** Parses complete lines and events, discarding the rest of a chunk when the signal aborts. */
27
+ process(buffer: ArrayBuffer | ArrayBufferView, dispatcher: (eventInfo: EventInfo) => void, signal?: AbortSignal): void;
28
+ private discard;
29
+ private processLine;
17
30
  }
31
+ /** @internal Parses bounded SSE millisecond values without accepting partial numbers. */
32
+ export declare function parseEventMilliseconds(value: string): number | undefined;
@@ -11,141 +11,113 @@
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
+ /** Incremental UTF-8 SSE parser. Create one instance per connection; incomplete events end with it. */
14
15
  export class EventParser {
15
- decoder = new TextDecoder('utf-8');
16
- unprocessedBuffer;
17
- process(buffer, dispatcher) {
18
- const availableBuffer = this.buildAvailableBuffer(buffer);
19
- if (!availableBuffer) {
20
- return;
21
- }
22
- const eventStrings = this.extractEventStringsFromBuffer(availableBuffer);
23
- if (!eventStrings.length) {
24
- return;
25
- }
26
- EventParser.parseAndDispatchEvents(eventStrings, dispatcher);
16
+ control;
17
+ // Node can strip two consecutive BOMs when the first spans chunks; remove exactly one here.
18
+ decoder = new TextDecoder('utf-8', { ignoreBOM: true });
19
+ atStart = true;
20
+ lineParts = [];
21
+ event = {};
22
+ data = [];
23
+ skipLF = false;
24
+ /** Receives each completed control line, even when EOF discards the unfinished message. */
25
+ constructor(control = () => { }) {
26
+ this.control = control;
27
27
  }
28
- buildAvailableBuffer(buffer) {
29
- const unprocessedBuffer = this.unprocessedBuffer;
30
- this.unprocessedBuffer = undefined;
31
- if (!buffer.byteLength) {
32
- return unprocessedBuffer;
33
- }
34
- else if (!unprocessedBuffer?.byteLength) {
35
- return buffer;
28
+ /** Parses complete lines and events, discarding the rest of a chunk when the signal aborts. */
29
+ process(buffer, dispatcher, signal) {
30
+ if (signal?.aborted) {
31
+ this.discard();
32
+ return;
36
33
  }
37
- const newBuffer = new Uint8Array(unprocessedBuffer.byteLength + buffer.byteLength);
38
- newBuffer.set(new Uint8Array(unprocessedBuffer), 0);
39
- newBuffer.set(new Uint8Array(buffer), unprocessedBuffer.byteLength);
40
- return newBuffer.buffer;
41
- }
42
- extractEventStringsFromBuffer(buffer) {
43
- const eventStrings = [];
44
- while (buffer.byteLength) {
45
- // Find end of next event separator in buffer, exiting if none found.
46
- const eventSeparator = EventParser.findEventSeparator(buffer);
47
- if (!eventSeparator) {
48
- // Save unprocessed data
49
- this.unprocessedBuffer = buffer;
50
- break;
51
- }
52
- const [endOfCurrentEventIdx, startOfNextEventIdx] = eventSeparator;
53
- const eventBuffer = buffer.slice(0, endOfCurrentEventIdx);
54
- buffer = buffer.slice(startOfNextEventIdx);
55
- const eventString = this.decoder.decode(eventBuffer, {
56
- stream: true,
57
- });
58
- eventStrings.push(eventString);
34
+ let text = this.decoder.decode(buffer, { stream: true });
35
+ if (this.atStart && text.length) {
36
+ this.atStart = false;
37
+ if (text[0] === '\ufeff')
38
+ text = text.slice(1);
59
39
  }
60
- return eventStrings;
61
- }
62
- static findEventSeparator(buffer) {
63
- const bytes = new Uint8Array(buffer);
64
- for (let idx = 0; idx < bytes.length; ++idx) {
65
- const byte = bytes[idx];
66
- switch (byte) {
67
- // line-feed
68
- case 0xa: {
69
- // if the next byte is the
70
- // same, we found a separator
71
- if (bytes[idx + 1] == 0xa) {
72
- return [idx, idx + 2];
73
- }
74
- break;
75
- }
76
- // carriage-return
77
- case 0xd: {
78
- // if the next byte is the
79
- // same, we found a separator
80
- if (bytes[idx + 1] == 0xd) {
81
- return [idx, idx + 2];
82
- }
83
- // if next is line-feed, and pattern
84
- // repeats, we found a separator.
85
- if (bytes[idx + 1] == 0xa &&
86
- bytes[idx + 2] == 0xd &&
87
- bytes[idx + 3] == 0xa) {
88
- return [idx, idx + 4];
89
- }
90
- break;
40
+ let start = 0;
41
+ for (let index = 0; index < text.length; index++) {
42
+ const character = text[index];
43
+ // A CR completes its line immediately; only its optional following LF is skipped.
44
+ if (this.skipLF) {
45
+ this.skipLF = false;
46
+ if (character === '\n') {
47
+ start = index + 1;
48
+ continue;
91
49
  }
92
- default:
93
50
  }
94
- }
95
- return undefined;
96
- }
97
- static parseAndDispatchEvents(eventStrings, dispatcher) {
98
- for (const eventString of eventStrings) {
99
- if (!eventString.length) {
51
+ if (character !== '\r' && character !== '\n')
100
52
  continue;
101
- }
102
- const parsedEvent = EventParser.parseEvent(eventString);
103
- dispatcher(parsedEvent);
104
- }
105
- }
106
- static parseEvent(eventString) {
107
- const event = {};
108
- for (const line of eventString.split(lineSeparatorsRegEx)) {
109
- const keyValueSeparatorIdx = line.indexOf(':');
110
- let key;
111
- let value;
112
- if (keyValueSeparatorIdx != -1) {
113
- key = line.slice(0, keyValueSeparatorIdx);
114
- value = line.slice(keyValueSeparatorIdx + 1);
53
+ this.lineParts.push(text.slice(start, index));
54
+ const line = this.lineParts.join('');
55
+ this.lineParts.length = 0;
56
+ this.skipLF = character === '\r';
57
+ start = index + 1;
58
+ if (line) {
59
+ this.processLine(line);
115
60
  }
116
61
  else {
117
- key = line;
118
- value = '';
62
+ const event = this.event;
63
+ if (this.data.length)
64
+ event.data = this.data.join('\n');
65
+ this.event = {};
66
+ this.data.length = 0;
67
+ if (event.data !== undefined || event.id !== undefined)
68
+ dispatcher(event);
119
69
  }
120
- switch (key) {
121
- case 'retry':
122
- event.retry = EventParser.trimFieldValue(value);
123
- break;
124
- case 'data': {
125
- const data = event.data ?? '';
126
- event.data = `${data}${EventParser.trimFieldValue(value)}\n`;
127
- break;
128
- }
129
- case '':
130
- // comment do nothing
131
- break;
132
- default: {
133
- event[key] =
134
- EventParser.trimFieldValue(value);
135
- }
70
+ if (signal?.aborted) {
71
+ this.discard();
72
+ return;
136
73
  }
137
74
  }
138
- if (event.data?.[event.data?.length - 1] == '\n') {
139
- event.data = event.data.slice(0, -1);
140
- }
141
- return event;
75
+ if (start < text.length)
76
+ this.lineParts.push(text.slice(start));
77
+ }
78
+ discard() {
79
+ // decode() without stream resets UTF-8/BOM state, including a partial character in the
80
+ // discarded tail. It must not contaminate a later call after cancellation.
81
+ this.decoder.decode();
82
+ this.atStart = true;
83
+ this.lineParts.length = 0;
84
+ this.event = {};
85
+ this.data.length = 0;
86
+ this.skipLF = false;
142
87
  }
143
- static trimFieldValue(value) {
144
- if (value[0] !== ' ') {
145
- return value;
88
+ processLine(line) {
89
+ const colon = line.indexOf(':');
90
+ const key = colon < 0 ? line : line.slice(0, colon);
91
+ let value = colon < 0 ? '' : line.slice(colon + 1);
92
+ if (value.startsWith(' '))
93
+ value = value.slice(1);
94
+ switch (key) {
95
+ case 'data':
96
+ this.data.push(value);
97
+ break;
98
+ case 'id':
99
+ if (!value.includes('\0'))
100
+ this.event.id = value;
101
+ break;
102
+ case 'retry':
103
+ if (parseEventMilliseconds(value) !== undefined)
104
+ this.control({ retry: value });
105
+ break;
106
+ case 'event':
107
+ this.event.event = value;
108
+ break;
109
+ case 'keepalive':
110
+ case 'retry-max':
111
+ this.control({ [key]: value });
112
+ break;
146
113
  }
147
- return value.slice(1);
148
114
  }
149
115
  }
150
- const lineSeparatorsRegEx = /\r\n|\r|\n/;
116
+ /** @internal Parses bounded SSE millisecond values without accepting partial numbers. */
117
+ export function parseEventMilliseconds(value) {
118
+ if (!/^\d+$/.test(value))
119
+ return undefined;
120
+ const milliseconds = Number(value);
121
+ return Number.isSafeInteger(milliseconds) ? milliseconds : undefined;
122
+ }
151
123
  //# sourceMappingURL=event-parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-parser.js","sourceRoot":"","sources":["../src/event-parser.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AASjC,MAAM,OAAO,WAAW;IACL,OAAO,GAAgB,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IACzD,iBAAiB,CAAe;IAExC,OAAO,CACL,MAAmB,EACnB,UAA0C;QAE1C,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,6BAA6B,CAAC,eAAe,CAAC,CAAC;QAEzE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,WAAW,CAAC,sBAAsB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC/D,CAAC;IAEO,oBAAoB,CAAC,MAAmB;QAC9C,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACjD,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;QAEnC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO,iBAAiB,CAAC;QAC3B,CAAC;aAAM,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,CAAC;YAC1C,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,UAAU,CAC9B,iBAAiB,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CACjD,CAAC;QACF,SAAS,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;QACpD,SAAS,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAEpE,OAAO,SAAS,CAAC,MAAM,CAAC;IAC1B,CAAC;IAEO,6BAA6B,CAAC,MAAmB;QACvD,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;YACzB,qEAAqE;YACrE,MAAM,cAAc,GAAG,WAAW,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC9D,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,wBAAwB;gBACxB,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC;gBAChC,MAAM;YACR,CAAC;YAED,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,cAAc,CAAC;YAEnE,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;YAC1D,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAE3C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;gBACnD,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YAEH,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,kBAAkB,CAC/B,MAAmB;QAEnB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAErC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YAExB,QAAQ,IAAI,EAAE,CAAC;gBACb,YAAY;gBACZ,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,0BAA0B;oBAC1B,6BAA6B;oBAC7B,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;wBAC1B,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;oBACxB,CAAC;oBACD,MAAM;gBACR,CAAC;gBAED,kBAAkB;gBAClB,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,0BAA0B;oBAC1B,6BAA6B;oBAC7B,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;wBAC1B,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;oBACxB,CAAC;oBAED,oCAAoC;oBACpC,iCAAiC;oBACjC,IACE,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG;wBACrB,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG;wBACrB,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG,EACrB,CAAC;wBACD,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;oBACxB,CAAC;oBAED,MAAM;gBACR,CAAC;gBAED,QAAQ;YACV,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,MAAM,CAAC,sBAAsB,CACnC,YAAsB,EACtB,UAA0C;QAE1C,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YAExD,UAAU,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,UAAU,CAAC,WAAmB;QAC3C,MAAM,KAAK,GAAc,EAAE,CAAC;QAE5B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1D,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAE/C,IAAI,GAAW,CAAC;YAChB,IAAI,KAAa,CAAC;YAClB,IAAI,oBAAoB,IAAI,CAAC,CAAC,EAAE,CAAC;gBAC/B,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;gBAC1C,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,IAAI,CAAC;gBACX,KAAK,GAAG,EAAE,CAAC;YACb,CAAC;YAED,QAAQ,GAAG,EAAE,CAAC;gBACZ,KAAK,OAAO;oBACV,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;oBAChD,MAAM;gBAER,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC9B,KAAK,CAAC,IAAI,GAAG,GAAG,IAAI,GAAG,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;oBAC7D,MAAM;gBACR,CAAC;gBAED,KAAK,EAAE;oBACL,qBAAqB;oBACrB,MAAM;gBAER,OAAO,CAAC,CAAC,CAAC;oBACP,KAAgC,CAAC,GAAG,CAAC;wBACpC,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YACjD,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,MAAM,CAAC,cAAc,CAAC,KAAa;QACzC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;CACF;AAED,MAAM,mBAAmB,GAAG,YAAY,CAAC"}
1
+ {"version":3,"file":"event-parser.js","sourceRoot":"","sources":["../src/event-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copies native Fetch request settings and transfers responsibility for its body. The old request
3
+ * must not subsequently consume the body. Supply a replacement after consuming a body.
4
+ */
5
+ export declare function copyRequest(request: Request, changes?: RequestInit & {
6
+ url?: string | URL;
7
+ duplex?: 'half';
8
+ }): Request;
9
+ /**
10
+ * Copies an inspectable response without teeing its body, retaining Fetch metadata.
11
+ * Opaque/error responses cannot be reconstructed with the platform Response constructor.
12
+ */
13
+ export declare function copyResponse(response: Response, changes?: ResponseInit & {
14
+ body?: BodyInit | null;
15
+ }): Response;