@wallarm-org/design-system 1.30.0 → 1.31.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.
Files changed (123) hide show
  1. package/dist/components/CodeEditor/CodeEditorContent.d.ts +17 -0
  2. package/dist/components/CodeEditor/CodeEditorContent.js +197 -0
  3. package/dist/components/CodeEditor/CodeEditorContext.d.ts +17 -0
  4. package/dist/components/CodeEditor/CodeEditorContext.js +8 -0
  5. package/dist/components/CodeEditor/CodeEditorRoot.d.ts +77 -0
  6. package/dist/components/CodeEditor/CodeEditorRoot.js +203 -0
  7. package/dist/components/CodeEditor/classes.d.ts +21 -0
  8. package/dist/components/CodeEditor/classes.js +41 -0
  9. package/dist/components/CodeEditor/engine/SearchPanel.d.ts +13 -0
  10. package/dist/components/CodeEditor/engine/SearchPanel.js +201 -0
  11. package/dist/components/CodeEditor/engine/adapterPainter.d.ts +23 -0
  12. package/dist/components/CodeEditor/engine/adapterPainter.js +110 -0
  13. package/dist/components/CodeEditor/engine/babelSyntax.d.ts +15 -0
  14. package/dist/components/CodeEditor/engine/babelSyntax.js +54 -0
  15. package/dist/components/CodeEditor/engine/completion.d.ts +17 -0
  16. package/dist/components/CodeEditor/engine/completion.js +129 -0
  17. package/dist/components/CodeEditor/engine/contentAttributes.d.ts +12 -0
  18. package/dist/components/CodeEditor/engine/contentAttributes.js +24 -0
  19. package/dist/components/CodeEditor/engine/diagnostics.d.ts +73 -0
  20. package/dist/components/CodeEditor/engine/diagnostics.js +327 -0
  21. package/dist/components/CodeEditor/engine/diff.d.ts +37 -0
  22. package/dist/components/CodeEditor/engine/diff.js +145 -0
  23. package/dist/components/CodeEditor/engine/folds.d.ts +25 -0
  24. package/dist/components/CodeEditor/engine/folds.js +458 -0
  25. package/dist/components/CodeEditor/engine/gutters.d.ts +22 -0
  26. package/dist/components/CodeEditor/engine/gutters.js +160 -0
  27. package/dist/components/CodeEditor/engine/index.d.ts +12 -0
  28. package/dist/components/CodeEditor/engine/index.js +387 -0
  29. package/dist/components/CodeEditor/engine/languages/http/index.d.ts +20 -0
  30. package/dist/components/CodeEditor/engine/languages/http/index.js +69 -0
  31. package/dist/components/CodeEditor/engine/languages/http/parser.d.ts +2 -0
  32. package/dist/components/CodeEditor/engine/languages/http/parser.js +31 -0
  33. package/dist/components/CodeEditor/engine/languages/http/parser.terms.d.ts +1 -0
  34. package/dist/components/CodeEditor/engine/languages/http/parser.terms.js +2 -0
  35. package/dist/components/CodeEditor/engine/languages/index.d.ts +8 -0
  36. package/dist/components/CodeEditor/engine/languages/index.js +41 -0
  37. package/dist/components/CodeEditor/engine/languages/json.d.ts +8 -0
  38. package/dist/components/CodeEditor/engine/languages/json.js +11 -0
  39. package/dist/components/CodeEditor/engine/languages/jsonPointers.d.ts +47 -0
  40. package/dist/components/CodeEditor/engine/languages/jsonPointers.js +125 -0
  41. package/dist/components/CodeEditor/engine/languages/yaml.d.ts +4 -0
  42. package/dist/components/CodeEditor/engine/languages/yaml.js +11 -0
  43. package/dist/components/CodeEditor/engine/lines.d.ts +22 -0
  44. package/dist/components/CodeEditor/engine/lines.js +131 -0
  45. package/dist/components/CodeEditor/engine/luaSyntax.d.ts +14 -0
  46. package/dist/components/CodeEditor/engine/luaSyntax.js +36 -0
  47. package/dist/components/CodeEditor/engine/positions.d.ts +19 -0
  48. package/dist/components/CodeEditor/engine/positions.js +22 -0
  49. package/dist/components/CodeEditor/engine/schema/complete.d.ts +12 -0
  50. package/dist/components/CodeEditor/engine/schema/complete.js +211 -0
  51. package/dist/components/CodeEditor/engine/schema/hover.d.ts +12 -0
  52. package/dist/components/CodeEditor/engine/schema/hover.js +73 -0
  53. package/dist/components/CodeEditor/engine/schema/loadSchema.d.ts +19 -0
  54. package/dist/components/CodeEditor/engine/schema/loadSchema.js +32 -0
  55. package/dist/components/CodeEditor/engine/schema/validate.d.ts +9 -0
  56. package/dist/components/CodeEditor/engine/schema/validate.js +67 -0
  57. package/dist/components/CodeEditor/engine/search.d.ts +13 -0
  58. package/dist/components/CodeEditor/engine/search.js +84 -0
  59. package/dist/components/CodeEditor/engine/searchMatches.d.ts +8 -0
  60. package/dist/components/CodeEditor/engine/searchMatches.js +15 -0
  61. package/dist/components/CodeEditor/engine/theme.d.ts +8 -0
  62. package/dist/components/CodeEditor/engine/theme.js +89 -0
  63. package/dist/components/CodeEditor/engine/types.d.ts +44 -0
  64. package/dist/components/CodeEditor/engine/types.js +0 -0
  65. package/dist/components/CodeEditor/hooks/useCodeEditor.d.ts +6 -0
  66. package/dist/components/CodeEditor/hooks/useCodeEditor.js +3 -0
  67. package/dist/components/CodeEditor/index.d.ts +6 -0
  68. package/dist/components/CodeEditor/index.js +5 -0
  69. package/dist/components/CodeEditor/lib/PortalOutlet.d.ts +11 -0
  70. package/dist/components/CodeEditor/lib/PortalOutlet.js +11 -0
  71. package/dist/components/CodeEditor/lib/httpCompletions.d.ts +7 -0
  72. package/dist/components/CodeEditor/lib/httpCompletions.js +102 -0
  73. package/dist/components/CodeEditor/lib/httpCompletionsData.d.ts +29 -0
  74. package/dist/components/CodeEditor/lib/httpCompletionsData.js +650 -0
  75. package/dist/components/CodeEditor/lib/keyboardHint.d.ts +5 -0
  76. package/dist/components/CodeEditor/lib/keyboardHint.js +2 -0
  77. package/dist/components/CodeEditor/lib/loadEngine.d.ts +7 -0
  78. package/dist/components/CodeEditor/lib/loadEngine.js +9 -0
  79. package/dist/components/CodeEditor/lib/portalRegistry.d.ts +20 -0
  80. package/dist/components/CodeEditor/lib/portalRegistry.js +47 -0
  81. package/dist/components/CodeEditor/lib/splitContentProps.d.ts +12 -0
  82. package/dist/components/CodeEditor/lib/splitContentProps.js +28 -0
  83. package/dist/components/CodeEditor/types.d.ts +72 -0
  84. package/dist/components/CodeEditor/types.js +0 -0
  85. package/dist/components/CodeSnippet/CodeSnippetCode.js +6 -23
  86. package/dist/components/CodeSnippet/CodeSnippetCopyButton.js +4 -3
  87. package/dist/components/CodeSnippet/CodeSnippetFrameContext.d.ts +25 -0
  88. package/dist/components/CodeSnippet/CodeSnippetFrameContext.js +3 -0
  89. package/dist/components/CodeSnippet/CodeSnippetFullscreenButton.js +2 -2
  90. package/dist/components/CodeSnippet/CodeSnippetRoot.d.ts +3 -5
  91. package/dist/components/CodeSnippet/CodeSnippetRoot.js +56 -50
  92. package/dist/components/CodeSnippet/CodeSnippetShowMoreButton.js +7 -5
  93. package/dist/components/CodeSnippet/CodeSnippetWrapButton.js +2 -2
  94. package/dist/components/CodeSnippet/adapters/highlightjs.js +1 -0
  95. package/dist/components/CodeSnippet/adapters/prism.js +3 -1
  96. package/dist/components/CodeSnippet/adapters/shiki.js +1 -0
  97. package/dist/components/CodeSnippet/adapters/types.d.ts +3 -3
  98. package/dist/components/CodeSnippet/classes.d.ts +3 -0
  99. package/dist/components/CodeSnippet/classes.js +14 -0
  100. package/dist/components/CodeSnippet/hooks/index.d.ts +1 -0
  101. package/dist/components/CodeSnippet/hooks/index.js +1 -0
  102. package/dist/components/CodeSnippet/hooks/useCodeSnippetFrame.d.ts +2 -0
  103. package/dist/components/CodeSnippet/hooks/useCodeSnippetFrame.js +8 -0
  104. package/dist/components/CodeSnippet/index.d.ts +2 -1
  105. package/dist/components/CodeSnippet/index.js +1 -1
  106. package/dist/components/CodeSnippet/internal/CodeSnippetFrame.d.ts +22 -0
  107. package/dist/components/CodeSnippet/internal/CodeSnippetFrame.js +81 -0
  108. package/dist/components/CodeSnippet/internal/CodeToken.d.ts +2 -1
  109. package/dist/components/CodeSnippet/internal/CodeToken.js +1 -1
  110. package/dist/components/CodeSnippet/internal/FoldSummary.d.ts +11 -0
  111. package/dist/components/CodeSnippet/internal/FoldSummary.js +27 -0
  112. package/dist/components/CodeSnippet/internal/FoldToggle.d.ts +2 -0
  113. package/dist/components/CodeSnippet/internal/FoldToggle.js +2 -1
  114. package/dist/components/CodeSnippet/internal/index.d.ts +1 -0
  115. package/dist/components/CodeSnippet/internal/index.js +1 -0
  116. package/dist/components/CodeSnippet/lib/foldUtils.d.ts +9 -2
  117. package/dist/components/CodeSnippet/lib/foldUtils.js +2 -2
  118. package/dist/components/CodeSnippet/lib/showMore.d.ts +7 -0
  119. package/dist/components/CodeSnippet/lib/showMore.js +7 -0
  120. package/dist/components/Copyable/Copyable.d.ts +5 -2
  121. package/dist/components/Copyable/Copyable.js +1 -1
  122. package/dist/metadata/components.json +1235 -5
  123. package/package.json +24 -1
