From 2670e49c2f2c345b0dd4c6764bb227db7e6b79fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Lenon?= Date: Sat, 23 Sep 2023 11:55:24 +0100 Subject: [PATCH] fix(path): add parseExt() and removeExt() --- package-lock.json | 74 +++++++++++++++++++++--------------------- package.json | 6 ++-- src/helpers/Path.ts | 44 ++++++++++++++++++++++--- tests/unit/PathTest.ts | 24 ++++++++++++++ 4 files changed, 103 insertions(+), 45 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d81063..cc818c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "chalk": "^5.3.0", "change-case": "^4.1.2", "collect.js": "^4.36.1", - "fastify": "^4.22.1", + "fastify": "^4.23.2", "got": "^12.6.1", "http-status-codes": "^2.2.0", "is-wsl": "^2.2.0", @@ -33,7 +33,7 @@ "youch-terminal": "^2.2.2" }, "devDependencies": { - "@athenna/test": "^4.4.0", + "@athenna/test": "^4.7.0", "@types/bytes": "^3.1.1", "@types/callsite": "^1.0.31", "@types/debug": "^4.1.7", @@ -105,16 +105,16 @@ "dev": true }, "node_modules/@athenna/test": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@athenna/test/-/test-4.4.0.tgz", - "integrity": "sha512-cMWz2ws9YbHD0EUGgeQpivaOnQOUQa2vglNPHNPkWNaBJimPm1dpX2tq/af2hYybD2FGmEqND5BP21YSRjBxdw==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@athenna/test/-/test-4.7.0.tgz", + "integrity": "sha512-2g5M9SVY55IIJ/ucznwUPIJIdRJXt5a1r4eR2oLGLR/EEdvCyDEf4oRCjCIfsM5KBq3H0ubHRm5ec7dAISg4HQ==", "dev": true, "dependencies": { "@japa/assert": "^1.4.1", "@japa/run-failed-tests": "^1.1.0", "@japa/runner": "^2.2.2", "@japa/spec-reporter": "^1.3.3", - "@types/sinon": "^10.0.15", + "@types/sinon": "^10.0.16", "sinon": "^15.1.0" } }, @@ -1420,9 +1420,9 @@ "dev": true }, "node_modules/@types/sinon": { - "version": "10.0.15", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.15.tgz", - "integrity": "sha512-3lrFNQG0Kr2LDzvjyjB6AMJk4ge+8iYhQfdnSwIwlG88FUOV43kPcQqDZkDa/h3WSZy6i8Fr0BSjfQtB1B3xuQ==", + "version": "10.0.16", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz", + "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==", "dev": true, "dependencies": { "@types/sinonjs__fake-timers": "*" @@ -4078,9 +4078,9 @@ "integrity": "sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==" }, "node_modules/fastify": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.22.1.tgz", - "integrity": "sha512-Jz4NFqARAjCuxteYio+jQmZ3W+MHJQWJK0rEE66qY818q9GFCFUOZRHm0hwF1VcX/CnmdxcAycjNUHSG54Gn7g==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.23.2.tgz", + "integrity": "sha512-WFSxsHES115svC7NrerNqZwwM0UOxbC/P6toT9LRHgAAFvG7o2AN5W+H4ihCtOGuYXjZf4z+2jXC89rVEoPWOA==", "dependencies": { "@fastify/ajv-compiler": "^3.5.0", "@fastify/error": "^3.2.0", @@ -4097,7 +4097,7 @@ "rfdc": "^1.3.0", "secure-json-parse": "^2.5.0", "semver": "^7.5.0", - "tiny-lru": "^11.0.1" + "toad-cache": "^3.2.0" } }, "node_modules/fastify-plugin": { @@ -8551,14 +8551,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tiny-lru": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.0.1.tgz", - "integrity": "sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==", - "engines": { - "node": ">=12" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -8571,6 +8563,14 @@ "node": ">=8.0" } }, + "node_modules/toad-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.2.0.tgz", + "integrity": "sha512-Hj5zSqBS6OHbZoQk9IU8VqIr+0JUpwzunnwSlFJhG8aJSInYUMEuzItl3kJsGteTPd1qtflafdRHlRtUazYeqg==", + "engines": { + "node": ">=12" + } + }, "node_modules/traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", @@ -9177,16 +9177,16 @@ "dev": true }, "@athenna/test": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@athenna/test/-/test-4.4.0.tgz", - "integrity": "sha512-cMWz2ws9YbHD0EUGgeQpivaOnQOUQa2vglNPHNPkWNaBJimPm1dpX2tq/af2hYybD2FGmEqND5BP21YSRjBxdw==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@athenna/test/-/test-4.7.0.tgz", + "integrity": "sha512-2g5M9SVY55IIJ/ucznwUPIJIdRJXt5a1r4eR2oLGLR/EEdvCyDEf4oRCjCIfsM5KBq3H0ubHRm5ec7dAISg4HQ==", "dev": true, "requires": { "@japa/assert": "^1.4.1", "@japa/run-failed-tests": "^1.1.0", "@japa/runner": "^2.2.2", "@japa/spec-reporter": "^1.3.3", - "@types/sinon": "^10.0.15", + "@types/sinon": "^10.0.16", "sinon": "^15.1.0" } }, @@ -10215,9 +10215,9 @@ "dev": true }, "@types/sinon": { - "version": "10.0.15", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.15.tgz", - "integrity": "sha512-3lrFNQG0Kr2LDzvjyjB6AMJk4ge+8iYhQfdnSwIwlG88FUOV43kPcQqDZkDa/h3WSZy6i8Fr0BSjfQtB1B3xuQ==", + "version": "10.0.16", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz", + "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" @@ -12184,9 +12184,9 @@ "integrity": "sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==" }, "fastify": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.22.1.tgz", - "integrity": "sha512-Jz4NFqARAjCuxteYio+jQmZ3W+MHJQWJK0rEE66qY818q9GFCFUOZRHm0hwF1VcX/CnmdxcAycjNUHSG54Gn7g==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.23.2.tgz", + "integrity": "sha512-WFSxsHES115svC7NrerNqZwwM0UOxbC/P6toT9LRHgAAFvG7o2AN5W+H4ihCtOGuYXjZf4z+2jXC89rVEoPWOA==", "requires": { "@fastify/ajv-compiler": "^3.5.0", "@fastify/error": "^3.2.0", @@ -12203,7 +12203,7 @@ "rfdc": "^1.3.0", "secure-json-parse": "^2.5.0", "semver": "^7.5.0", - "tiny-lru": "^11.0.1" + "toad-cache": "^3.2.0" } }, "fastify-plugin": { @@ -15516,11 +15516,6 @@ "convert-hrtime": "^3.0.0" } }, - "tiny-lru": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.0.1.tgz", - "integrity": "sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==" - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -15530,6 +15525,11 @@ "is-number": "^7.0.0" } }, + "toad-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.2.0.tgz", + "integrity": "sha512-Hj5zSqBS6OHbZoQk9IU8VqIr+0JUpwzunnwSlFJhG8aJSInYUMEuzItl3kJsGteTPd1qtflafdRHlRtUazYeqg==" + }, "traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", diff --git a/package.json b/package.json index 7eb992b..7d1af0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@athenna/common", - "version": "4.13.2", + "version": "4.14.0", "description": "The Athenna common helpers to use in any Node.js ESM project.", "license": "MIT", "author": "João Lenon ", @@ -56,7 +56,7 @@ "chalk": "^5.3.0", "change-case": "^4.1.2", "collect.js": "^4.36.1", - "fastify": "^4.22.1", + "fastify": "^4.23.2", "got": "^12.6.1", "http-status-codes": "^2.2.0", "is-wsl": "^2.2.0", @@ -74,7 +74,7 @@ "youch-terminal": "^2.2.2" }, "devDependencies": { - "@athenna/test": "^4.4.0", + "@athenna/test": "^4.7.0", "@types/bytes": "^3.1.1", "@types/callsite": "^1.0.31", "@types/debug": "^4.1.7", diff --git a/src/helpers/Path.ts b/src/helpers/Path.ts index 8240121..af51212 100644 --- a/src/helpers/Path.ts +++ b/src/helpers/Path.ts @@ -12,7 +12,7 @@ import callSite from 'callsite' import { fileURLToPath } from 'node:url' import { homedir, tmpdir } from 'node:os' import type { PathDirs } from '#src/types' -import { sep, normalize, dirname } from 'node:path' +import { sep, normalize, dirname, parse } from 'node:path' export class Path { public static dirs: PathDirs = { @@ -66,10 +66,7 @@ export class Path { * Return js or ts extension depending on IS_TS. */ public static ext(): string { - const isTs = !!( - process.env.IS_TS && - (process.env.IS_TS === 'true' || process.env.IS_TS === '(true)') - ) + const isTs = !!(process.env.IS_TS && process.env.IS_TS === 'true') if (isTs) { return 'ts' @@ -78,6 +75,43 @@ export class Path { return 'js' } + /** + * Remove the extension from a path. + */ + public static removeExt(path: string): string { + const parsedPath = parse(path) + + if (!parsedPath.dir) { + return parsedPath.name + } + + return parsedPath.dir.concat(sep, parsedPath.name) + } + + /** + * Parse the extension of a path using the `Path.ext()` method. + * If the path ends with .js and `Path.ext()` returns .ts, the + * path will be parsed to end with .ts. The same happens when + * the path ends with .ts and `Path.ext()` returns .js. + */ + public static parseExt(path: string): string { + if (path.endsWith('.d.ts')) { + return path + } + + const { ext } = parse(path) + + if (!ext) { + return path + } + + if (ext === `.${Path.ext()}`) { + return path + } + + return `${Path.removeExt(path)}.${Path.ext()}` + } + /** * Return the pwd path of your project. */ diff --git a/tests/unit/PathTest.ts b/tests/unit/PathTest.ts index bd72c81..2e8d86f 100644 --- a/tests/unit/PathTest.ts +++ b/tests/unit/PathTest.ts @@ -233,4 +233,28 @@ export default class PathTest { assert.isTrue(Path.src().endsWith('src')) assert.isTrue(Path.app().endsWith('app')) } + + @Test() + public shouldBeAbleToRemoveExtensionOfFilePath({ assert }: Context) { + assert.equal(Path.removeExt('file.ts'), 'file') + assert.equal(Path.removeExt('file.js'), 'file') + assert.equal(Path.removeExt('file'), 'file') + assert.equal(Path.removeExt(Path.app('hello.js')), Path.app('hello')) + assert.equal(Path.removeExt(Path.app('hello.java')), Path.app('hello')) + assert.equal(Path.removeExt(Path.app('hello')), Path.app('hello')) + assert.equal(Path.removeExt(Path.app('hello.service.js')), Path.app('hello.service')) + assert.equal(Path.removeExt(Path.app('hello.service.ts')), Path.app('hello.service')) + } + + @Test() + public shouldBeAbleToParseExtensionOfFilePathUsingPathExt({ assert }: Context) { + assert.equal(Path.parseExt('file.ts'), 'file.ts') + assert.equal(Path.parseExt('file.js'), 'file.ts') + assert.equal(Path.parseExt('file'), 'file') + assert.equal(Path.parseExt(Path.app('hello.js')), Path.app('hello.ts')) + assert.equal(Path.parseExt(Path.app('hello.java')), Path.app('hello.ts')) + assert.equal(Path.parseExt(Path.app('hello')), Path.app('hello')) + assert.equal(Path.parseExt(Path.app('hello.service.js')), Path.app('hello.service.ts')) + assert.equal(Path.parseExt(Path.app('hello.service.ts')), Path.app('hello.service.ts')) + } }