@portabletext/block-tools 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import createWordRules from './word'
7
7
 
8
8
  export function createRules(
9
9
  blockContentType: ArraySchemaType,
10
- options: BlockEnabledFeatures,
10
+ options: BlockEnabledFeatures & {keyGenerator?: () => string},
11
11
  ): DeserializerRule[] {
12
12
  return [
13
13
  ...createWordRules(),
package/src/index.ts CHANGED
@@ -23,7 +23,9 @@ export function htmlToBlocks(
23
23
  options: HtmlDeserializerOptions = {},
24
24
  ): (TypedObject | PortableTextTextBlock)[] {
25
25
  const deserializer = new HtmlDeserializer(blockContentType, options)
26
- return deserializer.deserialize(html).map((block) => normalizeBlock(block))
26
+ return deserializer
27
+ .deserialize(html)
28
+ .map((block) => normalizeBlock(block, {keyGenerator: options.keyGenerator}))
27
29
  }
28
30
 
29
31
  /**
@@ -39,9 +41,6 @@ export function getBlockContentFeatures(
39
41
  return blockContentTypeFeatures(blockContentType)
40
42
  }
41
43
 
42
- export {normalizeBlock}
43
- export {randomKey} from './util/randomKey'
44
- export type {BlockContentFeatures, HtmlDeserializerOptions, TypedObject}
45
44
  export type {
46
45
  ArbitraryTypedObject,
47
46
  BlockEditorSchemaProps,
@@ -50,3 +49,6 @@ export type {
50
49
  ResolvedAnnotationType,
51
50
  } from './types'
52
51
  export type {BlockNormalizationOptions} from './util/normalizeBlock'
52
+ export {randomKey} from './util/randomKey'
53
+ export {normalizeBlock}
54
+ export type {BlockContentFeatures, HtmlDeserializerOptions, TypedObject}
package/src/types.ts CHANGED
@@ -100,6 +100,7 @@ export type WhiteSpacePasteMode = 'preserve' | 'remove' | 'normalize'
100
100
  * @public
101
101
  */
102
102
  export interface HtmlDeserializerOptions {
103
+ keyGenerator?: () => string
103
104
  rules?: DeserializerRule[]
104
105
  parseHtml?: HtmlParser
105
106
  unstable_whitespaceOnPasteMode?: WhiteSpacePasteMode
@@ -5,7 +5,7 @@ import {
5
5
  } from '@sanity/types'
6
6
  import {isEqual} from 'lodash'
7
7
  import type {TypedObject} from '../types'
8
- import {randomKey} from './randomKey'
8
+ import {keyGenerator} from './randomKey'
9
9
 
10
10
  /**
11
11
  * Block normalization options
@@ -22,6 +22,11 @@ export interface BlockNormalizationOptions {
22
22
  * Name of the portable text block type, if not `block`
23
23
  */
24
24
  blockTypeName?: string
25
+
26
+ /**
27
+ * Custom key generator function
28
+ */
29
+ keyGenerator?: () => string
25
30
  }
26
31
 
27
32
  /**
@@ -51,26 +56,30 @@ export function normalizeBlock(
51
56
  if (node._type !== (options.blockTypeName || 'block')) {
52
57
  return '_key' in node
53
58
  ? (node as TypedObject & {_key: string})
54
- : {...node, _key: randomKey(12)}
59
+ : {
60
+ ...node,
61
+ _key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
62
+ }
55
63
  }
56
64
 
57
65
  const block: Omit<
58
66
  PortableTextTextBlock<TypedObject | PortableTextSpan>,
59
67
  'style'
60
68
  > = {
61
- _key: randomKey(12),
69
+ _key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
62
70
  children: [],
63
71
  markDefs: [],
64
72
  ...node,
65
73
  }
66
74
 
67
75
  const lastChild = block.children[block.children.length - 1]
76
+
68
77
  if (!lastChild) {
69
78
  // A block must at least have an empty span type child
70
79
  block.children = [
71
80
  {
72
81
  _type: 'span',
73
- _key: `${block._key}${0}`,
82
+ _key: options.keyGenerator ? options.keyGenerator() : keyGenerator(),
74
83
  text: '',
75
84
  marks: [],
76
85
  },
@@ -111,12 +120,15 @@ export function normalizeBlock(
111
120
  },
112
121
  [] as (TypedObject | PortableTextSpan)[],
113
122
  )
114
- .map((child, index) => {
123
+ .map((child) => {
115
124
  if (!child) {
116
125
  throw new Error('missing child')
117
126
  }
118
127
 
119
- child._key = `${block._key}${index}`
128
+ child._key = options.keyGenerator
129
+ ? options.keyGenerator()
130
+ : keyGenerator()
131
+
120
132
  if (isPortableTextSpan(child)) {
121
133
  if (!child.marks) {
122
134
  child.marks = []
@@ -138,5 +150,6 @@ export function normalizeBlock(
138
150
  block.markDefs = (block.markDefs || []).filter((markDef) =>
139
151
  usedMarkDefs.includes(markDef._key),
140
152
  )
153
+
141
154
  return block
142
155
  }
@@ -1,5 +1,9 @@
1
1
  import getRandomValues from 'get-random-values-esm'
2
2
 
3
+ export function keyGenerator() {
4
+ return randomKey(12)
5
+ }
6
+
3
7
  // WHATWG crypto RNG - https://w3c.github.io/webcrypto/Overview.html
4
8
  function whatwgRNG(length = 16) {
5
9
  const rnds8 = new Uint8Array(length)