@lorikeetai/node-sdk 0.13.2 → 1.0.1
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/CHANGELOG.md +247 -0
- package/README.md +17 -32
- package/core.d.ts +7 -4
- package/core.d.ts.map +1 -1
- package/core.js +16 -9
- package/core.js.map +1 -1
- package/core.mjs +16 -9
- package/core.mjs.map +1 -1
- package/index.d.mts +21 -3
- package/index.d.ts +21 -3
- package/index.d.ts.map +1 -1
- package/index.js +31 -7
- package/index.js.map +1 -1
- package/index.mjs +32 -8
- package/index.mjs.map +1 -1
- package/internal/qs/formats.d.ts +6 -0
- package/internal/qs/formats.d.ts.map +1 -0
- package/internal/qs/formats.js +11 -0
- package/internal/qs/formats.js.map +1 -0
- package/internal/qs/formats.mjs +8 -0
- package/internal/qs/formats.mjs.map +1 -0
- package/internal/qs/index.d.ts +10 -0
- package/internal/qs/index.d.ts.map +1 -0
- package/internal/qs/index.js +14 -0
- package/internal/qs/index.js.map +1 -0
- package/internal/qs/index.mjs +10 -0
- package/internal/qs/index.mjs.map +1 -0
- package/internal/qs/stringify.d.ts +3 -0
- package/internal/qs/stringify.d.ts.map +1 -0
- package/internal/qs/stringify.js +279 -0
- package/internal/qs/stringify.js.map +1 -0
- package/internal/qs/stringify.mjs +276 -0
- package/internal/qs/stringify.mjs.map +1 -0
- package/internal/qs/types.d.ts +57 -0
- package/internal/qs/types.d.ts.map +1 -0
- package/internal/qs/types.js +3 -0
- package/internal/qs/types.js.map +1 -0
- package/internal/qs/types.mjs +2 -0
- package/internal/qs/types.mjs.map +1 -0
- package/internal/qs/utils.d.ts +14 -0
- package/internal/qs/utils.d.ts.map +1 -0
- package/internal/qs/utils.js +229 -0
- package/internal/qs/utils.js.map +1 -0
- package/internal/qs/utils.mjs +217 -0
- package/internal/qs/utils.mjs.map +1 -0
- package/package.json +1 -5
- package/resource.d.ts +1 -1
- package/resource.d.ts.map +1 -1
- package/resource.js.map +1 -1
- package/resource.mjs.map +1 -1
- package/resources/conversation/chat.d.ts +19 -164
- package/resources/conversation/chat.d.ts.map +1 -1
- package/resources/conversation/chat.js.map +1 -1
- package/resources/conversation/chat.mjs.map +1 -1
- package/resources/conversation/conversation.d.ts +116 -0
- package/resources/conversation/conversation.d.ts.map +1 -1
- package/resources/conversation/conversation.js +36 -0
- package/resources/conversation/conversation.js.map +1 -1
- package/resources/conversation/conversation.mjs +36 -0
- package/resources/conversation/conversation.mjs.map +1 -1
- package/resources/conversation/email.d.ts +19 -164
- package/resources/conversation/email.d.ts.map +1 -1
- package/resources/conversation/email.js.map +1 -1
- package/resources/conversation/email.mjs.map +1 -1
- package/resources/conversation/index.d.ts +1 -1
- package/resources/conversation/index.d.ts.map +1 -1
- package/resources/conversation/index.js.map +1 -1
- package/resources/conversation/index.mjs +1 -1
- package/resources/conversation/index.mjs.map +1 -1
- package/resources/customer/customer.d.ts +296 -0
- package/resources/customer/customer.d.ts.map +1 -0
- package/resources/customer/customer.js +79 -0
- package/resources/customer/customer.js.map +1 -0
- package/resources/customer/customer.mjs +52 -0
- package/resources/customer/customer.mjs.map +1 -0
- package/resources/customer/index.d.ts +3 -0
- package/resources/customer/index.d.ts.map +1 -0
- package/resources/customer/index.js +9 -0
- package/resources/customer/index.js.map +1 -0
- package/resources/customer/index.mjs +4 -0
- package/resources/customer/index.mjs.map +1 -0
- package/resources/customer/profile.d.ts +71 -0
- package/resources/customer/profile.d.ts.map +1 -0
- package/resources/customer/profile.js +21 -0
- package/resources/customer/profile.js.map +1 -0
- package/resources/customer/profile.mjs +17 -0
- package/resources/customer/profile.mjs.map +1 -0
- package/resources/customer.d.ts +1 -291
- package/resources/customer.d.ts.map +1 -1
- package/resources/customer.js +15 -45
- package/resources/customer.js.map +1 -1
- package/resources/customer.mjs +1 -43
- package/resources/customer.mjs.map +1 -1
- package/resources/file.d.ts +7 -0
- package/resources/file.d.ts.map +1 -0
- package/resources/file.js +21 -0
- package/resources/file.js.map +1 -0
- package/resources/file.mjs +17 -0
- package/resources/file.mjs.map +1 -0
- package/resources/index.d.ts +6 -2
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js +10 -2
- package/resources/index.js.map +1 -1
- package/resources/index.mjs +6 -2
- package/resources/index.mjs.map +1 -1
- package/resources/ingest.d.ts +2 -0
- package/resources/ingest.d.ts.map +1 -1
- package/resources/ingest.js +9 -0
- package/resources/ingest.js.map +1 -1
- package/resources/ingest.mjs +9 -0
- package/resources/ingest.mjs.map +1 -1
- package/resources/oauth/authorization.d.ts +6 -0
- package/resources/oauth/authorization.d.ts.map +1 -0
- package/resources/oauth/authorization.js +15 -0
- package/resources/oauth/authorization.js.map +1 -0
- package/resources/oauth/authorization.mjs +11 -0
- package/resources/oauth/authorization.mjs.map +1 -0
- package/resources/oauth/index.d.ts +3 -0
- package/resources/oauth/index.d.ts.map +1 -0
- package/resources/oauth/index.js +9 -0
- package/resources/oauth/index.js.map +1 -0
- package/resources/oauth/index.mjs +4 -0
- package/resources/oauth/index.mjs.map +1 -0
- package/resources/oauth/oauth.d.ts +24 -0
- package/resources/oauth/oauth.d.ts.map +1 -0
- package/resources/oauth/oauth.js +65 -0
- package/resources/oauth/oauth.js.map +1 -0
- package/resources/oauth/oauth.mjs +38 -0
- package/resources/oauth/oauth.mjs.map +1 -0
- package/resources/oauth.d.ts +2 -0
- package/resources/oauth.d.ts.map +1 -0
- package/resources/oauth.js +19 -0
- package/resources/oauth.js.map +1 -0
- package/resources/oauth.mjs +3 -0
- package/resources/oauth.mjs.map +1 -0
- package/resources/suggestion.d.ts +7 -0
- package/resources/suggestion.d.ts.map +1 -0
- package/resources/suggestion.js +21 -0
- package/resources/suggestion.js.map +1 -0
- package/resources/suggestion.mjs +17 -0
- package/resources/suggestion.mjs.map +1 -0
- package/resources/ticket.d.ts +14 -0
- package/resources/ticket.d.ts.map +1 -0
- package/resources/ticket.js +16 -0
- package/resources/ticket.js.map +1 -0
- package/resources/ticket.mjs +12 -0
- package/resources/ticket.mjs.map +1 -0
- package/resources/top-level.d.ts +2 -0
- package/resources/top-level.d.ts.map +1 -0
- package/resources/top-level.js +4 -0
- package/resources/top-level.js.map +1 -0
- package/resources/top-level.mjs +3 -0
- package/resources/top-level.mjs.map +1 -0
- package/resources/webhooks.d.ts +6 -0
- package/resources/webhooks.d.ts.map +1 -0
- package/resources/webhooks.js +15 -0
- package/resources/webhooks.js.map +1 -0
- package/resources/webhooks.mjs +11 -0
- package/resources/webhooks.mjs.map +1 -0
- package/resources/workflow.d.ts +1 -0
- package/resources/workflow.d.ts.map +1 -1
- package/resources/workflow.js +3 -0
- package/resources/workflow.js.map +1 -1
- package/resources/workflow.mjs +3 -0
- package/resources/workflow.mjs.map +1 -1
- package/src/core.ts +17 -8
- package/src/index.ts +73 -10
- package/src/internal/qs/LICENSE.md +13 -0
- package/src/internal/qs/README.md +3 -0
- package/src/internal/qs/formats.ts +9 -0
- package/src/internal/qs/index.ts +13 -0
- package/src/internal/qs/stringify.ts +388 -0
- package/src/internal/qs/types.ts +71 -0
- package/src/internal/qs/utils.ts +265 -0
- package/src/resource.ts +1 -1
- package/src/resources/conversation/chat.ts +21 -217
- package/src/resources/conversation/conversation.ts +175 -0
- package/src/resources/conversation/email.ts +21 -217
- package/src/resources/conversation/index.ts +10 -1
- package/src/resources/customer/customer.ts +386 -0
- package/src/resources/customer/index.ts +13 -0
- package/src/resources/customer/profile.ts +89 -0
- package/src/resources/customer.ts +1 -372
- package/src/resources/file.ts +20 -0
- package/src/resources/index.ts +15 -2
- package/src/resources/ingest.ts +17 -0
- package/src/resources/oauth/authorization.ts +13 -0
- package/src/resources/oauth/index.ts +4 -0
- package/src/resources/oauth/oauth.ts +63 -0
- package/src/resources/oauth.ts +3 -0
- package/src/resources/suggestion.ts +20 -0
- package/src/resources/ticket.ts +30 -0
- package/src/resources/top-level.ts +3 -0
- package/src/resources/webhooks.ts +13 -0
- package/src/resources/workflow.ts +4 -0
- package/src/version.ts +1 -1
- package/version.d.ts +1 -1
- package/version.d.ts.map +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
- package/version.mjs +1 -1
- package/version.mjs.map +1 -1
package/src/index.ts
CHANGED
|
@@ -5,6 +5,22 @@ import * as Core from './core';
|
|
|
5
5
|
import * as Errors from './error';
|
|
6
6
|
import * as Uploads from './uploads';
|
|
7
7
|
import * as API from './resources/index';
|
|
8
|
+
import { File } from './resources/file';
|
|
9
|
+
import { Ingest, IngestTestParams } from './resources/ingest';
|
|
10
|
+
import { Suggestion } from './resources/suggestion';
|
|
11
|
+
import { Webhooks } from './resources/webhooks';
|
|
12
|
+
import { Workflow } from './resources/workflow';
|
|
13
|
+
import {
|
|
14
|
+
AttachmentDto,
|
|
15
|
+
Conversation,
|
|
16
|
+
ConversationCreateParams,
|
|
17
|
+
ConversationCreateResponse,
|
|
18
|
+
ConversationRetrieveTranscriptParams,
|
|
19
|
+
ConversationRetrieveTranscriptResponse,
|
|
20
|
+
TicketEvent,
|
|
21
|
+
TicketMessageDto,
|
|
22
|
+
} from './resources/conversation/conversation';
|
|
23
|
+
import { generateSignature } from './lib/generate-signature';
|
|
8
24
|
import {
|
|
9
25
|
Customer,
|
|
10
26
|
CustomerCreateParams,
|
|
@@ -14,11 +30,8 @@ import {
|
|
|
14
30
|
CustomerTokenResponse,
|
|
15
31
|
CustomerUpdateParams,
|
|
16
32
|
CustomerUpdateResponse,
|
|
17
|
-
} from './resources/customer';
|
|
18
|
-
import {
|
|
19
|
-
import { Workflow } from './resources/workflow';
|
|
20
|
-
import { Conversation } from './resources/conversation/conversation';
|
|
21
|
-
import { generateSignature } from './lib/generate-signature';
|
|
33
|
+
} from './resources/customer/customer';
|
|
34
|
+
import { OAuth, OAuthAuthorizeParams, OAuthCallbackParams } from './resources/oauth/oauth';
|
|
22
35
|
|
|
23
36
|
export interface ClientOptions {
|
|
24
37
|
/**
|
|
@@ -44,6 +57,8 @@ export interface ClientOptions {
|
|
|
44
57
|
*
|
|
45
58
|
* Note that request timeouts are retried by default, so in a worst-case scenario you may wait
|
|
46
59
|
* much longer than this timeout before the promise succeeds or fails.
|
|
60
|
+
*
|
|
61
|
+
* @unit milliseconds
|
|
47
62
|
*/
|
|
48
63
|
timeout?: number | undefined;
|
|
49
64
|
|
|
@@ -136,6 +151,7 @@ export class Lorikeet extends Core.APIClient {
|
|
|
136
151
|
|
|
137
152
|
super({
|
|
138
153
|
baseURL: options.baseURL!,
|
|
154
|
+
baseURLOverridden: baseURL ? baseURL !== 'https://api.lorikeetcx.ai' : false,
|
|
139
155
|
timeout: options.timeout ?? 60000 /* 1 minute */,
|
|
140
156
|
httpAgent: options.httpAgent,
|
|
141
157
|
maxRetries: options.maxRetries,
|
|
@@ -152,6 +168,21 @@ export class Lorikeet extends Core.APIClient {
|
|
|
152
168
|
customer: API.Customer = new API.Customer(this);
|
|
153
169
|
workflow: API.Workflow = new API.Workflow(this);
|
|
154
170
|
ingest: API.Ingest = new API.Ingest(this);
|
|
171
|
+
file: API.File = new API.File(this);
|
|
172
|
+
suggestion: API.Suggestion = new API.Suggestion(this);
|
|
173
|
+
oauth: API.OAuth = new API.OAuth(this);
|
|
174
|
+
webhooks: API.Webhooks = new API.Webhooks(this);
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Check whether the base URL is set to its default.
|
|
178
|
+
*/
|
|
179
|
+
#baseURLOverridden(): boolean {
|
|
180
|
+
return this.baseURL !== 'https://api.lorikeetcx.ai';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
retrieve(options?: Core.RequestOptions): Core.APIPromise<void> {
|
|
184
|
+
return this.get('/', { ...options, headers: { Accept: '*/*', ...options?.headers } });
|
|
185
|
+
}
|
|
155
186
|
|
|
156
187
|
protected override defaultQuery(): Core.DefaultQuery | undefined {
|
|
157
188
|
return this._options.defaultQuery;
|
|
@@ -165,7 +196,17 @@ export class Lorikeet extends Core.APIClient {
|
|
|
165
196
|
}
|
|
166
197
|
|
|
167
198
|
protected override authHeaders(opts: Core.FinalRequestOptions): Core.Headers {
|
|
168
|
-
|
|
199
|
+
return {
|
|
200
|
+
...this.lorikeetClientIdAuth(opts),
|
|
201
|
+
...this.lorikeetSignatureAuthV1Auth(opts),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
protected lorikeetClientIdAuth(opts: Core.FinalRequestOptions): Core.Headers {
|
|
206
|
+
return { authorization: `Bearer ${this.clientId}` };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
protected lorikeetSignatureAuthV1Auth(opts: Core.FinalRequestOptions): Core.Headers {
|
|
169
210
|
const signature = generateSignature(
|
|
170
211
|
opts.body ?
|
|
171
212
|
typeof opts.body === 'string' ?
|
|
@@ -175,10 +216,7 @@ export class Lorikeet extends Core.APIClient {
|
|
|
175
216
|
this.clientSecret,
|
|
176
217
|
);
|
|
177
218
|
return {
|
|
178
|
-
// backwards compatibility
|
|
179
|
-
'x-optech-webhook-signature': signature,
|
|
180
219
|
'x-lorikeet-signature': signature,
|
|
181
|
-
authorization: `Bearer ${this.clientId}`,
|
|
182
220
|
};
|
|
183
221
|
}
|
|
184
222
|
|
|
@@ -207,10 +245,23 @@ Lorikeet.Conversation = Conversation;
|
|
|
207
245
|
Lorikeet.Customer = Customer;
|
|
208
246
|
Lorikeet.Workflow = Workflow;
|
|
209
247
|
Lorikeet.Ingest = Ingest;
|
|
248
|
+
Lorikeet.File = File;
|
|
249
|
+
Lorikeet.Suggestion = Suggestion;
|
|
250
|
+
Lorikeet.OAuth = OAuth;
|
|
251
|
+
Lorikeet.Webhooks = Webhooks;
|
|
210
252
|
export declare namespace Lorikeet {
|
|
211
253
|
export type RequestOptions = Core.RequestOptions;
|
|
212
254
|
|
|
213
|
-
export {
|
|
255
|
+
export {
|
|
256
|
+
Conversation as Conversation,
|
|
257
|
+
type AttachmentDto as AttachmentDto,
|
|
258
|
+
type TicketEvent as TicketEvent,
|
|
259
|
+
type TicketMessageDto as TicketMessageDto,
|
|
260
|
+
type ConversationCreateResponse as ConversationCreateResponse,
|
|
261
|
+
type ConversationRetrieveTranscriptResponse as ConversationRetrieveTranscriptResponse,
|
|
262
|
+
type ConversationCreateParams as ConversationCreateParams,
|
|
263
|
+
type ConversationRetrieveTranscriptParams as ConversationRetrieveTranscriptParams,
|
|
264
|
+
};
|
|
214
265
|
|
|
215
266
|
export {
|
|
216
267
|
Customer as Customer,
|
|
@@ -226,6 +277,18 @@ export declare namespace Lorikeet {
|
|
|
226
277
|
export { Workflow as Workflow };
|
|
227
278
|
|
|
228
279
|
export { Ingest as Ingest, type IngestTestParams as IngestTestParams };
|
|
280
|
+
|
|
281
|
+
export { File as File };
|
|
282
|
+
|
|
283
|
+
export { Suggestion as Suggestion };
|
|
284
|
+
|
|
285
|
+
export {
|
|
286
|
+
OAuth as OAuth,
|
|
287
|
+
type OAuthAuthorizeParams as OAuthAuthorizeParams,
|
|
288
|
+
type OAuthCallbackParams as OAuthCallbackParams,
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
export { Webhooks as Webhooks };
|
|
229
292
|
}
|
|
230
293
|
|
|
231
294
|
export { toFile, fileFromPath } from './uploads';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014, Nathan LaFreniere and other [contributors](https://github.com/puruvj/neoqs/graphs/contributors) All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
8
|
+
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
10
|
+
|
|
11
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
12
|
+
|
|
13
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Format } from './types';
|
|
2
|
+
|
|
3
|
+
export const default_format: Format = 'RFC3986';
|
|
4
|
+
export const formatters: Record<Format, (str: PropertyKey) => string> = {
|
|
5
|
+
RFC1738: (v: PropertyKey) => String(v).replace(/%20/g, '+'),
|
|
6
|
+
RFC3986: (v: PropertyKey) => String(v),
|
|
7
|
+
};
|
|
8
|
+
export const RFC1738 = 'RFC1738';
|
|
9
|
+
export const RFC3986 = 'RFC3986';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { default_format, formatters, RFC1738, RFC3986 } from './formats';
|
|
2
|
+
|
|
3
|
+
const formats = {
|
|
4
|
+
formatters,
|
|
5
|
+
RFC1738,
|
|
6
|
+
RFC3986,
|
|
7
|
+
default: default_format,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { stringify } from './stringify';
|
|
11
|
+
export { formats };
|
|
12
|
+
|
|
13
|
+
export type { DefaultDecoder, DefaultEncoder, Format, ParseOptions, StringifyOptions } from './types';
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { encode, is_buffer, maybe_map } from './utils';
|
|
2
|
+
import { default_format, formatters } from './formats';
|
|
3
|
+
import type { NonNullableProperties, StringifyOptions } from './types';
|
|
4
|
+
|
|
5
|
+
const has = Object.prototype.hasOwnProperty;
|
|
6
|
+
|
|
7
|
+
const array_prefix_generators = {
|
|
8
|
+
brackets(prefix: PropertyKey) {
|
|
9
|
+
return String(prefix) + '[]';
|
|
10
|
+
},
|
|
11
|
+
comma: 'comma',
|
|
12
|
+
indices(prefix: PropertyKey, key: string) {
|
|
13
|
+
return String(prefix) + '[' + key + ']';
|
|
14
|
+
},
|
|
15
|
+
repeat(prefix: PropertyKey) {
|
|
16
|
+
return String(prefix);
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const is_array = Array.isArray;
|
|
21
|
+
const push = Array.prototype.push;
|
|
22
|
+
const push_to_array = function (arr: any[], value_or_array: any) {
|
|
23
|
+
push.apply(arr, is_array(value_or_array) ? value_or_array : [value_or_array]);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const to_ISO = Date.prototype.toISOString;
|
|
27
|
+
|
|
28
|
+
const defaults = {
|
|
29
|
+
addQueryPrefix: false,
|
|
30
|
+
allowDots: false,
|
|
31
|
+
allowEmptyArrays: false,
|
|
32
|
+
arrayFormat: 'indices',
|
|
33
|
+
charset: 'utf-8',
|
|
34
|
+
charsetSentinel: false,
|
|
35
|
+
delimiter: '&',
|
|
36
|
+
encode: true,
|
|
37
|
+
encodeDotInKeys: false,
|
|
38
|
+
encoder: encode,
|
|
39
|
+
encodeValuesOnly: false,
|
|
40
|
+
format: default_format,
|
|
41
|
+
formatter: formatters[default_format],
|
|
42
|
+
/** @deprecated */
|
|
43
|
+
indices: false,
|
|
44
|
+
serializeDate(date) {
|
|
45
|
+
return to_ISO.call(date);
|
|
46
|
+
},
|
|
47
|
+
skipNulls: false,
|
|
48
|
+
strictNullHandling: false,
|
|
49
|
+
} as NonNullableProperties<StringifyOptions & { formatter: (typeof formatters)['RFC1738'] }>;
|
|
50
|
+
|
|
51
|
+
function is_non_nullish_primitive(v: unknown): v is string | number | boolean | symbol | bigint {
|
|
52
|
+
return (
|
|
53
|
+
typeof v === 'string' ||
|
|
54
|
+
typeof v === 'number' ||
|
|
55
|
+
typeof v === 'boolean' ||
|
|
56
|
+
typeof v === 'symbol' ||
|
|
57
|
+
typeof v === 'bigint'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const sentinel = {};
|
|
62
|
+
|
|
63
|
+
function inner_stringify(
|
|
64
|
+
object: any,
|
|
65
|
+
prefix: PropertyKey,
|
|
66
|
+
generateArrayPrefix: StringifyOptions['arrayFormat'] | ((prefix: string, key: string) => string),
|
|
67
|
+
commaRoundTrip: boolean,
|
|
68
|
+
allowEmptyArrays: boolean,
|
|
69
|
+
strictNullHandling: boolean,
|
|
70
|
+
skipNulls: boolean,
|
|
71
|
+
encodeDotInKeys: boolean,
|
|
72
|
+
encoder: StringifyOptions['encoder'],
|
|
73
|
+
filter: StringifyOptions['filter'],
|
|
74
|
+
sort: StringifyOptions['sort'],
|
|
75
|
+
allowDots: StringifyOptions['allowDots'],
|
|
76
|
+
serializeDate: StringifyOptions['serializeDate'],
|
|
77
|
+
format: StringifyOptions['format'],
|
|
78
|
+
formatter: StringifyOptions['formatter'],
|
|
79
|
+
encodeValuesOnly: boolean,
|
|
80
|
+
charset: StringifyOptions['charset'],
|
|
81
|
+
sideChannel: WeakMap<any, any>,
|
|
82
|
+
) {
|
|
83
|
+
let obj = object;
|
|
84
|
+
|
|
85
|
+
let tmp_sc = sideChannel;
|
|
86
|
+
let step = 0;
|
|
87
|
+
let find_flag = false;
|
|
88
|
+
while ((tmp_sc = tmp_sc.get(sentinel)) !== void undefined && !find_flag) {
|
|
89
|
+
// Where object last appeared in the ref tree
|
|
90
|
+
const pos = tmp_sc.get(object);
|
|
91
|
+
step += 1;
|
|
92
|
+
if (typeof pos !== 'undefined') {
|
|
93
|
+
if (pos === step) {
|
|
94
|
+
throw new RangeError('Cyclic object value');
|
|
95
|
+
} else {
|
|
96
|
+
find_flag = true; // Break while
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (typeof tmp_sc.get(sentinel) === 'undefined') {
|
|
100
|
+
step = 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (typeof filter === 'function') {
|
|
105
|
+
obj = filter(prefix, obj);
|
|
106
|
+
} else if (obj instanceof Date) {
|
|
107
|
+
obj = serializeDate?.(obj);
|
|
108
|
+
} else if (generateArrayPrefix === 'comma' && is_array(obj)) {
|
|
109
|
+
obj = maybe_map(obj, function (value) {
|
|
110
|
+
if (value instanceof Date) {
|
|
111
|
+
return serializeDate?.(value);
|
|
112
|
+
}
|
|
113
|
+
return value;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (obj === null) {
|
|
118
|
+
if (strictNullHandling) {
|
|
119
|
+
return encoder && !encodeValuesOnly ?
|
|
120
|
+
// @ts-expect-error
|
|
121
|
+
encoder(prefix, defaults.encoder, charset, 'key', format)
|
|
122
|
+
: prefix;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
obj = '';
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (is_non_nullish_primitive(obj) || is_buffer(obj)) {
|
|
129
|
+
if (encoder) {
|
|
130
|
+
const key_value =
|
|
131
|
+
encodeValuesOnly ? prefix
|
|
132
|
+
// @ts-expect-error
|
|
133
|
+
: encoder(prefix, defaults.encoder, charset, 'key', format);
|
|
134
|
+
return [
|
|
135
|
+
formatter?.(key_value) +
|
|
136
|
+
'=' +
|
|
137
|
+
// @ts-expect-error
|
|
138
|
+
formatter?.(encoder(obj, defaults.encoder, charset, 'value', format)),
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
return [formatter?.(prefix) + '=' + formatter?.(String(obj))];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const values: string[] = [];
|
|
145
|
+
|
|
146
|
+
if (typeof obj === 'undefined') {
|
|
147
|
+
return values;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let obj_keys;
|
|
151
|
+
if (generateArrayPrefix === 'comma' && is_array(obj)) {
|
|
152
|
+
// we need to join elements in
|
|
153
|
+
if (encodeValuesOnly && encoder) {
|
|
154
|
+
// @ts-expect-error values only
|
|
155
|
+
obj = maybe_map(obj, encoder);
|
|
156
|
+
}
|
|
157
|
+
obj_keys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
|
|
158
|
+
} else if (is_array(filter)) {
|
|
159
|
+
obj_keys = filter;
|
|
160
|
+
} else {
|
|
161
|
+
const keys = Object.keys(obj);
|
|
162
|
+
obj_keys = sort ? keys.sort(sort) : keys;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const encoded_prefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix);
|
|
166
|
+
|
|
167
|
+
const adjusted_prefix =
|
|
168
|
+
commaRoundTrip && is_array(obj) && obj.length === 1 ? encoded_prefix + '[]' : encoded_prefix;
|
|
169
|
+
|
|
170
|
+
if (allowEmptyArrays && is_array(obj) && obj.length === 0) {
|
|
171
|
+
return adjusted_prefix + '[]';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
for (let j = 0; j < obj_keys.length; ++j) {
|
|
175
|
+
const key = obj_keys[j];
|
|
176
|
+
const value =
|
|
177
|
+
// @ts-ignore
|
|
178
|
+
typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key as any];
|
|
179
|
+
|
|
180
|
+
if (skipNulls && value === null) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// @ts-ignore
|
|
185
|
+
const encoded_key = allowDots && encodeDotInKeys ? (key as any).replace(/\./g, '%2E') : key;
|
|
186
|
+
const key_prefix =
|
|
187
|
+
is_array(obj) ?
|
|
188
|
+
typeof generateArrayPrefix === 'function' ?
|
|
189
|
+
generateArrayPrefix(adjusted_prefix, encoded_key)
|
|
190
|
+
: adjusted_prefix
|
|
191
|
+
: adjusted_prefix + (allowDots ? '.' + encoded_key : '[' + encoded_key + ']');
|
|
192
|
+
|
|
193
|
+
sideChannel.set(object, step);
|
|
194
|
+
const valueSideChannel = new WeakMap();
|
|
195
|
+
valueSideChannel.set(sentinel, sideChannel);
|
|
196
|
+
push_to_array(
|
|
197
|
+
values,
|
|
198
|
+
inner_stringify(
|
|
199
|
+
value,
|
|
200
|
+
key_prefix,
|
|
201
|
+
generateArrayPrefix,
|
|
202
|
+
commaRoundTrip,
|
|
203
|
+
allowEmptyArrays,
|
|
204
|
+
strictNullHandling,
|
|
205
|
+
skipNulls,
|
|
206
|
+
encodeDotInKeys,
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
generateArrayPrefix === 'comma' && encodeValuesOnly && is_array(obj) ? null : encoder,
|
|
209
|
+
filter,
|
|
210
|
+
sort,
|
|
211
|
+
allowDots,
|
|
212
|
+
serializeDate,
|
|
213
|
+
format,
|
|
214
|
+
formatter,
|
|
215
|
+
encodeValuesOnly,
|
|
216
|
+
charset,
|
|
217
|
+
valueSideChannel,
|
|
218
|
+
),
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return values;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function normalize_stringify_options(
|
|
226
|
+
opts: StringifyOptions = defaults,
|
|
227
|
+
): NonNullableProperties<Omit<StringifyOptions, 'indices'>> & { indices?: boolean } {
|
|
228
|
+
if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {
|
|
229
|
+
throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') {
|
|
233
|
+
throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
|
|
237
|
+
throw new TypeError('Encoder has to be a function.');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const charset = opts.charset || defaults.charset;
|
|
241
|
+
if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
|
|
242
|
+
throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
let format = default_format;
|
|
246
|
+
if (typeof opts.format !== 'undefined') {
|
|
247
|
+
if (!has.call(formatters, opts.format)) {
|
|
248
|
+
throw new TypeError('Unknown format option provided.');
|
|
249
|
+
}
|
|
250
|
+
format = opts.format;
|
|
251
|
+
}
|
|
252
|
+
const formatter = formatters[format];
|
|
253
|
+
|
|
254
|
+
let filter = defaults.filter;
|
|
255
|
+
if (typeof opts.filter === 'function' || is_array(opts.filter)) {
|
|
256
|
+
filter = opts.filter;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
let arrayFormat: StringifyOptions['arrayFormat'];
|
|
260
|
+
if (opts.arrayFormat && opts.arrayFormat in array_prefix_generators) {
|
|
261
|
+
arrayFormat = opts.arrayFormat;
|
|
262
|
+
} else if ('indices' in opts) {
|
|
263
|
+
arrayFormat = opts.indices ? 'indices' : 'repeat';
|
|
264
|
+
} else {
|
|
265
|
+
arrayFormat = defaults.arrayFormat;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') {
|
|
269
|
+
throw new TypeError('`commaRoundTrip` must be a boolean, or absent');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const allowDots =
|
|
273
|
+
typeof opts.allowDots === 'undefined' ?
|
|
274
|
+
!!opts.encodeDotInKeys === true ?
|
|
275
|
+
true
|
|
276
|
+
: defaults.allowDots
|
|
277
|
+
: !!opts.allowDots;
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
|
|
281
|
+
// @ts-ignore
|
|
282
|
+
allowDots: allowDots,
|
|
283
|
+
allowEmptyArrays:
|
|
284
|
+
typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
|
|
285
|
+
arrayFormat: arrayFormat,
|
|
286
|
+
charset: charset,
|
|
287
|
+
charsetSentinel:
|
|
288
|
+
typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
|
289
|
+
commaRoundTrip: !!opts.commaRoundTrip,
|
|
290
|
+
delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
|
|
291
|
+
encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
|
|
292
|
+
encodeDotInKeys:
|
|
293
|
+
typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys,
|
|
294
|
+
encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
|
|
295
|
+
encodeValuesOnly:
|
|
296
|
+
typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
|
|
297
|
+
filter: filter,
|
|
298
|
+
format: format,
|
|
299
|
+
formatter: formatter,
|
|
300
|
+
serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
|
|
301
|
+
skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
|
|
302
|
+
// @ts-ignore
|
|
303
|
+
sort: typeof opts.sort === 'function' ? opts.sort : null,
|
|
304
|
+
strictNullHandling:
|
|
305
|
+
typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export function stringify(object: any, opts: StringifyOptions = {}) {
|
|
310
|
+
let obj = object;
|
|
311
|
+
const options = normalize_stringify_options(opts);
|
|
312
|
+
|
|
313
|
+
let obj_keys: PropertyKey[] | undefined;
|
|
314
|
+
let filter;
|
|
315
|
+
|
|
316
|
+
if (typeof options.filter === 'function') {
|
|
317
|
+
filter = options.filter;
|
|
318
|
+
obj = filter('', obj);
|
|
319
|
+
} else if (is_array(options.filter)) {
|
|
320
|
+
filter = options.filter;
|
|
321
|
+
obj_keys = filter;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const keys: string[] = [];
|
|
325
|
+
|
|
326
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
327
|
+
return '';
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const generateArrayPrefix = array_prefix_generators[options.arrayFormat];
|
|
331
|
+
const commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip;
|
|
332
|
+
|
|
333
|
+
if (!obj_keys) {
|
|
334
|
+
obj_keys = Object.keys(obj);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (options.sort) {
|
|
338
|
+
obj_keys.sort(options.sort);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const sideChannel = new WeakMap();
|
|
342
|
+
for (let i = 0; i < obj_keys.length; ++i) {
|
|
343
|
+
const key = obj_keys[i]!;
|
|
344
|
+
|
|
345
|
+
if (options.skipNulls && obj[key] === null) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
push_to_array(
|
|
349
|
+
keys,
|
|
350
|
+
inner_stringify(
|
|
351
|
+
obj[key],
|
|
352
|
+
key,
|
|
353
|
+
// @ts-expect-error
|
|
354
|
+
generateArrayPrefix,
|
|
355
|
+
commaRoundTrip,
|
|
356
|
+
options.allowEmptyArrays,
|
|
357
|
+
options.strictNullHandling,
|
|
358
|
+
options.skipNulls,
|
|
359
|
+
options.encodeDotInKeys,
|
|
360
|
+
options.encode ? options.encoder : null,
|
|
361
|
+
options.filter,
|
|
362
|
+
options.sort,
|
|
363
|
+
options.allowDots,
|
|
364
|
+
options.serializeDate,
|
|
365
|
+
options.format,
|
|
366
|
+
options.formatter,
|
|
367
|
+
options.encodeValuesOnly,
|
|
368
|
+
options.charset,
|
|
369
|
+
sideChannel,
|
|
370
|
+
),
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const joined = keys.join(options.delimiter);
|
|
375
|
+
let prefix = options.addQueryPrefix === true ? '?' : '';
|
|
376
|
+
|
|
377
|
+
if (options.charsetSentinel) {
|
|
378
|
+
if (options.charset === 'iso-8859-1') {
|
|
379
|
+
// encodeURIComponent('✓'), the "numeric entity" representation of a checkmark
|
|
380
|
+
prefix += 'utf8=%26%2310003%3B&';
|
|
381
|
+
} else {
|
|
382
|
+
// encodeURIComponent('✓')
|
|
383
|
+
prefix += 'utf8=%E2%9C%93&';
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return joined.length > 0 ? prefix + joined : '';
|
|
388
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export type Format = 'RFC1738' | 'RFC3986';
|
|
2
|
+
|
|
3
|
+
export type DefaultEncoder = (str: any, defaultEncoder?: any, charset?: string) => string;
|
|
4
|
+
export type DefaultDecoder = (str: string, decoder?: any, charset?: string) => string;
|
|
5
|
+
|
|
6
|
+
export type BooleanOptional = boolean | undefined;
|
|
7
|
+
|
|
8
|
+
export type StringifyBaseOptions = {
|
|
9
|
+
delimiter?: string;
|
|
10
|
+
allowDots?: boolean;
|
|
11
|
+
encodeDotInKeys?: boolean;
|
|
12
|
+
strictNullHandling?: boolean;
|
|
13
|
+
skipNulls?: boolean;
|
|
14
|
+
encode?: boolean;
|
|
15
|
+
encoder?: (
|
|
16
|
+
str: any,
|
|
17
|
+
defaultEncoder: DefaultEncoder,
|
|
18
|
+
charset: string,
|
|
19
|
+
type: 'key' | 'value',
|
|
20
|
+
format?: Format,
|
|
21
|
+
) => string;
|
|
22
|
+
filter?: Array<PropertyKey> | ((prefix: PropertyKey, value: any) => any);
|
|
23
|
+
arrayFormat?: 'indices' | 'brackets' | 'repeat' | 'comma';
|
|
24
|
+
indices?: boolean;
|
|
25
|
+
sort?: ((a: PropertyKey, b: PropertyKey) => number) | null;
|
|
26
|
+
serializeDate?: (d: Date) => string;
|
|
27
|
+
format?: 'RFC1738' | 'RFC3986';
|
|
28
|
+
formatter?: (str: PropertyKey) => string;
|
|
29
|
+
encodeValuesOnly?: boolean;
|
|
30
|
+
addQueryPrefix?: boolean;
|
|
31
|
+
charset?: 'utf-8' | 'iso-8859-1';
|
|
32
|
+
charsetSentinel?: boolean;
|
|
33
|
+
allowEmptyArrays?: boolean;
|
|
34
|
+
commaRoundTrip?: boolean;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type StringifyOptions = StringifyBaseOptions;
|
|
38
|
+
|
|
39
|
+
export type ParseBaseOptions = {
|
|
40
|
+
comma?: boolean;
|
|
41
|
+
delimiter?: string | RegExp;
|
|
42
|
+
depth?: number | false;
|
|
43
|
+
decoder?: (str: string, defaultDecoder: DefaultDecoder, charset: string, type: 'key' | 'value') => any;
|
|
44
|
+
arrayLimit?: number;
|
|
45
|
+
parseArrays?: boolean;
|
|
46
|
+
plainObjects?: boolean;
|
|
47
|
+
allowPrototypes?: boolean;
|
|
48
|
+
allowSparse?: boolean;
|
|
49
|
+
parameterLimit?: number;
|
|
50
|
+
strictDepth?: boolean;
|
|
51
|
+
strictNullHandling?: boolean;
|
|
52
|
+
ignoreQueryPrefix?: boolean;
|
|
53
|
+
charset?: 'utf-8' | 'iso-8859-1';
|
|
54
|
+
charsetSentinel?: boolean;
|
|
55
|
+
interpretNumericEntities?: boolean;
|
|
56
|
+
allowEmptyArrays?: boolean;
|
|
57
|
+
duplicates?: 'combine' | 'first' | 'last';
|
|
58
|
+
allowDots?: boolean;
|
|
59
|
+
decodeDotInKeys?: boolean;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type ParseOptions = ParseBaseOptions;
|
|
63
|
+
|
|
64
|
+
export type ParsedQs = {
|
|
65
|
+
[key: string]: undefined | string | string[] | ParsedQs | ParsedQs[];
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Type to remove null or undefined union from each property
|
|
69
|
+
export type NonNullableProperties<T> = {
|
|
70
|
+
[K in keyof T]-?: Exclude<T[K], undefined | null>;
|
|
71
|
+
};
|