1
0
mirror of https://github.com/kremalicious/astro-redirect-from.git synced 2024-11-21 09:27:03 +01:00

migrate to biome (#149)

* migrate to biome

* add lint job on CI

* bump vitest packages
This commit is contained in:
Matthias Kretschmann 2024-07-26 14:13:02 +01:00 committed by GitHub
parent 177c2335d1
commit 1e1fb12647
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 815 additions and 2367 deletions

View File

@ -1,12 +0,0 @@
{
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "prettier"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}

View File

@ -11,6 +11,22 @@ on:
- '**' - '**'
jobs: jobs:
lint:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node: ['20']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- run: npm ci
- run: npm run lint
test: test:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
@ -19,8 +35,8 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
node: ['18', '20'] node: ['18', '20']
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: ${{ matrix.node }} node-version: ${{ matrix.node }}
cache: 'npm' cache: 'npm'
@ -40,8 +56,8 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
node: ['18', '20'] node: ['18', '20']
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: ${{ matrix.node }} node-version: ${{ matrix.node }}
cache: 'npm' cache: 'npm'
@ -53,7 +69,7 @@ jobs:
needs: [test] needs: [test]
if: ${{ success() && github.actor != 'dependabot[bot]' }} if: ${{ success() && github.actor != 'dependabot[bot]' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v3
with: with:
name: coverage-ubuntu-latest-18 name: coverage-ubuntu-latest-18
@ -62,12 +78,12 @@ jobs:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
publish: publish:
needs: [test, build] needs: [lint, test, build]
if: success() && startsWith(github.ref, 'refs/tags') if: success() && startsWith(github.ref, 'refs/tags')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'

View File

@ -1,7 +0,0 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "none",
"tabWidth": 2,
"endOfLine": "lf"
}

3
biome.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": ["@kremalicious/config/biome"]
}

3044
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,37 +13,31 @@
"start": "rm -rf ./dist && tsc --watch", "start": "rm -rf ./dist && tsc --watch",
"test": "npm run validate && npm run test:unit", "test": "npm run validate && npm run test:unit",
"test:unit": "vitest run --coverage --config ./test/vitest.config.ts", "test:unit": "vitest run --coverage --config ./test/vitest.config.ts",
"lint": "eslint --ignore-path .gitignore ./{src,test}/**/*.ts", "lint": "biome check --write .",
"typecheck": "tsc --noEmit --pretty", "typecheck": "tsc --noEmit --pretty",
"format": "prettier --write './src/**/*.{ts,js,json,md}'",
"changelog": "auto-changelog -p", "changelog": "auto-changelog -p",
"release": "release-it --non-interactive", "release": "release-it --non-interactive",
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
"prepare": "husky", "prepare": "husky",
"validate": "run-p --silent typecheck lint" "validate": "run-p --silent typecheck lint"
}, },
"files": [ "files": ["./dist"],
"./dist"
],
"devDependencies": { "devDependencies": {
"@types/node": "^20.14.2", "@biomejs/biome": "^1.8.3",
"@typescript-eslint/eslint-plugin": "^7.12.0", "@kremalicious/config": "^1.0.2",
"@vitest/coverage-v8": "^1.6.0", "@types/node": "^20.14.12",
"@vitest/coverage-v8": "^2.0.4",
"auto-changelog": "^2.4.0", "auto-changelog": "^2.4.0",
"eslint": "^8.57.0", "husky": "^9.1.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"husky": "^9.0.11",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^3.3.1", "release-it": "^17.6.0",
"release-it": "^17.3.0", "typescript": "^5.5.4",
"typescript": "^5.4.5", "vite": "^5.3.5",
"vite": "^5.2.13", "vitest": "^2.0.4"
"vitest": "^1.6.0"
}, },
"dependencies": { "dependencies": {
"astro": ">= 3", "astro": ">= 3",
"globby": "^14.0.1", "globby": "^14.0.2",
"gray-matter": "^4.0.3" "gray-matter": "^4.0.3"
}, },
"engines": { "engines": {
@ -92,13 +86,8 @@
} }
], ],
"lint-staged": { "lint-staged": {
"*.ts": [ "*": [
"tsc --noEmit --pretty", "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
"prettier --write",
"eslint"
],
"**/*.json": [
"prettier --write"
] ]
} }
} }

