@segment/analytics-node
Advanced tools
Comparing version 1.0.0 to 1.1.0
# @segment/analytics-node | ||
## 1.1.0 | ||
### Minor Changes | ||
- [#880](https://github.com/segmentio/analytics-next/pull/880) [`5f50363`](https://github.com/segmentio/analytics-next/commit/5f5036332a3b21d5eb5324c2ed332190b42b2318) Thanks [@silesky](https://github.com/silesky)! - Add `httpClient` setting. This allow users to override default HTTP client with a custom one. | ||
## 1.0.0 | ||
@@ -4,0 +10,0 @@ |
@@ -13,2 +13,3 @@ "use strict"; | ||
const event_queue_1 = require("./event-queue"); | ||
const http_client_1 = require("../lib/http-client"); | ||
class Analytics extends emitter_1.NodeEmitter { | ||
@@ -33,2 +34,5 @@ constructor(settings) { | ||
flushInterval, | ||
httpClient: typeof settings.httpClient === 'function' | ||
? new http_client_1.FetchHTTPClient(settings.httpClient) | ||
: settings.httpClient ?? new http_client_1.FetchHTTPClient(), | ||
}, this); | ||
@@ -35,0 +39,0 @@ this._publisher = publisher; |
@@ -5,3 +5,3 @@ "use strict"; | ||
// This file is generated. | ||
exports.version = '1.0.0'; | ||
exports.version = '1.1.0'; | ||
//# sourceMappingURL=version.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Context = exports.Analytics = void 0; | ||
exports.FetchHTTPClient = exports.Context = exports.Analytics = void 0; | ||
var analytics_node_1 = require("./app/analytics-node"); | ||
@@ -8,2 +8,4 @@ Object.defineProperty(exports, "Analytics", { enumerable: true, get: function () { return analytics_node_1.Analytics; } }); | ||
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } }); | ||
var http_client_1 = require("./lib/http-client"); | ||
Object.defineProperty(exports, "FetchHTTPClient", { enumerable: true, get: function () { return http_client_1.FetchHTTPClient; } }); | ||
// export Analytics as both a named export and a default export (for backwards-compat. reasons) | ||
@@ -10,0 +12,0 @@ const analytics_node_2 = require("./app/analytics-node"); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.abortSignalAfterTimeout = void 0; | ||
exports.abortSignalAfterTimeout = exports.AbortSignal = void 0; | ||
/** | ||
@@ -40,2 +40,3 @@ * use non-native event emitter for the benefit of non-node runtimes like CF workers. | ||
} | ||
exports.AbortSignal = AbortSignal; | ||
/** | ||
@@ -42,0 +43,0 @@ * This polyfill is only neccessary to support versions of node < 14.17. |
@@ -30,6 +30,6 @@ "use strict"; | ||
return globalThis.fetch(...args); | ||
} // @ts-ignore | ||
} | ||
// This guard causes is important, as it causes dead-code elimination to be enabled inside this block. | ||
// @ts-ignore | ||
else if (typeof EdgeRuntime !== 'string') { | ||
// @ts-ignore | ||
return (await Promise.resolve().then(() => __importStar(require('node-fetch')))).default(...args); | ||
@@ -36,0 +36,0 @@ } |
@@ -5,6 +5,4 @@ "use strict"; | ||
const analytics_core_1 = require("@segment/analytics-core"); | ||
const abort_1 = require("../../lib/abort"); | ||
const create_url_1 = require("../../lib/create-url"); | ||
const extract_promise_parts_1 = require("../../lib/extract-promise-parts"); | ||
const fetch_1 = require("../../lib/fetch"); | ||
const context_batch_1 = require("./context-batch"); | ||
@@ -20,3 +18,3 @@ const base_64_encode_1 = require("../../lib/base-64-encode"); | ||
class Publisher { | ||
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, disable, }, emitter) { | ||
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, httpClient, disable, }, emitter) { | ||
this._emitter = emitter; | ||
@@ -30,2 +28,3 @@ this._maxRetries = maxRetries; | ||
this._disable = Boolean(disable); | ||
this._httpClient = httpClient; | ||
} | ||
@@ -129,3 +128,2 @@ createBatch() { | ||
const events = batch.getEvents(); | ||
const payload = JSON.stringify({ batch: events }); | ||
const maxAttempts = this._maxRetries + 1; | ||
@@ -136,6 +134,8 @@ let currentAttempt = 0; | ||
let failureReason; | ||
const [signal, timeoutId] = (0, abort_1.abortSignalAfterTimeout)(this._httpRequestTimeout); | ||
try { | ||
const requestInit = { | ||
signal: signal, | ||
if (this._disable) { | ||
return batch.resolveEvents(); | ||
} | ||
const request = { | ||
url: this._url, | ||
method: 'POST', | ||
@@ -147,17 +147,13 @@ headers: { | ||
}, | ||
body: payload, | ||
data: { batch: events }, | ||
httpRequestTimeout: this._httpRequestTimeout, | ||
}; | ||
this._emitter.emit('http_request', { | ||
url: this._url, | ||
method: requestInit.method, | ||
headers: requestInit.headers, | ||
body: requestInit.body, | ||
body: request.data, | ||
method: request.method, | ||
url: request.url, | ||
headers: request.headers, | ||
}); | ||
if (this._disable) { | ||
clearTimeout(timeoutId); | ||
return batch.resolveEvents(); | ||
} | ||
const response = await (0, fetch_1.fetch)(this._url, requestInit); | ||
clearTimeout(timeoutId); | ||
if (response.ok) { | ||
const response = await this._httpClient.makeRequest(request); | ||
if (response.status >= 200 && response.status < 300) { | ||
// Successfully sent events, so exit! | ||
@@ -164,0 +160,0 @@ batch.resolveEvents(); |
@@ -10,2 +10,3 @@ import { bindAll, pTimeout } from '@segment/analytics-core'; | ||
import { NodeEventQueue } from './event-queue'; | ||
import { FetchHTTPClient } from '../lib/http-client'; | ||
export class Analytics extends NodeEmitter { | ||
@@ -30,2 +31,5 @@ constructor(settings) { | ||
flushInterval, | ||
httpClient: typeof settings.httpClient === 'function' | ||
? new FetchHTTPClient(settings.httpClient) | ||
: settings.httpClient ?? new FetchHTTPClient(), | ||
}, this); | ||
@@ -32,0 +36,0 @@ this._publisher = publisher; |
// This file is generated. | ||
export const version = '1.0.0'; | ||
export const version = '1.1.0'; | ||
//# sourceMappingURL=version.js.map |
export { Analytics } from './app/analytics-node'; | ||
export { Context } from './app/context'; | ||
export { FetchHTTPClient, } from './lib/http-client'; | ||
// export Analytics as both a named export and a default export (for backwards-compat. reasons) | ||
@@ -4,0 +5,0 @@ import { Analytics } from './app/analytics-node'; |
@@ -9,3 +9,3 @@ /** | ||
*/ | ||
class AbortSignal { | ||
export class AbortSignal { | ||
constructor() { | ||
@@ -12,0 +12,0 @@ this.onabort = null; |
export const fetch = async (...args) => { | ||
if (globalThis.fetch) { | ||
return globalThis.fetch(...args); | ||
} // @ts-ignore | ||
} | ||
// This guard causes is important, as it causes dead-code elimination to be enabled inside this block. | ||
// @ts-ignore | ||
else if (typeof EdgeRuntime !== 'string') { | ||
// @ts-ignore | ||
return (await import('node-fetch')).default(...args); | ||
@@ -9,0 +9,0 @@ } |
import { backoff } from '@segment/analytics-core'; | ||
import { abortSignalAfterTimeout } from '../../lib/abort'; | ||
import { tryCreateFormattedUrl } from '../../lib/create-url'; | ||
import { extractPromiseParts } from '../../lib/extract-promise-parts'; | ||
import { fetch } from '../../lib/fetch'; | ||
import { ContextBatch } from './context-batch'; | ||
@@ -16,3 +14,3 @@ import { b64encode } from '../../lib/base-64-encode'; | ||
export class Publisher { | ||
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, disable, }, emitter) { | ||
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, httpClient, disable, }, emitter) { | ||
this._emitter = emitter; | ||
@@ -26,2 +24,3 @@ this._maxRetries = maxRetries; | ||
this._disable = Boolean(disable); | ||
this._httpClient = httpClient; | ||
} | ||
@@ -125,3 +124,2 @@ createBatch() { | ||
const events = batch.getEvents(); | ||
const payload = JSON.stringify({ batch: events }); | ||
const maxAttempts = this._maxRetries + 1; | ||
@@ -132,6 +130,8 @@ let currentAttempt = 0; | ||
let failureReason; | ||
const [signal, timeoutId] = abortSignalAfterTimeout(this._httpRequestTimeout); | ||
try { | ||
const requestInit = { | ||
signal: signal, | ||
if (this._disable) { | ||
return batch.resolveEvents(); | ||
} | ||
const request = { | ||
url: this._url, | ||
method: 'POST', | ||
@@ -143,17 +143,13 @@ headers: { | ||
}, | ||
body: payload, | ||
data: { batch: events }, | ||
httpRequestTimeout: this._httpRequestTimeout, | ||
}; | ||
this._emitter.emit('http_request', { | ||
url: this._url, | ||
method: requestInit.method, | ||
headers: requestInit.headers, | ||
body: requestInit.body, | ||
body: request.data, | ||
method: request.method, | ||
url: request.url, | ||
headers: request.headers, | ||
}); | ||
if (this._disable) { | ||
clearTimeout(timeoutId); | ||
return batch.resolveEvents(); | ||
} | ||
const response = await fetch(this._url, requestInit); | ||
clearTimeout(timeoutId); | ||
if (response.ok) { | ||
const response = await this._httpClient.makeRequest(request); | ||
if (response.status >= 200 && response.status < 300) { | ||
// Successfully sent events, so exit! | ||
@@ -160,0 +156,0 @@ batch.resolveEvents(); |
@@ -16,3 +16,3 @@ import { CoreEmitterContract, Emitter } from '@segment/analytics-core'; | ||
headers: Record<string, string>; | ||
body: string; | ||
body: Record<string, any>; | ||
} | ||
@@ -19,0 +19,0 @@ ]; |
@@ -0,1 +1,2 @@ | ||
import { HTTPClient, HTTPFetchFn } from '../lib/http-client'; | ||
export interface AnalyticsSettings { | ||
@@ -7,3 +8,2 @@ /** | ||
/** | ||
/** | ||
* The base URL of the API. Default: "https://api.segment.io" | ||
@@ -36,4 +36,10 @@ */ | ||
disable?: boolean; | ||
/** | ||
* Supply a default http client implementation (such as one supporting proxy). | ||
* Accepts either an HTTPClient instance or a fetch function. | ||
* Default: an HTTP client that uses globalThis.fetch, with node-fetch as a fallback. | ||
*/ | ||
httpClient?: HTTPFetchFn | HTTPClient; | ||
} | ||
export declare const validateSettings: (settings: AnalyticsSettings) => void; | ||
//# sourceMappingURL=settings.d.ts.map |
@@ -1,2 +0,2 @@ | ||
export declare const version = "1.0.0"; | ||
export declare const version = "1.1.0"; | ||
//# sourceMappingURL=version.d.ts.map |
export { Analytics } from './app/analytics-node'; | ||
export { Context } from './app/context'; | ||
export { HTTPClient, FetchHTTPClient, HTTPFetchRequest, HTTPResponse, HTTPFetchFn, HTTPClientRequest, } from './lib/http-client'; | ||
export type { Plugin, GroupTraits, UserTraits, TrackParams, IdentifyParams, AliasParams, GroupParams, PageParams, } from './app/types'; | ||
@@ -4,0 +5,0 @@ export type { AnalyticsSettings } from './app/settings'; |
/// <reference types="node" /> | ||
/** | ||
* use non-native event emitter for the benefit of non-node runtimes like CF workers. | ||
*/ | ||
import { Emitter } from '@segment/analytics-core'; | ||
/** | ||
* adapted from: https://www.npmjs.com/package/node-abort-controller | ||
*/ | ||
export declare class AbortSignal { | ||
onabort: globalThis.AbortSignal['onabort']; | ||
aborted: boolean; | ||
eventEmitter: Emitter<{ | ||
[x: string]: any[]; | ||
}>; | ||
toString(): string; | ||
get [Symbol.toStringTag](): string; | ||
removeEventListener(...args: Parameters<Emitter['off']>): void; | ||
addEventListener(...args: Parameters<Emitter['on']>): void; | ||
dispatchEvent(type: string): void; | ||
} | ||
/** | ||
* @param timeoutMs - Set a request timeout, after which the request is cancelled. | ||
@@ -4,0 +23,0 @@ */ |
@@ -1,2 +0,3 @@ | ||
export declare const fetch: typeof globalThis.fetch; | ||
import type { HTTPFetchFn } from './http-client'; | ||
export declare const fetch: HTTPFetchFn; | ||
//# sourceMappingURL=fetch.d.ts.map |
import type { Context } from '../../app/context'; | ||
import { NodeEmitter } from '../../app/emitter'; | ||
import { HTTPClient } from '../../lib/http-client'; | ||
export interface PublisherProps { | ||
@@ -12,2 +13,3 @@ host?: string; | ||
disable?: boolean; | ||
httpClient: HTTPClient; | ||
} | ||
@@ -29,3 +31,4 @@ /** | ||
private _disable; | ||
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, disable, }: PublisherProps, emitter: NodeEmitter); | ||
private _httpClient; | ||
constructor({ host, path, maxRetries, maxEventsInBatch, flushInterval, writeKey, httpRequestTimeout, httpClient, disable, }: PublisherProps, emitter: NodeEmitter); | ||
private createBatch; | ||
@@ -32,0 +35,0 @@ private clearBatch; |
{ | ||
"name": "@segment/analytics-node", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"main": "./dist/cjs/index.js", | ||
@@ -45,5 +45,6 @@ "module": "./dist/esm/index.js", | ||
"@internal/config": "0.0.0", | ||
"@types/node": "^16" | ||
"@types/node": "^16", | ||
"axios": "^1.4.0" | ||
}, | ||
"packageManager": "yarn@3.4.1" | ||
} |
@@ -6,3 +6,3 @@ # @segment/analytics-node | ||
### OFFICIAL DOCUMENTATION (FULL) | ||
- https://segment.com/docs/connections/sources/catalog/libraries/server/node/quickstart | ||
- https://segment.com/docs/connections/sources/catalog/libraries/server/node | ||
@@ -9,0 +9,0 @@ ### LEGACY NODE SDK MIGRATION GUIDE: |
@@ -19,2 +19,3 @@ import { CoreAnalytics, bindAll, pTimeout } from '@segment/analytics-core' | ||
import { NodeEventQueue } from './event-queue' | ||
import { FetchHTTPClient } from '../lib/http-client' | ||
@@ -55,2 +56,6 @@ export class Analytics extends NodeEmitter implements CoreAnalytics { | ||
flushInterval, | ||
httpClient: | ||
typeof settings.httpClient === 'function' | ||
? new FetchHTTPClient(settings.httpClient) | ||
: settings.httpClient ?? new FetchHTTPClient(), | ||
}, | ||
@@ -57,0 +62,0 @@ this as NodeEmitter |
@@ -17,3 +17,3 @@ import { CoreEmitterContract, Emitter } from '@segment/analytics-core' | ||
headers: Record<string, string> | ||
body: string | ||
body: Record<string, any> | ||
} | ||
@@ -20,0 +20,0 @@ ] |
import { ValidationError } from '@segment/analytics-core' | ||
import { HTTPClient, HTTPFetchFn } from '../lib/http-client' | ||
@@ -9,3 +10,2 @@ export interface AnalyticsSettings { | ||
/** | ||
/** | ||
* The base URL of the API. Default: "https://api.segment.io" | ||
@@ -38,2 +38,8 @@ */ | ||
disable?: boolean | ||
/** | ||
* Supply a default http client implementation (such as one supporting proxy). | ||
* Accepts either an HTTPClient instance or a fetch function. | ||
* Default: an HTTP client that uses globalThis.fetch, with node-fetch as a fallback. | ||
*/ | ||
httpClient?: HTTPFetchFn | HTTPClient | ||
} | ||
@@ -40,0 +46,0 @@ |
// This file is generated. | ||
export const version = '1.0.0' | ||
export const version = '1.1.0' |
export { Analytics } from './app/analytics-node' | ||
export { Context } from './app/context' | ||
export { | ||
HTTPClient, | ||
FetchHTTPClient, | ||
HTTPFetchRequest, | ||
HTTPResponse, | ||
HTTPFetchFn, | ||
HTTPClientRequest, | ||
} from './lib/http-client' | ||
export type { | ||
@@ -4,0 +13,0 @@ Plugin, |
@@ -10,3 +10,3 @@ /** | ||
*/ | ||
class AbortSignal { | ||
export class AbortSignal { | ||
onabort: globalThis.AbortSignal['onabort'] = null | ||
@@ -13,0 +13,0 @@ aborted = false |
@@ -1,9 +0,11 @@ | ||
export const fetch: typeof globalThis.fetch = async (...args) => { | ||
import type { HTTPFetchFn } from './http-client' | ||
export const fetch: HTTPFetchFn = async (...args) => { | ||
if (globalThis.fetch) { | ||
return globalThis.fetch(...args) | ||
} // @ts-ignore | ||
} | ||
// This guard causes is important, as it causes dead-code elimination to be enabled inside this block. | ||
// @ts-ignore | ||
else if (typeof EdgeRuntime !== 'string') { | ||
// @ts-ignore | ||
return (await import('node-fetch')).default(...args) as Response | ||
return (await import('node-fetch')).default(...args) | ||
} else { | ||
@@ -10,0 +12,0 @@ throw new Error( |
import { backoff } from '@segment/analytics-core' | ||
import { abortSignalAfterTimeout } from '../../lib/abort' | ||
import type { Context } from '../../app/context' | ||
import { tryCreateFormattedUrl } from '../../lib/create-url' | ||
import { extractPromiseParts } from '../../lib/extract-promise-parts' | ||
import { fetch } from '../../lib/fetch' | ||
import { ContextBatch } from './context-batch' | ||
import { NodeEmitter } from '../../app/emitter' | ||
import { b64encode } from '../../lib/base-64-encode' | ||
import { HTTPClient, HTTPClientRequest } from '../../lib/http-client' | ||
@@ -31,2 +30,3 @@ function sleep(timeoutInMs: number): Promise<void> { | ||
disable?: boolean | ||
httpClient: HTTPClient | ||
} | ||
@@ -50,2 +50,3 @@ | ||
private _disable: boolean | ||
private _httpClient: HTTPClient | ||
constructor( | ||
@@ -60,2 +61,3 @@ { | ||
httpRequestTimeout, | ||
httpClient, | ||
disable, | ||
@@ -76,2 +78,3 @@ }: PublisherProps, | ||
this._disable = Boolean(disable) | ||
this._httpClient = httpClient | ||
} | ||
@@ -190,3 +193,2 @@ | ||
const events = batch.getEvents() | ||
const payload = JSON.stringify({ batch: events }) | ||
const maxAttempts = this._maxRetries + 1 | ||
@@ -199,8 +201,9 @@ | ||
let failureReason: unknown | ||
const [signal, timeoutId] = abortSignalAfterTimeout( | ||
this._httpRequestTimeout | ||
) | ||
try { | ||
const requestInit = { | ||
signal: signal, | ||
if (this._disable) { | ||
return batch.resolveEvents() | ||
} | ||
const request: HTTPClientRequest = { | ||
url: this._url, | ||
method: 'POST', | ||
@@ -212,22 +215,16 @@ headers: { | ||
}, | ||
body: payload, | ||
data: { batch: events }, | ||
httpRequestTimeout: this._httpRequestTimeout, | ||
} | ||
this._emitter.emit('http_request', { | ||
url: this._url, | ||
method: requestInit.method, | ||
headers: requestInit.headers, | ||
body: requestInit.body, | ||
body: request.data, | ||
method: request.method, | ||
url: request.url, | ||
headers: request.headers, | ||
}) | ||
if (this._disable) { | ||
clearTimeout(timeoutId) | ||
return batch.resolveEvents() | ||
} | ||
const response = await this._httpClient.makeRequest(request) | ||
const response = await fetch(this._url, requestInit) | ||
clearTimeout(timeoutId) | ||
if (response.ok) { | ||
if (response.status >= 200 && response.status < 300) { | ||
// Successfully sent events, so exit! | ||
@@ -234,0 +231,0 @@ batch.resolveEvents() |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
181006
179
3146
1
3