@appsignal/nodejs
Advanced tools
Comparing version
@@ -10,4 +10,21 @@ import { HashMap } from "@appsignal/types"; | ||
agentDiagnosticTestDefinition(): HashMap<any>; | ||
printConfiguration({ options, sources }: { | ||
options: { | ||
[key: string]: any; | ||
}; | ||
sources: { | ||
[source: string]: { | ||
[key: string]: any; | ||
}; | ||
}; | ||
}): void; | ||
configurationKeySources(key: string, sources: { | ||
[source: string]: { | ||
[key: string]: any; | ||
}; | ||
}): { | ||
[source: string]: any; | ||
}; | ||
print_newline(): void; | ||
colorize(value: string): string; | ||
} |
@@ -67,2 +67,4 @@ "use strict"; | ||
console.log(` Library type: ${format_value(data["installation"]["build"]["library_type"])}`); | ||
console.log(` Dependencies: ${format_value(data["installation"]["build"]["dependencies"])}`); | ||
console.log(` Flags: ${format_value(data["installation"]["build"]["flags"])}`); | ||
console.log(` Host details`); | ||
@@ -82,8 +84,3 @@ console.log(` Root user: ${format_value(data["installation"]["host"]["root_user"])}`); | ||
this.print_newline(); | ||
console.log(`Configuration`); | ||
Object.keys(data["config"]["options"]) | ||
.sort() | ||
.forEach(key => { | ||
console.log(` ${key}: ${format_value(data["config"]["options"][key])}`); | ||
}); | ||
this.printConfiguration(data["config"]); | ||
this.print_newline(); | ||
@@ -246,2 +243,40 @@ console.log(`Read more about how the diagnose config output is rendered`); | ||
} | ||
printConfiguration({ options, sources }) { | ||
console.log(`Configuration`); | ||
Object.keys(options) | ||
.sort() | ||
.forEach(key => { | ||
let keySources = this.configurationKeySources(key, sources); | ||
if (Object.keys(keySources).length == 1) { | ||
const source = Object.keys(keySources)[0]; | ||
let extra = ""; | ||
if (source !== "default") { | ||
extra = ` (Loaded from: ${source})`; | ||
} | ||
console.log(` ${key}: ${format_value(options[key])}${extra}`); | ||
} | ||
else { | ||
console.log(` ${key}: ${format_value(options[key])}`); | ||
console.log(` Sources:`); | ||
const maxSourceLength = Object.keys(keySources) | ||
// Adding one to account for the `:` after the source name. | ||
.map(source => source.length + 1) | ||
.reduce((max, source) => Math.max(max, source), 0); | ||
Object.entries(keySources).forEach(([source, value]) => { | ||
source = `${source}:`.padEnd(maxSourceLength, " "); | ||
console.log(` ${source} ${format_value(value)}`); | ||
}); | ||
} | ||
}); | ||
} | ||
configurationKeySources(key, sources) { | ||
return Object.entries(sources).reduce((keySources, [source, sourceOptions]) => { | ||
if (sourceOptions.hasOwnProperty(key)) { | ||
return { ...keySources, [source]: sourceOptions[key] }; | ||
} | ||
else { | ||
return keySources; | ||
} | ||
}, {}); | ||
} | ||
print_newline() { | ||
@@ -264,3 +299,8 @@ console.log(``); | ||
function format_value(value) { | ||
return util.inspect(value); | ||
if (typeof value == "object") { | ||
return JSON.stringify(value); | ||
} | ||
else { | ||
return util.inspect(value); | ||
} | ||
} |
@@ -15,3 +15,3 @@ import { Client, Metrics, Plugin, Tracer, AppsignalOptions } from "./interfaces"; | ||
#private; | ||
readonly VERSION = "2.2.4"; | ||
readonly VERSION = "2.2.5"; | ||
config: Configuration; | ||
@@ -77,2 +77,6 @@ extension: Extension; | ||
demo(): void; | ||
/** | ||
* Stores the client in global object after initializing | ||
*/ | ||
private storeInGlobal; | ||
} |
@@ -42,2 +42,3 @@ "use strict"; | ||
bootstrap_1.initCoreProbes(this.metrics(), { enableMinutelyProbes }); | ||
this.storeInGlobal(); | ||
} | ||
@@ -64,3 +65,3 @@ /** | ||
else { | ||
console.error("Not starting, no valid config for this environment"); | ||
console.error("Not starting, no valid AppSignal configuration found"); | ||
} | ||
@@ -129,4 +130,10 @@ } | ||
} | ||
/** | ||
* Stores the client in global object after initializing | ||
*/ | ||
storeInGlobal() { | ||
global.__APPSIGNAL__ = this; | ||
} | ||
} | ||
exports.BaseClient = BaseClient; | ||
_tracer = new WeakMap(), _metrics = new WeakMap(); |
import { AppsignalOptions } from "./interfaces/options"; | ||
import { HashMap } from "@appsignal/types"; | ||
/** | ||
@@ -12,2 +13,3 @@ * The AppSignal configuration object. | ||
data: Partial<AppsignalOptions>; | ||
sources: HashMap<Partial<AppsignalOptions>>; | ||
constructor(options: Partial<AppsignalOptions>); | ||
@@ -20,7 +22,13 @@ /** | ||
* Returns `true` if the current configuration is valid. | ||
* | ||
* @todo | ||
*/ | ||
get isValid(): boolean; | ||
get logFilePath(): string | undefined; | ||
/** | ||
* Returns default OS tmp dir. Uses OS package for Windows. Linux and macOS | ||
* have `/tmp` hardcoded as a default | ||
* | ||
* @private | ||
*/ | ||
private _tmpdir; | ||
/** | ||
* Explicit default configuration values | ||
@@ -32,2 +40,8 @@ * | ||
/** | ||
* Config options based on the host environment. | ||
* | ||
* @private | ||
*/ | ||
private _systemValues; | ||
/** | ||
* Loads environment variables into a key-value structure. | ||
@@ -43,3 +57,11 @@ * | ||
*/ | ||
private _write; | ||
private writePrivateConfig; | ||
/** | ||
* Writes private environment variables that are not user configured, | ||
* and static in the lifecycle of the agent. | ||
* | ||
* @function | ||
* @private | ||
*/ | ||
private writePrivateConstants; | ||
} |
@@ -6,3 +6,5 @@ "use strict"; | ||
const path_1 = tslib_1.__importDefault(require("path")); | ||
const os_1 = tslib_1.__importDefault(require("os")); | ||
const version_1 = require("./version"); | ||
const utils_1 = require("./utils"); | ||
const configmap_1 = require("./config/configmap"); | ||
@@ -19,9 +21,17 @@ /** | ||
constructor(options) { | ||
writePrivateConstants(); | ||
this.data = { | ||
...this._defaultValues(), | ||
...this._loadFromEnvironment(), | ||
...options | ||
if (options.apiKey) { | ||
console.warn("DEPRECATED: The `apiKey` config option was renamed to `pushApiKey`. Please rename the config option given to the Appsignal module."); | ||
options.pushApiKey = options.apiKey; | ||
delete options.apiKey; | ||
} | ||
this.sources = { | ||
default: this._defaultValues(), | ||
system: this._systemValues(), | ||
env: this._loadFromEnvironment(), | ||
initial: options | ||
}; | ||
this._write(this.data); | ||
this.data = Object.values(this.sources).reduce((data, options) => { | ||
return { ...data, ...options }; | ||
}, {}); | ||
this.writePrivateConfig(this.data); | ||
} | ||
@@ -36,9 +46,49 @@ /** | ||
* Returns `true` if the current configuration is valid. | ||
* | ||
* @todo | ||
*/ | ||
get isValid() { | ||
return true; | ||
return (this.data.pushApiKey || "").trim() !== ""; | ||
} | ||
get logFilePath() { | ||
const filename = "appsignal.log"; | ||
let logPath = this.data["logPath"]; | ||
if (logPath && path_1.default.extname(logPath) != "") { | ||
console.warn("DEPRECATED: File names are no longer supported in the 'logPath' config option. Changing the filename to 'appsignal.log'"); | ||
logPath = path_1.default.dirname(logPath); | ||
} | ||
if (logPath && utils_1.isWritable(logPath)) { | ||
return path_1.default.join(logPath, filename); | ||
} | ||
else { | ||
const tmpDir = this._tmpdir(); | ||
if (utils_1.isWritable(tmpDir)) { | ||
if (logPath) { | ||
console.warn(`Unable to log to '${logPath}'. Logging to '${tmpDir}' instead. Please check the permissions of the 'logPath' directory.`); | ||
} | ||
return path_1.default.join(tmpDir, filename); | ||
} | ||
else { | ||
let configuredPath = ""; | ||
if (logPath) { | ||
configuredPath = `'${logPath}' or `; | ||
} | ||
console.warn(`Unable to log to ${configuredPath}'${tmpDir}' fallback. Please check the permissions of these directories.`); | ||
} | ||
} | ||
} | ||
/** | ||
* Returns default OS tmp dir. Uses OS package for Windows. Linux and macOS | ||
* have `/tmp` hardcoded as a default | ||
* | ||
* @private | ||
*/ | ||
_tmpdir() { | ||
const isWindows = process.platform == "win32"; | ||
if (isWindows) { | ||
return os_1.default.tmpdir(); | ||
} | ||
else { | ||
return "/tmp"; | ||
} | ||
} | ||
/** | ||
* Explicit default configuration values | ||
@@ -59,3 +109,2 @@ * | ||
filesWorldAccessible: true, | ||
filterDataKeys: [], | ||
filterParameters: [], | ||
@@ -67,3 +116,12 @@ filterSessionData: [], | ||
log: "file", | ||
logPath: "/tmp", | ||
requestHeaders: [ | ||
"accept", | ||
"accept-charset", | ||
"accept-encoding", | ||
"accept-language", | ||
"cache-control", | ||
"connection", | ||
"content-length", | ||
"range" | ||
], | ||
transactionDebugMode: false | ||
@@ -73,2 +131,14 @@ }; | ||
/** | ||
* Config options based on the host environment. | ||
* | ||
* @private | ||
*/ | ||
_systemValues() { | ||
const config = {}; | ||
if (process.env.DYNO) { | ||
config["log"] = "stdout"; | ||
} | ||
return config; | ||
} | ||
/** | ||
* Loads environment variables into a key-value structure. | ||
@@ -99,10 +169,8 @@ * | ||
*/ | ||
_write(config) { | ||
// First write log file path based on log path | ||
if (config["logPath"].endsWith("appsignal.log")) { | ||
config["logFilePath"] = config["logPath"]; | ||
writePrivateConfig(config) { | ||
this.writePrivateConstants(); | ||
const logFilePath = this.logFilePath; | ||
if (logFilePath) { | ||
process.env["_APPSIGNAL_LOG_FILE_PATH"] = logFilePath; | ||
} | ||
else { | ||
config["logFilePath"] = path_1.default.join(config["logPath"], "appsignal.log"); | ||
} | ||
// write to a "private" environment variable if it exists in the | ||
@@ -120,22 +188,21 @@ // config structure | ||
}); | ||
return; | ||
} | ||
/** | ||
* Writes private environment variables that are not user configured, | ||
* and static in the lifecycle of the agent. | ||
* | ||
* @function | ||
* @private | ||
*/ | ||
writePrivateConstants() { | ||
const priv = { | ||
// @TODO: is this path always correct? | ||
_APPSIGNAL_AGENT_PATH: path_1.default.join(__dirname, "/../../nodejs-ext/ext"), | ||
_APPSIGNAL_PROCESS_NAME: process.title, | ||
_APPSIGNAL_LANGUAGE_INTEGRATION_VERSION: `nodejs-${version_1.VERSION}`, | ||
_APPSIGNAL_APP_PATH: process.cwd() | ||
}; | ||
Object.entries(priv).forEach(([k, v]) => (process.env[k] = v)); | ||
} | ||
} | ||
exports.Configuration = Configuration; | ||
/** | ||
* Writes private environment variables that are not user configured, | ||
* and static in the lifecycle of the agent. | ||
* | ||
* @function | ||
* @private | ||
*/ | ||
function writePrivateConstants() { | ||
const priv = { | ||
// @TODO: is this path always correct? | ||
_APPSIGNAL_AGENT_PATH: path_1.default.join(__dirname, "/../../nodejs-ext/ext"), | ||
_APPSIGNAL_PROCESS_NAME: process.title, | ||
_APPSIGNAL_LANGUAGE_INTEGRATION_VERSION: `nodejs-${version_1.VERSION}`, | ||
_APPSIGNAL_APP_PATH: process.cwd() | ||
}; | ||
Object.entries(priv).forEach(([k, v]) => (process.env[k] = v)); | ||
} |
@@ -26,3 +26,3 @@ "use strict"; | ||
APPSIGNAL_PUSH_API_ENDPOINT: "endpoint", | ||
APPSIGNAL_PUSH_API_KEY: "apiKey", | ||
APPSIGNAL_PUSH_API_KEY: "pushApiKey", | ||
APPSIGNAL_REQUEST_HEADERS: "requestHeaders", | ||
@@ -47,3 +47,4 @@ APPSIGNAL_RUNNING_IN_CONTAINER: "runningInContainer", | ||
_APPSIGNAL_FILES_WORLD_ACCESSIBLE: "filesWorldAccessible", | ||
_APPSIGNAL_FILTER_DATA_KEYS: "filterDataKeys", | ||
_APPSIGNAL_FILTER_PARAMETERS: "filterParameters", | ||
_APPSIGNAL_FILTER_SESSION_DATA: "filterSessionData", | ||
_APPSIGNAL_HOSTNAME: "hostname", | ||
@@ -55,5 +56,4 @@ _APPSIGNAL_HTTP_PROXY: "httpProxy", | ||
_APPSIGNAL_LOG: "log", | ||
_APPSIGNAL_LOG_FILE_PATH: "logFilePath", | ||
_APPSIGNAL_PUSH_API_ENDPOINT: "endpoint", | ||
_APPSIGNAL_PUSH_API_KEY: "apiKey", | ||
_APPSIGNAL_PUSH_API_KEY: "pushApiKey", | ||
_APPSIGNAL_RUNNING_IN_CONTAINER: "runningInContainer", | ||
@@ -67,3 +67,3 @@ _APPSIGNAL_TRANSACTION_DEBUG_MODE: "debug", | ||
active: "active", | ||
apiKey: "push_api_key", | ||
pushApiKey: "push_api_key", | ||
caFilePath: "ca_file_path", | ||
@@ -78,3 +78,2 @@ debug: "debug", | ||
filesWorldAccessible: "files_world_accessible", | ||
filterDataKeys: "filter_data_keys", | ||
filterParameters: "filter_parameters", | ||
@@ -88,4 +87,4 @@ filterSessionData: "filter_session_data", | ||
logPath: "log_path", | ||
logFilePath: "log_file_path", | ||
name: "name", | ||
requestHeaders: "request_headers", | ||
revision: "revision", | ||
@@ -92,0 +91,0 @@ runningInContainer: "running_in_container", |
/// <reference types="node" /> | ||
import { AppsignalOptions } from "."; | ||
import { HashMap } from "@appsignal/types"; | ||
interface FileMetadata { | ||
@@ -41,6 +43,4 @@ content?: string[]; | ||
config: { | ||
options: { | ||
[key: string]: any; | ||
}; | ||
sources: {}; | ||
options: Partial<AppsignalOptions>; | ||
sources: HashMap<Partial<AppsignalOptions>>; | ||
}; | ||
@@ -64,7 +64,18 @@ validation: { | ||
* Reads all configuration and re-maps it to keys with | ||
* snake_case names as they appear in our API. | ||
* snake_case names. | ||
*/ | ||
private getConfigData; | ||
sendReport(data: object): void; | ||
/** | ||
* Converts an AppsignalOptions object into a plain JS object, | ||
* re-mapping its keys to snake_case names as they appear | ||
* in our API. | ||
*/ | ||
private optionsObject; | ||
/** | ||
* Reads all configuration sources, remapping each source's | ||
* option keys with snake_case names. | ||
*/ | ||
private getSources; | ||
sendReport(data: HashMap<any>): void; | ||
} | ||
export {}; |
@@ -12,2 +12,3 @@ "use strict"; | ||
const crypto_1 = require("crypto"); | ||
const utils_1 = require("./utils"); | ||
const extension_1 = require("./extension"); | ||
@@ -39,4 +40,4 @@ const config_1 = require("./config"); | ||
config: { | ||
options: this.getConfigData(), | ||
sources: {} | ||
options: tslib_1.__classPrivateFieldGet(this, _config).data, | ||
sources: tslib_1.__classPrivateFieldGet(this, _config).sources | ||
}, | ||
@@ -94,6 +95,12 @@ validation: { push_api_key: pushApiKeyValidation }, | ||
const config = tslib_1.__classPrivateFieldGet(this, _config).data; | ||
const params = new url_1.URLSearchParams({ api_key: config["apiKey"] }); | ||
const params = new url_1.URLSearchParams({ | ||
api_key: config["pushApiKey"] || "", | ||
name: config["name"] || "", | ||
environment: config["environment"] || "", | ||
hostname: config["hostname"] || "" | ||
}); | ||
const url = new url_1.URL(`/1/auth?${params.toString()}`, config["endpoint"]); | ||
const options = { method: "POST" }; | ||
const request = https_1.default.request(url, options, function (response) { | ||
const requestModule = url.protocol == "http:" ? http_1.default : https_1.default; | ||
const request = requestModule.request(url, options, function (response) { | ||
const status = response.statusCode; | ||
@@ -107,6 +114,6 @@ if (status === 200) { | ||
else { | ||
reject(`Failed with status ${status}`); | ||
reject(`Failed to validate: status ${status}`); | ||
} | ||
}); | ||
request.write("{}"); // Send empty JSON body | ||
request.write(""); // Send empty body | ||
request.end(); | ||
@@ -117,7 +124,4 @@ }); | ||
const paths = {}; | ||
// we want to fall over if this value isn't present | ||
// (it should be) | ||
const logFilePath = tslib_1.__classPrivateFieldGet(this, _config).data.logFilePath; | ||
// add any paths we want to check to this object! | ||
const files = { | ||
const logFilePath = tslib_1.__classPrivateFieldGet(this, _config).logFilePath; | ||
const pathsToCheck = { | ||
working_dir: { | ||
@@ -127,27 +131,37 @@ path: process.cwd() | ||
log_dir_path: { | ||
path: tslib_1.__classPrivateFieldGet(this, _config).data.logPath.replace("/appsignal.log", "") | ||
path: logFilePath ? path_1.default.dirname(logFilePath) : "" | ||
}, | ||
"appsignal.log": { | ||
path: logFilePath, | ||
content: safeReadFromPath(logFilePath).trimEnd().split("\n") | ||
path: logFilePath || "", | ||
content: logFilePath | ||
? safeReadFromPath(logFilePath).trimEnd().split("\n") | ||
: [] | ||
} | ||
}; | ||
Object.entries(files).forEach(([key, data]) => { | ||
Object.entries(pathsToCheck).forEach(([key, data]) => { | ||
const { path } = data; | ||
try { | ||
const stats = fs_1.default.statSync(path); | ||
const { mode, gid, uid } = stats; | ||
paths[key] = { | ||
...data, | ||
exists: true, | ||
mode: mode.toString(8), | ||
ownership: { | ||
gid, | ||
uid | ||
}, | ||
type: getPathType(stats), | ||
writable: isWriteableFile(path) | ||
}; | ||
if (fs_1.default.existsSync(path)) { | ||
try { | ||
let stats = fs_1.default.statSync(path); | ||
const { mode, gid, uid } = stats; | ||
paths[key] = { | ||
...data, | ||
exists: true, | ||
mode: mode.toString(8), | ||
ownership: { | ||
gid, | ||
uid | ||
}, | ||
type: getPathType(stats), | ||
writable: utils_1.isWritable(path) | ||
}; | ||
} | ||
catch (_) { | ||
paths[key] = { | ||
...data, | ||
exists: true | ||
}; | ||
} | ||
} | ||
catch (_) { | ||
else { | ||
paths[key] = { | ||
@@ -163,16 +177,40 @@ ...data, | ||
* Reads all configuration and re-maps it to keys with | ||
* snake_case names as they appear in our API. | ||
* snake_case names. | ||
*/ | ||
getConfigData() { | ||
return this.optionsObject(tslib_1.__classPrivateFieldGet(this, _config).data); | ||
} | ||
/** | ||
* Converts an AppsignalOptions object into a plain JS object, | ||
* re-mapping its keys to snake_case names as they appear | ||
* in our API. | ||
*/ | ||
optionsObject(options) { | ||
const config = {}; | ||
Object.keys(tslib_1.__classPrivateFieldGet(this, _config).data).forEach(key => { | ||
Object.keys(options).forEach(key => { | ||
const newKey = configmap_1.JS_TO_RUBY_MAPPING[key]; | ||
config[newKey] = tslib_1.__classPrivateFieldGet(this, _config).data[key]; | ||
config[newKey] = options[key]; | ||
}); | ||
return config; | ||
} | ||
/** | ||
* Reads all configuration sources, remapping each source's | ||
* option keys with snake_case names. | ||
*/ | ||
getSources() { | ||
return Object.entries(tslib_1.__classPrivateFieldGet(this, _config).sources).reduce((sources, [name, options]) => { | ||
return { ...sources, [name]: this.optionsObject(options) }; | ||
}, {}); | ||
} | ||
sendReport(data) { | ||
data.config.options = this.getConfigData(); | ||
data.config.sources = this.getSources(); | ||
const json = JSON.stringify({ diagnose: data }); | ||
const config = tslib_1.__classPrivateFieldGet(this, _config).data; | ||
const params = new url_1.URLSearchParams({ api_key: config["apiKey"] || "" }); | ||
const params = new url_1.URLSearchParams({ | ||
api_key: config["pushApiKey"] || "", | ||
name: config["name"] || "", | ||
environment: config["environment"] || "", | ||
hostname: config["hostname"] || "" | ||
}); | ||
const diagnoseEndpoint = process.env.APPSIGNAL_DIAGNOSE_ENDPOINT || "https://appsignal.com/diag"; | ||
@@ -226,11 +264,2 @@ const url = new url_1.URL(diagnoseEndpoint); | ||
} | ||
function isWriteableFile(path) { | ||
try { | ||
fs_1.default.accessSync(path, fs_1.default.constants.R_OK); | ||
return true; | ||
} | ||
catch (e) { | ||
return false; | ||
} | ||
} | ||
function getPathType(stats) { | ||
@@ -237,0 +266,0 @@ if (stats.isDirectory()) { |
@@ -29,4 +29,5 @@ "use strict"; | ||
const [req, res] = args; | ||
const { method = "GET", url = "/" } = req; | ||
const { method = "GET", url = "/", headers } = req; | ||
const { pathname, query } = url_1.parse(url); | ||
const allowedHeaders = filterHeaders(headers); | ||
// don't start a span for ignored urls | ||
@@ -54,2 +55,3 @@ if (url && DEFAULT_IGNORED_URLS.some(el => el.test(url))) { | ||
.set("method", method) | ||
.setSampleData("environment", allowedHeaders) | ||
.setSampleData("params", query ? { query } : {}); | ||
@@ -73,2 +75,12 @@ return tracer.withSpan(rootSpan, span => { | ||
} | ||
function filterHeaders(headers) { | ||
let filtered = {}; | ||
const headersAllowList = global.__APPSIGNAL__.config.data.requestHeaders || []; | ||
headersAllowList.forEach(key => { | ||
if (headers[key] != undefined) { | ||
filtered[key] = headers[key]; | ||
} | ||
}); | ||
return filtered; | ||
} | ||
function getPatchIncomingRequestFunction(tracer) { | ||
@@ -75,0 +87,0 @@ return function (original) { |
@@ -24,2 +24,3 @@ export interface AppsignalOptions { | ||
name: string; | ||
pushApiKey: string; | ||
requestHeaders: string[]; | ||
@@ -26,0 +27,0 @@ revision: string; |
import { HashMap } from "@appsignal/types"; | ||
import { datamap, dataarray } from "../extension_wrapper"; | ||
export declare class Data { | ||
static generate(data: Array<any> | HashMap<any>, filtered?: boolean): any; | ||
static generate(data: Array<any> | HashMap<any>): any; | ||
static toJson(data: typeof datamap | typeof dataarray): any; | ||
@@ -6,0 +6,0 @@ private static mapObject; |
@@ -6,8 +6,8 @@ "use strict"; | ||
class Data { | ||
static generate(data, filtered = false) { | ||
static generate(data) { | ||
if (data.constructor.name === "Object") { | ||
return this.mapObject(data, filtered); | ||
return this.mapObject(data); | ||
} | ||
else if (Array.isArray(data)) { | ||
return this.mapArray(data, filtered); | ||
return this.mapArray(data); | ||
} | ||
@@ -21,4 +21,4 @@ else { | ||
} | ||
static mapObject(hash_value, filtered) { | ||
let map = filtered ? extension_wrapper_1.datamap.createFiltered() : extension_wrapper_1.datamap.create(); | ||
static mapObject(hash_value) { | ||
let map = extension_wrapper_1.datamap.create(); | ||
Object.entries(hash_value).forEach(([key, value]) => { | ||
@@ -51,6 +51,6 @@ switch (typeof value) { | ||
else if (Array.isArray(value)) { | ||
extension_wrapper_1.datamap.setData(key, this.mapArray(value, filtered), map); | ||
extension_wrapper_1.datamap.setData(key, this.mapArray(value), map); | ||
} | ||
else if ((value === null || value === void 0 ? void 0 : value.constructor.name) === "Object") { | ||
extension_wrapper_1.datamap.setData(key, this.mapObject(value, filtered), map); | ||
extension_wrapper_1.datamap.setData(key, this.mapObject(value), map); | ||
} | ||
@@ -66,3 +66,3 @@ else { | ||
} | ||
static mapArray(array_value, filtered) { | ||
static mapArray(array_value) { | ||
let array = extension_wrapper_1.dataarray.create(); | ||
@@ -97,6 +97,6 @@ array_value.forEach(value => { | ||
else if (Array.isArray(value)) { | ||
extension_wrapper_1.dataarray.appendData(this.mapArray(value, filtered), array); | ||
extension_wrapper_1.dataarray.appendData(this.mapArray(value), array); | ||
} | ||
else if ((value === null || value === void 0 ? void 0 : value.constructor.name) === "Object") { | ||
extension_wrapper_1.dataarray.appendData(this.mapObject(value, filtered), array); | ||
extension_wrapper_1.dataarray.appendData(this.mapObject(value), array); | ||
} | ||
@@ -103,0 +103,0 @@ else { |
@@ -106,3 +106,3 @@ "use strict"; | ||
try { | ||
extension_wrapper_1.span.setSpanSampleData(this._ref, key, data_1.Data.generate(data, true)); | ||
extension_wrapper_1.span.setSpanSampleData(this._ref, key, data_1.Data.generate(data)); | ||
} | ||
@@ -109,0 +109,0 @@ catch (e) { |
@@ -19,1 +19,5 @@ /** | ||
}; | ||
/** | ||
* Checks if the given path is writable by the process. | ||
*/ | ||
export declare function isWritable(path: string): boolean; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getAgentTimestamps = exports.getPackageVerson = void 0; | ||
exports.isWritable = exports.getAgentTimestamps = exports.getPackageVerson = void 0; | ||
const tslib_1 = require("tslib"); | ||
const fs_1 = tslib_1.__importDefault(require("fs")); | ||
const path_1 = tslib_1.__importDefault(require("path")); | ||
@@ -37,1 +38,14 @@ /** | ||
exports.getAgentTimestamps = getAgentTimestamps; | ||
/** | ||
* Checks if the given path is writable by the process. | ||
*/ | ||
function isWritable(path) { | ||
try { | ||
fs_1.default.accessSync(path, fs_1.default.constants.W_OK); | ||
return true; | ||
} | ||
catch (e) { | ||
return false; | ||
} | ||
} | ||
exports.isWritable = isWritable; |
@@ -1,2 +0,2 @@ | ||
export declare const VERSION = "2.2.4"; | ||
export declare const AGENT_VERSION = "09308fb"; | ||
export declare const VERSION = "2.2.5"; | ||
export declare const AGENT_VERSION = "5b63505"; |
@@ -5,3 +5,3 @@ "use strict"; | ||
// Do not touch this file, auto-generated by scripts/create-versionfile | ||
exports.VERSION = "2.2.4"; | ||
exports.AGENT_VERSION = "09308fb"; | ||
exports.VERSION = "2.2.5"; | ||
exports.AGENT_VERSION = "5b63505"; |
{ | ||
"name": "@appsignal/nodejs", | ||
"version": "2.2.4", | ||
"version": "2.2.5", | ||
"main": "dist/index", | ||
@@ -19,3 +19,3 @@ "types": "dist/index", | ||
"optionalDependencies": { | ||
"@appsignal/nodejs-ext": "=2.0.3" | ||
"@appsignal/nodejs-ext": "=2.0.4" | ||
}, | ||
@@ -22,0 +22,0 @@ "devDependencies": { |
@@ -36,3 +36,3 @@ # `@appsignal/nodejs` | ||
name: "<YOUR APPLICATION NAME>" | ||
apiKey: "<YOUR API KEY>" | ||
pushApiKey: "<YOUR API KEY>" | ||
}); | ||
@@ -39,0 +39,0 @@ |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
368597
2.23%3928
6.13%19
18.75%