78 lines
2.3 KiB
JavaScript
78 lines
2.3 KiB
JavaScript
import { useDocument } from '@terrace/core'
|
|
import { createStringReader } from '@terrace/core/readers/js-string'
|
|
|
|
export async function parse(lines) {
|
|
const { tail, each, match, buildObject } = useDocument(createStringReader(lines))
|
|
|
|
const structure = {
|
|
name: null,
|
|
version: null,
|
|
license: null,
|
|
exports: null,
|
|
scripts: null,
|
|
devDependencies: null,
|
|
author: null
|
|
}
|
|
|
|
await each(async () => {
|
|
if (match('name')) structure.name = tail().trim()
|
|
if (match('version')) structure.version = tail().trim()
|
|
if (match('license')) structure.license = tail().trim()
|
|
// FIXME: Order of operations causes other parts to break if this doesn't run first?!
|
|
if (match('exports')) structure.exports = await buildObject([], async () => {
|
|
const section = { import: null, require: null }
|
|
|
|
await each(() => {
|
|
if (match('import')) section.import = tail().trim()
|
|
if (match('require')) section.require = tail().trim()
|
|
if (section.import && section.require) return true
|
|
})
|
|
|
|
return section
|
|
})
|
|
if (match('scripts')) structure.scripts = await buildObject()
|
|
if (match('devDependencies')) structure.devDependencies = await buildObject()
|
|
if (match('author')) structure.author = await buildObject(['name', 'email', '#text'])
|
|
|
|
return structure.name &&
|
|
structure.version &&
|
|
structure.license &&
|
|
structure.exports &&
|
|
structure.scripts &&
|
|
structure.devDependencies &&
|
|
structure.author
|
|
})
|
|
|
|
return structure
|
|
}
|
|
|
|
export async function toArrays(lines) {
|
|
const { next, level, line } = useDocument(createStringReader(lines))
|
|
|
|
const levelTracker = []
|
|
|
|
function createScope(level, line) {
|
|
levelTracker.length = level
|
|
const scope = levelTracker[level] = [line, []]
|
|
return scope
|
|
}
|
|
createScope(0, 'root')
|
|
|
|
// Simple parser that produces canonical array structure for blocks.
|
|
while (true) {
|
|
// If next() returns true we've ended the document.
|
|
if (await next()) break;
|
|
// Determine parent for this scope.
|
|
const parent = levelTracker[level()]
|
|
// If there's no parent, skip this line.
|
|
if (!parent) continue
|
|
|
|
// Create new scope
|
|
const scope = createScope(level() + 1, line())
|
|
// Add current scope to parent.
|
|
parent[1].push(scope)
|
|
}
|
|
|
|
return levelTracker[0]
|
|
}
|