diff --git a/.changeset/selfish-fans-pump.md b/.changeset/selfish-fans-pump.md new file mode 100644 index 00000000..c27a1225 --- /dev/null +++ b/.changeset/selfish-fans-pump.md @@ -0,0 +1,5 @@ +--- +"@terrazzo/parser": patch +--- + +Fix bug in alias resolution diff --git a/.changeset/serious-wombats-invent.md b/.changeset/serious-wombats-invent.md new file mode 100644 index 00000000..cd69cd5f --- /dev/null +++ b/.changeset/serious-wombats-invent.md @@ -0,0 +1,5 @@ +--- +"@terrazzo/parser": patch +--- + +Fix type error with parser output diff --git a/packages/parser/src/parse/alias.ts b/packages/parser/src/parse/alias.ts index f2c992f3..87c527c9 100644 --- a/packages/parser/src/parse/alias.ts +++ b/packages/parser/src/parse/alias.ts @@ -130,7 +130,7 @@ export function applyAliases( const { id: aliasID, mode: aliasMode } = parseAlias(subvalue); const aliasToken = tokens[aliasOfID]!; const possibleTypes: string[] = expectedAliasTypes?.[property as keyof typeof expectedAliasTypes] || []; - if (!possibleTypes.includes(aliasToken.$type)) { + if (possibleTypes.length && !possibleTypes.includes(aliasToken.$type)) { const elementNode = ($valueNode as ArrayNode).elements[i]!.value; logger.error({ message: `Invalid alias: expected $type: "${possibleTypes.join('" or "')}", received $type: "${aliasToken.$type}".`, diff --git a/packages/parser/src/parse/index.ts b/packages/parser/src/parse/index.ts index bd4b5ef2..df3ebda4 100644 --- a/packages/parser/src/parse/index.ts +++ b/packages/parser/src/parse/index.ts @@ -3,11 +3,10 @@ import { type Token, type TokenNormalized, isTokenMatch, pluralize, splitID } fr import type ytm from 'yaml-to-momoa'; import lintRunner from '../lint/index.js'; import Logger from '../logger.js'; -import type { ConfigInit } from '../types.js'; +import type { ConfigInit, InputSource } from '../types.js'; import { applyAliases } from './alias.js'; import { getObjMembers, injectObjMembers, maybeJSONString, traverse } from './json.js'; import normalize from './normalize.js'; -import type { ParseInput } from './types.js'; import validate from './validate.js'; export * from './validate.js'; @@ -31,12 +30,12 @@ export interface ParseOptions { export interface ParseResult { tokens: Record; - sources: Record; + sources: InputSource[]; } /** Parse */ export default async function parse( - input: ParseInput[], + input: Omit[], { logger = new Logger(), skipLint = false, @@ -48,7 +47,7 @@ export default async function parse( let tokens: Record = {}; // note: only keeps track of sources with locations on disk; in-memory sources are discarded // (it’s only for reporting line numbers, which doesn’t mean as much for dynamic sources) - const sources: Record = {}; + const sources: Record = {}; if (!Array.isArray(input)) { logger.error({ group: 'parser', label: 'init', message: 'Input must be an array of input objects.' }); @@ -86,6 +85,7 @@ export default async function parse( sources[input[i]!.filename!.protocol === 'file:' ? input[i]!.filename!.href : input[i]!.filename!.href] = { filename: input[i]!.filename, src: result.src, + document: result.document, }; } } @@ -170,7 +170,7 @@ export default async function parse( return { tokens, - sources, + sources: Object.values(sources), }; } @@ -449,5 +449,9 @@ async function parseSingle( timing: performance.now() - normalizeStart, }); - return { tokens, document, src }; + return { + tokens, + document, + src, + }; } diff --git a/packages/parser/src/parse/types.ts b/packages/parser/src/parse/types.ts deleted file mode 100644 index fb2fd6eb..00000000 --- a/packages/parser/src/parse/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface ParseInput { - /** Source filename (if read from disk) */ - filename?: URL; - /** JSON/YAML string, or JSON-serializable object (if already in memory) */ - src: string | object; -} diff --git a/packages/plugin-css/test/cli.test.ts b/packages/plugin-css/test/cli.test.ts index 96ac6dad..fd90cf49 100644 --- a/packages/plugin-css/test/cli.test.ts +++ b/packages/plugin-css/test/cli.test.ts @@ -67,7 +67,7 @@ describe('tz build', () => { it('outDir', async () => { const cwd = new URL('./fixtures/cli-config-outdir/', import.meta.url); await execa('node', [cmd, 'build'], { cwd }); - expect(fs.readFileSync(new URL('./styles/out/actual.css', cwd), 'utf8')).toMatchFileSnapshot( + await expect(fs.readFileSync(new URL('./styles/out/actual.css', cwd), 'utf8')).toMatchFileSnapshot( fileURLToPath(new URL('./styles/out/want.css', cwd)), ); }); diff --git a/packages/plugin-css/test/js.test.ts b/packages/plugin-css/test/js.test.ts index b9d9914a..1f383260 100644 --- a/packages/plugin-css/test/js.test.ts +++ b/packages/plugin-css/test/js.test.ts @@ -62,7 +62,7 @@ describe('Node.js API', () => { config, }); const result = await build(tokens, { sources, config }); - expect(result.outputFiles.find((f) => f.filename === output)?.contents).toMatchFileSnapshot( + await expect(result.outputFiles.find((f) => f.filename === output)?.contents).toMatchFileSnapshot( fileURLToPath(new URL('./want.css', cwd)), ); }, @@ -93,12 +93,16 @@ describe('Node.js API', () => { { cwd }, ); const tokensJSON = new URL('./tokens.json', cwd); - const { tokens, sources } = await parse([{ filename: tokensJSON, src: fs.readFileSync(tokensJSON, 'utf8') }], { - config, - }); - const result = await build(tokens, { sources, config }); - expect(result.outputFiles.find((f) => f.filename === output)?.contents).toMatchFileSnapshot( - fileURLToPath(new URL('./want.css', cwd)), - ); + try { + const { tokens, sources } = await parse([{ filename: tokensJSON, src: fs.readFileSync(tokensJSON, 'utf8') }], { + config, + }); + const result = await build(tokens, { sources, config }); + await expect(result.outputFiles.find((f) => f.filename === output)?.contents).toMatchFileSnapshot( + fileURLToPath(new URL('./want.css', cwd)), + ); + } catch (err) { + console.error(err); + } }); }); diff --git a/packages/plugin-js/test/index.test.ts b/packages/plugin-js/test/index.test.ts index 668fb2a0..f33c35b0 100644 --- a/packages/plugin-js/test/index.test.ts +++ b/packages/plugin-js/test/index.test.ts @@ -24,10 +24,10 @@ describe('@terrazzo/plugin-js', () => { config, }); const result = await build(tokens, { sources, config }); - expect(result.outputFiles.find((f) => f.filename === filename)?.contents).toMatchFileSnapshot( + await expect(result.outputFiles.find((f) => f.filename === filename)?.contents).toMatchFileSnapshot( fileURLToPath(new URL('./want.js', cwd)), ); - expect( + await expect( result.outputFiles.find((f) => f.filename === filename.replace(/\.js$/, '.d.ts'))?.contents, ).toMatchFileSnapshot(fileURLToPath(new URL('./want.d.ts', cwd))); diff --git a/packages/plugin-sass/test/index.test.ts b/packages/plugin-sass/test/index.test.ts index cba304a8..9067ada2 100644 --- a/packages/plugin-sass/test/index.test.ts +++ b/packages/plugin-sass/test/index.test.ts @@ -30,7 +30,7 @@ describe('@terrazzo/plugin-scss', () => { config, }); const result = await build(tokens, { sources, config }); - expect(result.outputFiles.find((f) => f.filename === filename)?.contents).toMatchFileSnapshot( + await expect(result.outputFiles.find((f) => f.filename === filename)?.contents).toMatchFileSnapshot( fileURLToPath(new URL('./want.scss', cwd)), ); }); diff --git a/packages/plugin-swift/test/index.test.ts b/packages/plugin-swift/test/index.test.ts index 670eee53..10a6cdff 100644 --- a/packages/plugin-swift/test/index.test.ts +++ b/packages/plugin-swift/test/index.test.ts @@ -24,7 +24,7 @@ describe('@terrazzo/plugin-swift', () => { }); const result = await build(tokens, { config, sources }); for (const { filename, contents } of result.outputFiles) { - expect(contents).toMatchFileSnapshot(fileURLToPath(new URL(filename, cwd))); + await expect(contents).toMatchFileSnapshot(fileURLToPath(new URL(filename, cwd))); } }); }); diff --git a/packages/plugin-tailwind/test/index.test.ts b/packages/plugin-tailwind/test/index.test.ts index 7d5d3e25..b84ed7ff 100644 --- a/packages/plugin-tailwind/test/index.test.ts +++ b/packages/plugin-tailwind/test/index.test.ts @@ -60,20 +60,16 @@ describe('@cobalt-ui/plugin-tailwind', () => { const config = defineConfig( { outDir: './cjs/', - plugins: [ - pluginTailwind({ - ...baseConfig, - filename: './actual.js', - format: 'cjs', - }), - ], + plugins: [pluginTailwind({ ...baseConfig, filename: './actual.js', format: 'cjs' })], }, { cwd }, ); - const { tokens, ast } = await parse(fs.readFileSync(new URL('../tokens.yaml', cwd), 'utf8')); - await build(tokens, { ast, config }); + const { tokens, sources } = await parse([{ src: fs.readFileSync(new URL('../tokens.yaml', cwd), 'utf8') }], { + config, + }); + await build(tokens, { sources, config }); - expect(fs.readFileSync(new URL('./actual.js', cwd), 'utf8')).toMatchFileSnapshot( + await expect(fs.readFileSync(new URL('./actual.js', cwd), 'utf8')).toMatchFileSnapshot( fileURLToPath(new URL('./want.js', cwd)), ); }); @@ -83,20 +79,16 @@ describe('@cobalt-ui/plugin-tailwind', () => { const config = defineConfig( { outDir: './cjs/', - plugins: [ - pluginTailwind({ - ...baseConfig, - filename: './actual.js', - format: 'esm', - }), - ], + plugins: [pluginTailwind({ ...baseConfig, filename: './actual.js', format: 'esm' })], }, { cwd }, ); - const { tokens, ast } = await parse(fs.readFileSync(new URL('../tokens.yaml', cwd), 'utf8')); - await build(tokens, { ast, config }); + const { tokens, sources } = await parse([{ src: fs.readFileSync(new URL('../tokens.yaml', cwd), 'utf8') }], { + config, + }); + await build(tokens, { sources, config }); - expect(fs.readFileSync(new URL('./actual.js', cwd), 'utf8')).toMatchFileSnapshot( + await expect(fs.readFileSync(new URL('./actual.js', cwd), 'utf8')).toMatchFileSnapshot( fileURLToPath(new URL('./want.js', cwd)), ); });