Skip to content

Commit

Permalink
Add visitor support
Browse files Browse the repository at this point in the history
  • Loading branch information
eemeli committed Feb 24, 2024
1 parent 4e667e4 commit 495f92d
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 4 deletions.
2 changes: 1 addition & 1 deletion config/jest.config.js
@@ -1,6 +1,6 @@
let moduleNameMapper
const transform = {
'[/\\\\]tests[/\\\\].*\\.(js|ts)$': [
'[/\\\\]tests[/\\\\].*\\.(m?js|ts)$': [
'babel-jest',
{ configFile: './config/babel.config.js' }
]
Expand Down
2 changes: 1 addition & 1 deletion config/rollup.node-config.mjs
Expand Up @@ -14,7 +14,7 @@ export default {
esModule: false,
preserveModules: true
},
external: ['node:util'],
external: ['node:path', 'node:util'],
plugins: [
typescript(),
{
Expand Down
11 changes: 10 additions & 1 deletion src/cli.ts
@@ -1,5 +1,6 @@
#!/usr/bin/env node

import { resolve } from 'node:path'
import { parseArgs } from 'node:util'

import { type Token, prettyToken } from './parse/cst.js'
Expand All @@ -9,6 +10,7 @@ import { Composer } from './compose/composer.js'
import { LineCounter } from './parse/line-counter.js'
import { type Document } from './doc/Document.js'
import { prettifyError } from './errors.js'
import { visit, type visitor } from './visit.js'

const help = `\
yaml: A command-line YAML processor and inspector
Expand All @@ -29,6 +31,7 @@ Additional options for bare "yaml" command:
--doc, -d Output pretty-printed JS Document objects.
--single, -1 Require the input to consist of a single YAML document.
--strict, -s Stop on errors.
--visit, -v Apply a visitor to each document (requires a path to import)
--yaml 1.1 Set the YAML version. (default: 1.2)`

class UserError extends Error {
Expand All @@ -43,14 +46,15 @@ class UserError extends Error {

/* istanbul ignore if */
if (require.main === module)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
main(process.stdin, error => {
if (error instanceof UserError) {
console.error(`${help}\n\n${error.message}`)
process.exitCode = error.code
} else if (error) throw error
})

export function main(
export async function main(
stdin: NodeJS.ReadableStream,
done: (error?: Error) => void,
argv?: string[]
Expand All @@ -66,6 +70,7 @@ export function main(
json: { type: 'boolean', short: 'j' },
single: { type: 'boolean', short: '1' },
strict: { type: 'boolean', short: 's' },
visit: { type: 'string', short: 'v' },
yaml: { type: 'string', default: '1.2' }
}
})
Expand Down Expand Up @@ -129,6 +134,9 @@ export function main(
const parser = new Parser(lineCounter.addNewLine)
// @ts-expect-error Version is validated at runtime
const composer = new Composer({ version: opt.yaml })
const visitor: visitor | null = opt.visit
? (await import(resolve(opt.visit))).default
: null
let source = ''
let hasDoc = false
let reqDocEnd = false
Expand All @@ -151,6 +159,7 @@ export function main(
prettifyError(source, lineCounter)(warning)
console.error(warning)
}
if (visitor) visit(doc, visitor)
if (mode === 'valid') doc.toJS()
else if (opt.json) data.push(doc)
else if (opt.doc) {
Expand Down
6 changes: 6 additions & 0 deletions tests/artifacts/cli-singlequote.mjs
@@ -0,0 +1,6 @@
/** @type {import('../../src/index').visitor} */
export default {
Scalar(_, node) {
node.type = 'QUOTE_SINGLE'
}
}
10 changes: 10 additions & 0 deletions tests/artifacts/cli-unstyle.cjs
@@ -0,0 +1,10 @@
/** @type {import('../../src/index').visitor} */
module.exports = {
Collection(_, node) {
delete node.flow
},
Scalar(_, node) {
delete node.format
delete node.type
}
}
16 changes: 16 additions & 0 deletions tests/cli.ts
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-floating-promises */

import { Readable } from 'node:stream'
import { main } from 'yaml/cli'

Expand Down Expand Up @@ -128,6 +130,20 @@ const skip = Number(major) < 20
[{ name: 'YAMLParseError' }]
)
})
describe('--visit', () => {
ok(
'unstyle',
'{"hello":"world"}',
['--visit', './tests/artifacts/cli-unstyle.cjs'],
['hello: world']
)
ok(
'singlequote',
'{"hello":"world"}',
['--visit', './tests/artifacts/cli-singlequote.mjs'],
["{ 'hello': 'world' }"]
)
})
})

describe('CST parser', () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/tsconfig.json
Expand Up @@ -11,5 +11,5 @@
"rootDir": "..",
"types": ["jest", "node"]
},
"include": ["**/*.ts"]
"include": ["**/*.ts", "artifacts/cli-*"]
}
1 change: 1 addition & 0 deletions tsconfig.json
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"module": "ESNext",
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
Expand Down

0 comments on commit 495f92d

Please sign in to comment.