Skip to content

Commit

Permalink
feat: pass module id of package directory or manifest
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <[email protected]>
  • Loading branch information
unicornware committed Feb 21, 2023
1 parent c4517bb commit a710037
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 100 deletions.
8 changes: 4 additions & 4 deletions .markdownlint.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,17 @@
},
"MD045": true,
"MD046": {
"style": "consistent"
"style": "fenced"
},
"MD047": true,
"MD048": {
"style": "consistent"
"style": "backtick"
},
"MD049": {
"style": "consistent"
"style": "asterisk"
},
"MD050": {
"style": "consistent"
"style": "asterisk"
},
"default": true,
"extends": null
Expand Down
42 changes: 34 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Toggle [`type`][1] fields in `package.json` files
- [When should I use this?](#when-should-i-use-this)
- [Install](#install)
- [Use](#use)
- [API](#api)
- [`toggle([command][, id])`](#togglecommand-id)
- [Types](#types)
- [Type Definitions](#type-definitions)
- [Contribute](#contribute)
Expand All @@ -26,8 +28,9 @@ This package lets you toggle [`type`][1] fields in `package.json` files.

## When should I use this?

`toggle-pkg-type` was created as a workaround for [`evanw/esbuild#2026`][2]. Use this package when you use `default`
exports and also [ship code in ES module and CommonJS format][3].
`toggle-pkg-type` was created as a workaround for [`evanw/esbuild#2026`][2].

Use this package when you use `default` exports and also [ship code in ES module and CommonJS format][3].

The original issue was closed as "working as intended", but the solution provided is not suitable for all users:

Expand Down Expand Up @@ -65,11 +68,13 @@ yarn add -D @flex-development/toggle-pkg-type@flex-development/toggle-pkg-type
$ toggle-pkg-type [off|on] [options]

Options
-i, --id Module id of package directory or manifest (default process.env.npm_package_json)
-v, --version Displays current version
-h, --help Displays this message

Examples
$ toggle-pkg-type
$ toggle-pkg-type --id /path/to/manifest
$ toggle-pkg-type off
$ toggle-pkg-type on
```
Expand All @@ -78,15 +83,36 @@ yarn add -D @flex-development/toggle-pkg-type@flex-development/toggle-pkg-type

This package exports no identifiers. The default export is `toggle`.

### `toggle(command?: Command)`
### `toggle([command][, id])`

Enable or disable the [`type`][1] field in a `package.json` file.

The field is disabled by changing the field name to `#type`. The field value will not be modified.

Command Manifest:

- `NIL` (`null`, `undefined`): Disable `type` if enabled, re-enable otherwise
- `off`: Disable `type` field
- `on`: Re-enable `type` field

This is a **no-op** under any of the following conditions:

- A `package.json` file is not found
- The `type` field is not defined in the located manifest
- The `#type` field is not defined in the located manifest (i.e. the `type` field was not previously disabled)

#### Parameters

- `{Nilable<Command>?}` **`[command=null]`** &mdash; Toggle command
- `{mlly.ModuleId?}` **`[id='.']`** &mdash; Module id of package directory or manifest

#### Returns

Enable or disable `type` in `package.json`.
`{void}` Nothing when complete.

#### `command?`
#### Source

- `'off'`: disable `type`
- `'on'`: enable `type`
- `undefined`: disable `type` if enabled, enable if disabled
> [`src/toggle.ts`](src/toggle.ts)
## Types

Expand Down
22 changes: 22 additions & 0 deletions __mocks__/@flex-development/mlly.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @file Mocks - @flex-development/mlly
* @module mocks/flex-development/mlly
* @see https://github.com/flex-development/mlly
*/

/**
* [`@flex-development/mlly`][1] module type.
*
* [1]: https://github.com/flex-development/mlly
*/
type Actual = typeof import('@flex-development/mlly')

/**
* `@flex-development/mlly` module.
*
* @const {Actual} actual
*/
const actual: Actual = await vi.importActual<Actual>('@flex-development/mlly')

export const readPackageJson = vi.fn(actual.readPackageJson)
export const toURL = vi.fn(actual.toURL)
33 changes: 10 additions & 23 deletions __mocks__/fs.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,24 @@
/**
* @file Mocks - fs
* @module mocks/fs
* @see https://nodejs.org/docs/latest-v16.x/api/fs.html
* @see https://nodejs.org/api/fs.html
*/

import volume from '#fixtures/volume'
import type { TDataOut } from 'memfs/lib/encoding'
import type { IWriteFileOptions, TData, TFileId } from 'memfs/lib/volume'

/**
* Synchronously returns the contents of `path`.
*
* @see https://nodejs.org/docs/latest-v16.x/api/fs.html#fsreadfilesyncpath-options
*
* @param {TFileId} path - Filename or file descriptor
* @param {IWriteFileOptions | string} [options] - Read file options
* @return {TDataOut} File content
*/
export const readFileSync = vi.fn(volume.readFileSync.bind(volume))
import type fs from 'node:fs'

/**
* Synchronously writes `data` to `file`, replacing `file` if it already exists.
*
* @see https://nodejs.org/docs/latest-v16.x/api/fs.html#fswritefilesyncfile-data-options
* @see https://nodejs.org/api/fs.html#fswritefilesyncfile-data-options
*
* @param {TFileId} file - Filename or file descriptor
* @param {TData} data - File content
* @param {IWriteFileOptions} [options] - Write file options
* @param {fs.PathOrFileDescriptor} file - Filename or file descriptor
* @param {ArrayBufferView | string} data - File content
* @param {fs.WriteFileOptions} [options] - Write options
* @return {Promise<void>} Nothing when complete
*/
export const writeFileSync = vi.fn(volume.writeFileSync.bind(volume))
export const writeFileSync = vi
.fn(volume.writeFileSync.bind(volume))
.mockName('writeFileSync')

export default {
readFileSync,
writeFileSync
}
export default { writeFileSync }
1 change: 1 addition & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const config: Config = defineBuildConfig({
{ ignore: ['cli.ts'] },
{
bundle: true,
external: ['node-fetch'],
keepNames: true,
minify: true,
platform: 'node',
Expand Down
13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,16 @@
"typecheck": "vitest typecheck --run",
"typecheck:watch": "vitest typecheck"
},
"dependencies": {
"@flex-development/mlly": "1.0.0-alpha.11",
"@flex-development/pathe": "1.0.3",
"@flex-development/tutils": "6.0.0-alpha.10"
},
"devDependencies": {
"@commitlint/cli": "17.3.0",
"@commitlint/config-conventional": "17.3.0",
"@flex-development/mkbuild": "1.0.0-alpha.13",
"@flex-development/mlly": "1.0.0-alpha.11",
"@flex-development/pathe": "1.0.3",
"@flex-development/pkg-types": "1.0.0",
"@flex-development/tutils": "6.0.0-alpha.10",
"@flex-development/pkg-types": "2.0.0",
"@graphql-eslint/eslint-plugin": "3.16.0",
"@types/chai": "4.3.4",
"@types/conventional-changelog": "3.1.1",
Expand All @@ -91,6 +93,7 @@
"@types/git-raw-commits": "2.0.1",
"@types/is-ci": "3.0.0",
"@types/node": "18.14.0",
"@types/node-fetch": "2.6.2",
"@types/node-notifier": "8.0.2",
"@types/prettier": "2.7.2",
"@types/semver": "7.3.13",
Expand Down Expand Up @@ -148,7 +151,7 @@
"@flex-development/tutils": "6.0.0-alpha.10"
},
"engines": {
"node": ">=14.16",
"node": ">=14.17.0",
"yarn": "4.0.0-rc.39"
},
"packageManager": "[email protected]",
Expand Down
109 changes: 81 additions & 28 deletions src/__tests__/toggle.functional.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,135 @@
*/

import vfs from '#fixtures/volume'
import type { PackageJson } from '@flex-development/pkg-types'
import type { Spy } from '#tests/interfaces'
import * as mlly from '@flex-development/mlly'
import pathe from '@flex-development/pathe'
import type { PackageJson, Type } from '@flex-development/pkg-types'
import fs from 'node:fs'
import testSubject from '../toggle'

vi.mock('@flex-development/mlly')
vi.mock('fs')

describe('functional:toggle', () => {
let id: string
let mockReadPackageJson: Spy<(typeof mlly)['readPackageJson']>
let pkg: PackageJson
let type: Type

afterEach(() => {
vfs.reset()
})

it('should do nothing if package type is undefined', () => {
beforeAll(() => {
id = pathe.resolve('package.json')
pkg = { name: 'foo-package' }
type = 'module'

mockReadPackageJson =
mlly.readPackageJson as unknown as typeof mockReadPackageJson
})

it('should do nothing if package.json file is not found', () => {
// Act
testSubject(null, '__fixtures__/package.json')

// Expect
expect(fs.writeFileSync).toHaveBeenCalledTimes(0)
})

it('should do nothing if package type cannot be toggled', () => {
// Arrange
const pkg: PackageJson = { name: 'foo', version: '1.0.0' }
const pkgstring: string = JSON.stringify(pkg, null, 2) + '\n'
vfs.writeFileSync('./package.json', pkgstring)
mockReadPackageJson.mockReturnValueOnce(pkg)

// Act
testSubject()

// Expect
expect(vfs.readFileSync('./package.json', 'utf8')).to.equal(pkgstring)
expect(fs.writeFileSync).toHaveBeenCalledTimes(0)
})

describe('disable', () => {
const pkg: PackageJson = { type: 'module' }
let data: string

beforeAll(() => {
data = `${JSON.stringify({ ...pkg, '#type': type }, null, 2)}\n`
})

beforeEach(() => {
vfs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n')
mockReadPackageJson.mockReturnValue({ ...pkg, type })
})

it('should disable package type with "off"', () => {
it('should disable package type given ["off"]', () => {
// Act
testSubject('off')

// Expect
expect(JSON.parse(vfs.readFileSync('./package.json', 'utf8') as string))
.to.have.property('#type')
.that.equals(pkg.type)
expect(fs.writeFileSync).toHaveBeenCalledOnce()
expect(fs.writeFileSync).toHaveBeenCalledWith(id, data)
expect(vfs.toJSON()).to.have.property(pathe.resolve(id)).equal(data)
})

it('should disable package type without command', () => {
it('should disable package type given [null]', () => {
// Act
testSubject()
testSubject(null)

// Expect
expect(JSON.parse(vfs.readFileSync('./package.json', 'utf8') as string))
.to.have.property('#type')
.that.equals(pkg.type)
expect(fs.writeFileSync).toHaveBeenCalledOnce()
expect(fs.writeFileSync).toHaveBeenCalledWith(id, data)
expect(vfs.toJSON()).to.have.property(pathe.resolve(id)).equal(data)
})

it('should disable package type given [undefined]', () => {
// Act
testSubject(undefined)

// Expect
expect(fs.writeFileSync).toHaveBeenCalledOnce()
expect(fs.writeFileSync).toHaveBeenCalledWith(id, data)
expect(vfs.toJSON()).to.have.property(pathe.resolve(id)).equal(data)
})
})

describe('enable', () => {
const pkg: PackageJson = { '#type': 'module' }
let data: string

beforeAll(() => {
data = `${JSON.stringify({ ...pkg, type }, null, 2)}\n`
})

beforeEach(() => {
vfs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n')
mockReadPackageJson.mockReturnValue({ ...pkg, '#type': type })
})

it('should enable package type with "on"', () => {
it('should enable package type given ["on"]', () => {
// Act
testSubject('on')

// Expect
expect(JSON.parse(vfs.readFileSync('./package.json', 'utf8') as string))
.to.have.property('type')
.that.equals(pkg['#type'])
expect(fs.writeFileSync).toHaveBeenCalledOnce()
expect(fs.writeFileSync).toHaveBeenCalledWith(id, data)
expect(vfs.toJSON()).to.have.property(pathe.resolve(id)).equal(data)
})

it('should enable package type given [null]', () => {
// Act
testSubject(null)

// Expect
expect(fs.writeFileSync).toHaveBeenCalledOnce()
expect(fs.writeFileSync).toHaveBeenCalledWith(id, data)
expect(vfs.toJSON()).to.have.property(pathe.resolve(id)).equal(data)
})

it('should enable package type without command', () => {
it('should enable package type given [undefined]', () => {
// Act
testSubject()
testSubject(undefined)

// Expect
expect(JSON.parse(vfs.readFileSync('./package.json', 'utf8') as string))
.to.have.property('type')
.that.equals(pkg['#type'])
expect(fs.writeFileSync).toHaveBeenCalledOnce()
expect(fs.writeFileSync).toHaveBeenCalledWith(id, data)
expect(vfs.toJSON()).to.have.property(pathe.resolve(id)).equal(data)
})
})
})
Loading

0 comments on commit a710037

Please sign in to comment.