Skip to content

Commit

Permalink
feat(extension): rudimentary extends implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
tobua committed Apr 19, 2024
1 parent 97b0020 commit 2d5c0d0
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 25 deletions.
3 changes: 2 additions & 1 deletion configuration/biome.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const templates = {
recommended: {
$schema: 'https://biomejs.dev/schemas/1.6.4/schema.json',
$schema: 'node_modules/@biomejs/biome/configuration_schema.json',
organizeImports: {
enabled: true,
},
Expand All @@ -10,6 +10,7 @@ export const templates = {
all: true,
style: {
useBlockStatements: 'off',
noNamespaceImport: 'off',
},
},
},
Expand Down
4 changes: 3 additions & 1 deletion configuration/eslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export const templates = {
},
}

export const extension = (path: string) => ({ extends: path })

export function createFile(configuration: object) {
return { name: 'eslint.config.js', contents: `export default [${configuration}]` }
return { name: 'eslint.config.js', contents: `export default [${JSON.stringify(configuration, null, 2)}]` }
}
2 changes: 2 additions & 0 deletions configuration/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const templates = {
},
}

export const extension = (path: string) => ({ extends: path })

export function createFile(configuration: object) {
return { name: 'tsconfig.json', contents: JSON.stringify(configuration, null, 2) }
}
24 changes: 5 additions & 19 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as playwright from './configuration/playwright'
import * as prettier from './configuration/prettier'
import * as typescript from './configuration/typescript'
import * as vscode from './configuration/vscode'
import { parse } from './parse'
import type { Configuration } from './types'

const log = create('zero-configuration', 'blue')
Expand Down Expand Up @@ -60,25 +61,10 @@ const userConfiguration = packageJson.configuration ?? moduleContents
for (const { name, alias, configuration } of configurations) {
const value = userConfiguration[name] ?? (alias && userConfiguration[alias])
if (!value) continue

if (typeof value === 'string' && Object.hasOwn(configuration.templates, value)) {
const configurationTemplate = configuration.templates[value as keyof typeof configuration.templates]
const file = configuration.createFile(configurationTemplate)
await Bun.write(file.name, file.contents)
ignores.push(file.name)
}

if (typeof value === 'object') {
const file = configuration.createFile(value)
await Bun.write(file.name, file.contents)
ignores.push(file.name)
}

if (value === true) {
const file = configuration.createFile()
await Bun.write(file.name, file.contents)
ignores.push(file.name)
}
const file = await parse(value, configuration)
if (!file) continue
await Bun.write(file.name, file.contents)
ignores.push(file.name)
}

if (ignores.length === 0) {
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
"logua": "^3.0.3"
},
"devDependencies": {
"@biomejs/biome": "^1.6.4",
"@types/bun": "^1.0.12",
"@biomejs/biome": "^1.7.0",
"@types/bun": "^1.1.0",
"eslint-config-airbnb": "^19.0.4",
"typescript": "^5.4.5"
},
"peerDependencies": {
Expand Down
35 changes: 35 additions & 0 deletions parse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { existsSync } from 'node:fs'
import { join } from 'node:path'
import { it } from 'avait'
import type { Configuration } from './types'

const isExtension = async (value: string) => {
// NOTE dynamic import in tests will resolve relative to project node_modules and not fixture.
const { error } = await it(import(value))
if (!error) return true
const paths = [value, join(process.cwd(), value), join(process.cwd(), 'node_modules', value)]
const fileExists = paths.some(existsSync)
if (fileExists) return true
return false
}

export async function parse(value: string | object | boolean, configuration: Configuration['configuration']) {
// Template.
if (typeof value === 'string' && Object.hasOwn(configuration.templates, value)) {
const configurationTemplate = configuration.templates[value as keyof typeof configuration.templates]
return configuration.createFile(configurationTemplate)
}

// File extension.
if (typeof value === 'string' && (await isExtension(value)) && typeof configuration.extension === 'function') {
return configuration.createFile(configuration.extension(value))
}

if (typeof value === 'object') {
return configuration.createFile(value)
}

if (value === true) {
return configuration.createFile()
}
}
12 changes: 12 additions & 0 deletions test/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,15 @@ test('Adds configuration files for basic file setup.', () => {

expect(existsSync(join(fixturePath, 'prettier.config.js'))).toBe(true)
})

test('Extends existing configurations.', () => {
const fixturePath = './test/fixture/extends'

execSync('bun ./../../../index.ts', {
cwd: fixturePath,
stdio: 'inherit',
})

expect(existsSync(join(fixturePath, 'eslint.config.js'))).toBe(true)
expect(existsSync(join(fixturePath, 'tsconfig.json'))).toBe(true)
})
7 changes: 7 additions & 0 deletions test/fixture/extends/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "extends",
"configuration": {
"eslint": "eslint-config-airbnb",
"typescript": "my-shared-tsconfig/tsconfig.json"
}
}
3 changes: 1 addition & 2 deletions test/fixture/file/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { devices } from '@playwright/test'
// NOTE imports will fail in fixture.

export const prettier = 'recommended'

Expand All @@ -8,7 +8,6 @@ export const playwright = {
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
webServer: {
Expand Down
1 change: 1 addition & 0 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export type Configuration = {
templates: Template
// biome-ignore lint/suspicious/noExplicitAny: Will be specified in file explicitly.
createFile: (value?: any) => { name: string; contents: string }
extension?: (path: string) => object
}
}

0 comments on commit 2d5c0d0

Please sign in to comment.