View File

@ -6,11 +6,11 @@ export function createRedirect(
redirectFrom: string[], redirectFrom: string[],
postSlug: string postSlug: string
) { ) {
postSlug = prependForwardSlash(postSlug) const newPostSlug = prependForwardSlash(postSlug)
for (let slug of redirectFrom) { for (let slug of redirectFrom) {
slug = prependForwardSlash(slug) slug = prependForwardSlash(slug)
redirects[slug] = postSlug redirects[slug] = newPostSlug
} }
return redirects return redirects

View File

@ -1,7 +1,7 @@
import path from 'node:path' import path from 'node:path'
import type { Redirects } from '.' import type { Redirects } from '.'
import { getMarkdownFrontmatter } from './utils.js'
import { createRedirect } from './createRedirect.js' import { createRedirect } from './createRedirect.js'
import { getMarkdownFrontmatter } from './utils.js'
export async function getRedirects( export async function getRedirects(
files: string[], files: string[],

View File

@ -1,7 +1,7 @@
import path from 'node:path' import path from 'node:path'
import type { AstroIntegration } from 'astro' import type { AstroIntegration } from 'astro'
import { getMarkdownFiles, getSlugFromFilePath, writeJson } from './utils.js'
import { getRedirects } from './getRedirects.js' import { getRedirects } from './getRedirects.js'
import { getMarkdownFiles, getSlugFromFilePath, writeJson } from './utils.js'
export type GetSlug = (filePath: string) => string export type GetSlug = (filePath: string) => string
@ -11,7 +11,7 @@ export type PluginOptions = {
} }
export type HookOptions = Parameters< export type HookOptions = Parameters<
AstroIntegration['hooks']['astro:config:setup'] & { 0: any } AstroIntegration['hooks']['astro:config:setup'] & { 0: number }
>[0] >[0]
export type Redirects = { [old: string]: string } export type Redirects = { [old: string]: string }
@ -54,7 +54,7 @@ export async function initPlugin(
logger.info( logger.info(
`Added ${Object.keys(redirects).length} redirects to Astro config` `Added ${Object.keys(redirects).length} redirects to Astro config`
) )
} catch (error: any) { } catch (error: unknown) {
logger.error((error as Error).message) logger.error((error as Error).message)
} }
} }

View File

