Repository: eemeli/yaml
Pull request #234 (2021-02-27 16:58:14)

Merge 'yaml/types' into 'yaml' & fiddle with 'yaml/util'
Especially with the port to TypeScript, it makes less sense now to expose `'yaml/types'` separately from `'yaml'`. So let's not.

This is how you'll need to update your imports, if using:

```diff
-import { Alias, Merge, Pair, Scalar, YAMLMap, YAMLSeq } from 'yaml/types'
+import { Alias, Merge, Pair, Scalar, YAMLMap, YAMLSeq } from 'yaml'

-import { binaryOptions, boolOptions, intOptions, nullOptions, strOptions } from 'yaml/types'
+import { scalarOptions } from 'yaml'
+const boolOptions = scalarOptions.bool
```

A couple of the `'yaml/util'` exports also make more sense on `'yaml'`:

```diff
-import { Type, YAMLError, YAMLParseError, YAMLWarning } from 'yaml/util'
+import { Type, YAMLError, YAMLParseError, YAMLWarning } from 'yaml'
```

While we're at this, let's also add a couple of things to `'yaml/util'` that weren't exposed before:

```js
import { debug, warn, foldFlowLines } from 'yaml/util'
```

And finally, let's clear up things from the repo root that aren't needed anymore, or that we can easily hide in a `config/` directory. Leaving the Prettier & ESLint config there at least for now, because otherwise editors wouldn't find them automatically.

If you're using ES modules in Node.js < 14.10, this may change how you need to import `'yaml/util'`, as the automatic named exports weren't generated for CommonJS imports until then. My suspicion is that this would affect a vanishingly small number of users, but please do let me know if it's a problem:

```diff
// Both forms are fine in Node.js 14.10 & later, and for all bundlers
-import { stringifyNumber } from 'yaml/util'
+import Util from 'yaml/util'
+const { stringifyNumber } = Util
```


