diff --git a/.size-limit.js b/.size-limit.js index a32e7e4..93b2ba6 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -28,7 +28,7 @@ export default [ name: 'merge' }, { - limit: '2.005 kB', + limit: '2.04 kB', name: 'all', path: 'index.js' } diff --git a/lib/parse/flat-parse.js b/lib/parse/flat-parse.js index ff47d56..2a090f1 100644 --- a/lib/parse/flat-parse.js +++ b/lib/parse/flat-parse.js @@ -13,14 +13,15 @@ const itemEnhancer = opts => { } } -const bookmarksBuilder = ({ add, describe, enhance }) => { +const bookmarksBuilder = ({ add, describe, enhance, transform }) => { const foldersStack = [] let currFolder return { addBookmark: (title, attrs) => { const bookmark = enhance({ folder: currFolder, title }, attrs) - add(bookmark) + const transformed = transform(bookmark) + transformed && add(transformed) }, closeFolder: () => { foldersStack.pop() @@ -40,7 +41,8 @@ export const flatParse = (txt, opts = {}) => { const add = b => bookmarks.push(b) const describe = d => (bookmarks.at(-1).description = d) const enhance = itemEnhancer(opts) - const handlers = bookmarksBuilder({ add, describe, enhance }) + const transform = opts.transform || (x => x) + const handlers = bookmarksBuilder({ add, describe, enhance, transform }) traverse(txt, handlers) return bookmarks } diff --git a/readme.md b/readme.md index 409543a..78188eb 100644 --- a/readme.md +++ b/readme.md @@ -135,10 +135,11 @@ const bookmarks = flatParse(html) You can configure the output by activating options passed as the second argument. -| Option | Type | Description | -| -------------- | ---------- | ------------------------------------------------------------------------------------------- | -| `excludeAttrs` | `string[]` | Excludes specified attributes from output. See [attributes definition](./types/attrs.d.ts). | -| `withId` | `boolean` | Adds incremental numeric `id` to items. | +| Option | Type | Description | +| -------------- | --------------------------- | ------------------------------------------ | +| `excludeAttrs` | `string[]` | Excludes specified attributes from output. | +| `withId` | `boolean` | Adds incremental numeric `id` to items. | +| `transform` | `(item: FlatBookmark) => T` | Transforms items, omitting falsy returns. | ### `customParse` @@ -183,7 +184,7 @@ const stringified = stringify(parsed) Converts the flat list from `flatParse` back into an HTML string. -> It requires using `flatParse` with `{ withId: true }` to ensure unique item IDs. +> It requires using `flatParse` with `{ withId: true }` to ensure unique item IDs, and without `transform` to ensure a known structure. ```js import { flatParse, flatStringify } from 'nbff-parser' diff --git a/test/parse/flat-parse.spec.js b/test/parse/flat-parse.spec.js index db8464c..35447d6 100644 --- a/test/parse/flat-parse.spec.js +++ b/test/parse/flat-parse.spec.js @@ -185,6 +185,41 @@ describe('flat-parse', () => { deepEqual(actual, expected) }) + test('with transform', () => { + const initial = ` +

JavaScript

+

+

TC39 - Specifying JavaScript. +

Engines

+

+

V8 JavaScript engine +

+

+ ` + + const transform = item => { + if (item.personal_toolbar_folder) return + + return { + tag: item.folder.map(f => f.title).join(' / '), + title: item.title, + url: item.href + } + } + + const actual = flatParse(initial, { transform }) + + const expected = [ + { + tag: 'JavaScript / Engines', + title: 'V8 JavaScript engine', + url: 'https://v8.dev/' + } + ] + + deepEqual(actual, expected) + }) + describe('bookmarks-1.html', () => { const initial = readFile('./bookmarks-1.html') diff --git a/test/parse/flat-parse.types.ts b/test/parse/flat-parse.types.ts index ad48807..df5ddbb 100644 --- a/test/parse/flat-parse.types.ts +++ b/test/parse/flat-parse.types.ts @@ -1,4 +1,4 @@ -import { FlatBookmark, FlatBookmarkWithId } from '../../index.js' +import { FlatBookmark, FlatBookmarkWithId, flatParse } from '../../index.js' // We check the relevance of types here via `pnpm test:types`. @@ -45,3 +45,25 @@ const bookmarkWithId: Required = { ], id: 0 } + +const parser = flatParse('..') +parser satisfies FlatBookmark[] + +const parserWithId = flatParse('..', { withId: true }) +parserWithId satisfies FlatBookmark[] +parserWithId satisfies FlatBookmarkWithId[] + +const parserWithTransform = flatParse('..', { + transform: item => { + if (!item.href) return + return ({ name: item.title, url: item.href }) + } +}) +parserWithTransform satisfies { name: string, url: string }[] + +const parserWithIdent = flatParse('..', { transform: item => item }) +parserWithIdent satisfies FlatBookmark[] + +const parserWithIdAndIdent = flatParse('..', { withId: true, transform: item => item }) +parserWithIdAndIdent satisfies FlatBookmark[] +parserWithIdAndIdent satisfies FlatBookmarkWithId[] diff --git a/types/parse/flat-parse.d.ts b/types/parse/flat-parse.d.ts index d42cfeb..61e430b 100644 --- a/types/parse/flat-parse.d.ts +++ b/types/parse/flat-parse.d.ts @@ -15,18 +15,22 @@ export type FlatBookmarkWithId = WithId< } > +type Truthy = V extends null | undefined | false | 0 | "" ? never : V + // Overload signatures. -export function flatParse( +export function flatParse( text: string, options?: Partial<{ excludeAttrs: AllAttrKeys[] withId: false + transform: (item: FlatBookmark) => T }> -): FlatBookmark[] -export function flatParse( +): Truthy[] +export function flatParse( text: string, options: { excludeAttrs?: AllAttrKeys[] withId: true + transform?: (item: FlatBookmarkWithId) => T } -): FlatBookmarkWithId[] +): Truthy[]