From 682ae80bb2f3f859128f388339c89a93723ee2af Mon Sep 17 00:00:00 2001 From: Nathan OGER Date: Mon, 4 May 2026 21:19:40 +0200 Subject: [PATCH 1/2] fix: preserve comment lines with quotes + modernize deps (#1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: preserve comment lines with quotes and modernize dependencies Fix issue #54: emptyObjProps() now checks __COMMENT_ keys before the # logic, preventing comment text from being truncated when it contains single or double quotes. Two regression tests added. Dependency updates (107 → 9 vulnerabilities, all remaining in dev tools): - meow 5 → 8.1.2 (last CJS release; update flags API with explicit aliases) - TypeScript 3.9 → 5.4 - mocha 6 → 10, ts-node 8 → 10, nyc 14 → 15 - sinon 7 → 17, chai 4.2 → 4.4, nodemon 1 → 3, rimraf 2 → 5 - eslint 5 → 8 with @typescript-eslint plugin; remove babel-eslint - Remove parcel-plugin-shebang (dragged in parcel-bundler v1 CVEs) - Remove coveralls and np (both depend on abandoned request library) - Replace test/mocha.opts with .mocharc.yml (mocha 10 dropped .opts) - Update tsconfig target to ES2020 * chore: remove parcel targets config and ignore parcel cache * chore: ignore compiled TypeScript output in lib/ --- .eslintrc | 17 +++++++++-- .gitignore | 7 +++++ .mocharc.yml | 5 ++++ lib/index.ts | 18 ++++++------ lib/lib.ts | 11 ++++---- package.json | 73 ++++++++++++++++++++---------------------------- test/lib.spec.ts | 18 +++++++++++- test/mocha.opts | 4 --- tsconfig.json | 6 ++-- 9 files changed, 93 insertions(+), 66 deletions(-) create mode 100644 .mocharc.yml delete mode 100644 test/mocha.opts diff --git a/.eslintrc b/.eslintrc index 6989eda..2432ca0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,12 +1,19 @@ { - "extends": ["wesbos"], "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], + "plugins": ["@typescript-eslint", "import", "prettier"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/recommended", + "plugin:import/typescript", + "prettier" + ], "parserOptions": { "project": "./tsconfig.json" }, "rules": { - "no-console": "error" + "no-console": "error", + "prettier/prettier": "error" }, "settings": { "import/resolver": { @@ -14,5 +21,9 @@ "extensions": [".js", ".ts"] } } + }, + "env": { + "node": true, + "es2020": true } } diff --git a/.gitignore b/.gitignore index c9d1bbd..3f246f8 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,10 @@ typings/ dist **/.rts* sample.js + +# Parcel cache +.parcel-cache + +# Compiled TypeScript output in source directory +lib/**/*.js +lib/**/*.d.ts diff --git a/.mocharc.yml b/.mocharc.yml new file mode 100644 index 0000000..565ca36 --- /dev/null +++ b/.mocharc.yml @@ -0,0 +1,5 @@ +spec: test/**/*.spec.ts +watch-files: + - test/**/*.spec.ts +require: ts-node/register +exit: true diff --git a/lib/index.ts b/lib/index.ts index 052f332..4f84f97 100755 --- a/lib/index.ts +++ b/lib/index.ts @@ -9,34 +9,34 @@ const cli = meow( Usage: sync-dotenv [options] Options: - + -e, --env file .......... .env file location -s, --sample file ....... alternate sample env file to sync with -S, --samples "file.*" ........ alternate sample env files pattern to sync with - Note: If options is omitted, sync-dotenv will attempt to sync .env + Note: If options is omitted, sync-dotenv will attempt to sync .env with .env.example in the current working directory. Examples: - - $ sync-dotenv + + $ sync-dotenv $ sync-dotenv --sample .env.development $ sync-dotenv --env server/.env --sample example.env $ sync-dotenv --samples ".env.*" `, { flags: { - sample: { - type: "string" - } + sample: { type: "string", alias: "s" }, + env: { type: "string", alias: "e" }, + samples: { type: "string", alias: "S" }, } } ); -const { sample, s, env, e, samples, S } = cli.flags; +const { sample, env, samples } = cli.flags; -syncEnv(sample || s, env || e, samples || S) +syncEnv(sample, env, samples) .then(sampleEnv => cp.exec(`git add ${sampleEnv}`)) .catch(({ message, code }) => { console.log(message); diff --git a/lib/lib.ts b/lib/lib.ts index f9aa5bc..faf7d2f 100644 --- a/lib/lib.ts +++ b/lib/lib.ts @@ -32,13 +32,17 @@ export const writeToSampleEnv = (path: string, parsedEnv: object) => { try { fs.writeFileSync(path, envToString(parsedEnv)); } catch (e) { - throw new Error(`Sync failed. ${e.message}`); + throw new Error(`Sync failed. ${(e as Error).message}`); } }; export const emptyObjProps = (obj: EnvObject) => { const objCopy = { ...obj }; Object.keys(objCopy).forEach(key => { + if (key.startsWith("__COMMENT_")) { + return; + } + if (objCopy[key].includes("#")) { if (objCopy[key].match(/(".*"|'.*')/g)) { const objArr = objCopy[key].split(/(".*"|'.*')/); @@ -51,10 +55,7 @@ export const emptyObjProps = (obj: EnvObject) => { return; } - /* istanbul ignore else */ - if (!key.startsWith("__COMMENT_")) { - objCopy[key] = ""; - } + objCopy[key] = ""; }); return objCopy; diff --git a/package.json b/package.json index a7d0080..071546d 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,13 @@ "LICENSE.md", "README.md" ], - "homepage": "https://github.com/codeshifu/sync-dotenv#readme", + "homepage": "https://github.com/Miniluchi/sync-dotenv#readme", "bugs": { - "url": "https://github.com/codeshifu/sync-dotenv/issues" + "url": "https://github.com/Miniluchi/sync-dotenv/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/codeshifu/sync-dotenv.git" + "url": "git+https://github.com/Miniluchi/sync-dotenv.git" }, "license": "MIT", "author": "Luqman Olushi (https://codeshifu.github.io/)", @@ -42,56 +42,45 @@ "build": "npm-run-all clean start", "bundle": "npm-run-all clean parcel", "clean": "rimraf dist", - "coverage": "nyc report --reporter=text-lcov | coveralls", + "coverage": "nyc report --reporter=text-lcov", "parcel": "parcel build", - "release": "npm run bundle && np", + "release": "npm run bundle && npm publish", "start": "node dist/index.js", "start:dev": "nodemon --watch lib -e ts --exec npm run build", "test": "nyc --reporter=html --reporter=text mocha", "test:watch": "nodemon --watch test -e .ts --exec npm test" }, "devDependencies": { - "@parcel/packager-ts": "2.3.2", - "@parcel/transformer-typescript-types": "2.3.2", - "@types/chai": "4.1.7", - "@types/execa": "0.9.0", - "@types/globby": "9.1.0", - "@types/meow": "5.0.0", - "@types/mocha": "5.2.6", - "@types/sinon": "7.0.11", - "@types/sinon-chai": "3.2.2", - "all-contributors-cli": "6.2.0", - "babel-eslint": "9.0.0", - "chai": "4.2.0", - "coveralls": "3.0.3", - "dotenv": "7.0.0", - "eslint": "5.16.0", - "eslint-config-airbnb": "17.1.0", - "eslint-config-prettier": "4.1.0", - "eslint-config-wesbos": "0.0.19", - "eslint-plugin-html": "5.0.3", - "eslint-plugin-import": "2.16.0", - "eslint-plugin-jsx-a11y": "6.2.1", - "eslint-plugin-prettier": "3.0.1", - "eslint-plugin-react": "7.12.4", - "eslint-plugin-react-hooks": "1.6.0", - "mocha": "6.1.4", - "nodemon": "1.18.11", - "np": "3.1.0", + "@parcel/packager-ts": "^2.12.0", + "@parcel/transformer-typescript-types": "^2.12.0", + "@types/chai": "^4.3.14", + "@types/mocha": "^10.0.6", + "@types/sinon": "^17.0.3", + "@types/sinon-chai": "^3.2.12", + "all-contributors-cli": "^6.26.1", + "chai": "^4.4.1", + "dotenv": "^16.4.5", + "@typescript-eslint/eslint-plugin": "^7.9.0", + "@typescript-eslint/parser": "^7.9.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.1.3", + "mocha": "^10.4.0", + "nodemon": "^3.1.7", "npm-run-all": "4.1.5", - "nyc": "14.1.1", - "parcel": "^2.3.2", - "parcel-plugin-shebang": "^1.2.8", - "prettier": "1.16.4", - "rimraf": "2.6.3", - "sinon": "7.3.1", - "sinon-chai": "3.3.0", - "ts-node": "^8.10.2", - "typescript": "^3.9.7" + "nyc": "^15.1.0", + "parcel": "^2.12.0", + "prettier": "^3.3.0", + "rimraf": "^5.0.5", + "sinon": "^17.0.1", + "sinon-chai": "^3.7.0", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" }, "dependencies": { "globby": "^11.1.0", - "meow": "5.0.0", + "meow": "^8.1.2", "parse-dotenv": "2.1.0", "pkg-conf": "^3.1.0" }, diff --git a/test/lib.spec.ts b/test/lib.spec.ts index dadbe0d..69c50e1 100644 --- a/test/lib.spec.ts +++ b/test/lib.spec.ts @@ -92,7 +92,7 @@ describe("sync-dotenv lib", () => { try { lib.writeToSampleEnv(SAMPLE_ENV_PATH, parseEnv(ENV_PATH)); } catch (error) { - expect(error.message).contains(message); + expect((error as Error).message).contains(message); } }); }); @@ -102,6 +102,22 @@ describe("sync-dotenv lib", () => { const obj = { foo: "bar" }; expect(lib.emptyObjProps(obj)).to.have.deep.property("foo", ""); }); + + it("preserves comment lines with single quotes intact (bug #54)", () => { + const obj = { "__COMMENT_0__": "# don't use 'production' here" }; + expect(lib.emptyObjProps(obj)).to.have.deep.property( + "__COMMENT_0__", + "# don't use 'production' here" + ); + }); + + it("preserves comment lines with double quotes intact (bug #54)", () => { + const obj = { "__COMMENT_0__": `# use "staging" not "production"` }; + expect(lib.emptyObjProps(obj)).to.have.deep.property( + "__COMMENT_0__", + `# use "staging" not "production"` + ); + }); }); describe("getUniqueVarsFromEnv()", () => { diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index bb6081a..0000000 --- a/test/mocha.opts +++ /dev/null @@ -1,4 +0,0 @@ -test/**/*.spec.ts ---watch-extensions ts ---require ts-node/register ---exit diff --git a/tsconfig.json b/tsconfig.json index 4c79cf2..7102be2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,12 @@ { "compilerOptions": { - "target": "es6", + "target": "es2020", + "lib": ["es2020"], "declaration": true, "strict": true, "esModuleInterop": true, - "moduleResolution": "node" + "moduleResolution": "node", + "skipLibCheck": true }, "include": ["lib/**/*.ts"] } From 4645073828777b768f8fbe12b5d7a6e1980d9445 Mon Sep 17 00:00:00 2001 From: Nathan OGER Date: Mon, 4 May 2026 22:11:28 +0200 Subject: [PATCH 2/2] fix: restore original author --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 071546d..7a3ea5e 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,13 @@ "LICENSE.md", "README.md" ], - "homepage": "https://github.com/Miniluchi/sync-dotenv#readme", + "homepage": "https://github.com/codeshifu/sync-dotenv#readme", "bugs": { - "url": "https://github.com/Miniluchi/sync-dotenv/issues" + "url": "https://github.com/codeshifu/sync-dotenv/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/Miniluchi/sync-dotenv.git" + "url": "git+https://github.com/codeshifu/sync-dotenv.git" }, "license": "MIT", "author": "Luqman Olushi (https://codeshifu.github.io/)",