@@ -0,0 +1,387 @@
1
+ import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
2
+ import { defaultKeymap, history as commands_history, historyKeymap, indentWithTab } from "@codemirror/commands";
3
+ import { bracketMatching, indentOnInput } from "@codemirror/language";
4
+ import { openSearchPanel } from "@codemirror/search";
5
+ import { Annotation, Compartment, EditorState, Transaction } from "@codemirror/state";
6
+ import { EditorView, ViewPlugin, crosshairCursor, drawSelection, dropCursor, keymap, rectangularSelection } from "@codemirror/view";
7
+ import { adapterPainter } from "./adapterPainter.js";
8
+ import { completionExtension } from "./completion.js";
9
+ import { sanitizeContentAttributes } from "./contentAttributes.js";
10
+ import { diagnosticsExtension, jsonRegion } from "./diagnostics.js";
11
+ import { diffDeletedRowCount, diffExtension } from "./diff.js";
12
+ import { foldAllRegions, foldsExtension, getCollapsedRanges, getVisibleRowCount, unfoldAllRegions } from "./folds.js";
13
+ import { guttersExtension } from "./gutters.js";
14
+ import { isLazyLanguage, languageExtension, loadLanguageExtension } from "./languages/index.js";
15
+ import { linesExtension } from "./lines.js";
16
+ import { schemaHover } from "./schema/hover.js";
17
+ import { validateAgainstSchema } from "./schema/validate.js";
18
+ import { searchConfigured, searchExtension } from "./search.js";
19
+ import { editorTheme, maxHeightTheme } from "./theme.js";
20
+ const externalChange = Annotation.define();
21
+ const isHighSurrogate = (code)=>code >= 0xd800 && code <= 0xdbff;
22
+ const isLowSurrogate = (code)=>code >= 0xdc00 && code <= 0xdfff;
23
+ const minimalChange = (from, to)=>{
24
+ if (from === to) return null;
25
+ const max = Math.min(from.length, to.length);
26
+ let prefix = 0;
27
+ while(prefix < max && from.charCodeAt(prefix) === to.charCodeAt(prefix))prefix++;
28
+ if (prefix > 0 && isHighSurrogate(from.charCodeAt(prefix - 1))) prefix--;
29
+ let suffix = 0;
30
+ while(suffix < max - prefix && from.charCodeAt(from.length - 1 - suffix) === to.charCodeAt(to.length - 1 - suffix))suffix++;
31
+ if (suffix > 0 && isLowSurrogate(from.charCodeAt(from.length - suffix))) suffix--;
32
+ return {
33
+ from: prefix,
34
+ to: from.length - suffix,
35
+ insert: to.slice(prefix, to.length - suffix)
36
+ };
37
+ };
38
+ const CORE_KEYS = [
39
+ 'language',
40
+ 'readOnly',
41
+ 'wrap',
42
+ 'maxHeight',
43
+ 'contentAttributes',
44
+ 'cspNonce'
45
+ ];
46
+ const FEATURE_KEYS = [
47
+ 'painter',
48
+ 'lines',
49
+ 'folds',
50
+ 'search',
51
+ 'diagnostics',
52
+ 'completion',
53
+ 'diff'
54
+ ];
55
+ const TAIL_KEYS = [
56
+ 'gutterTestId',
57
+ 'gutterAria'
58
+ ];
59
+ const SLOT_KEYS = [
60
+ ...CORE_KEYS,
61
+ ...FEATURE_KEYS,
62
+ ...TAIL_KEYS
63
+ ];
64
+ const DERIVED_DEPS = {
65
+ diffEnabled: (o)=>void 0 !== o.original
66
+ };
67
+ const SLOT_DEPS = {
68
+ language: [
69
+ 'language'
70
+ ],
71
+ readOnly: [
72
+ 'readOnly'
73
+ ],
74
+ wrap: [
75
+ 'wrapLines'
76
+ ],
77
+ maxHeight: [
78
+ 'maxHeight'
79
+ ],
80
+ contentAttributes: [
81
+ 'contentAttributes',
82
+ 'testId'
83
+ ],
84
+ cspNonce: [
85
+ 'cspNonce'
86
+ ],
87
+ painter: [
88
+ 'adapter',
89
+ 'language'
90
+ ],
91
+ lines: [
92
+ 'lines',
93
+ 'startingLineNumber',
94
+ 'lineNumbers',
95
+ 'testId',
96
+ 'folds',
97
+ 'diffEnabled'
98
+ ],
99
+ folds: [
100
+ 'folds',
101
+ 'startingLineNumber',
102
+ 'testId'
103
+ ],
104
+ search: [
105
+ 'readOnly',
106
+ 'testId'
107
+ ],
108
+ diagnostics: [
109
+ 'language',
110
+ 'schema',
111
+ 'diagnostics',
112
+ 'startingLineNumber'
113
+ ],
114
+ completion: [
115
+ 'language',
116
+ 'schema',
117
+ 'completions',
118
+ 'startingLineNumber'
119
+ ],
120
+ diff: [
121
+ 'original'
122
+ ],
123
+ gutterTestId: [
124
+ 'testId'
125
+ ],
126
+ gutterAria: []
127
+ };
128
+ const buildFolds = (o, portals)=>foldsExtension({
129
+ folds: o.folds,
130
+ startingLineNumber: o.startingLineNumber,
131
+ portals,
132
+ testId: o.testId
133
+ });
134
+ const featureExtensions = (options, callbacks)=>({
135
+ painter: ()=>adapterPainter({
136
+ adapter: options.adapter,
137
+ language: options.language
138
+ }),
139
+ lines: ()=>[
140
+ linesExtension({
141
+ lines: options.lines,
142
+ startingLineNumber: options.startingLineNumber
143
+ }),
144
+ guttersExtension({
145
+ lines: options.lines,
146
+ startingLineNumber: options.startingLineNumber,
147
+ lineNumbers: options.lineNumbers,
148
+ foldGutter: buildFolds(options, callbacks.portals).gutter,
149
+ portals: callbacks.portals,
150
+ testId: options.testId,
151
+ diff: DERIVED_DEPS.diffEnabled(options)
152
+ })
153
+ ],
154
+ folds: ()=>buildFolds(options, callbacks.portals).extension,
155
+ search: ()=>searchExtension({
156
+ portals: callbacks.portals,
157
+ readOnly: options.readOnly,
158
+ testId: options.testId
159
+ }),
160
+ diagnostics: ()=>{
161
+ const { schema } = options;
162
+ return [
163
+ diagnosticsExtension({
164
+ language: options.language,
165
+ schema,
166
+ external: options.diagnostics,
167
+ startingLineNumber: options.startingLineNumber,
168
+ onChange: callbacks.onDiagnosticsChange,
169
+ schemaSource: void 0 === schema ? void 0 : (state, region)=>validateAgainstSchema(state, region, schema)
170
+ }),
171
+ void 0 === schema ? [] : schemaHover(()=>schema, (state)=>jsonRegion(state, options.language))
172
+ ];
173
+ },
174
+ completion: ()=>completionExtension({
175
+ language: options.language,
176
+ schema: options.schema,
177
+ sources: options.completions,
178
+ startingLineNumber: options.startingLineNumber
179
+ }),
180
+ diff: ()=>void 0 === options.original ? [] : diffExtension({
181
+ original: options.original,
182
+ portals: callbacks.portals
183
+ })
184
+ });
185
+ const contentAttributesFor = (options)=>{
186
+ const attrs = sanitizeContentAttributes(options.contentAttributes);
187
+ if (options.testId) attrs['data-testid'] = `${options.testId}--editor`;
188
+ return attrs;
189
+ };
190
+ const gutterTestId = (testId)=>{
191
+ if (!testId) return [];
192
+ const id = `${testId}--gutter`;
193
+ const apply = (view)=>{
194
+ const gutters = view.scrollDOM.querySelector(':scope > .cm-gutters');
195
+ if (gutters && gutters.getAttribute('data-testid') !== id) gutters.setAttribute('data-testid', id);
196
+ };
197
+ return [
198
+ ViewPlugin.define((view)=>{
199
+ apply(view);
200
+ return {};
201
+ }),
202
+ EditorView.updateListener.of((update)=>apply(update.view))
203
+ ];
204
+ };
205
+ const syncGutterAria = (view)=>{
206
+ for (const container of view.scrollDOM.querySelectorAll(':scope > .cm-gutters')){
207
+ const columns = Array.from(container.querySelectorAll(':scope > .cm-gutter'));
208
+ const hasFolds = columns.some((column)=>column.classList.contains('cm-ds-fold-gutter'));
209
+ if (!hasFolds) {
210
+ if ('true' !== container.getAttribute('aria-hidden')) container.setAttribute('aria-hidden', 'true');
211
+ continue;
212
+ }
213
+ if (container.hasAttribute('aria-hidden')) container.removeAttribute('aria-hidden');
214
+ for (const column of columns)if (column.classList.contains('cm-ds-fold-gutter')) {
215
+ if (column.hasAttribute('aria-hidden')) column.removeAttribute('aria-hidden');
216
+ } else if ('true' !== column.getAttribute('aria-hidden')) column.setAttribute('aria-hidden', 'true');
217
+ }
218
+ };
219
+ const gutterAria = [
220
+ ViewPlugin.define((view)=>{
221
+ syncGutterAria(view);
222
+ return {};
223
+ }),
224
+ EditorView.updateListener.of((update)=>syncGutterAria(update.view))
225
+ ];
226
+ const slotExtensions = (options, callbacks)=>({
227
+ language: ()=>languageExtension(options.language),
228
+ readOnly: ()=>EditorState.readOnly.of(options.readOnly),
229
+ wrap: ()=>options.wrapLines ? EditorView.lineWrapping : [],
230
+ maxHeight: ()=>maxHeightTheme(options.maxHeight),
231
+ contentAttributes: ()=>EditorView.contentAttributes.of(contentAttributesFor(options)),
232
+ cspNonce: ()=>options.cspNonce ? EditorView.cspNonce.of(options.cspNonce) : [],
233
+ ...featureExtensions(options, callbacks),
234
+ gutterTestId: ()=>gutterTestId(options.testId),
235
+ gutterAria: ()=>gutterAria
236
+ });
237
+ const shallowEqualRecord = (a, b)=>{
238
+ const aKeys = Object.keys(a);
239
+ if (aKeys.length !== Object.keys(b).length) return false;
240
+ return aKeys.every((key)=>Object.hasOwn(b, key) && a[key] === b[key]);
241
+ };
242
+ const changedOptionKeys = (prev, next)=>{
243
+ const changed = new Set();
244
+ for (const key of Object.keys(DERIVED_DEPS))if (DERIVED_DEPS[key](prev) !== DERIVED_DEPS[key](next)) changed.add(key);
245
+ for (const key of Object.keys(next))if ('contentAttributes' === key) {
246
+ if (!shallowEqualRecord(prev.contentAttributes, next.contentAttributes)) changed.add(key);
247
+ } else if (prev[key] !== next[key]) changed.add(key);
248
+ return changed;
249
+ };
250
+ const visibleRowCount = (state)=>getVisibleRowCount(state) + diffDeletedRowCount(state, getCollapsedRanges(state));
251
+ const createEditor = (parent, initialOptions, callbacks)=>{
252
+ const compartments = {};
253
+ for (const key of SLOT_KEYS)compartments[key] = new Compartment();
254
+ const cache = new Map();
255
+ let options = initialOptions;
256
+ let lastRowCount = -1;
257
+ let destroyed = false;
258
+ const reportRowCount = (state)=>{
259
+ const rows = visibleRowCount(state);
260
+ if (rows === lastRowCount) return;
261
+ lastRowCount = rows;
262
+ callbacks.onVisibleRowCountChange(rows);
263
+ };
264
+ const listener = EditorView.updateListener.of((update)=>{
265
+ if (update.docChanged && !update.transactions.some((tr)=>true === tr.annotation(externalChange))) callbacks.onChange(update.state.doc.toString());
266
+ if (update.docChanged || update.selectionSet || update.transactions.some((tr)=>tr.effects.length > 0)) reportRowCount(update.state);
267
+ });
268
+ const baseExtensions = [
269
+ commands_history(),
270
+ drawSelection(),
271
+ dropCursor(),
272
+ EditorState.allowMultipleSelections.of(true),
273
+ rectangularSelection(),
274
+ crosshairCursor(),
275
+ indentOnInput(),
276
+ bracketMatching(),
277
+ closeBrackets(),
278
+ keymap.of([
279
+ ...closeBracketsKeymap,
280
+ ...defaultKeymap,
281
+ ...historyKeymap,
282
+ indentWithTab
283
+ ]),
284
+ editorTheme,
285
+ listener
286
+ ];
287
+ const createState = (doc, opts)=>{
288
+ const builders = slotExtensions(opts, callbacks);
289
+ return EditorState.create({
290
+ doc,
291
+ extensions: [
292
+ baseExtensions,
293
+ ...SLOT_KEYS.map((key)=>compartments[key].of(builders[key]()))
294
+ ]
295
+ });
296
+ };
297
+ const view = new EditorView({
298
+ state: createState(initialOptions.value, initialOptions),
299
+ parent
300
+ });
301
+ const ensureLazyLanguage = (lang)=>{
302
+ if (!isLazyLanguage(lang)) return;
303
+ loadLanguageExtension(lang).then((extension)=>{
304
+ if (destroyed || options.language !== lang) return;
305
+ view.dispatch({
306
+ effects: compartments.language.reconfigure(extension)
307
+ });
308
+ }, (error)=>{
309
+ console.error(`[CodeEditor] failed to load the ${lang} parser`, error);
310
+ });
311
+ };
312
+ ensureLazyLanguage(initialOptions.language);
313
+ const reconfigure = (prev, next)=>{
314
+ const changed = changedOptionKeys(prev, next);
315
+ const builders = slotExtensions(next, callbacks);
316
+ const effects = SLOT_KEYS.filter((key)=>SLOT_DEPS[key].some((dep)=>changed.has(dep))).map((key)=>compartments[key].reconfigure(builders[key]()));
317
+ if (effects.length > 0) view.dispatch({
318
+ effects
319
+ });
320
+ };
321
+ const syncValue = (value)=>{
322
+ const changes = minimalChange(view.state.doc.toString(), value);
323
+ if (!changes) return;
324
+ view.dispatch({
325
+ changes,
326
+ annotations: [
327
+ externalChange.of(true),
328
+ Transaction.addToHistory.of(false)
329
+ ]
330
+ });
331
+ };
332
+ const swapDocument = (prev, next)=>{
333
+ if (void 0 !== prev.documentId) cache.set(prev.documentId, {
334
+ state: view.state,
335
+ options: prev
336
+ });
337
+ const cached = void 0 === next.documentId ? void 0 : cache.get(next.documentId);
338
+ if (cached) {
339
+ view.setState(cached.state);
340
+ reconfigure(cached.options, next);
341
+ syncValue(next.value);
342
+ } else view.setState(createState(next.value, next));
343
+ reportRowCount(view.state);
344
+ ensureLazyLanguage(next.language);
345
+ };
346
+ const update = (next)=>{
347
+ const prev = options;
348
+ options = next;
349
+ if (next.documentId !== prev.documentId) return void swapDocument(prev, next);
350
+ reconfigure(prev, next);
351
+ if (next.language !== prev.language) ensureLazyLanguage(next.language);
352
+ syncValue(next.value);
353
+ };
354
+ const api = {
355
+ focus: ()=>view.focus(),
356
+ getValue: ()=>view.state.doc.toString(),
357
+ insertText: (text)=>{
358
+ if (view.state.readOnly) return;
359
+ view.dispatch({
360
+ ...view.state.replaceSelection(text),
361
+ userEvent: 'input',
362
+ scrollIntoView: true
363
+ });
364
+ },
365
+ openSearch: ()=>{
366
+ if (view.state.facet(searchConfigured)) openSearchPanel(view);
367
+ },
368
+ foldAll: ()=>{
369
+ foldAllRegions(view);
370
+ },
371
+ unfoldAll: ()=>{
372
+ unfoldAllRegions(view);
373
+ }
374
+ };
375
+ reportRowCount(view.state);
376
+ return {
377
+ update,
378
+ api,
379
+ view,
380
+ destroy: ()=>{
381
+ destroyed = true;
382
+ cache.clear();
383
+ view.destroy();
384
+ }
385
+ };
386
+ };
387
+ export { createEditor, externalChange, minimalChange, searchConfigured };
@@ -0,0 +1,20 @@
1
+ import { LanguageSupport, LRLanguage } from '@codemirror/language';
2
+ import type { EditorState } from '@codemirror/state';
3
+ import type { CodeEditorHttpContext } from '../../../types';
4
+ /** HTTP/1.x message language: start line, headers, body; JSON bodies get a nested JSON tree. */
5
+ export declare const httpLanguage: LRLanguage;
6
+ export declare const http: () => LanguageSupport;
7
+ /**
8
+ * Range of the HTTP body that is parsed as JSON (the mounted `JsonText` node), or `null`
9
+ * when the state is not HTTP or the body is absent / not JSON.
10
+ */
11
+ export declare const findJsonBodyRange: (state: EditorState) => {
12
+ from: number;
13
+ to: number;
14
+ } | null;
15
+ /**
16
+ * Where `pos` sits in an HTTP message. Line-based, with the same rules as the grammar and
17
+ * getHttpFolds, so it is exact even while the tree is still being parsed.
18
+ * Returns `undefined` when the state's language is not HTTP.
19
+ */
20
+ export declare const httpContextAt: (state: EditorState, pos: number) => CodeEditorHttpContext | undefined;
@@ -0,0 +1,69 @@
1
+ import { LRLanguage, LanguageSupport, ensureSyntaxTree, language, syntaxTree } from "@codemirror/language";
2
+ import { parseMixed } from "@lezer/common";
3
+ import { jsonEditorLanguage } from "../json.js";
4
+ import { parser } from "./parser.js";
5
+ import { Body, Header, HeaderName, HeaderValue } from "./parser.terms.js";
6
+ const BLANK_LINE = /^[ \t]*$/;
7
+ const JSON_MEDIA_TYPE = /^[\w.+-]+\/(?:[\w.!#$&^-]+\+)?json$/i;
8
+ const JSON_START = /^\s*[[{]/;
9
+ const RESPONSE_START_LINE = /^HTTP\//;
10
+ const ENSURE_TREE_TIMEOUT = 200;
11
+ const readNode = (node, input)=>node ? input.read(node.from, node.to) : '';
12
+ const isJsonBody = (body, input)=>{
13
+ const message = body.parent;
14
+ if (message) for (const header of message.getChildren(Header)){
15
+ const name = readNode(header.getChild(HeaderName), input).trim().toLowerCase();
16
+ if ('content-type' !== name) continue;
17
+ const mediaType = readNode(header.getChild(HeaderValue), input).split(';')[0] ?? '';
18
+ return JSON_MEDIA_TYPE.test(mediaType.trim());
19
+ }
20
+ return JSON_START.test(input.read(body.from, body.to));
21
+ };
22
+ const mountJsonBody = parseMixed((node, input)=>{
23
+ if (node.type.id !== Body) return null;
24
+ return isJsonBody(node.node, input) ? {
25
+ parser: jsonEditorLanguage.parser
26
+ } : null;
27
+ });
28
+ const httpLanguage = LRLanguage.define({
29
+ name: 'http',
30
+ parser: parser.configure({
31
+ wrap: mountJsonBody
32
+ })
33
+ });
34
+ const http = ()=>new LanguageSupport(httpLanguage);
35
+ const isHttpState = (state)=>state.facet(language) === httpLanguage;
36
+ const findJsonBodyRange = (state)=>{
37
+ if (!isHttpState(state)) return null;
38
+ const tree = ensureSyntaxTree(state, state.doc.length, ENSURE_TREE_TIMEOUT) ?? syntaxTree(state);
39
+ for(let child = tree.topNode.firstChild; child; child = child.nextSibling)if ('JsonText' === child.name) return {
40
+ from: child.from,
41
+ to: child.to
42
+ };
43
+ return null;
44
+ };
45
+ const httpContextAt = (state, pos)=>{
46
+ if (!isHttpState(state)) return;
47
+ const { doc } = state;
48
+ const messageKind = RESPONSE_START_LINE.test(doc.line(1).text) ? 'response' : 'request';
49
+ const line = doc.lineAt(pos);
50
+ if (1 === line.number) return {
51
+ section: 'start-line',
52
+ messageKind
53
+ };
54
+ for(let n = 2; n < line.number; n++)if (BLANK_LINE.test(doc.line(n).text)) return {
55
+ section: 'body',
56
+ messageKind
57
+ };
58
+ const colon = line.text.indexOf(':');
59
+ if (colon < 0 || pos - line.from <= colon) return {
60
+ section: 'header-name',
61
+ messageKind
62
+ };
63
+ return {
64
+ section: 'header-value',
65
+ headerName: line.text.slice(0, colon).trim(),
66
+ messageKind
67
+ };
68
+ };
69
+ export { findJsonBodyRange, http, httpContextAt, httpLanguage };
@@ -0,0 +1,2 @@
1
+ import { LRParser } from "@lezer/lr";
2
+ export declare const parser: LRParser;
@@ -0,0 +1,31 @@
1
+ import { LRParser } from "@lezer/lr";
2
+ const parser = LRParser.deserialize({
3
+ version: 14,
4
+ states: "%WOQOPOOOcOQO'#C_OhOQO'#CcOOOO'#C^'#C^QmOPOOOrOQO,58yOwOSO,58}Q|OWO'#ClQmOPOOO![OQO1G.eO!gOQO1G.iO!rOWO'#CgO!}O`O'#CgO#YOWO'#CjOOOO,59W,59WQ#hOpOOQ#mOPOOOOOO-E6j-E6jO#rOPO7+$PO#}O!bO7+$TO$YO`O,59ROOOO,59R,59RO$eOWO,59RQOOOOOP$pOWO'#ClO${OQO<<GkOOOO<<Go<<GoOOOO1G.m1G.mO%WO`O1G.mP%cOWO'#CgOOOOAN=VAN=VOOOO7+$X7+$X",
5
+ stateData: "%q~OSPOUQOYROaQPcQP~ObTO~ObUO~OcVO~OTXO~OWYO~O[ZOc_Od]Oe[O~ObbOaRicRi~ObcOaVicVi~OedOaZXcZX~O]eOaZXcZX~O[fOedOa^Xc^X~O_gO~Oc_O~OUiOaRqcRq~OXjOaVqcVq~O]kOaZacZa~OelOaZacZa~O[ZOdmOe[O~ObnOaRycRy~O]oOaZicZi~O[fOedO~OUSd[Y~",
6
+ goto: "uaPPbePPPePPPhPPlPoRSORROT^VhR`VQWSRaW",
7
+ nodeNames: "⚠ Message StartLine RequestLine Method Target Version StatusLine StatusCode ReasonPhrase StartLineText Header HeaderName HeaderValue BlankLine Body",
8
+ maxTerm: 21,
9
+ skippedNodes: [
10
+ 0
11
+ ],
12
+ repeatNodeCount: 1,
13
+ tokenData: "2b#sR^OX}XY&TYZ'UZp}pq&Tq![}![!]'f!]!c}!c!j(a!j!k)v!k!}(a!};'S};'S;=`%}<%lO}#s!`Y_p]`X!bWSTQ[WYPOX}XY#OYZ#rZp}pq#Oq![}![!]%O!];'S};'S;=`%}<%lO}#m#]V_p]`X!b[WYPOY#OYZ#rZ![#O![!]$W!];'S#O;'S;=`$x<%lO#Op#wR_pO;'S#r;'S;=`$Q<%lO#rp$TP;=`<%l#r#e$cT_p]`X!bYPOY$WYZ#rZ;'S$W;'S;=`$r<%lO$W#e$uP;=`<%l$W#m${P;=`<%l#O#k%_W_p]`X!bWSTQYPOX%OXY$WYZ#rZp%Opq$Wq;'S%O;'S;=`%w<%lO%O#k%zP;=`<%l%O#s&QP;=`<%l}#o&fY_p]`X!bbQdW[WYPOX#OXY&TYZ#rZp#Opq&Tq![#O![!]$W!];'S#O;'S;=`$x<%lO#O#o']R_pc!}O;'S#r;'S;=`$Q<%lO#r#s'wWeW_p]`X!bWSTQYPOX%OXY$WYZ#rZp%Opq$Wq;'S%O;'S;=`%w<%lO%O#s(t`_p]`X!bWSTQSP[WYPOX}XY#OYZ#rZp}pq#Oq}}}!O(a!O![}![!]%O!]!c}!c!}(a!}#R}#R#S(a#S;'S};'S;=`%}<%lO}#s*Zb_p]`X!bWSTQSP[WYPOX}XY#OYZ#rZp}pq#Oq}}}!O(a!O![}![!]%O!]!c}!c!v(a!v!w+c!w!}(a!}#R}#R#S(a#S;'S};'S;=`%}<%lO}#s+vb_p]`X!bWSTQSP[WYPOX}XY#OYZ#rZp}pq#Oq}}}!O(a!O![}![!]%O!]!c}!c!v(a!v!w-O!w!}(a!}#R}#R#S(a#S;'S};'S;=`%}<%lO}#s-cb_p]`X!bWSTQSP[WYPOX}XY#OYZ#rZp}pq#Oq}}}!O(a!O![}![!]%O!]!c}!c!r(a!r!s.k!s!}(a!}#R}#R#S(a#S;'S};'S;=`%}<%lO}#s/Ob_p]`X!bWSTQSP[WYPOX}XY#OYZ#rZp}pq#Oq}}}!O(a!O!P}!P!Q0W!Q![}![!]%O!]!c}!c!}(a!}#R}#R#S(a#S;'S};'S;=`%}<%lO}#s0kY_p]`X!bWSTQUP[WYPOX0WXY#OYZ#rZp0Wpq#Oq![0W![!]1Z!];'S0W;'S;=`2[<%lO0W#k1lW_p]`X!bWSTQUPYPOX1ZXY$WYZ#rZp1Zpq$Wq;'S1Z;'S;=`2U<%lO1Z#k2XP;=`<%l1Z#s2_P;=`<%l0W",
14
+ tokenizers: [
15
+ 0,
16
+ 1,
17
+ 2,
18
+ 3,
19
+ 4,
20
+ 5,
21
+ 6
22
+ ],
23
+ topRules: {
24
+ Message: [
25
+ 0,
26
+ 1
27
+ ]
28
+ },
29
+ tokenPrec: 211
30
+ });
31
+ export { parser };
@@ -0,0 +1 @@
1
+ export declare const Message = 1, StartLine = 2, RequestLine = 3, Method = 4, Target = 5, Version = 6, StatusLine = 7, StatusCode = 8, ReasonPhrase = 9, StartLineText = 10, Header = 11, HeaderName = 12, HeaderValue = 13, BlankLine = 14, Body = 15;
@@ -0,0 +1,2 @@
1
+ const Message = 1, StartLine = 2, RequestLine = 3, Method = 4, Target = 5, Version = 6, StatusLine = 7, StatusCode = 8, ReasonPhrase = 9, StartLineText = 10, Header = 11, HeaderName = 12, HeaderValue = 13, BlankLine = 14, Body = 15;
2
+ export { BlankLine, Body, Header, HeaderName, HeaderValue, Message, Method, ReasonPhrase, RequestLine, StartLine, StartLineText, StatusCode, StatusLine, Target, Version };
@@ -0,0 +1,8 @@
1
+ import type { Extension } from '@codemirror/state';
2
+ import type { CodeEditorLanguage } from '../../types';
3
+ export { findJsonBodyRange, http, httpContextAt, httpLanguage } from './http';
4
+ /** CodeMirror language support for a CodeEditor `language`. `bash` and `text` have no structure parser. */
5
+ export declare const languageExtension: (language: CodeEditorLanguage) => Extension;
6
+ export declare const isLazyLanguage: (language: CodeEditorLanguage) => boolean;
7
+ /** Loads the parser for a lazy language (cached). Resolves [] for languages that are available synchronously. */
8
+ export declare const loadLanguageExtension: (language: CodeEditorLanguage) => Promise<Extension>;
@@ -0,0 +1,41 @@
1
+ import { StreamLanguage } from "@codemirror/language";
2
+ import { findJsonBodyRange, http, httpContextAt, httpLanguage } from "./http/index.js";
3
+ import { json } from "./json.js";
4
+ import { yaml } from "./yaml.js";
5
+ const noLanguage = ()=>[];
6
+ const LANGUAGE_EXTENSIONS = {
7
+ http: http,
8
+ json: json,
9
+ yaml: yaml,
10
+ bash: noLanguage,
11
+ text: noLanguage,
12
+ javascript: noLanguage,
13
+ typescript: noLanguage,
14
+ python: noLanguage,
15
+ lua: noLanguage
16
+ };
17
+ const LAZY_LANGUAGES = {
18
+ javascript: ()=>import("@codemirror/lang-javascript").then((m)=>m.javascript()),
19
+ typescript: ()=>import("@codemirror/lang-javascript").then((m)=>m.javascript({
20
+ typescript: true
21
+ })),
22
+ python: ()=>import("@codemirror/lang-python").then((m)=>m.python()),
23
+ lua: ()=>import("@codemirror/legacy-modes/mode/lua").then((m)=>StreamLanguage.define(m.lua))
24
+ };
25
+ const lazyCache = new Map();
26
+ const languageExtension = (language)=>LANGUAGE_EXTENSIONS[language]();
27
+ const isLazyLanguage = (language)=>language in LAZY_LANGUAGES;
28
+ const loadLanguageExtension = (language)=>{
29
+ const load = LAZY_LANGUAGES[language];
30
+ if (!load) return Promise.resolve([]);
31
+ let pending = lazyCache.get(language);
32
+ if (!pending) {
33
+ pending = load().catch((error)=>{
34
+ lazyCache.delete(language);
35
+ throw error;
36
+ });
37
+ lazyCache.set(language, pending);
38
+ }
39
+ return pending;
40
+ };
41
+ export { findJsonBodyRange, http, httpContextAt, httpLanguage, isLazyLanguage, languageExtension, loadLanguageExtension };
@@ -0,0 +1,8 @@
1
+ import { LanguageSupport, type LRLanguage } from '@codemirror/language';
2
+ /**
3
+ * lang-json's JSON language with its Object/Array syntax folds switched off.
4
+ * CodeSnippet folds only what the `folds` prop describes, so CodeEditor does the same (spec §7.4).
5
+ * Indentation, bracket and language data are kept.
6
+ */
7
+ export declare const jsonEditorLanguage: LRLanguage;
8
+ export declare const json: () => LanguageSupport;
@@ -0,0 +1,11 @@
1
+ import { jsonLanguage } from "@codemirror/lang-json";
2
+ import { LanguageSupport, foldNodeProp } from "@codemirror/language";
3
+ const jsonEditorLanguage = jsonLanguage.configure({
4
+ props: [
5
+ foldNodeProp.add({
6
+ 'Object Array': ()=>null
7
+ })
8
+ ]
9
+ });
10
+ const json = ()=>new LanguageSupport(jsonEditorLanguage);
11
+ export { json, jsonEditorLanguage };
@@ -0,0 +1,47 @@
1
+ import type { EditorState } from '@codemirror/state';
2
+ import type { SyntaxNode } from '@lezer/common';
3
+ /** Absolute document offsets of one JSON value (and of its key, for object members). */
4
+ export interface JsonPointerEntry {
5
+ pointer: string;
6
+ keyFrom?: number;
7
+ keyTo?: number;
8
+ valueFrom: number;
9
+ valueTo: number;
10
+ }
11
+ /** A range of the document that holds one JSON text (the whole doc, or an http body). */
12
+ export interface JsonRegion {
13
+ from: number;
14
+ to: number;
15
+ }
16
+ /** Lezer JSON node names that are complete values (error nodes `⚠` are not). */
17
+ export declare const VALUE_NODE_NAMES: ReadonlySet<string>;
18
+ /** Upper bound for the parse work a pointer lookup may force, in ms. */
19
+ export declare const ENSURE_TREE_TIMEOUT = 200;
20
+ /** RFC 6901 reference-token escaping: `~` → `~0`, `/` → `~1`. */
21
+ export declare const escapePointerSegment: (segment: string) => string;
22
+ export declare const isValueNode: (node: SyntaxNode) => boolean;
23
+ /** Decoded text of a `PropertyName` / `String` node; the raw inner text when it is not valid JSON. */
24
+ export declare const readJsonKey: (state: EditorState, node: SyntaxNode) => string;
25
+ /**
26
+ * The `JsonText` node of the region: the whole tree for `json`, the `parseMixed`
27
+ * mount for an `http` body. `null` when the region holds no JSON tree.
28
+ */
29
+ export declare const findJsonText: (state: EditorState, region: JsonRegion) => SyntaxNode | null;
30
+ /**
31
+ * RFC 6901 pointer (`''` = root, `/a/0/b`, `~0`/`~1` escaped) → absolute key/value ranges,
32
+ * built from the Lezer JSON tree inside `region`. Unfinished members (no value yet) are skipped.
33
+ */
34
+ export declare const getJsonPointers: (state: EditorState, region: JsonRegion) => Map<string, JsonPointerEntry>;
35
+ /**
36
+ * Pointer of the innermost key or value that contains `pos` (a key counts as its member).
37
+ * `undefined` outside the JSON value.
38
+ */
39
+ export declare const pointerAt: (state: EditorState, pos: number, region: JsonRegion) => string | undefined;
40
+ /**
41
+ * Best-effort data for a value node of a possibly unfinished document: complete members
42
+ * and items are kept, unfinished ones (no value yet, error nodes) are dropped. Used to
43
+ * reduce `oneOf` / `if` schemas while the text is not valid JSON yet.
44
+ */
45
+ export declare const readPartialJson: (state: EditorState, value: SyntaxNode) => unknown;
46
+ /** `JSON.parse` of the region when valid, otherwise {@link readPartialJson} of its root value. */
47
+ export declare const readRegionData: (state: EditorState, region: JsonRegion) => unknown;