diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 521a9f7..0000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -legacy-peer-deps=true diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22 diff --git a/DEPENDENCY-AUDIT.md b/DEPENDENCY-AUDIT.md index 614fdd3..1cb08ea 100644 --- a/DEPENDENCY-AUDIT.md +++ b/DEPENDENCY-AUDIT.md @@ -30,7 +30,7 @@ bunyan's **`optionalDependencies`** (`mv`, `moment`, `dtrace-provider`, - **B (clean):** replace `bunyan-category` logger with a maintained logger (e.g. `pino`). Kills the whole EOL bunyan tree; requires rewriting logger usage in `src/index.ts`. -Recommend **A** for the Nov 1 release; file **B** as follow-up. +Recommend **A** for the core release; file **B** as follow-up. --- @@ -129,8 +129,20 @@ Keep those on their last CJS major and patch to latest-in-major. No ESM conversi 1. **Coverage net (nock)** — ✅ **DONE.** `src/index.nock.test.ts`, 38 tests, all 15 graphClient methods (success + error). `index.ts` coverage 41.6% → **64.6%** stmts, funcs 34% → 68%. 72 tests total (34 PollyJS + 38 nock) green. 3 Apollo-4-sensitive behaviors pinned in `PUBLIC-API.md` §6a. 2. **Migrate yarn → npm** (Section 4a) — ✅ **DONE.** `yarn.lock` removed, `package-lock.json` generated. Scripts/CI/husky/lint-staged swapped. Added `.npmrc` `legacy-peer-deps=true` (bunyan-category's exact `@types/bunyan@1.8.6` peer — removed once Phase 1b lands). CI bumped to Node 22 + setup-node@v4. `npm test` → 72 pass; `npm run build` emits d.ts. npm audit: 322 → **35** (dedup from fresh install). -3. **Phase 0** — quick wins + transitive resolutions/overrides. -4. **Phase 1b** — kill `inflight` chain (TD-9488). +3. **Phase 0** — ✅ **DONE.** `.nvmrc` (22), `engines: >=22`, `js-yaml 3.13.1 → 4.3.2` + (`safeLoad`→`load` at `j1cli.ts:207`; removes the js-yaml high). Contract unchanged, + 72 tests green, build clean (TS 3.8 intact). **Transitive-vuln `overrides` deferred to + Phase 1a** — `npm audit fix` overreached into the dev tree and pulled a modern + `@types/babel__traverse` that TS 3.8 can't parse (TS1005). Clean fix requires the TS + upgrade first. Residual **prod** vulns (0 critical, 4 high) map to later phases: + `lodash`→Phase 2 (apollo), `moment`→Phase 1b (bunyan optionals), `tmp`/`inquirer`/ + `external-editor`→Phase 1a (inquirer), `brace-expansion`/`minimatch`→Phase 1a overrides. +4. **Phase 1b** — ✅ **DONE.** Replaced `bunyan-category` with `pino ^8.21.0` (pino 8 types + parse under TS 3.8). `inflight` + `mv`/`rimraf@2`/`glob@6` **gone from prod tree**. `Logger` + now an exported structural interface (`JupiterOneClientOptions.logger` backward-compatible) — + approved contract change, baseline updated (see `PUBLIC-API.md` §6b). Removed `.npmrc` + `legacy-peer-deps` (no longer needed — bunyan-category's `@types/bunyan` peer was the cause). + Prod vulns 7 → **4**. 72 tests green, build clean. 5. **Phase 2** — Apollo + graphql (TD-9488 core). Verified by step 1's nock tests. 6. **Phase 1a / Phase 3** — tooling + CLI fleet (follow-up, post-Nov-1 if needed). diff --git a/PUBLIC-API.baseline.d.ts b/PUBLIC-API.baseline.d.ts index da1c3d7..5efd430 100644 --- a/PUBLIC-API.baseline.d.ts +++ b/PUBLIC-API.baseline.d.ts @@ -1,6 +1,5 @@ import { ApolloClient, QueryOptions } from 'apollo-client'; import { Response as FetchResponse } from 'node-fetch'; -import Logger from 'bunyan-category'; import { Entity, EntityForSync, Relationship, RelationshipForSync, IntegrationDefinition, IntegrationInstance, ListIntegrationInstancesOptions, EntitySource } from './types'; import { QueryTypes } from './util/query'; export declare class FetchError extends Error { @@ -46,6 +45,20 @@ export interface QueryResult { entity: object; properties: object; } +/** + * Minimal structural logger interface. Any bunyan/pino-style logger satisfies it, + * so consumers can continue passing their existing logger. Each method accepts + * either `(msg)` or `(mergeObject, msg)`, matching both bunyan and pino. + */ +export declare type LogFn = (objOrMsg: unknown, msg?: string) => void; +export interface Logger { + trace(objOrMsg: unknown, msg?: string): void; + debug(objOrMsg: unknown, msg?: string): void; + info(objOrMsg: unknown, msg?: string): void; + warn(objOrMsg: unknown, msg?: string): void; + error(objOrMsg: unknown, msg?: string): void; + fatal(objOrMsg: unknown, msg?: string): void; +} export interface JupiterOneClientOptions { account: string; accessToken?: string; diff --git a/PUBLIC-API.md b/PUBLIC-API.md index 0d3eda0..e251e8e 100644 --- a/PUBLIC-API.md +++ b/PUBLIC-API.md @@ -199,3 +199,13 @@ NOT change them silently in the upgrade. If the Apollo 4 swap alters any, call i - **`integrationInstances.update` / `.delete` pass the `query` keyword into `mutate()`.** apollo-client 2.6 tolerates it; **Apollo 4 is stricter and may reject** — explicit upgrade risk. - `integrationDefinitions.list` uses `errorPolicy: 'all'` → collects partial errors without throwing. + +### 6b. Approved contract change — Phase 1b (bunyan → pino) +**Baseline `.d.ts` updated** to reflect this. `bunyan-category` replaced with `pino` to +remove the `mv → rimraf → glob → inflight` chain from the consumer tree (TD-9488). +- **Before:** `logger?: Logger` where `Logger` = default import from `bunyan-category` (not exported). +- **After:** `Logger` is a **structural interface exported from the package** + (`{ trace, debug, info, warn, error, fatal }`, each `(objOrMsg, msg?) => void`), plus + exported `LogFn`. Any bunyan/pino-style logger still satisfies it. +- **Break risk:** only a consumer who imported bunyan's `Logger` type and used + bunyan methods beyond those six. Runtime log output drops the bunyan `category` field. diff --git a/package-lock.json b/package-lock.json index 8339c39..29d1936 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,16 +16,16 @@ "apollo-link": "^1.2.14", "apollo-link-batch-http": "^1.2.13", "apollo-link-retry": "^2.2.13", - "bunyan-category": "^0.4.0", "chalk": "^4.1.2", "cli-progress": "^3.12.0", "commander": "^5.0.0", "graphql": "^14.6.0", "graphql-tag": "^2.10.1", "inquirer": "^8.2.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "node-fetch": "^2.6.7", - "p-all": "^2.1.0" + "p-all": "^2.1.0", + "pino": "^8.21.0" }, "bin": { "j1": "bin/j1" @@ -33,7 +33,6 @@ "devDependencies": { "@pollyjs/adapter-node-http": "^2.7.0", "@pollyjs/core": "^2.6.3", - "@types/bunyan": "^1.8.8", "@types/jest": "^27.4.0", "@types/node": "^13.9.8", "@types/node-fetch": "^3.0.3", @@ -50,6 +49,9 @@ "prettier": "^2.0.2", "ts-jest": "^27.1.3", "typescript": "^3.8.3" + }, + "engines": { + "node": ">=22" } }, "node_modules/@ampproject/remapping": { @@ -606,11 +608,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "4.0.6", "dev": true, @@ -619,17 +616,6 @@ "node": ">= 4" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.3", "dev": true, @@ -662,6 +648,16 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", "dev": true, @@ -670,6 +666,20 @@ "node": ">=6" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", + "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.2", "dev": true, @@ -1076,14 +1086,6 @@ "@babel/types": "^7.3.0" } }, - "node_modules/@types/bunyan": { - "version": "1.8.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "dev": true, @@ -1440,6 +1442,18 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { "version": "8.7.0", "dev": true, @@ -1944,11 +1958,10 @@ } }, "node_modules/argparse": { - "version": "1.0.10", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/array-union": { "version": "2.1.0", @@ -1971,6 +1984,15 @@ "dev": true, "license": "MIT" }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/babel-jest": { "version": "27.4.6", "dev": true, @@ -2060,7 +2082,7 @@ }, "node_modules/balanced-match": { "version": "1.0.0", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -2101,7 +2123,7 @@ }, "node_modules/brace-expansion": { "version": "1.1.11", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2192,32 +2214,6 @@ "dev": true, "license": "MIT" }, - "node_modules/bunyan": { - "version": "1.8.15", - "engines": [ - "node >=0.10.0" - ], - "license": "MIT", - "bin": { - "bunyan": "bin/bunyan" - }, - "optionalDependencies": { - "dtrace-provider": "~0.8", - "moment": "^2.19.3", - "mv": "~2", - "safe-json-stringify": "~1" - } - }, - "node_modules/bunyan-category": { - "version": "0.4.0", - "license": "MIT", - "dependencies": { - "bunyan": "^1.8.15" - }, - "peerDependencies": { - "@types/bunyan": "1.8.6" - } - }, "node_modules/call-bind": { "version": "1.0.2", "dev": true, @@ -2470,7 +2466,7 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/convert-source-map": { @@ -2671,18 +2667,6 @@ "node": ">=6" } }, - "node_modules/dtrace-provider": { - "version": "0.8.8", - "hasInstallScript": true, - "license": "BSD-2-Clause", - "optional": true, - "dependencies": { - "nan": "^2.14.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "dev": true, @@ -2904,11 +2888,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "dev": true, @@ -2932,17 +2911,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/espree": { "version": "9.3.0", "dev": true, @@ -2958,6 +2926,7 @@ }, "node_modules/esprima": { "version": "4.0.1", + "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -3004,6 +2973,24 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/execa": { "version": "5.1.1", "dev": true, @@ -3099,6 +3086,15 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/fastq": { "version": "1.13.0", "dev": true, @@ -3475,7 +3471,23 @@ } }, "node_modules/ieee754": { - "version": "1.1.13", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "BSD-3-Clause" }, "node_modules/ignore": { @@ -3543,7 +3555,7 @@ }, "node_modules/inflight": { "version": "1.0.6", - "devOptional": true, + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -4331,11 +4343,22 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.13.1", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -4807,7 +4830,7 @@ }, "node_modules/minimatch": { "version": "3.1.2", - "devOptional": true, + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -4818,7 +4841,7 @@ }, "node_modules/minimist": { "version": "1.2.8", - "devOptional": true, + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4826,7 +4849,7 @@ }, "node_modules/mkdirp": { "version": "0.5.4", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "minimist": "^1.2.5" @@ -4835,14 +4858,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/moment": { - "version": "2.29.4", - "license": "MIT", - "optional": true, - "engines": { - "node": "*" - } - }, "node_modules/ms": { "version": "2.1.2", "dev": true, @@ -4852,63 +4867,11 @@ "version": "0.0.8", "license": "ISC" }, - "node_modules/mv": { - "version": "2.1.1", - "license": "MIT", - "optional": true, - "dependencies": { - "mkdirp": "~0.5.1", - "ncp": "~2.0.0", - "rimraf": "~2.4.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/mv/node_modules/glob": { - "version": "6.0.4", - "license": "ISC", - "optional": true, - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mv/node_modules/rimraf": { - "version": "2.4.5", - "license": "ISC", - "optional": true, - "dependencies": { - "glob": "^6.0.1" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/nan": { - "version": "2.15.0", - "license": "MIT", - "optional": true - }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, "license": "MIT" }, - "node_modules/ncp": { - "version": "2.0.0", - "license": "MIT", - "optional": true, - "bin": { - "ncp": "bin/ncp" - } - }, "node_modules/nock": { "version": "11.9.1", "dev": true, @@ -4984,9 +4947,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/once": { "version": "1.4.0", - "devOptional": true, + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -5148,7 +5120,7 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5191,6 +5163,84 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pino": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.21.0.tgz", + "integrity": "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.2.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^3.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.7.0", + "thread-stream": "^2.6.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "license": "MIT", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.8.0.tgz", + "integrity": "sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", + "license": "MIT" + }, "node_modules/pirates": { "version": "4.0.5", "dev": true, @@ -5252,6 +5302,21 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", + "license": "MIT" + }, "node_modules/prompts": { "version": "2.0.4", "dev": true, @@ -5323,6 +5388,12 @@ ], "license": "MIT" }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, "node_modules/react-is": { "version": "17.0.2", "dev": true, @@ -5340,6 +5411,15 @@ "node": ">= 6" } }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/regexpp": { "version": "3.2.0", "dev": true, @@ -5495,10 +5575,14 @@ "dev": true, "license": "MIT" }, - "node_modules/safe-json-stringify": { - "version": "1.2.0", + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "license": "MIT", - "optional": true + "engines": { + "node": ">=10" + } }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -5631,6 +5715,15 @@ "node": ">=4.0.0" } }, + "node_modules/sonic-boom": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "dev": true, @@ -5653,8 +5746,20 @@ "dev": true, "license": "MIT" }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/stack-utils": { @@ -5848,6 +5953,15 @@ "dev": true, "license": "MIT" }, + "node_modules/thread-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz", + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/throat": { "version": "6.0.1", "dev": true, @@ -6194,7 +6308,7 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "devOptional": true, + "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { diff --git a/package.json b/package.json index 311159f..28d7758 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,9 @@ "url": "https://github.com/JupiterOne/jupiterone-client-nodejs" }, "license": "MIT", + "engines": { + "node": ">=22" + }, "main": "dist/index.js", "types": "dist/index.d.ts", "author": "JupiterOne ", @@ -46,21 +49,20 @@ "apollo-link": "^1.2.14", "apollo-link-batch-http": "^1.2.13", "apollo-link-retry": "^2.2.13", - "bunyan-category": "^0.4.0", "chalk": "^4.1.2", "cli-progress": "^3.12.0", "commander": "^5.0.0", "graphql": "^14.6.0", "graphql-tag": "^2.10.1", "inquirer": "^8.2.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "node-fetch": "^2.6.7", - "p-all": "^2.1.0" + "p-all": "^2.1.0", + "pino": "^8.21.0" }, "devDependencies": { "@pollyjs/adapter-node-http": "^2.7.0", "@pollyjs/core": "^2.6.3", - "@types/bunyan": "^1.8.8", "@types/jest": "^27.4.0", "@types/node": "^13.9.8", "@types/node-fetch": "^3.0.3", diff --git a/src/index.ts b/src/index.ts index d9e2461..214c1ef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import { retry } from '@lifeomic/attempt'; import gql from 'graphql-tag'; import cliProgress from 'cli-progress'; -import Logger, { createLogger } from 'bunyan-category'; +import pino from 'pino'; import { networkRequest } from './networkRequest'; @@ -172,6 +172,26 @@ export interface QueryResult { properties: object; } +/** + * Minimal structural logger interface. Any bunyan/pino-style logger satisfies it, + * so consumers can continue passing their existing logger. Each method accepts + * either `(msg)` or `(mergeObject, msg)`, matching both bunyan and pino. + */ +export type LogFn = (objOrMsg: unknown, msg?: string) => void; + +export interface Logger { + // Declared as methods (not `trace: LogFn` properties) on purpose: method + // signatures are checked bivariantly, so overloaded bunyan/pino loggers still + // satisfy this interface under `strictFunctionTypes`. Property form would be + // contravariant and reject them. `LogFn` is exported for standalone use. + trace(objOrMsg: unknown, msg?: string): void; + debug(objOrMsg: unknown, msg?: string): void; + info(objOrMsg: unknown, msg?: string): void; + warn(objOrMsg: unknown, msg?: string): void; + error(objOrMsg: unknown, msg?: string): void; + fatal(objOrMsg: unknown, msg?: string): void; +} + export interface JupiterOneClientOptions { account: string; accessToken?: string; @@ -314,7 +334,7 @@ export class JupiterOneClient { this.logger = logger || - createLogger({ + pino({ name: 'jupiterone-client-nodejs', level: 'info', }); diff --git a/src/j1cli.ts b/src/j1cli.ts index 276155c..e74ec07 100644 --- a/src/j1cli.ts +++ b/src/j1cli.ts @@ -204,7 +204,7 @@ function jParse(filePath) { const data = fs.readFileSync(filePath, 'utf8'); const fileExtension = path.extname(filePath); if (fileExtension === '.yml' || fileExtension === '.yaml') { - return yaml.safeLoad(data); + return yaml.load(data); } else { return JSON.parse(data); } diff --git a/src/yaml-parsing.test.ts b/src/yaml-parsing.test.ts new file mode 100644 index 0000000..6754933 --- /dev/null +++ b/src/yaml-parsing.test.ts @@ -0,0 +1,22 @@ +import yaml from 'js-yaml'; + +/** + * Pins the YAML scalar behavior the CLI (`j1cli.ts` -> `jParse`) relies on. + * + * js-yaml 4 moved from the YAML 1.1 schema (js-yaml 3) to the YAML 1.2 core + * schema. That silently changes how some unquoted scalars resolve. These tests + * lock the 1.2 behavior so a future js-yaml change that reverts it is caught. + */ +describe('js-yaml 4 (YAML 1.2 core schema) scalar parsing', () => { + test('leading-zero integers are decimal, not octal (1.1 parsed 0777 as 511)', () => { + expect(yaml.load('0777')).toBe(777); + }); + + test('colon-separated values are strings, not sexagesimal (1.1 parsed 12:30 as 750)', () => { + expect(yaml.load('window: 12:30')).toEqual({ window: '12:30' }); + }); + + test('explicit octal still works via the 0o prefix', () => { + expect(yaml.load('0o777')).toBe(511); + }); +});