Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add normalizeAliases and filename in /utils subpath #34

Merged
merged 15 commits into from Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Expand Up @@ -21,5 +21,6 @@ jobs:
- run: pnpm install
- run: pnpm lint
- run: pnpm build
- run: pnpm test:types
- run: pnpm vitest --coverage
- uses: codecov/codecov-action@v3
7 changes: 6 additions & 1 deletion package.json
Expand Up @@ -9,6 +9,10 @@
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./utils": {
"import": "./dist/utils.mjs",
"require": "./dist/utils.cjs"
}
},
"main": "./dist/index.cjs",
Expand All @@ -22,7 +26,8 @@
"lint": "eslint --ext .ts .",
"prepublishOnly": "pnpm build",
"release": "pnpm vitest run && standard-version && git push --follow-tags && pnpm publish",
"test": "pnpm lint && vitest run --coverage"
"test": "pnpm lint && vitest run --coverage",
"test:types": "tsc --noEmit"
},
"devDependencies": {
"@nuxtjs/eslint-config-typescript": "latest",
Expand Down
7 changes: 7 additions & 0 deletions src/_internal.ts
@@ -0,0 +1,7 @@
// Util to normalize windows paths to posix
export function normalizeWindowsPath (input: string = '') {
if (!input || !input.includes('\\')) {
return input
}
return input.replace(/\\/g, '/')
}
2 changes: 1 addition & 1 deletion src/path.ts
Expand Up @@ -8,7 +8,7 @@ Check LICENSE file

import type path from 'path'

import { normalizeWindowsPath } from './utils'
import { normalizeWindowsPath } from './_internal'

const _UNC_REGEX = /^[\\/]{2}/
const _IS_ABSOLUTE_RE = /^[\\/](?![\\/])|^[\\/]{2}(?!\.)|^[a-zA-Z]:[\\/]/
Expand Down
33 changes: 28 additions & 5 deletions src/utils.ts
@@ -1,7 +1,30 @@
// Util to normalize windows paths to posix
export function normalizeWindowsPath (input: string = '') {
if (!input || !input.includes('\\')) {
return input
const pathSeparators = ['/', '\\', undefined]

export function normalizeAliases (_aliases: Record<string, string>) {
// Sort aliases from specific to general (ie. fs/promises before fs)
const aliases = Object.fromEntries(Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b)))
// Resolve alias values in relation to each other
for (const key in aliases) {
for (const alias in aliases) {
// don't resolve a more specific alias with regard to a less specific one
if (alias === key || key.startsWith(alias)) { continue }

if (aliases[key].startsWith(alias) && pathSeparators.includes(aliases[key][alias.length])) {
aliases[key] = aliases[alias] + aliases[key].slice(alias.length)
}
}
}
return input.replace(/\\/g, '/')
return aliases
}

const FILENAME_RE = /(?<=^|[\\/])([^\\/]+?)(?=(\.[^.]+)?$)/

export function filename (path: string) {
return path.match(FILENAME_RE)?.[0]
}

// --- internals ---

function _compareAliases (a: string, b: string) {
return b.split('/').length - a.split('/').length
}
2 changes: 1 addition & 1 deletion test/index.spec.ts
Expand Up @@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest'

import { basename, dirname, extname, format, parse, relative, delimiter, isAbsolute, join, normalize, resolve, sep, toNamespacedPath, normalizeString } from '../src'

import { normalizeWindowsPath } from '../src/utils'
import { normalizeWindowsPath } from '../src/_internal'

runTest('normalizeWindowsPath', normalizeWindowsPath, {
// POSIX
Expand Down
43 changes: 43 additions & 0 deletions test/utils.spec.ts
@@ -0,0 +1,43 @@
import { describe, expect, it } from 'vitest'

import { normalizeAliases, filename } from '../src/utils'

describe('normalizeAliases', () => {
it('should work', () => {
expect(normalizeAliases({
'@foo/bar': '@foo/bar/dist/index.mjs',
'@foo/bar/utils': '@foo/bar/dist/utils.mjs',
'@': '/root',
bingpot: '@/bingpot/index.ts',
unchanged: '@bingpot/index.ts'
})).toMatchInlineSnapshot(`
{
"@": "/root",
"@foo/bar": "@foo/bar/dist/index.mjs",
"@foo/bar/utils": "@foo/bar/dist/utils.mjs",
"bingpot": "/root/bingpot/index.ts",
"unchanged": "@bingpot/index.ts",
}
`)
})
})

describe('filename', () => {
const files = {
// POSIX
'test.html': 'test',
'/temp/myfile.html': 'myfile',
'./myfile.html': 'myfile',

// Windows
'C:\\temp\\': undefined,
'C:\\temp\\myfile.html': 'myfile',
'\\temp\\myfile.html': 'myfile',
'.\\myfile.html': 'myfile'
}
for (const file in files) {
it(file, () => {
expect(filename(file)).toEqual(files[file])
})
}
})
4 changes: 3 additions & 1 deletion tsconfig.json
Expand Up @@ -3,9 +3,11 @@
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"skipLibCheck": true,
"esModuleInterop": true
},
"include": [
"src"
"src",
"test"
]
}