Patch:
diff --git a/README.md b/README.md
index 0d06d13..23e905e 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ const YAML = require('yaml')
 - [`YAML.visit(node, visitor)`](https://eemeli.org/yaml/#modifying-nodes)
 
 ```js
-import { Pair, YAMLMap, YAMLSeq } from 'yaml/types'
+import { Pair, YAMLMap, YAMLSeq } from 'yaml'
 ```
 
 - [`new Pair(key, value)`](https://eemeli.org/yaml/#creating-nodes)
diff --git a/babel.config.js b/config/babel.config.js
similarity index 100%
rename from babel.config.js
rename to config/babel.config.js
diff --git a/config/jest.config.js b/config/jest.config.js
new file mode 100644
index 0000000..851154b
--- /dev/null
+++ b/config/jest.config.js
@@ -0,0 +1,39 @@
+let moduleNameMapper
+const testPathIgnorePatterns = ['tests/_import', 'cst/common']
+
+// The npm script name is significant.
+switch (process.env.npm_lifecycle_event) {
+  case 'test:dist':
+    moduleNameMapper = {
+      '^yaml$': '<rootDir>/dist/index.js',
+      '^yaml/util$': '<rootDir>/dist/util.js',
+      '^yaml/test-events$': '<rootDir>/dist/test-events.js'
+    }
+    testPathIgnorePatterns.push('doc/createNode', 'doc/types')
+    break
+
+  case 'test':
+  default:
+    process.env.TRACE_LEVEL = 'log'
+    moduleNameMapper = {
+      '^yaml$': '<rootDir>/src/index.ts',
+      '^yaml/util$': '<rootDir>/src/util.ts',
+      '^yaml/test-events$': '<rootDir>/src/test-events.ts'
+    }
+}
+
+module.exports = {
+  collectCoverageFrom: ['src/**/*.{js,ts}', '!src/**/*.d.ts'],
+  moduleNameMapper,
+  resolver: 'jest-ts-webcompat-resolver',
+  rootDir: '..',
+  testEnvironment: 'node',
+  testMatch: ['**/tests/**/*.{js,ts}'],
+  testPathIgnorePatterns,
+  transform: {
+    '/(src|tests)/.*\\.(js|ts)$': [
+      'babel-jest',
+      { configFile: './config/babel.config.js' }
+    ]
+  }
+}
diff --git a/rollup.browser-config.js b/config/rollup.browser-config.js
similarity index 93%
rename from rollup.browser-config.js
rename to config/rollup.browser-config.js
index 61737ac..28dae73 100644
--- a/rollup.browser-config.js
+++ b/config/rollup.browser-config.js
@@ -5,7 +5,6 @@ import typescript from '@rollup/plugin-typescript'
 export default {
   input: {
     index: 'src/index.ts',
-    types: 'src/types.ts',
     util: 'src/util.ts'
   },
   output: { dir: 'browser/dist', format: 'esm', preserveModules: true },
@@ -16,6 +15,7 @@ export default {
     }),
     babel({
       babelHelpers: 'bundled',
+      configFile: './config/babel.config.js',
       presets: [['@babel/env', { modules: false }]]
     }),
     typescript({ declaration: false, outDir: 'browser/dist' })
diff --git a/rollup.node-config.js b/config/rollup.node-config.js
similarity index 93%
rename from rollup.node-config.js
rename to config/rollup.node-config.js
index 21e6b85..e148483 100644
--- a/rollup.node-config.js
+++ b/config/rollup.node-config.js
@@ -6,7 +6,6 @@ export default {
   input: {
     index: 'src/index.ts',
     'test-events': 'src/test-events.ts',
-    types: 'src/types.ts',
     util: 'src/util.ts'
   },
   output: {
@@ -18,6 +17,7 @@ export default {
   plugins: [
     babel({
       babelHelpers: 'bundled',
+      configFile: './config/babel.config.js',
       presets: [['@babel/env', { modules: false, targets: { node: '10.0' } }]]
     }),
     typescript(),
diff --git a/docs/01_intro.md b/docs/01_intro.md
index fff1edc..39886a5 100644
--- a/docs/01_intro.md
+++ b/docs/01_intro.md
@@ -52,7 +52,7 @@ const YAML = require('yaml')
 - [`YAML.visit(node, visitor)`](#modifying-nodes)
 
 ```js
-import { Pair, YAMLMap, YAMLSeq } from 'yaml/types'
+import { Pair, YAMLMap, YAMLSeq } from 'yaml'
 ```
 
 - [`new Pair(key, value)`](#creating-nodes)
diff --git a/docs/03_options.md b/docs/03_options.md
index 1f2c549..aadf163 100644
--- a/docs/03_options.md
+++ b/docs/03_options.md
@@ -98,8 +98,6 @@ YAML.stringify({ this: null, that: 'value' })
 
 Some customization options are availabe to control the parsing and stringification of scalars. Note that these values are used by all documents.
 
-These options objects are also exported individually from `'yaml/types'`.
-
 | Option             | Type      | Default value                                       | Description                                                                                                                                                                |
 | ------------------ | --------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 | binary.defaultType | `Type`    | `'BLOCK_LITERAL'`                                   | The type of string literal used to stringify `!!binary` values                                                                                                             |
diff --git a/docs/05_content_nodes.md b/docs/05_content_nodes.md
index 5940d70..7fedeb5 100644
--- a/docs/05_content_nodes.md
+++ b/docs/05_content_nodes.md
@@ -175,10 +175,9 @@ The primary purpose of this method is to enable attaching comments or other meta
 <h4 style="clear:both"><code>new YAMLMap(), new YAMLSeq(), doc.createPair(key, value)</code></h4>
 
 ```js
-import YAML from 'yaml'
-import { YAMLSeq } from 'yaml/types'
+import { Document, YAMLSeq } from 'yaml'
 
-const doc = new YAML.Document(new YAMLSeq())
+const doc = new Document(new YAMLSeq())
 doc.contents.items = [
   'some values',
   42,
@@ -194,9 +193,9 @@ doc.toString()
 // - 1: a number
 ```
 
-To construct a `YAMLSeq` or `YAMLMap`, use `doc.createNode()` with array, object or iterable input, or create the collections directly by importing the classes from `yaml/types`.
+To construct a `YAMLSeq` or `YAMLMap`, use `new Document()` or `doc.createNode()` with array, object or iterable input, or create the collections directly by importing the classes from `yaml`.
 
-Once created, normal array operations may be used to modify the `items` array. New `Pair` objects may created either by importing the class from `yaml/types` and using its `new Pair(key, value)` constructor, or by using the `doc.createPair(key, value, options?)` method. The latter will recursively wrap the `key` and `value` as nodes, and accepts the same options as `doc.createNode()`
+Once created, normal array operations may be used to modify the `items` array. New `Pair` objects may created either by importing the class from `yaml` and using its `new Pair(key, value)` constructor, or by using the `doc.createPair(key, value, options?)` method. The latter will recursively wrap the `key` and `value` as nodes, and accepts the same options as `doc.createNode()`
 
 ## Modifying Nodes
 
diff --git a/docs/06_custom_tags.md b/docs/06_custom_tags.md
index 5b65394..dbbe4b8 100644
--- a/docs/06_custom_tags.md
+++ b/docs/06_custom_tags.md
@@ -127,12 +127,13 @@ Finally, `stringify(item, ctx, ...): string` defines how your data should be rep
 <!-- prettier-ignore -->
 ```js
 import {
+  debug, // (logLevel, ...messages) => void -- Log debug messages to console
   findPair, // (items, key) => Pair? -- Given a key, find a matching Pair
+  foldFlowLines, // (text, indent, mode, options) => string -- Fold long lines
   stringifyNumber, // (node) => string
   stringifyString, // (node, ctx, ...) => string
   toJS, // (value, arg, ctx) => any -- Recursively convert to plain JS
-  Type, // { [string]: string } -- Used as enum for node types
-  YAMLError, YAMLParseError, YAMLWarning
+  warn // (logLevel, warning) => void -- Emit a warning
 } from 'yaml/util'
 ```
 
diff --git a/index.d.ts b/index.d.ts
deleted file mode 100644
index 9247c2a..0000000
--- a/index.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export * from './dist/index'
diff --git a/index.js b/index.js
deleted file mode 100644
index 2d2f3c0..0000000
--- a/index.js
+++ /dev/null
@@ -1,1 +0,0 @@
-module.exports = require('./dist')
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index 104b2dc..0000000
--- a/jest.config.js
+++ /dev/null
@@ -1,39 +0,0 @@
-let moduleNameMapper
-const testPathIgnorePatterns = ['tests/_import', 'cst/common']
-
-// The npm script name is significant.
-switch (process.env.npm_lifecycle_event) {
-  case 'test:dist':
-    moduleNameMapper = {}
-    testPathIgnorePatterns.push(
-      'cst/Node',
-      'cst/set-value',
-      'cst/source-utils',
-      'cst/YAML-1.2',
-      'doc/createNode',
-      'doc/errors',
-      'doc/foldFlowLines',
-      'doc/types'
-    )
-    break
-
-  case 'test':
-  default:
-    process.env.TRACE_LEVEL = 'log'
-    moduleNameMapper = {
-      '^\\./dist$': '<rootDir>/src/index.ts',
-      '^\\./dist/types(\\.js)?$': '<rootDir>/src/types.ts',
-      '^\\./dist/(.+)$': '<rootDir>/src/$1',
-      '^\\.\\./dist/test-events.js$': '<rootDir>/src/test-events.ts'
-    }
-}
-
-module.exports = {
-  collectCoverageFrom: ['src/**/*.{js,ts}', '!src/**/*.d.ts'],
-  moduleNameMapper,
-  resolver: 'jest-ts-webcompat-resolver',
-  testEnvironment: 'node',
-  testMatch: ['**/tests/**/*.{js,ts}'],
-  testPathIgnorePatterns,
-  transform: { '/(src|tests)/.*\\.(js|ts)$': 'babel-jest' }
-}
diff --git a/package.json b/package.json
index be6b6bd..3d90758 100644
--- a/package.json
+++ b/package.json
@@ -13,55 +13,38 @@
   "homepage": "https://eemeli.org/yaml/",
   "files": [
     "browser/",
-    "dist/",
-    "types/",
-    "*.d.ts",
-    "*.js",
-    "*.mjs",
-    "!*config.js"
+    "dist/"
   ],
   "type": "commonjs",
-  "main": "./index.js",
+  "main": "./dist/index.js",
   "browser": {
     "./index.js": "./browser/index.js",
-    "./types.js": "./browser/dist/types.js",
-    "./types.mjs": "./browser/dist/types.js",
     "./util.js": "./browser/dist/util.js",
     "./util.mjs": "./browser/dist/util.js"
   },
   "exports": {
     ".": {
-      "node": "./index.js",
+      "node": "./dist/index.js",
       "default": "./browser/index.js"
     },
     "./package.json": "./package.json",
-    "./types": {
-      "node": {
-        "import": "./types.mjs",
-        "require": "./types.js"
-      },
-      "default": "./browser/dist/types.js"
-    },
     "./util": {
-      "node": {
-        "import": "./util.mjs",
-        "require": "./util.js"
-      },
+      "node": "./dist/util.js",
       "default": "./browser/dist/util.js"
     }
   },
   "scripts": {
     "build": "npm run build:node && npm run build:browser",
-    "build:browser": "rollup -c rollup.browser-config.js",
-    "build:node": "rollup -c rollup.node-config.js",
+    "build:browser": "rollup -c config/rollup.browser-config.js",
+    "build:node": "rollup -c config/rollup.node-config.js",
     "clean": "git clean -fdxe node_modules",
     "lint": "eslint src/",
     "prettier": "prettier --write .",
     "prestart": "npm run build:node",
     "start": "node -i -e 'YAML=require(\"./dist/index.js\")'",
-    "test": "jest",
+    "test": "jest --config config/jest.config.js",
     "test:browsers": "cd playground && npm test",
-    "test:dist": "npm run build:node && jest",
+    "test:dist": "npm run build:node && jest --config config/jest.config.js",
     "test:types": "tsc --noEmit",
     "docs:install": "cd docs-slate && bundle install",
     "docs:deploy": "cd docs-slate && ./deploy.sh",
diff --git a/src/index.ts b/src/index.ts
index b4aa6f9..d20de80 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,7 +1,13 @@
 export { Composer } from './compose/composer.js'
+export { Type } from './constants.js'
+
 export { CreateNodeOptions, Document } from './doc/Document.js'
-export { Options, defaultOptions, scalarOptions } from './options.js'
+export { Schema } from './doc/Schema.js'
+
+export { YAMLError, YAMLParseError, YAMLWarning } from './errors.js'
 
+export { Alias } from './nodes/Alias.js'
+export { Merge } from './nodes/Merge.js'
 export {
   isAlias,
   isCollection,
@@ -14,6 +20,12 @@ export {
   Node,
   ParsedNode
 } from './nodes/Node.js'
+export { Pair, PairType } from './nodes/Pair.js'
+export { Scalar } from './nodes/Scalar.js'
+export { YAMLMap } from './nodes/YAMLMap.js'
+export { YAMLSeq } from './nodes/YAMLSeq.js'
+
+export { Options, defaultOptions, scalarOptions } from './options.js'
 
 export { Lexer } from './parse/lexer.js'
 export { LineCounter } from './parse/line-counter.js'
diff --git a/src/log.ts b/src/log.ts
index 0d5f68e..b9df8a9 100644
--- a/src/log.ts
+++ b/src/log.ts
@@ -1,5 +1,3 @@
-/* global console, process */
-
 import { LogLevel, LogLevelId } from './constants.js'
 
 export function debug(logLevel: LogLevelId, ...messages: any[]) {
diff --git a/src/public-api.ts b/src/public-api.ts
index d49801d..543d09f 100644
--- a/src/public-api.ts
+++ b/src/public-api.ts
@@ -47,7 +47,7 @@ export function parseAllDocuments<T extends ParsedNode = ParsedNode>(
 export function parseDocument<T extends ParsedNode = ParsedNode>(
   source: string,
   options?: Options
-): Document.Parsed<T> | null {
+) {
   let doc: Document.Parsed<T> | null = null
   const composer = new Composer(_doc => {
     if (!doc) doc = _doc as Document.Parsed<T>
@@ -60,7 +60,8 @@ export function parseDocument<T extends ParsedNode = ParsedNode>(
   const parser = new Parser(composer.next, options?.lineCounter?.addNewLine)
   parser.parse(source)
   composer.end(true, source.length)
-  return doc
+  // `doc` is always set by compose.end(true) at the very latest
+  return (doc as unknown) as Document.Parsed<T>
 }
 
 /**
diff --git a/src/stringify/foldFlowLines.ts b/src/stringify/foldFlowLines.ts
index ffa7c12..7f20aee 100644
--- a/src/stringify/foldFlowLines.ts
+++ b/src/stringify/foldFlowLines.ts
@@ -37,10 +37,6 @@ export interface FoldOptions {
  * Tries to keep input at up to `lineWidth` characters, splitting only on spaces
  * not followed by newlines or spaces unless `mode` is `'quoted'`. Lines are
  * terminated with `\n` and started with `indent`.
- *
- * @param {string} text
- * @param {string} indent
- * @param {Object} options
  */
 export function foldFlowLines(
   text: string,
diff --git a/src/types.ts b/src/types.ts
deleted file mode 100644
index 1331180..0000000
--- a/src/types.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export * from './tags/options.js'
-export { Schema } from './doc/Schema.js'
-export { Alias } from './nodes/Alias.js'
-export { Merge } from './nodes/Merge.js'
-export { Pair } from './nodes/Pair.js'
-export { Scalar } from './nodes/Scalar.js'
-export { YAMLMap } from './nodes/YAMLMap.js'
-export { YAMLSeq } from './nodes/YAMLSeq.js'
diff --git a/src/util.ts b/src/util.ts
index a8c976a..cf6c984 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -1,6 +1,7 @@
+export type { LogLevelId } from './constants.js'
+export { debug, warn } from './log.js'
 export { findPair } from './nodes/YAMLMap.js'
-export { toJS, ToJSContext } from './nodes/toJS.js'
+export { toJS, ToJSAnchorValue, ToJSContext } from './nodes/toJS.js'
+export { foldFlowLines } from './stringify/foldFlowLines'
 export { stringifyNumber } from './stringify/stringifyNumber.js'
 export { stringifyString } from './stringify/stringifyString.js'
-export { Type } from './constants.js'
-export * from './errors.js'
diff --git a/src/visit.ts b/src/visit.ts
index c6b4acd..0606d15 100644
--- a/src/visit.ts
+++ b/src/visit.ts
@@ -64,7 +64,7 @@ export type visitor =
  * `Alias` and `Scalar` node.
  */
 export function visit(
-  node: Node | Document,
+  node: Node | Document | null,
   visitor:
     | visitorFn<unknown>
     | {
diff --git a/types.d.ts b/types.d.ts
deleted file mode 100644
index 64a93dd..0000000
--- a/types.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export * from './dist/types'
diff --git a/types.js b/types.js
deleted file mode 100644
index 9cc1748..0000000
--- a/types.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const types = require('./dist/types')
-
-exports.binaryOptions = types.binaryOptions
-exports.boolOptions = types.boolOptions
-exports.intOptions = types.intOptions
-exports.nullOptions = types.nullOptions
-exports.strOptions = types.strOptions
-
-exports.Schema = types.Schema
-exports.Alias = types.Alias
-exports.Collection = types.Collection
-exports.Merge = types.Merge
-exports.Pair = types.Pair
-exports.Scalar = types.Scalar
-exports.YAMLMap = types.YAMLMap
-exports.YAMLSeq = types.YAMLSeq
diff --git a/types.mjs b/types.mjs
deleted file mode 100644
index 292621e..0000000
--- a/types.mjs
+++ /dev/null
@@ -1,16 +0,0 @@
-import types from './dist/types.js'
-
-export const binaryOptions = types.binaryOptions
-export const boolOptions = types.boolOptions
-export const intOptions = types.intOptions
-export const nullOptions = types.nullOptions
-export const strOptions = types.strOptions
-
-export const Schema = types.Schema
-export const Alias = types.Alias
-export const Collection = types.Collection
-export const Merge = types.Merge
-export const Pair = types.Pair
-export const Scalar = types.Scalar
-export const YAMLMap = types.YAMLMap
-export const YAMLSeq = types.YAMLSeq
diff --git a/util.d.ts b/util.d.ts
deleted file mode 100644
index be0bfa8..0000000
--- a/util.d.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-export * from './dist/util'
diff --git a/util.js b/util.js
deleted file mode 100644
index fd4bf26..0000000
--- a/util.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const util = require('./dist/util')
-
-exports.findPair = util.findPair
-exports.toJSON = util.toJSON
-
-exports.stringifyNumber = util.stringifyNumber
-exports.stringifyString = util.stringifyString
-exports.Type = util.Type
-
-exports.YAMLError = util.YAMLError
-exports.YAMLParseError = util.YAMLParseError
-exports.YAMLWarning = util.YAMLWarning
diff --git a/util.mjs b/util.mjs
deleted file mode 100644
index c4a0477..0000000
--- a/util.mjs
+++ /dev/null
@@ -1,13 +0,0 @@
-import util from './dist/util.js'
-
-export const findPair = util.findPair
-export const toJSON = util.toJSON
-
-export const stringifyNumber = util.stringifyNumber
-export const stringifyString = util.stringifyString
-
-export const Type = util.Type
-
-export const YAMLError = util.YAMLError
-export const YAMLParseError = util.YAMLParseError
-export const YAMLWarning = util.YAMLWarning


Test patch:
diff --git a/tests/doc/YAML-1.1.spec.js b/tests/doc/YAML-1.1.spec.js
index 7fe51e3..5032af8 100644
--- a/tests/doc/YAML-1.1.spec.js
+++ b/tests/doc/YAML-1.1.spec.js
@@ -1,5 +1,5 @@
 import { source } from 'common-tags'
-import * as YAML from '../../index.js'
+import * as YAML from 'yaml'
 
 const orig = {}
 beforeAll(() => {
diff --git a/tests/doc/YAML-1.2.spec.js b/tests/doc/YAML-1.2.spec.js
index 8f48429..ed02381 100644
--- a/tests/doc/YAML-1.2.spec.js
+++ b/tests/doc/YAML-1.2.spec.js
@@ -1,5 +1,5 @@
-import * as YAML from '../../index.js'
-import { YAMLError } from '../../util.js'
+import * as YAML from 'yaml'
+import { YAMLError } from 'yaml'
 
 const collectionKeyWarning = /^Keys with collection values will be stringified due to JS Object restrictions/
 
diff --git a/tests/doc/anchors.js b/tests/doc/anchors.js
index 1bcc703..11c60f7 100644
--- a/tests/doc/anchors.js
+++ b/tests/doc/anchors.js
@@ -1,5 +1,4 @@
-import * as YAML from '../../index.js'
-import { Merge, YAMLMap } from '../../types.js'
+import * as YAML from 'yaml'
 
 test('basic', () => {
   const src = `- &a 1\n- *a\n`
@@ -162,9 +161,9 @@ describe('merge <<', () => {
     ])
     doc.contents.items.slice(5).forEach(({ items }) => {
       const merge = items[0]
-      expect(merge).toBeInstanceOf(Merge)
+      expect(merge).toBeInstanceOf(YAML.Merge)
       merge.value.items.forEach(({ source }) => {
-        expect(source).toBeInstanceOf(YAMLMap)
+        expect(source).toBeInstanceOf(YAML.YAMLMap)
       })
     })
   })
diff --git a/tests/doc/collection-access.js b/tests/doc/collection-access.js
index 56476db..bfb7dd4 100644
--- a/tests/doc/collection-access.js
+++ b/tests/doc/collection-access.js
@@ -1,10 +1,9 @@
-import * as YAML from '../../index.js'
-import { Pair } from '../../types.js'
+import { Document, parseDocument, Pair } from 'yaml'
 
 describe('Map', () => {
   let doc, map
   beforeEach(() => {
-    doc = new YAML.Document({ a: 1, b: { c: 3, d: 4 } })
+    doc = new Document({ a: 1, b: { c: 3, d: 4 } })
     map = doc.contents
     expect(map.items).toMatchObject([
       { key: { value: 'a' }, value: { value: 1 } },
@@ -88,7 +87,7 @@ describe('Map', () => {
   })
 
   test('set scalar node with anchor', () => {
-    doc = YAML.parseDocument('a: &A value\nb: *A\n')
+    doc = parseDocument('a: &A value\nb: *A\n')
     doc.set('a', 'foo')
     expect(doc.get('a', true)).toMatchObject({ value: 'foo' })
     expect(String(doc)).toBe('a: &A foo\nb: *A\n')
@@ -98,7 +97,7 @@ describe('Map', () => {
 describe('Seq', () => {
   let doc, seq
   beforeEach(() => {
-    doc = new YAML.Document([1, [2, 3]])
+    doc = new Document([1, [2, 3]])
     seq = doc.contents
     expect(seq.items).toMatchObject([
       { value: 1 },
@@ -180,7 +179,7 @@ describe('Seq', () => {
 describe('Set', () => {
   let doc, set
   beforeEach(() => {
-    doc = new YAML.Document(null, { version: '1.1' })
+    doc = new Document(null, { version: '1.1' })
     set = doc.createNode([1, 2, 3], { tag: '!!set' })
     doc.contents = set
     expect(set.items).toMatchObject([
@@ -228,7 +227,7 @@ describe('Set', () => {
 describe('OMap', () => {
   let doc, omap
   beforeEach(() => {
-    doc = new YAML.Document(null, { version: '1.1' })
+    doc = new Document(null, { version: '1.1' })
     omap = doc.createNode([{ a: 1 }, { b: { c: 3, d: 4 } }], { tag: '!!omap' })
     doc.contents = omap
     expect(omap.items).toMatchObject([
@@ -291,7 +290,7 @@ describe('OMap', () => {
 describe('Collection', () => {
   let doc, map
   beforeEach(() => {
-    doc = new YAML.Document({ a: 1, b: [2, 3] })
+    doc = new Document({ a: 1, b: [2, 3] })
     map = doc.contents
   })
 
@@ -359,7 +358,7 @@ describe('Collection', () => {
 describe('Document', () => {
   let doc
   beforeEach(() => {
-    doc = new YAML.Document({ a: 1, b: [2, 3] })
+    doc = new Document({ a: 1, b: [2, 3] })
     expect(doc.contents.items).toMatchObject([
       { key: { value: 'a' }, value: { value: 1 } },
       {
@@ -512,7 +511,7 @@ describe('Document', () => {
   })
 
   test('setIn on parsed document', () => {
-    doc = YAML.parseDocument('{ a: 1, b: [2, 3] }')
+    doc = parseDocument('{ a: 1, b: [2, 3] }')
     doc.setIn(['c', 1], 9)
     expect(String(doc)).toBe('{ a: 1, b: [ 2, 3 ], c: [ null, 9 ] }\n')
   })
diff --git a/tests/doc/comments.js b/tests/doc/comments.js
index 1c052c1..e0a899a 100644
--- a/tests/doc/comments.js
+++ b/tests/doc/comments.js
@@ -1,6 +1,5 @@
 import { source } from 'common-tags'
-import * as YAML from '../../index.js'
-import { Pair } from '../../types.js'
+import * as YAML from 'yaml'
 
 describe('parse comments', () => {
   describe('body', () => {
@@ -858,20 +857,20 @@ a:
 describe('Pair.commentBefore', () => {
   test('Should get key comment', () => {
     const key = new YAML.Document().createNode('foo')
-    const pair = new Pair(key, 42)
+    const pair = new YAML.Pair(key, 42)
     key.commentBefore = 'cc'
     expect(pair.commentBefore).toBe('cc')
   })
 
   test('Should set key comment', () => {
     const key = new YAML.Document().createNode('foo')
-    const pair = new Pair(key, 42)
+    const pair = new YAML.Pair(key, 42)
     pair.commentBefore = 'cc'
     expect(key.commentBefore).toBe('cc')
   })
 
   test('Should create a key from a null value', () => {
-    const pair = new Pair(null, 42)
+    const pair = new YAML.Pair(null, 42)
     expect(pair.key).toBeNull()
     pair.commentBefore = 'cc'
     expect(pair.key).not.toBeNull()
@@ -879,7 +878,7 @@ describe('Pair.commentBefore', () => {
   })
 
   test('Should throw for non-Node key', () => {
-    const pair = new Pair({ foo: 'bar' }, 42)
+    const pair = new YAML.Pair({ foo: 'bar' }, 42)
     expect(() => {
       pair.commentBefore = 'cc'
     }).toThrow(/commentBefore is an alias/)
diff --git a/tests/doc/createNode.js b/tests/doc/createNode.js
index ba7b496..b309adf 100644
--- a/tests/doc/createNode.js
+++ b/tests/doc/createNode.js
@@ -1,13 +1,9 @@
-import * as YAML from '../../src/index.js'
-import { PairType } from '../../src/nodes/Pair.js'
-import { Scalar } from '../../src/nodes/Scalar.js'
-import { YAMLMap } from '../../src/nodes/YAMLMap.js'
-import { YAMLSeq } from '../../src/nodes/YAMLSeq.js'
+import { Document, PairType, Scalar, YAMLMap, YAMLSeq } from 'yaml'
 import { YAMLSet } from '../../src/tags/yaml-1.1/set.js'
 
 let doc
 beforeEach(() => {
-  doc = new YAML.Document()
+  doc = new Document()
 })
 
 describe('createNode(value)', () => {
@@ -77,7 +73,7 @@ describe('arrays', () => {
     })
     test('set doc contents', () => {
       const res = '- 3\n- - four\n  - 5\n'
-      const doc = new YAML.Document(array)
+      const doc = new Document(array)
       expect(String(doc)).toBe(res)
       doc.contents = array
       expect(String(doc)).toBe(res)
@@ -142,7 +138,7 @@ y:
 z:
   w: five
   v: 6\n`
-      const doc = new YAML.Document(object)
+      const doc = new Document(object)
       expect(String(doc)).toBe(res)
       doc.contents = object
       expect(String(doc)).toBe(res)
@@ -177,7 +173,7 @@ describe('Set', () => {
     })
     test('set doc contents', () => {
       const res = '- 3\n- - four\n  - 5\n'
-      const doc = new YAML.Document(set)
+      const doc = new Document(set)
       expect(String(doc)).toBe(res)
       doc.contents = set
       expect(String(doc)).toBe(res)
@@ -185,7 +181,7 @@ describe('Set', () => {
       expect(String(doc)).toBe(res)
     })
     test('Schema#createNode() - YAML 1.2', () => {
-      const doc = new YAML.Document(null)
+      const doc = new Document(null)
       const s = doc.createNode(set)
       expect(s).toBeInstanceOf(YAMLSeq)
       expect(s.items).toMatchObject([
@@ -194,7 +190,7 @@ describe('Set', () => {
       ])
     })
     test('Schema#createNode() - YAML 1.1', () => {
-      const doc = new YAML.Document(null, { version: '1.1' })
+      const doc = new Document(null, { version: '1.1' })
       const s = doc.createNode(set)
       expect(s).toBeInstanceOf(YAMLSet)
       expect(s.items).toMatchObject([
@@ -255,7 +251,7 @@ y:
 ? w: five
   v: 6
 : z\n`
-      const doc = new YAML.Document(map)
+      const doc = new Document(map)
       expect(String(doc)).toBe(res)
       doc.contents = map
       expect(String(doc)).toBe(res)
@@ -277,7 +273,7 @@ describe('circular references', () => {
   test('parent at root', () => {
     const map = { foo: 'bar' }
     map.map = map
-    const doc = new YAML.Document(null)
+    const doc = new Document(null)
     expect(doc.createNode(map)).toMatchObject({
       items: [
         { key: { value: 'foo' }, value: { value: 'bar' } },
@@ -301,7 +297,7 @@ describe('circular references', () => {
     const baz = {}
     const map = { foo: { bar: { baz } } }
     baz.map = map
-    const doc = new YAML.Document(null)
+    const doc = new Document(null)
     const node = doc.createNode(map)
     expect(node.getIn(['foo', 'bar', 'baz', 'map'])).toMatchObject({
       type: 'ALIAS',
@@ -316,7 +312,7 @@ describe('circular references', () => {
     const one = ['one']
     const two = ['two']
     const seq = [one, two, one, one, two]
-    const doc = new YAML.Document(null)
+    const doc = new Document(null)
     expect(doc.createNode(seq)).toMatchObject({
       items: [
         { items: [{ value: 'one' }] },
@@ -335,7 +331,7 @@ describe('circular references', () => {
   test('further relatives', () => {
     const baz = { a: 1 }
     const seq = [{ foo: { bar: { baz } } }, { fe: { fi: { fo: { baz } } } }]
-    const doc = new YAML.Document(null)
+    const doc = new Document(null)
     const node = doc.createNode(seq)
     const source = node.getIn([0, 'foo', 'bar', 'baz'])
     const alias = node.getIn([1, 'fe', 'fi', 'fo', 'baz'])
diff --git a/tests/doc/errors.js b/tests/doc/errors.js
index 73e6be7..931c959 100644
--- a/tests/doc/errors.js
+++ b/tests/doc/errors.js
@@ -1,11 +1,10 @@
-import { YAMLError } from '../../src/errors.js'
-import * as YAML from '../../src/index.js'
+import * as YAML from 'yaml'
 
 test('require a message and source for all errors', () => {
   const exp = /Invalid arguments/
-  expect(() => new YAMLError()).toThrow(exp)
-  expect(() => new YAMLError('Foo')).toThrow(exp)
-  expect(() => new YAMLError('Foo', {})).toThrow(exp)
+  expect(() => new YAML.YAMLError()).toThrow(exp)
+  expect(() => new YAML.YAMLError('Foo')).toThrow(exp)
+  expect(() => new YAML.YAMLError('Foo', {})).toThrow(exp)
 })
 
 test('fail on map value indented with tab', () => {
diff --git a/tests/doc/foldFlowLines.js b/tests/doc/foldFlowLines.js
index 237a8c8..c6917c6 100644
--- a/tests/doc/foldFlowLines.js
+++ b/tests/doc/foldFlowLines.js
@@ -1,9 +1,8 @@
-import {
-  foldFlowLines as fold,
-  FOLD_FLOW,
-  FOLD_QUOTED
-} from '../../src/stringify/foldFlowLines.js'
-import * as YAML from '../../src/index.js'
+import * as YAML from 'yaml'
+import { foldFlowLines as fold } from 'yaml/util'
+
+const FOLD_FLOW = 'flow'
+const FOLD_QUOTED = 'quoted'
 
 describe('plain', () => {
   const src = 'abc def ghi jkl mno pqr stu vwx yz\n'
diff --git a/tests/doc/parse.js b/tests/doc/parse.js
index 364704e..4cb8317 100644
--- a/tests/doc/parse.js
+++ b/tests/doc/parse.js
@@ -1,6 +1,6 @@
 import fs from 'fs'
 import path from 'path'
-import * as YAML from '../../index.js'
+import * as YAML from 'yaml'
 
 describe('scalars', () => {
   test('empty block scalar at end of document', () => {
diff --git a/tests/doc/stringify.js b/tests/doc/stringify.js
index 66fe7b2..147b4df 100644
--- a/tests/doc/stringify.js
+++ b/tests/doc/stringify.js
@@ -1,9 +1,9 @@
 /* global BigInt */
 
 import { source } from 'common-tags'
-import * as YAML from '../../index.js'
-import { Pair, Scalar } from '../../types.js'
-import { Type, stringifyString } from '../../util.js'
+import * as YAML from 'yaml'
+import { Pair, Scalar, Type } from 'yaml'
+import { stringifyString } from 'yaml/util'
 
 for (const [name, version] of [
   ['YAML 1.1', '1.1'],
diff --git a/tests/doc/types.js b/tests/doc/types.js
index 7322bb8..b614a0c 100644
--- a/tests/doc/types.js
+++ b/tests/doc/types.js
@@ -1,6 +1,5 @@
-import * as YAML from '../../src/index.js'
-import { Scalar } from '../../src/nodes/Scalar.js'
-import { YAMLSeq } from '../../src/nodes/YAMLSeq.js'
+import * as YAML from 'yaml'
+import { Scalar, YAMLSeq } from 'yaml'
 import { binary } from '../../src/tags/yaml-1.1/binary.js'
 import { YAMLOMap } from '../../src/tags/yaml-1.1/omap.js'
 import { YAMLSet } from '../../src/tags/yaml-1.1/set.js'
diff --git a/tests/is-node.ts b/tests/is-node.ts
index 4307d9e..fd903c1 100644
--- a/tests/is-node.ts
+++ b/tests/is-node.ts
@@ -1,5 +1,5 @@
-import { Alias, Pair, Scalar, YAMLMap, YAMLSeq } from '../types.js'
 import {
+  Alias,
   Document,
   isAlias,
   isCollection,
@@ -9,8 +9,12 @@ import {
   isPair,
   isScalar,
   isSeq,
-  parseDocument
-} from '../index.js'
+  Pair,
+  parseDocument,
+  Scalar,
+  YAMLMap,
+  YAMLSeq
+} from 'yaml'
 
 for (const { fn, exp } of [
   {
@@ -125,12 +129,12 @@ for (const { fn, exp } of [
 
     test('parsed alias', () => {
       const doc = parseDocument<YAMLSeq.Parsed>('[ &a foo, *a ]')
-      expect(fn(doc.contents.items[1])).toBe(exp.alias)
+      expect(fn(doc.contents?.items[1])).toBe(exp.alias)
     })
 
     test('parsed pair', () => {
       const doc = parseDocument<YAMLMap.Parsed>('foo: bar')
-      expect(fn(doc.contents.items[0])).toBe(exp.pair)
+      expect(fn(doc.contents?.items[0])).toBe(exp.pair)
     })
 
     test('created doc', () => {
diff --git a/tests/line-counter.ts b/tests/line-counter.ts
index c3b57fa..3835f06 100644
--- a/tests/line-counter.ts
+++ b/tests/line-counter.ts
@@ -1,4 +1,4 @@
-import { LineCounter, parseDocument } from '../index.js'
+import { LineCounter, parseDocument } from 'yaml'
 
 test('Parse error, no newlines', () => {
   const lineCounter = new LineCounter()
diff --git a/tests/properties.ts b/tests/properties.ts
index 4635af7..b25e072 100644
--- a/tests/properties.ts
+++ b/tests/properties.ts
@@ -1,5 +1,5 @@
 import * as fc from 'fast-check'
-import { parse, stringify } from '../index.js'
+import { parse, stringify } from 'yaml'
 
 describe('properties', () => {
   test('parse stringified object', () => {
diff --git a/tests/stream.ts b/tests/stream.ts
index 676ec8f..148cc7c 100644
--- a/tests/stream.ts
+++ b/tests/stream.ts
@@ -1,4 +1,4 @@
-import { Composer, Document, Parser, parseDocument } from '../index.js'
+import { Composer, Document, Parser, parseDocument } from 'yaml'
 
 const src = `
 #c0\n \n
@@ -46,7 +46,7 @@ describe('Input in parts', () => {
         '[ ee, ff ]': { 'gg gg': ['GG'] },
         '{ hh }': ['HH', 'II\rII II']
       })
-      const cb = [doc.commentBefore, doc.contents.commentBefore]
+      const cb = [doc.commentBefore, doc.contents?.commentBefore]
       expect(cb).toMatchObject(['c0\n\nc1', 'c2'])
 
       for (let i = 1; i < src.length - 1; ++i) {
@@ -65,7 +65,7 @@ describe('Input in parts', () => {
         try {
           expect(res.map(doc => doc.toJS())).toMatchObject(exp)
           expect(res[0].commentBefore).toBe(cb[0])
-          expect(res[0].contents.commentBefore).toBe(cb[1])
+          expect(res[0].contents?.commentBefore).toBe(cb[1])
         } catch (error) {
           console.log({ start, end, res })
           throw error
diff --git a/tests/tsconfig.json b/tests/tsconfig.json
new file mode 100644
index 0000000..c419157
--- /dev/null
+++ b/tests/tsconfig.json
@@ -0,0 +1,13 @@
+{
+  "extends": "../tsconfig.json",
+  "compilerOptions": {
+    "baseUrl": ".",
+    "declaration": false,
+    "paths": {
+      "yaml": ["../src/index.ts"]
+    },
+    "rootDir": "..",
+    "target": "ES3"
+  },
+  "include": ["**/*.ts"]
+}
diff --git a/tests/visit.ts b/tests/visit.ts
index 00b357b..794ee05 100644
--- a/tests/visit.ts
+++ b/tests/visit.ts
@@ -1,4 +1,4 @@
-import { Document, parseDocument, visit } from '../index.js'
+import { Document, Pair, ParsedNode, parseDocument, Scalar, visit } from 'yaml'
 
 test('Map', () => {
   const doc = parseDocument('{ one: 1, two }')
@@ -57,7 +57,7 @@ test('Seq in Map', () => {
 test('Visit called with non-Document root', () => {
   const doc = parseDocument('foo:\n  - "one"\n  - \'two\'\n')
   const fn = jest.fn()
-  visit(doc.get('foo'), fn)
+  visit(doc.get('foo') as Scalar, fn)
   expect(fn.mock.calls).toMatchObject([
     [null, { type: 'SEQ' }, []],
     [0, { type: 'QUOTE_DOUBLE', value: 'one' }, [{ type: 'SEQ' }]],
@@ -107,7 +107,8 @@ test('Change key value within Pair', () => {
   const doc = parseDocument('foo:\n  - "one"\n  - \'two\'\n')
   visit(doc, {
     Pair(_, pair) {
-      if (pair.key.value === 'foo') pair.key.value = 'bar'
+      const sc = pair.key as Scalar
+      if (sc.value === 'foo') sc.value = 'bar'
     }
   })
   expect(String(doc)).toBe('bar:\n  - "one"\n  - \'two\'\n')
diff --git a/tests/yaml-test-suite.js b/tests/yaml-test-suite.js
index 0977cf9..69eeaec 100644
--- a/tests/yaml-test-suite.js
+++ b/tests/yaml-test-suite.js
@@ -1,8 +1,8 @@
 import fs from 'fs'
 import path from 'path'
 
-import * as YAML from '../index.js'
-import { testEvents } from '../dist/test-events.js'
+import * as YAML from 'yaml'
+import { testEvents } from 'yaml/test-events'
 
 const skip = {
   B63P: ['errors'], // allow ... after directives