@ -1,5 +1,5 @@
import path from 'node:path'
import { promises as fs, type PathLike } from 'node:fs' import { promises as fs, type PathLike } from 'node:fs'
import path from 'node:path'
import { globby } from 'globby' import { globby } from 'globby'
import matter from 'gray-matter' import matter from 'gray-matter'
@ -19,7 +19,7 @@ export async function getMarkdownFrontmatter(filePath: string) {
export function getSlugFromFilePath(filePath: string) { export function getSlugFromFilePath(filePath: string) {
const parsedPath = path.parse(filePath) const parsedPath = path.parse(filePath)
let slug let slug: string
// construct slug as full path from either: // construct slug as full path from either:
// - folder name if file name is index.md, or // - folder name if file name is index.md, or
@ -40,5 +40,5 @@ export async function writeJson<T>(path: PathLike, data: T) {
} }
export function prependForwardSlash(str: string) { export function prependForwardSlash(str: string) {
return str.startsWith('/') ? str : '/' + str return str.startsWith('/') ? str : `/${str}`
} }

View File

@ -1,7 +1,7 @@
import { describe, it, expect, vi } from 'vitest' import { describe, expect, it, vi } from 'vitest'
import astroRedirectFrom, { initPlugin } from '../src/index'
import * as utils from '../src/utils'
import * as redirects from '../src/getRedirects' import * as redirects from '../src/getRedirects'
import astroRedirectFrom, { type HookOptions, initPlugin } from '../src/index'
import * as utils from '../src/utils'
const mockLogger = { const mockLogger = {
warn: vi.fn(), warn: vi.fn(),
@ -16,14 +16,14 @@ const hookOptionsMock = {
}, },
command: 'dev', command: 'dev',
updateConfig: vi.fn() updateConfig: vi.fn()
} } as unknown as HookOptions
describe('initPlugin', () => { describe('initPlugin', () => {
it('should handle no markdown files scenario', async () => { it('should handle no markdown files scenario', async () => {
const getMarkdownFilesSpy = vi.spyOn(utils, 'getMarkdownFiles') const getMarkdownFilesSpy = vi.spyOn(utils, 'getMarkdownFiles')
getMarkdownFilesSpy.mockResolvedValue([]) getMarkdownFilesSpy.mockResolvedValue([])
await initPlugin(hookOptionsMock as any) await initPlugin(hookOptionsMock)
expect(mockLogger.warn).toBeCalledWith('No markdown files found') expect(mockLogger.warn).toBeCalledWith('No markdown files found')
expect(hookOptionsMock.updateConfig).not.toBeCalled() expect(hookOptionsMock.updateConfig).not.toBeCalled()
@ -36,7 +36,7 @@ describe('initPlugin', () => {
const getRedirectsSpy = vi.spyOn(redirects, 'getRedirects') const getRedirectsSpy = vi.spyOn(redirects, 'getRedirects')
getRedirectsSpy.mockResolvedValue({}) getRedirectsSpy.mockResolvedValue({})
await initPlugin(hookOptionsMock as any) await initPlugin(hookOptionsMock)
expect(mockLogger.warn).toBeCalledWith( expect(mockLogger.warn).toBeCalledWith(
'No redirects found in markdown files' 'No redirects found in markdown files'
@ -54,7 +54,7 @@ describe('initPlugin', () => {
const writeJsonSpy = vi.spyOn(utils, 'writeJson') const writeJsonSpy = vi.spyOn(utils, 'writeJson')
writeJsonSpy.mockImplementation(() => Promise.resolve()) writeJsonSpy.mockImplementation(() => Promise.resolve())
await initPlugin(hookOptionsMock as any) await initPlugin(hookOptionsMock)
expect(hookOptionsMock.updateConfig).toBeCalledWith({ expect(hookOptionsMock.updateConfig).toBeCalledWith({
redirects: { '/old': '/new' } redirects: { '/old': '/new' }
@ -71,7 +71,10 @@ describe('initPlugin', () => {
throw new Error('Mocked error') throw new Error('Mocked error')
}) })
await initPlugin({ ...hookOptionsMock, logger: mockLogger } as any) await initPlugin({
...hookOptionsMock,
logger: mockLogger as unknown as HookOptions['logger']
})
expect(mockLogger.error).toHaveBeenCalledWith('Mocked error') expect(mockLogger.error).toHaveBeenCalledWith('Mocked error')
}) })
@ -102,7 +105,7 @@ describe('astroRedirectFrom', () => {
// Invoke the hook // Invoke the hook
if (integration.hooks['astro:config:setup']) { if (integration.hooks['astro:config:setup']) {
await integration.hooks['astro:config:setup'](hookOptionsMock as any) await integration.hooks['astro:config:setup'](hookOptionsMock)
} }
}) })
}) })

View File

@ -1,7 +1,7 @@
import { expect, it, describe } from 'vitest' import { describe, expect, it } from 'vitest'
import { createRedirect } from '../src/createRedirect'
import { getRedirects } from '../src/getRedirects' import { getRedirects } from '../src/getRedirects'
import { getMarkdownFiles, getSlugFromFilePath } from '../src/utils' import { getMarkdownFiles, getSlugFromFilePath } from '../src/utils'
import { createRedirect } from '../src/createRedirect'
describe('getRedirects', async () => { describe('getRedirects', async () => {
// handling this more as an integration test // handling this more as an integration test

View File

@ -1,5 +1,5 @@
import { expect, describe, it, afterAll } from 'vitest'
import { promises as fs } from 'node:fs' import { promises as fs } from 'node:fs'
import { afterAll, describe, expect, it } from 'vitest'
import { import {
getMarkdownFiles, getMarkdownFiles,
getMarkdownFrontmatter, getMarkdownFrontmatter,