@sasjs/adapter 4.11.2 → 4.12.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.
Files changed (59) hide show
  1. package/SASViyaApiClient.d.ts +25 -2
  2. package/SASjs.d.ts +20 -2
  3. package/api/viya/writeStream.d.ts +1 -1
  4. package/auth/getTokenRequestErrorPrefix.d.ts +2 -2
  5. package/file/generateFileUploadForm.d.ts +1 -1
  6. package/file/generateTableUploadForm.d.ts +1 -1
  7. package/index-dev.js +77153 -3
  8. package/index.js +77153 -2
  9. package/job-execution/JobExecutor.d.ts +1 -1
  10. package/minified_sas9.js +16558 -2
  11. package/node/SASViyaApiClient.d.ts +25 -2
  12. package/node/SASjs.d.ts +20 -2
  13. package/node/api/viya/writeStream.d.ts +1 -1
  14. package/node/auth/getTokenRequestErrorPrefix.d.ts +2 -2
  15. package/node/file/generateFileUploadForm.d.ts +1 -1
  16. package/node/file/generateTableUploadForm.d.ts +1 -1
  17. package/node/index.js +28247 -2
  18. package/node/job-execution/JobExecutor.d.ts +1 -1
  19. package/node/request/RequestClient.d.ts +11 -2
  20. package/node/types/FileResource.d.ts +32 -0
  21. package/node/types/PollOptions.d.ts +1 -1
  22. package/node/types/RequestClient.d.ts +1 -1
  23. package/node/types/WriteStream.d.ts +6 -3
  24. package/node/utils/getFormData.d.ts +1 -1
  25. package/package.json +12 -9
  26. package/request/RequestClient.d.ts +11 -2
  27. package/spec/SAS9ApiClient.spec.d.ts +1 -0
  28. package/spec/SASjsApiClient.spec.d.ts +1 -0
  29. package/src/SAS9ApiClient.ts +1 -1
  30. package/src/SASViyaApiClient.ts +124 -6
  31. package/src/SASjs.ts +54 -4
  32. package/src/SASjsApiClient.ts +1 -1
  33. package/src/api/viya/writeStream.ts +10 -5
  34. package/src/auth/refreshTokensForViya.ts +1 -1
  35. package/src/file/generateFileUploadForm.ts +1 -1
  36. package/src/file/generateTableUploadForm.ts +1 -1
  37. package/src/job-execution/Sas9JobExecutor.ts +1 -1
  38. package/src/job-execution/SasjsJobExecutor.ts +5 -3
  39. package/src/job-execution/WebJobExecutor.ts +5 -3
  40. package/src/request/RequestClient.ts +73 -81
  41. package/src/request/Sas9RequestClient.ts +5 -5
  42. package/src/test/SAS_server_app.ts +10 -2
  43. package/src/types/FileResource.ts +33 -0
  44. package/src/types/WriteStream.ts +9 -3
  45. package/src/utils/convertToCsv.ts +5 -1
  46. package/src/utils/getFormData.ts +2 -2
  47. package/src/utils/validateInput.ts +16 -13
  48. package/types/FileResource.d.ts +32 -0
  49. package/types/PollOptions.d.ts +1 -1
  50. package/types/RequestClient.d.ts +1 -1
  51. package/types/WriteStream.d.ts +6 -3
  52. package/types/errors/spec/SAS9AuthError.spec.d.ts +1 -0
  53. package/utils/getFormData.d.ts +1 -1
  54. package/utils/spec/parseSasViyaLog.spec.d.ts +1 -0
  55. package/utils/spec/parseViyaDebugResponse.spec.d.ts +1 -0
  56. package/index-dev.js.LICENSE.txt +0 -110
  57. package/index.js.LICENSE.txt +0 -110
  58. package/minified_sas9.js.LICENSE.txt +0 -15
  59. package/node/index.js.LICENSE.txt +0 -106
@@ -2,9 +2,9 @@ import {
2
2
  AxiosError,
3
3
  AxiosInstance,
4
4
  AxiosRequestConfig,
5
+ AxiosRequestHeaders,
5
6
  AxiosResponse
6
7
  } from 'axios'
7
- import axios from 'axios'
8
8
  import * as https from 'https'
9
9
  import { CsrfToken } from '..'
10
10
  import { isAuthorizeFormRequired, isLogInRequired } from '../auth'
