127 lines
3.1 KiB
JavaScript

import { useDocument } from '@terrace/core'
import { createStringReader } from '@terrace/core/readers/js-string'
const lines = [
`name @terrace/core`,
`version 0.0.1`,
`randomthing test`,
`license MIT`,
`license GPL`,
`exports`,
` .`,
` import ./dist/index.js`,
` require ./dist/index.cjs`,
` ./parser`,
` import ./dist/parser.js`,
` require ./dist/parser.cjs`,
``,
` ./document`,
` import ./dist/document.js`,
` require ./dist/document.cjs`,
``,
` ./readers/node-readline`,
` import ./dist/readers/node-readline.js`,
` require ./dist/readers/node-readline.cjs`,
``,
` ./readers/js-string`,
` import ./dist/readers/js-string.js`,
` require ./dist/readers/js-string.cjs`,
`scripts`,
` test vitest ./src`,
` build vite build`,
`devDependencies`,
` vite ^3.2.3`,
` vitest ^0.24.5`,
``,
`authors`,
` author`,
` name Joshua Bemenderfer`,
` email josh@thederf.com`,
``,
` Further comments below. As I will now demonstrate, there is no simple`,
` even if embedded`,
` way of dealing with this problem.`,
` author`,
` name Second Person`,
` email second@secondperson.com`,
` More text,`,
` across two lines.`,
`list`,
` - item1`,
` - item2`
]
// Schema
// name tail
// version tail
// license tail
// exports object
// #any object
// import tail
// require tail
// scripts object
// #any tail
// devDependencies
// #any tail
// author object
// name tail
// email tail
// #text
async function main() {
const { head, tail, next, match, level, line } = useDocument(createStringReader(lines))
const structure = {}
async function kvObject(handle) {
const obj = {}
const l = level()
while (await next(l)) {
if (!head()) continue
obj[head()] = handle ? await handle(level()) : tail().trim()
}
return obj
}
while (await next()) {
if (match('name')) structure.name = tail().trim()
if (match('version')) structure.version = tail().trim()
if (match('exports')) structure.exports = await kvObject(async l => {
const obj = {}
while (await next(l)) {
if (match('import')) obj.import = tail().trim()
if (match('require')) obj.require = tail().trim()
}
return obj
})
if (match('scripts')) structure.scripts = await kvObject()
if (match('devDependencies')) structure.devDependencies = await kvObject()
if (match('author')) {
if (!structure.authors) structure.authors = []
const author = {}
structure.authors.push(author)
const l = level()
while (await next(l)) {
if (!head()) continue
if (match('name')) author.name = tail().trim()
else if (match('email')) author.email = tail().trim()
else {
if (!author['#text']) author['#text'] = [level(), line(l + 1)]
// Loop through all remaining lines to avoid re-matching name or email above.
while(await next(l)) {
author['#text'].push(level(), line(l + 1))
}
}
}
}
}
console.dir(structure, { depth: null })
}
main()