@prismicio/richtext
Advanced tools
Comparing version 1.1.0 to 2.0.0-alpha.0
108
package.json
{ | ||
"name": "@prismicio/richtext", | ||
"version": "1.1.0", | ||
"description": "Convert Rich Text raw data to generic tree to simplify serialization", | ||
"main": "dist/prismic-richtext.min.js", | ||
"scripts": { | ||
"build": "webpack --debug; webpack -p", | ||
"dev": "webpack -d --watch", | ||
"prepublish": "npm run build; npm run docs", | ||
"docs": "typedoc --mode file --out ./docs/ ./src/", | ||
"lint": "tslint src", | ||
"posttest": "tslint lib", | ||
"test": "mocha -r jsdom-global/register" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/prismicio/prismic-richtext.git" | ||
}, | ||
"author": "", | ||
"license": "ISC", | ||
"bugs": { | ||
"url": "https://github.com/prismicio/prismic-richtext/issues" | ||
}, | ||
"homepage": "https://github.com/prismicio/prismic-richtext#readme", | ||
"devDependencies": { | ||
"@babel/core": "^7.2.2", | ||
"@babel/plugin-transform-modules-commonjs": "^7.2.0", | ||
"@babel/preset-env": "^7.4.5", | ||
"@babel/preset-typescript": "^7.1.0", | ||
"@types/node": "^12.7.5", | ||
"@types/ramda": "0.25.44", | ||
"babel-loader": "^8.0.4", | ||
"babel-plugin-ramda": "^2.0.0", | ||
"chai": "^4.1.2", | ||
"chai-subset": "^1.6.0", | ||
"jsdom": "^13.1.0", | ||
"jsdom-global": "^3.0.2", | ||
"mocha": "^4.0.1", | ||
"tslint": "^5.11.0", | ||
"typedoc": "^0.15.0", | ||
"typescript": "^3.2.2", | ||
"webpack": "^4.27.1", | ||
"webpack-cli": "^3.1.2", | ||
"yargs": "^10.0.3" | ||
} | ||
"name": "@prismicio/richtext", | ||
"version": "2.0.0-alpha.0", | ||
"description": "A parser and serializer for Prismic's Rich Text format", | ||
"keywords": [ | ||
"typescript", | ||
"prismic" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "ssh://git@github.com/prismicio/prismic-richtext.git" | ||
}, | ||
"license": "Apache-2.0", | ||
"author": "Prismic <contact@prismic.io> (https://prismic.io)", | ||
"type": "module", | ||
"exports": { | ||
".": { | ||
"require": "./dist/index.cjs", | ||
"import": "./dist/index.mjs" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"scripts": { | ||
"build": "siroc build", | ||
"dev": "siroc build --watch", | ||
"format": "prettier --write .", | ||
"prepare": "npm run build", | ||
"release": "npm run build && npm run test && standard-version && git push --follow-tags && npm run build && npm publish", | ||
"release:dry": "standard-version --dry-run", | ||
"release:alpha": "npm run build && npm run test && standard-version --release-as major --prerelease alpha && git push --follow-tags && npm run build && npm publish --tag alpha", | ||
"release:alpha:dry": "standard-version --release-as major --prerelease alpha --dry-run", | ||
"lint": "eslint --ext .js,.ts .", | ||
"unit": "nyc --reporter=lcovonly --reporter=text --exclude-after-remap=false ava", | ||
"test": "npm run lint && npm run unit" | ||
}, | ||
"dependencies": { | ||
"@prismicio/types": "^0.0.10" | ||
}, | ||
"devDependencies": { | ||
"@typescript-eslint/eslint-plugin": "^4.28.0", | ||
"@typescript-eslint/parser": "^4.28.0", | ||
"ava": "^3.15.0", | ||
"eslint": "^7.29.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-plugin-prettier": "^3.4.0", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.3.1", | ||
"siroc": "^0.11.1", | ||
"standard-version": "^9.3.0", | ||
"ts-eager": "^2.0.2", | ||
"typescript": "^4.3.4" | ||
}, | ||
"engines": { | ||
"node": ">=12.7.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
100
README.md
@@ -1,21 +0,91 @@ | ||
## A helper to build generic tree from rich text raw json | ||
# @prismicio/richtext | ||
### Get a generic tree from a richtext | ||
```javascript | ||
import PrismicRichText from 'prismic-richtext'; | ||
[![npm version][npm-version-src]][npm-version-href] | ||
[![npm downloads][npm-downloads-src]][npm-downloads-href] | ||
[![Github Actions CI][github-actions-ci-src]][github-actions-ci-href] | ||
[![Codecov][codecov-src]][codecov-href] | ||
[![Conventional Commits][conventional-commits-src]][conventional-commits-href] | ||
[![License][license-src]][license-href] | ||
PrismicRichText.asTree(doc.data.myRichText) | ||
A parser and serializer for [Prismic][prismic]'s Rich Text format. | ||
- 🌳 Builds a generic tree from Rich Text | ||
- 🧬 Serializes Rich Text into a different format (e.g. HTML or React components) | ||
- ✂️ Strips formatting from Rich Text to extract raw text | ||
You probably do not need to use this package directly. The following libraries provide a more accessible API: | ||
- [`@prismicio/helpers`](https://github.com/prismicio/prismic-helpers): `asText`, `asHTML` | ||
- [`@prismicio/react`](https://github.com/prismicio/prismic-reactjs): `<PrismicText>`, `<PrismicRichText>` | ||
- [`@prismicio/vue`](https://github.com/prismicio/prismic-vue): `<prismic-rich-text>` | ||
## Install | ||
```bash | ||
npm install @prismicio/richtext | ||
``` | ||
### Get a serialized tree from a richtext | ||
## Documentation | ||
You can find an example here: https://github.com/prismicio/prismic-dom/blob/master/src/index.js | ||
To discover what's new on this package check out [the changelog][changelog]. For full documentation, visit the [official Prismic documentation][prismic-docs]. | ||
```javascript | ||
import PrismicRichText from 'prismic-richtext'; | ||
// define a serialize function to manage your fragment | ||
// you can use the 'Element' Helper from PrismicRichText to match the different fragments | ||
function serialize() {...} | ||
PrismicRichText.serialize(doc.data.myRichText, serialize, htmlSerializer) | ||
``` | ||
## Contributing | ||
Whether you're helping us fix bugs, improve the docs, or spread the word, we'd love to have you as part of the Prismic developer community! | ||
**Asking a question**: [Open a new topic][forum-question] on our community forum explaining what you want to achieve / your question. Our support team will get back to you shortly. | ||
**Reporting a bug**: [Open an issue][repo-bug-report] explaining your application's setup and the bug you're encountering. | ||
**Suggesting an improvement**: [Open an issue][repo-feature-request] explaining your improvement or feature so we can discuss and learn more. | ||
**Submitting code changes**: For small fixes, feel free to [open a PR][repo-pull-requests] with a description of your changes. For large changes, please first [open an issue][repo-feature-request] so we can discuss if and how the changes should be implemented. | ||
## License | ||
``` | ||
Copyright 2013-2021 Prismic <contact@prismic.io> (https://prismic.io) | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
``` | ||
<!-- Links --> | ||
[prismic]: https://prismic.io | ||
<!-- TODO: Replace link with a more useful one if available --> | ||
[prismic-docs]: https://prismic.io/docs | ||
[changelog]: /CHANGELOG.md | ||
<!-- TODO: Replace link with a more useful one if available --> | ||
[forum-question]: https://community.prismic.io | ||
[repo-bug-report]: https://github.com/prismicio/prismic-richtext/issues/new?assignees=&labels=bug&template=bug_report.md&title= | ||
[repo-feature-request]: https://github.com/prismicio/prismic-richtext/issues/new?assignees=&labels=enhancement&template=feature_request.md&title= | ||
[repo-pull-requests]: https://github.com/prismicio/prismic-richtext/pulls | ||
<!-- Badges --> | ||
[npm-version-src]: https://img.shields.io/npm/v/@prismicio/richtext/latest.svg | ||
[npm-version-href]: https://npmjs.com/package/@prismicio/richtext | ||
[npm-downloads-src]: https://img.shields.io/npm/dm/@prismicio/richtext.svg | ||
[npm-downloads-href]: https://npmjs.com/package/@prismicio/richtext | ||
[github-actions-ci-src]: https://github.com/prismicio/prismic-richtext/workflows/ci/badge.svg | ||
[github-actions-ci-href]: https://github.com/prismicio/prismic-richtext/actions?query=workflow%3Aci | ||
[codecov-src]: https://img.shields.io/codecov/c/github/prismicio/prismic-richtext.svg | ||
[codecov-href]: https://codecov.io/gh/prismicio/prismic-richtext | ||
[conventional-commits-src]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg | ||
[conventional-commits-href]: https://conventionalcommits.org | ||
[license-src]: https://img.shields.io/npm/l/@prismicio/richtext.svg | ||
[license-href]: https://npmjs.com/package/@prismicio/richtext |
@@ -1,11 +0,16 @@ | ||
import asText from "./astext"; | ||
import Tree from "./tree"; | ||
import Serialize from "./serialize"; | ||
import { NODE_TYPES } from "./types"; | ||
export { asTree } from "./asTree"; | ||
export { asText } from "./asText"; | ||
module.exports = { | ||
asText, | ||
asTree: Tree.fromRichText, | ||
serialize: Serialize, | ||
Elements: NODE_TYPES, | ||
}; | ||
export { serialize } from "./serialize"; | ||
export { wrapMapSerializer } from "./wrapMapSerializer"; | ||
export { composeSerializers } from "./composeSerializers"; | ||
export { RichTextNodeType as Element } from "@prismicio/types"; | ||
export { RichTextError } from "./RichTextError"; | ||
export type { | ||
RichTextFunctionSerializer, | ||
RichTextMapSerializer, | ||
RichTextMapSerializerFunction, | ||
} from "./types"; |
@@ -1,29 +0,53 @@ | ||
import Tree from './tree'; | ||
import { Node, SpanNode, NodeElement } from './nodes'; | ||
import { RichTextBlock } from './richtext'; | ||
import { RichTextField } from "@prismicio/types"; | ||
import { RichTextFunctionSerializer, TreeNode } from "./types"; | ||
import { asTree } from "./asTree"; | ||
type Serializer<T> = (type: string, element: NodeElement, text: string | null, children: T[], index: number) => T; | ||
/** | ||
* Serializes a rich text or title field with a given serializer | ||
* | ||
* @param richTextField - A rich text or title field from Prismic | ||
* @param serializer - A function serializer to apply | ||
* | ||
* @returns An array of serialized nodes | ||
* | ||
* @typeParam SerializerReturnType - Return type of the serializer | ||
* | ||
* @see Templating rich text and title fields from Prismic {@link https://prismic.io/docs/technologies/templating-rich-text-and-title-fields-javascript} | ||
* | ||
* @remarks | ||
* | ||
* This is a low level helper mainly intended to be used by higher level packages | ||
* Most users aren't expected to this function directly | ||
*/ | ||
export const serialize = <SerializerReturnType>( | ||
richTextField: RichTextField, | ||
serializer: RichTextFunctionSerializer<SerializerReturnType>, | ||
): SerializerReturnType[] => { | ||
return serializeTreeNodes<SerializerReturnType>( | ||
asTree(richTextField).children, | ||
serializer, | ||
); | ||
}; | ||
function fromRichText<T>(richText: RichTextBlock[], serialize: Serializer<T>, htmlSerializer?: Serializer<T>): T[] { | ||
const tree = Tree.fromRichText(richText); | ||
return tree.children.map((node: Node, index: number) => { | ||
return serializeNode<T>(node, serialize, index, htmlSerializer); | ||
}); | ||
} | ||
const serializeTreeNodes = <T>( | ||
nodes: TreeNode[], | ||
serializer: RichTextFunctionSerializer<T>, | ||
): T[] => { | ||
const serializedTreeNodes: T[] = []; | ||
function serializeNode<T>(parentNode: Node, serializer: Serializer<T>, index: number, htmlSerializer?: Serializer<T>): T { | ||
for (let i = 0; i < nodes.length; i++) { | ||
const node = nodes[i]; | ||
function step(node: Node, idx: number): T { | ||
const text = node instanceof SpanNode ? node.text : null; | ||
const serializedChildren = node.children.reduce<T[]>((acc: T[], node: Node, i: number) => { | ||
return acc.concat([step(node, i)]); | ||
}, []); | ||
serializedTreeNodes.push( | ||
serializer( | ||
node.type, | ||
node.node, | ||
node.text, | ||
serializeTreeNodes(node.children, serializer), | ||
node.key, | ||
), | ||
); | ||
} | ||
const maybeSerialized = htmlSerializer && htmlSerializer(node.type, node.element, text, serializedChildren, idx); | ||
return maybeSerialized || serializer(node.type, node.element, text, serializedChildren, idx); | ||
} | ||
return step(parentNode, index); | ||
} | ||
export default fromRichText; | ||
return serializedTreeNodes; | ||
}; |
212
src/types.ts
@@ -1,45 +0,173 @@ | ||
import { SpanNode } from './nodes'; | ||
import { | ||
RichTextNodeType, | ||
RTBlockNode, | ||
RTEmbedNode, | ||
RTEmNode, | ||
RTHeading1Node, | ||
RTHeading2Node, | ||
RTHeading3Node, | ||
RTHeading4Node, | ||
RTHeading5Node, | ||
RTHeading6Node, | ||
RTImageNode, | ||
RTInlineNode, | ||
RTLabelNode, | ||
RTLinkNode, | ||
RTListItemNode, | ||
RTListNode, | ||
RTOListItemNode, | ||
RTOListNode, | ||
RTParagraphNode, | ||
RTPreformattedNode, | ||
RTSpanNode, | ||
RTStrongNode, | ||
RTTextNodeBase, | ||
} from "@prismicio/types"; | ||
export const NODE_TYPES = { | ||
heading1: "heading1", | ||
heading2: "heading2", | ||
heading3: "heading3", | ||
heading4: "heading4", | ||
heading5: "heading5", | ||
heading6: "heading6", | ||
paragraph: "paragraph", | ||
preformatted: "preformatted", | ||
strong: "strong", | ||
em: "em", | ||
listItem: "list-item", | ||
oListItem: "o-list-item", | ||
list: "group-list-item", | ||
oList: "group-o-list-item", | ||
image: "image", | ||
embed: "embed", | ||
hyperlink: "hyperlink", | ||
label: "label", | ||
span: "span", | ||
// Serializers | ||
/** | ||
* Serializes a node from a rich text or title field with a function | ||
* | ||
* @typeParam ReturnType - Return type of the function serializer | ||
* | ||
* @see Templating rich text and title fields from Prismic {@link https://prismic.io/docs/technologies/templating-rich-text-and-title-fields-javascript} | ||
*/ | ||
export type RichTextFunctionSerializer<ReturnType> = ( | ||
type: RichTextNodeType, | ||
node: RTAnyNode, | ||
text: string | undefined, | ||
children: ReturnType[], | ||
key: string, | ||
) => ReturnType; | ||
/** | ||
* Map serializer's tag function serializer, can be helpful for typing those handlers | ||
* | ||
* @typeParam ReturnType - Return type of the tag serializer | ||
*/ | ||
export type RichTextMapSerializerFunction< | ||
ReturnType, | ||
Node extends { type: RichTextNodeType } = RTBlockNode | RTInlineNode, | ||
TextType = string | undefined, | ||
ChildrenType = ReturnType, | ||
> = (payload: { | ||
type: Node["type"]; | ||
node: Node; | ||
text: TextType; | ||
children: ChildrenType[]; | ||
key: string; | ||
}) => ReturnType; | ||
/** | ||
* Serializes a node from a rich text or title field with a map | ||
* | ||
* @typeParam ReturnType - Return type of the map serializer | ||
* | ||
* @see Templating rich text and title fields from Prismic {@link https://prismic.io/docs/technologies/templating-rich-text-and-title-fields-javascript} | ||
* | ||
* @remarks | ||
* | ||
* This type of serializer needs to be processed through {@link wrapMapSerializer} | ||
* before being used with {@link serialize} | ||
*/ | ||
export type RichTextMapSerializer<ReturnType> = { | ||
heading1?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTHeading1Node, | ||
undefined | ||
>; | ||
heading2?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTHeading2Node, | ||
undefined | ||
>; | ||
heading3?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTHeading3Node, | ||
undefined | ||
>; | ||
heading4?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTHeading4Node, | ||
undefined | ||
>; | ||
heading5?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTHeading5Node, | ||
undefined | ||
>; | ||
heading6?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTHeading6Node, | ||
undefined | ||
>; | ||
paragraph?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTParagraphNode, | ||
undefined | ||
>; | ||
preformatted?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTPreformattedNode, | ||
undefined | ||
>; | ||
strong?: RichTextMapSerializerFunction<ReturnType, RTStrongNode, string>; | ||
em?: RichTextMapSerializerFunction<ReturnType, RTEmNode, string>; | ||
listItem?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTListItemNode, | ||
undefined | ||
>; | ||
oListItem?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTOListItemNode, | ||
undefined | ||
>; | ||
list?: RichTextMapSerializerFunction<ReturnType, RTListNode, undefined>; | ||
oList?: RichTextMapSerializerFunction<ReturnType, RTOListNode, undefined>; | ||
image?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTImageNode, | ||
undefined, | ||
never | ||
>; | ||
embed?: RichTextMapSerializerFunction< | ||
ReturnType, | ||
RTEmbedNode, | ||
undefined, | ||
never | ||
>; | ||
hyperlink?: RichTextMapSerializerFunction<ReturnType, RTLinkNode, string>; | ||
label?: RichTextMapSerializerFunction<ReturnType, RTLabelNode, string>; | ||
span?: RichTextMapSerializerFunction<ReturnType, RTSpanNode, string, never>; | ||
}; | ||
export const PRIORITIES = { | ||
[NODE_TYPES.heading1]: 4, | ||
[NODE_TYPES.heading2]: 4, | ||
[NODE_TYPES.heading3]: 4, | ||
[NODE_TYPES.heading4]: 4, | ||
[NODE_TYPES.heading5]: 4, | ||
[NODE_TYPES.heading6]: 4, | ||
[NODE_TYPES.paragraph]: 3, | ||
[NODE_TYPES.preformatted]: 5, | ||
[NODE_TYPES.strong]: 6, | ||
[NODE_TYPES.em]: 6, | ||
[NODE_TYPES.oList]: 1, | ||
[NODE_TYPES.list]: 1, | ||
[NODE_TYPES.listItem]: 1, | ||
[NODE_TYPES.oListItem]: 1, | ||
[NODE_TYPES.image]: 1, | ||
[NODE_TYPES.embed]: 1, | ||
[NODE_TYPES.hyperlink]: 3, | ||
[NODE_TYPES.label]: 4, | ||
[NODE_TYPES.span]: 7, | ||
}; | ||
// Tree | ||
export interface Tree { | ||
key: string; | ||
children: TreeNode[]; | ||
} | ||
export interface TreeNode { | ||
key: string; | ||
type: RichTextNodeType; | ||
text?: string; | ||
node: RTAnyNode; | ||
children: TreeNode[]; | ||
} | ||
// Helpers | ||
export type RTAnyNode = RTBlockNode | RTInlineNode | RTBlockSpanNode; | ||
// Internal node type used when building the tree | ||
export interface RTBlockSpanNode extends RTTextNodeBase { | ||
type: RichTextNodeType.span; | ||
} | ||
export const RichTextReversedNodeType = { | ||
[RichTextNodeType.listItem]: "listItem", | ||
[RichTextNodeType.oListItem]: "oListItem", | ||
[RichTextNodeType.list]: "list", | ||
[RichTextNodeType.oList]: "oList", | ||
} as const; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
12
92
0
Yes
48514
1
14
989
2
+ Added@prismicio/types@^0.0.10
+ Added@prismicio/types@0.0.10(transitive)