datocms-structured-text-utils
Advanced tools
Comparing version 1.0.3 to 1.0.4
@@ -5,3 +5,32 @@ export declare type Node = BlockNode | InlineNode; | ||
export declare type RootType = 'root'; | ||
/** Root represents a document */ | ||
/** | ||
* Every `dast` document MUST start with a `root` node. | ||
* | ||
* ```json | ||
* { | ||
* "type": "root", | ||
* "children": [ | ||
* { | ||
* "type": "heading", | ||
* "level": 1, | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "Title" | ||
* } | ||
* ] | ||
* }, | ||
* { | ||
* "type": "paragraph", | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "A simple paragraph!" | ||
* } | ||
* ] | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Root = { | ||
@@ -12,3 +41,17 @@ type: RootType; | ||
export declare type ParagraphType = 'paragraph'; | ||
/** Paragraph represents a unit of textual content */ | ||
/** | ||
* A `paragraph` node represents a unit of textual content. | ||
* | ||
* ```json | ||
* { | ||
* "type": "paragraph", | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "A simple paragraph!" | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Paragraph = { | ||
@@ -19,3 +62,19 @@ type: ParagraphType; | ||
export declare type HeadingType = 'heading'; | ||
/** Heading represents a heading of a section */ | ||
/** | ||
* An `heading` node represents a heading of a section. Using the `level` attribute you | ||
* can control the rank of the heading. | ||
* | ||
* ```json | ||
* { | ||
* "type": "heading", | ||
* "level": 2, | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "An h2 heading!" | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Heading = { | ||
@@ -28,7 +87,28 @@ type: HeadingType; | ||
/** | ||
List represents a list of items. | ||
Unordered lists must have its `style` field set to `bulleted`. | ||
Ordered lists, instead, have its `style` field set to `numbered`. | ||
*/ | ||
* A `list` node represents a list of items. Unordered lists must have its `style` field | ||
* set to `bulleted`, while ordered lists, instead, have its `style` field set to `numbered`. | ||
* | ||
* ```json | ||
* { | ||
* "type": "list", | ||
* "style": "bulleted", | ||
* "children": [ | ||
* { | ||
* "type": "listItem", | ||
* "children": [ | ||
* { | ||
* "type": "paragraph", | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "This is a list item!" | ||
* } | ||
* ] | ||
* } | ||
* ] | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type List = { | ||
@@ -40,3 +120,22 @@ type: ListType; | ||
export declare type ListItemType = 'listItem'; | ||
/** ListItem represents an item in a List */ | ||
/** | ||
* A `listItem` node represents an item in a list. | ||
* | ||
* ```json | ||
* { | ||
* "type": "listItem", | ||
* "children": [ | ||
* { | ||
* "type": "paragraph", | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "This is a list item!" | ||
* } | ||
* ] | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type ListItem = { | ||
@@ -47,15 +146,48 @@ type: ListItemType; | ||
export declare type CodeType = 'code'; | ||
/** Code represents a block of preformatted text, such as computer code */ | ||
/** | ||
* A `code` node represents a block of preformatted text, such as computer code. | ||
* | ||
* ```json | ||
* { | ||
* "type": "code", | ||
* "language": "javascript", | ||
* "highlight": [1], | ||
* "code": "function greetings() {\n console.log('Hi!');\n}" | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Code = { | ||
type: CodeType; | ||
/** optional, represents the language of computer code being marked up */ | ||
/** The language of computer code being marked up (ie. `"javascript"`) */ | ||
language?: string; | ||
/** optional, represents an array of line numbers to highlight */ | ||
/** A zero-based array of line numbers to highlight (ie. `[0, 1, 3]`)*/ | ||
highlight?: Array<number>; | ||
/** The marked up computer code */ | ||
code: string; | ||
}; | ||
export declare type BlockquoteType = 'blockquote'; | ||
/** Blockquote is a containter that represents text which is an extended quotation */ | ||
/** | ||
* A `blockquote` node is a containter that represents text which is an extended quotation. | ||
* | ||
* ```json | ||
* { | ||
* "type": "blockquote", | ||
* "attribution": "Oscar Wilde", | ||
* "children": [ | ||
* { | ||
* "type": "paragraph", | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "Be yourself; everyone else is taken." | ||
* } | ||
* ] | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Blockquote = { | ||
type: BlockquoteType; | ||
/** Attribution for the quote (ie `"Mark Smith"`) */ | ||
attribution?: string; | ||
@@ -65,15 +197,41 @@ children: Array<Paragraph>; | ||
export declare type BlockType = 'block'; | ||
/** Block is a DatoCMS block records references */ | ||
/** | ||
* Similarly to [Modular Content](https://www.datocms.com/docs/content-modelling/modular-content) fields, | ||
* you can also embed block records into Structured Text. A `block` node stores a reference to a | ||
* DatoCMS block record embedded inside the `dast` document. | ||
* | ||
* This type of node can only be put as a direct child of the [`root`](#root) node. | ||
* | ||
* ```json | ||
* { | ||
* "type": "block", | ||
* "item": "1238455312" | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Block = { | ||
type: BlockType; | ||
/** The record ID. */ | ||
/** The DatoCMS block record ID */ | ||
item: string; | ||
}; | ||
export declare type SpanType = 'span'; | ||
/** Supported marks for Span nodes */ | ||
/** Supported marks for `span` nodes */ | ||
export declare type Mark = 'strong' | 'code' | 'emphasis' | 'underline' | 'strikethrough' | 'highlight'; | ||
/** Span represents a text node. It might optionally contain formatting styles called marks */ | ||
/** | ||
* A `span` node represents a text node. It might optionally contain decorators called `marks`. | ||
* | ||
* ```json | ||
* { | ||
* "type": "span", | ||
* "marks": ["highlight", "emphasis"], | ||
* "value": "Some random text here, move on!" | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Span = { | ||
type: SpanType; | ||
/** optional, array of styles for the current chunk of text */ | ||
/** | ||
* Array of decorators for the current chunk of text. | ||
* Valid marks are: `strong`, `code`, `emphasis`, `underline`, `strikethrough` and `highlight`. | ||
*/ | ||
marks?: Mark[]; | ||
@@ -83,3 +241,19 @@ value: string; | ||
export declare type LinkType = 'link'; | ||
/** Link represents a hyperlink */ | ||
/** | ||
* A `link` node represents a normal hyperlink. You can also link to DatoCMS records using | ||
* the [`itemLink`](#itemLink) node. | ||
* | ||
* ```json | ||
* { | ||
* "type": "link", | ||
* "url": "https://www.datocms.com/" | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "The best CMS in town" | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type Link = { | ||
@@ -91,6 +265,26 @@ type: LinkType; | ||
export declare type ItemLinkType = 'itemLink'; | ||
/** ItemLink is similar to a Link node, but instead of linking a portion of text to a URL, it links the document to another record present in the DatoCMS project */ | ||
/** | ||
* An `itemLink` node is similar to a [`link`](#link) node node, but instead of | ||
* linking a portion of text to a URL, it links the document to another record | ||
* present in the same DatoCMS project. | ||
* | ||
* If you want to link to a DatoCMS record without having to specify some | ||
* inner content, then please use the [`inlineItem`](#inlineItem) node. | ||
* | ||
* ```json | ||
* { | ||
* "type": "itemLink", | ||
* "item": "38945648" | ||
* "children": [ | ||
* { | ||
* "type": "span", | ||
* "value": "Matteo Giaccone" | ||
* } | ||
* ] | ||
* } | ||
* ``` | ||
*/ | ||
export declare type ItemLink = { | ||
type: ItemLinkType; | ||
/** the record ID */ | ||
/** The linked DatoCMS record ID */ | ||
item: string; | ||
@@ -100,6 +294,20 @@ children: Array<Span>; | ||
export declare type InlineItemType = 'inlineItem'; | ||
/** InlineItem, similarly to ItemLink, links the document to another record but does not specify any inner content (children) */ | ||
/** | ||
* An `inlineItem`, similarly to [`itemLink`](#itemLink), links the document to | ||
* another record but does not specify any inner content (children). | ||
* | ||
* It can be used in situations where it is up to the frontend to decide how to present the | ||
* record (ie. a widget, or an `<a>` tag pointing to the URL of the record with a text that | ||
* is the title of the linked record). | ||
* | ||
* ```json | ||
* { | ||
* "type": "inlineItem", | ||
* "item": "74619345" | ||
* } | ||
* ``` | ||
*/ | ||
export declare type InlineItem = { | ||
type: InlineItemType; | ||
/** the record ID */ | ||
/** The DatoCMS record ID */ | ||
item: string; | ||
@@ -109,3 +317,4 @@ }; | ||
/** | ||
A DatoCMS compatible document. | ||
* A Structured Text `dast`-compatible value, composed by the `dast` document | ||
* itself and the `schema` attribute. | ||
*/ | ||
@@ -118,5 +327,8 @@ export declare type Document = { | ||
/** | ||
Structured Text enables authors to create rich text content, on par with traditional editors. | ||
Additionally, it allows records and Media Area assets to be linked dynamically and embedded within the flow of the text. | ||
*/ | ||
* Structured Text enables authors to create rich text content, on par with | ||
* traditional editors. | ||
* | ||
* Additionally, it allows records and Media Area assets to be linked dynamically | ||
* and embedded within the flow of the text. | ||
*/ | ||
export declare type StructuredText<R extends Record = Record> = { | ||
@@ -123,0 +335,0 @@ /** A DatoCMS compatible document */ |
{ | ||
"name": "datocms-structured-text-utils", | ||
"version": "1.0.3", | ||
"version": "1.0.4", | ||
"description": "A set of Typescript types and helpers to work with DatoCMS Structured Text fields", | ||
@@ -38,3 +38,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "a1f48c8cc4e30209eccb138d5c60eea8941eaddc" | ||
"gitHead": "7f39864c4987d37a2676c06def2eaf914dacf84f" | ||
} |
166
README.md
# `datocms-structured-text-utils` | ||
> TODO: description | ||
A set of Typescript types and helpers to work with DatoCMS Structured Text fields. | ||
## Usage | ||
## Installation | ||
Using [npm](http://npmjs.org/): | ||
```sh | ||
npm install datocms-structured-text-utils | ||
``` | ||
const datocmsStructuredTextUtils = require('datocms-structured-text-utils'); | ||
// TODO: DEMONSTRATE API | ||
Using [yarn](https://yarnpkg.com/): | ||
```sh | ||
yarn add datocms-structured-text-utils | ||
``` | ||
## `dast` document validation | ||
You can use the `validate()` function to check if an object is compatible with the `dast` specification: | ||
```js | ||
import { validate } from 'datocms-structured-text-utils'; | ||
const structuredText = { | ||
value: { | ||
schema: 'dast', | ||
document: { | ||
type: 'root', | ||
children: [ | ||
{ | ||
type: 'heading', | ||
level: 1, | ||
children: [ | ||
{ | ||
type: 'span', | ||
value: 'Hello!', | ||
marks: ['foobar'], | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
}, | ||
}; | ||
const result = validate(structuredText); | ||
if (!result.valid) { | ||
console.error(result.message); // "span has an invalid mark "foobar" | ||
} | ||
``` | ||
## `dast` format specs | ||
The package exports a number of constants that represents the rules of the `dast` specification. | ||
Take a look a the [definitions.ts](https://github.com/datocms/structured-text/blob/main/packages/utils/src/definitions.ts) file for their definition: | ||
```javascript | ||
const blockquoteNodeType = 'blockquote'; | ||
const blockNodeType = 'block'; | ||
const codeNodeType = 'code'; | ||
const headingNodeType = 'heading'; | ||
const inlineItemNodeType = 'inlineItem'; | ||
const itemLinkNodeType = 'itemLink'; | ||
const linkNodeType = 'link'; | ||
const listItemNodeType = 'listItem'; | ||
const listNodeType = 'list'; | ||
const paragraphNodeType = 'paragraph'; | ||
const rootNodeType = 'root'; | ||
const spanNodeType = 'span'; | ||
export const allowedNodeTypes = [ | ||
'paragraph', | ||
'list', | ||
// ... | ||
]; | ||
export const allowedChildren = { | ||
paragraph: 'inlineNodes', | ||
list: ['listItem'], | ||
// ... | ||
}; | ||
export const inlineNodeTypes = [ | ||
'span', | ||
'link', | ||
// ... | ||
]; | ||
export const allowedAttributes = { | ||
heading: ['level', 'children'], | ||
// ... | ||
}; | ||
export const allowedMarks = [ | ||
'strong', | ||
'code', | ||
// ... | ||
]; | ||
``` | ||
## Typescript Types | ||
The package exports Typescript types for all the different nodes that a `dast` document can contain. | ||
Take a look a the [types.ts](https://github.com/datocms/structured-text/blob/main/packages/utils/src/types.ts) file for their definition: | ||
```typescript | ||
type Node | ||
type BlockNode | ||
type InlineNode | ||
type RootType | ||
type Root | ||
type ParagraphType | ||
type Paragraph | ||
type HeadingType | ||
type Heading | ||
type ListType | ||
type List | ||
type ListItemType | ||
type ListItem | ||
type CodeType | ||
type Code | ||
type BlockquoteType | ||
type Blockquote | ||
type BlockType | ||
type Block | ||
type SpanType | ||
type Mark | ||
type Span | ||
type LinkType | ||
type Link | ||
type ItemLinkType | ||
type ItemLink | ||
type InlineItemType | ||
type InlineItem | ||
type WithChildrenNode | ||
type Document | ||
type NodeType | ||
type StructuredText | ||
type Record | ||
``` | ||
## Typescript Type guards | ||
It also exports all a number of [type guards](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards) that you can use to guarantees the type of a node in some scope. | ||
Take a look a the [guards.ts](https://github.com/datocms/structured-text/blob/main/packages/utils/src/guards.ts) file for their definition: | ||
```typescript | ||
function hasChildren(node: Node): node is WithChildrenNode {} | ||
function isInlineNode(node: Node): node is InlineNode {} | ||
function isHeading(node: Node): node is Heading {} | ||
function isSpan(node: Node): node is Span {} | ||
function isRoot(node: Node): node is Root {} | ||
function isParagraph(node: Node): node is Paragraph {} | ||
function isList(node: Node): node is List {} | ||
function isListItem(node: Node): node is ListItem {} | ||
function isBlockquote(node: Node): node is Blockquote {} | ||
function isBlock(node: Node): node is Block {} | ||
function isCode(node: Node): node is Code {} | ||
function isLink(node: Node): node is Link {} | ||
function isItemLink(node: Node): node is ItemLink {} | ||
function isInlineItem(node: Node): node is InlineItem {} | ||
function isStructuredText(object: any): object is StructuredText {} | ||
``` |
40960
745
170