@@ -160,7 +160,7 @@ export class RequestClient implements HttpClient {
160
160
  const requestConfig: AxiosRequestConfig = {
161
161
  headers,
162
162
  responseType: contentType === 'text/plain' ? 'text' : 'json',
163
- withCredentials: true
163
+ withXSRFToken: true
164
164
  }
165
165
 
166
166
  if (contentType === 'text/plain') {
@@ -191,6 +191,13 @@ export class RequestClient implements HttpClient {
191
191
  })
192
192
  }
193
193
 
194
+ /**
195
+ * @param contentType Newer version of Axios is more strict so if you don't
196
+ * set the contentType to `form data` while sending a FormData object
197
+ * application/json will be used by default, axios won’t treat it as FormData.
198
+ * Instead, it serializes data as JSON—resulting in a payload like
199
+ * {"sometable":{}} and we lose the multipart/form-data formatting.
200
+ */
194
201
  public async post<T>(
195
202
  url: string,
196
203
  data: any,
@@ -207,7 +214,7 @@ export class RequestClient implements HttpClient {
207
214
  return this.httpClient
208
215
  .post<T>(url, data, {
209
216
  headers,
210
- withCredentials: true,
217
+ withXSRFToken: true,
211
218
  ...additionalSettings
212
219
  })
213
220
  .then((response) => {
@@ -234,7 +241,7 @@ export class RequestClient implements HttpClient {
234
241
  }
235
242
 
236
243
  return this.httpClient
237
- .put<T>(url, data, { headers, withCredentials: true })
244
+ .put<T>(url, data, { headers, withXSRFToken: true })
238
245
  .then((response) => {
239
246
  throwIfError(response)
240
247
  return this.parseResponse<T>(response)
@@ -253,7 +260,7 @@ export class RequestClient implements HttpClient {
253
260
  const headers = this.getHeaders(accessToken, 'application/json')
254
261
 
255
262
  return this.httpClient
256
- .delete<T>(url, { headers, withCredentials: true })
263
+ .delete<T>(url, { headers, withXSRFToken: true })
257
264
  .then((response) => {
258
265
  throwIfError(response)
259
266
  return this.parseResponse<T>(response)
@@ -271,7 +278,7 @@ export class RequestClient implements HttpClient {
271
278
  const headers = this.getHeaders(accessToken, 'application/json')
272
279
 
273
280
  return this.httpClient
274
- .patch<T>(url, data, { headers, withCredentials: true })
281
+ .patch<T>(url, data, { headers, withXSRFToken: true })
275
282
  .then((response) => {
276
283
  throwIfError(response)
277
284
  return this.parseResponse<T>(response)
@@ -413,95 +420,67 @@ export class RequestClient implements HttpClient {
413
420
  return bodyLines.join('\n')
414
421
  }
415
422
 
416
- private defaultInterceptionCallBack = (
417
- axiosResponse: AxiosResponse | AxiosError
418
- ) => {
423
+ private handleAxiosResponse = (response: AxiosResponse) => {
424
+ const { status, config, request, data } = response
425
+
426
+ const reqHeaders = request?._header ?? 'Not provided\n'
427
+ const rawHeaders = request?.res?.rawHeaders ?? ['Not provided']
428
+
429
+ const resHeaders = this.formatHeaders(rawHeaders)
430
+ const parsedResBody = this.parseInterceptedBody(data)
431
+
432
+ process.logger?.info(`HTTP Request (first 50 lines):
433
+ ${reqHeaders}${this.parseInterceptedBody(config.data)}
434
+
435
+ HTTP Response Code: ${this.prettifyString(status)}
436
+
437
+ HTTP Response (first 50 lines):
438
+ ${resHeaders}${parsedResBody ? `\n\n${parsedResBody}` : ''}
439
+ `)
440
+
441
+ return response
442
+ }
443
+
444
+ private handleAxiosError = (error: AxiosError) => {
419
445
  // Message indicating absent value.
420
446
  const noValueMessage = 'Not provided'
447
+ const { response, request, config } = error
421
448
 
422
449
  // Fallback request object that can be safely used to form request summary.
423
- type FallbackRequest = { _header?: string; res: { rawHeaders: string[] } }
424
450
  // _header is not present in responses with status 1**
425
451
  // rawHeaders are not present in responses with status 1**
426
- let fallbackRequest: FallbackRequest = {
452
+ let fallbackRequest = {
427
453
  _header: `${noValueMessage}\n`,
428
454
  res: { rawHeaders: [noValueMessage] }
429
455
  }
430
456
 
431
- // Fallback response object that can be safely used to form response summary.
432
- type FallbackResponse = {
433
- status?: number | string
434
- request?: FallbackRequest
435
- config: { data?: string }
436
- data?: unknown
437
- }
438
- let fallbackResponse: FallbackResponse = axiosResponse
439
-
440
- if (axios.isAxiosError(axiosResponse)) {
441
- const { response, request, config } = axiosResponse
442
-
443
- // Try to use axiosResponse.response to form response summary.
444
- if (response) {
445
- fallbackResponse = response
446
- } else {
447
- // Try to use axiosResponse.request to form request summary.
448
- if (request) {
449
- const { _header, _currentRequest } = request
450
-
451
- // Try to use axiosResponse.request._header to form request summary.
452
- if (_header) {
453
- fallbackRequest._header = _header
454
- }
455
- // Try to use axiosResponse.request._currentRequest._header to form request summary.
456
- else if (_currentRequest && _currentRequest._header) {
457
- fallbackRequest._header = _currentRequest._header
458
- }
459
-
460
- const { res } = request
461
-
462
- // Try to use axiosResponse.request.res.rawHeaders to form request summary.
463
- if (res && res.rawHeaders) {
464
- fallbackRequest.res.rawHeaders = res.rawHeaders
465
- }
466
- }
467
-
468
- // Fallback config that can be safely used to form response summary.
469
- const fallbackConfig = { data: noValueMessage }
470
-
471
- fallbackResponse = {
472
- status: noValueMessage,
473
- request: fallbackRequest,
474
- config: config || fallbackConfig,
475
- data: noValueMessage
476
- }
457
+ if (request) {
458
+ fallbackRequest = {
459
+ _header:
460
+ request._header ?? request._currentRequest?._header ?? noValueMessage,
461
+ res: { rawHeaders: request.res?.rawHeaders ?? [noValueMessage] }
477
462
  }
478
463
  }
479
464
 
480
- const { status, config, request, data: resData } = fallbackResponse
481
- const { data: reqData } = config
482
- const { _header: reqHeaders, res } = request || fallbackRequest
483
- const { rawHeaders } = res
484
-
485
- // Converts an array of strings into a single string with the following format:
486
- // <headerName>: <headerValue>
487
- const resHeaders = rawHeaders.reduce(
488
- (acc: string, value: string, i: number) => {
489
- if (i % 2 === 0) {
490
- acc += `${i === 0 ? '' : '\n'}${value}`
491
- } else {
492
- acc += `: ${value}`
493
- }
494
-
495
- return acc
465
+ // Fallback response object that can be safely used to form response summary.
466
+ let fallbackResponse = response || {
467
+ status: noValueMessage,
468
+ request: fallbackRequest,
469
+ config: config || {
470
+ data: noValueMessage,
471
+ headers: {} as AxiosRequestHeaders
496
472
  },
497
- ''
498
- )
473
+ data: noValueMessage
474
+ }
475
+
476
+ const { status, request: req, data: resData } = fallbackResponse
477
+ const { _header: reqHeaders, res } = req
499
478
 
479
+ const resHeaders = this.formatHeaders(res.rawHeaders)
500
480
  const parsedResBody = this.parseInterceptedBody(resData)
501
481
 
502
- // HTTP response summary.
503
482
  process.logger?.info(`HTTP Request (first 50 lines):
504
- ${reqHeaders}${this.parseInterceptedBody(reqData)}
483
+ ${reqHeaders}${this.parseInterceptedBody(config?.data)}
505
484
 
506
485
  HTTP Response Code: ${this.prettifyString(status)}
507
486
 
@@ -509,7 +488,20 @@ HTTP Response (first 50 lines):
509
488
  ${resHeaders}${parsedResBody ? `\n\n${parsedResBody}` : ''}
510
489
  `)
511
490
 
512
- return axiosResponse
491
+ return error
492
+ }
493
+
494
+ // Converts an array of strings into a single string with the following format:
495
+ // <headerName>: <headerValue>
496
+ private formatHeaders = (rawHeaders: string[]): string => {
497
+ return rawHeaders.reduce((acc, value, i) => {
498
+ if (i % 2 === 0) {
499
+ acc += `${i === 0 ? '' : '\n'}${value}`
500
+ } else {
501
+ acc += `: ${value}`
502
+ }
503
+ return acc
504
+ }, '')
513
505
  }
514
506
 
515
507
  /**
@@ -529,8 +521,8 @@ ${resHeaders}${parsedResBody ? `\n\n${parsedResBody}` : ''}
529
521
  * @param errorCallBack - function that should be triggered on every HTTP response with the status different from 2**.
530
522
  */
531
523
  public enableVerboseMode = (
532
- successCallBack = this.defaultInterceptionCallBack,
533
- errorCallBack = this.defaultInterceptionCallBack
524
+ successCallBack = this.handleAxiosResponse,
525
+ errorCallBack = this.handleAxiosError
534
526
  ) => {
535
527
  this.httpInterceptor = this.httpClient.interceptors.response.use(
536
528
  successCallBack,
@@ -645,7 +637,7 @@ ${resHeaders}${parsedResBody ? `\n\n${parsedResBody}` : ''}
645
637
  // Fetching root and creating CSRF cookie
646
638
  await this.httpClient
647
639
  .get('/', {
648
- withCredentials: true
640
+ withXSRFToken: true
649
641
  })
650
642
  .then((response) => {
651
643
  const cookie =
@@ -1,6 +1,6 @@
1
1
  import * as https from 'https'
2
2
  import { AxiosRequestConfig } from 'axios'
3
- import axiosCookieJarSupport from 'axios-cookiejar-support'
3
+ import { wrapper } from 'axios-cookiejar-support'
4
4
  import * as tough from 'tough-cookie'
5
5
  import { prefixMessage } from '@sasjs/utils/error'
6
6
  import { RequestClient, throwIfError } from './RequestClient'
@@ -17,8 +17,8 @@ export class Sas9RequestClient extends RequestClient {
17
17
  this.httpClient.defaults.validateStatus = (status) =>
18
18
  status >= 200 && status < 303
19
19
 
20
- if (axiosCookieJarSupport) {
21
- axiosCookieJarSupport(this.httpClient)
20
+ if (wrapper) {
21
+ wrapper(this.httpClient)
22
22
  this.httpClient.defaults.jar = new tough.CookieJar()
23
23
  }
24
24
  }
@@ -50,7 +50,7 @@ export class Sas9RequestClient extends RequestClient {
50
50
  const requestConfig: AxiosRequestConfig = {
51
51
  headers,
52
52
  responseType: contentType === 'text/plain' ? 'text' : 'json',
53
- withCredentials: true
53
+ withXSRFToken: true
54
54
  }
55
55
  if (contentType === 'text/plain') {
56
56
  requestConfig.transformResponse = undefined
@@ -103,7 +103,7 @@ export class Sas9RequestClient extends RequestClient {
103
103
  }
104
104
 
105
105
  return this.httpClient
106
- .post<T>(url, data, { headers, withCredentials: true })
106
+ .post<T>(url, data, { headers, withXSRFToken: true })
107
107
  .then(async (response) => {
108
108
  if (response.status === 302) {
109
109
  return await this.get(
@@ -1,7 +1,15 @@
1
1
  import express = require('express')
2
+ import cors from 'cors'
2
3
 
3
4
  export const app = express()
4
5
 
6
+ app.use(
7
+ cors({
8
+ origin: 'http://localhost', // Allow requests only from this origin
9
+ credentials: true // Allow credentials (cookies, auth headers, etc.)
10
+ })
11
+ )
12
+
5
13
  export const mockedAuthResponse = {
6
14
  access_token: 'access_token',
7
15
  token_type: 'bearer',
@@ -12,11 +20,11 @@ export const mockedAuthResponse = {
12
20
  jti: 'jti'
13
21
  }
14
22
 
15
- app.get('/', function (req: any, res: any) {
23
+ app.get('/', (req: any, res: any) => {
16
24
  res.send('Hello World')
17
25
  })
18
26
 
19
- app.post('/SASLogon/oauth/token', function (req: any, res: any) {
27
+ app.post('/SASLogon/oauth/token', (req: any, res: any) => {
20
28
  let valid = true
21
29
 
22
30
  // capture the encoded form data
@@ -0,0 +1,33 @@
1
+ export interface FileResource {
2
+ creationTimeStamp: string
3
+ modifiedTimeStamp: string
4
+ createdBy: string
5
+ modifiedBy: string
6
+ id: string
7
+ properties: Properties
8
+ contentDisposition: string
9
+ contentType: string
10
+ encoding: string
11
+ links: Link[]
12
+ name: string
13
+ size: number
14
+ searchable: boolean
15
+ fileStatus: string
16
+ fileVersion: number
17
+ typeDefName: string
18
+ version: number
19
+ virusDetected: boolean
20
+ urlDetected: boolean
21
+ quarantine: boolean
22
+ }
23
+
24
+ export interface Link {
25
+ method: string
26
+ rel: string
27
+ href: string
28
+ uri: string
29
+ type?: string
30
+ responseType?: string
31
+ }
32
+
33
+ export interface Properties {}
@@ -1,4 +1,10 @@
1
- export interface WriteStream {
2
- write: (content: string, callback: (err?: Error) => any) => void
3
- path: string
1
+ import { WriteStream as FsWriteStream } from 'fs'
2
+
3
+ export interface WriteStream extends FsWriteStream {
4
+ write(
5
+ chunk: any,
6
+ encoding?: BufferEncoding | ((error: Error | null | undefined) => void),
7
+ cb?: (error: Error | null | undefined) => void
8
+ ): boolean
9
+ path: string | Buffer
4
10
  }
@@ -10,10 +10,14 @@ export const convertToCSV = (
10
10
  tableName: string
11
11
  ) => {
12
12
  if (!data[tableName]) {
13
- throw prefixMessage(
13
+ const error = prefixMessage(
14
14
  'No table provided to be converted to CSV.',
15
15
  'Error while converting to CSV. '
16
16
  )
17
+
18
+ if (typeof error === 'string') throw new Error(error)
19
+
20
+ throw error
17
21
  }
18
22
 
19
23
  const table = data[tableName]
@@ -1,5 +1,5 @@
1
1
  import { isNode } from './'
2
- import * as NodeFormData from 'form-data'
2
+ import NodeFormData from 'form-data'
3
3
 
4
- export const getFormData = () =>
4
+ export const getFormData = (): NodeFormData | FormData =>
5
5
  isNode() ? new NodeFormData() : new FormData()
@@ -52,19 +52,22 @@ export const validateInput = (
52
52
  }
53
53
  }
54
54
 
55
- for (const item of data[key]) {
56
- if (getType(item) !== 'object') {
57
- return {
58
- status: false,
59
- msg: `Table ${key} contains invalid structure. ${MORE_INFO}`
60
- }
61
- } else {
62
- const attributes = Object.keys(item)
63
- for (const attribute of attributes) {
64
- if (item[attribute] === undefined) {
65
- return {
66
- status: false,
67
- msg: `A row in table ${key} contains invalid value. Can't assign undefined to ${attribute}.`
55
+ // ES6 is stricter so we had to include the check for the array
56
+ if (Array.isArray(data[key])) {
57
+ for (const item of data[key]) {
58
+ if (getType(item) !== 'object') {
59
+ return {
60
+ status: false,
61
+ msg: `Table ${key} contains invalid structure. ${MORE_INFO}`
62
+ }
63
+ } else {
64
+ const attributes = Object.keys(item)
65
+ for (const attribute of attributes) {
66
+ if (item[attribute] === undefined) {
67
+ return {
68
+ status: false,
69
+ msg: `A row in table ${key} contains invalid value. Can't assign undefined to ${attribute}.`
70
+ }
68
71
  }
69
72
  }
70
73
  }
@@ -0,0 +1,32 @@
1
+ export interface FileResource {
2
+ creationTimeStamp: string;
3
+ modifiedTimeStamp: string;
4
+ createdBy: string;
5
+ modifiedBy: string;
6
+ id: string;
7
+ properties: Properties;
8
+ contentDisposition: string;
9
+ contentType: string;
10
+ encoding: string;
11
+ links: Link[];
12
+ name: string;
13
+ size: number;
14
+ searchable: boolean;
15
+ fileStatus: string;
16
+ fileVersion: number;
17
+ typeDefName: string;
18
+ version: number;
19
+ virusDetected: boolean;
20
+ urlDetected: boolean;
21
+ quarantine: boolean;
22
+ }
23
+ export interface Link {
24
+ method: string;
25
+ rel: string;
26
+ href: string;
27
+ uri: string;
28
+ type?: string;
29
+ responseType?: string;
30
+ }
31
+ export interface Properties {
32
+ }
@@ -5,4 +5,4 @@ export interface PollOptions {
5
5
  streamLog?: boolean;
6
6
  logFolderPath?: string;
7
7
  }
8
- export declare type PollStrategy = PollOptions[];
8
+ export type PollStrategy = PollOptions[];
@@ -43,4 +43,4 @@ export interface SasjsParsedResponse<T> {
43
43
  status: number;
44
44
  printOutput?: string;
45
45
  }
46
- export declare type VerboseMode = boolean | 'bleached';
46
+ export type VerboseMode = boolean | 'bleached';
@@ -1,4 +1,7 @@
1
- export interface WriteStream {
2
- write: (content: string, callback: (err?: Error) => any) => void;
3
- path: string;
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { WriteStream as FsWriteStream } from 'fs';
4
+ export interface WriteStream extends FsWriteStream {
5
+ write(chunk: any, encoding?: BufferEncoding | ((error: Error | null | undefined) => void), cb?: (error: Error | null | undefined) => void): boolean;
6
+ path: string | Buffer;
4
7
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,2 +1,2 @@
1
- import * as NodeFormData from 'form-data';
1
+ import NodeFormData from 'form-data';
2
2
  export declare const getFormData: () => NodeFormData | FormData;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,110 +0,0 @@
1
- /*!
2
- * Copyright (c) 2015, Salesforce.com, Inc.
3
- * All rights reserved.
4
- *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
7
- *
8
- * 1. Redistributions of source code must retain the above copyright notice,
9
- * this list of conditions and the following disclaimer.
10
- *
11
- * 2. Redistributions in binary form must reproduce the above copyright notice,
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- *
15
- * 3. Neither the name of Salesforce.com nor the names of its contributors may
16
- * be used to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- * POSSIBILITY OF SUCH DAMAGE.
30
- */
31
-
32
- /*!
33
- * Copyright (c) 2015-2020, Salesforce.com, Inc.
34
- * All rights reserved.
35
- *
36
- * Redistribution and use in source and binary forms, with or without
37
- * modification, are permitted provided that the following conditions are met:
38
- *
39
- * 1. Redistributions of source code must retain the above copyright notice,
40
- * this list of conditions and the following disclaimer.
41
- *
42
- * 2. Redistributions in binary form must reproduce the above copyright notice,
43
- * this list of conditions and the following disclaimer in the documentation
44
- * and/or other materials provided with the distribution.
45
- *
46
- * 3. Neither the name of Salesforce.com nor the names of its contributors may
47
- * be used to endorse or promote products derived from this software without
48
- * specific prior written permission.
49
- *
50
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
51
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
54
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60
- * POSSIBILITY OF SUCH DAMAGE.
61
- */
62
-
63
- /*!
64
- * Copyright (c) 2018, Salesforce.com, Inc.
65
- * All rights reserved.
66
- *
67
- * Redistribution and use in source and binary forms, with or without
68
- * modification, are permitted provided that the following conditions are met:
69
- *
70
- * 1. Redistributions of source code must retain the above copyright notice,
71
- * this list of conditions and the following disclaimer.
72
- *
73
- * 2. Redistributions in binary form must reproduce the above copyright notice,
74
- * this list of conditions and the following disclaimer in the documentation
75
- * and/or other materials provided with the distribution.
76
- *
77
- * 3. Neither the name of Salesforce.com nor the names of its contributors may
78
- * be used to endorse or promote products derived from this software without
79
- * specific prior written permission.
80
- *
81
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
82
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
85
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
86
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
87
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
88
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
89
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
90
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
91
- * POSSIBILITY OF SUCH DAMAGE.
92
- */
93
-
94
- /*!
95
- * The buffer module from node.js, for the browser.
96
- *
97
- * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
98
- * @license MIT
99
- */
100
-
101
- /*!
102
- * The buffer module from node.js, for the browser.
103
- *
104
- * @author Feross Aboukhadijeh <https://feross.org>
105
- * @license MIT
106
- */
107
-
108
- /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
109
-
110
- /*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */