@mongodb-js/compass-editor 0.70.0 → 0.71.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.
@@ -1,7 +1,9 @@
1
1
  import type { CompletionSource } from '@codemirror/autocomplete';
2
2
  /**
3
- * Autocompleter for the document object, only autocompletes field names in the
4
- * appropriate format (either escaped or not) both for javascript and json modes
3
+ * Autocompleter for the document object. Completes field names in the
4
+ * appropriate format (either escaped or not) both for javascript and json
5
+ * modes, and bson constructors (`ObjectId()`, `ISODate()`, ...) in value
6
+ * position, which are only valid outside of json mode.
5
7
  */
6
8
  export declare const createDocumentAutocompleter: (fields: string[]) => CompletionSource;
7
9
  //# sourceMappingURL=document-autocompleter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"document-autocompleter.d.ts","sourceRoot":"","sources":["../../src/codemirror/document-autocompleter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AA2BjE;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GACtC,QAAQ,MAAM,EAAE,KACf,gBAqCF,CAAC"}
1
+ {"version":3,"file":"document-autocompleter.d.ts","sourceRoot":"","sources":["../../src/codemirror/document-autocompleter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAgCjE;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,GACtC,QAAQ,MAAM,EAAE,KACf,gBAiEF,CAAC"}
@@ -23,14 +23,18 @@ function isJavaScriptPropertyName(token) {
23
23
  (!token.prevSibling || token.prevSibling.name === '['));
24
24
  }
25
25
  /**
26
- * Autocompleter for the document object, only autocompletes field names in the
27
- * appropriate format (either escaped or not) both for javascript and json modes
26
+ * Autocompleter for the document object. Completes field names in the
27
+ * appropriate format (either escaped or not) both for javascript and json
28
+ * modes, and bson constructors (`ObjectId()`, `ISODate()`, ...) in value
29
+ * position, which are only valid outside of json mode.
28
30
  */
29
31
  const createDocumentAutocompleter = (fields) => {
30
32
  const completions = (0, autocompleter_1.completer)('', { fields, meta: ['field:identifier'] });
33
+ const bsonCompletions = (0, autocompleter_1.completer)('', { meta: ['bson'] });
31
34
  return (context) => {
32
35
  const token = (0, utils_1.resolveTokenAtCursor)(context);
33
- const shouldAlwaysEscapeProperty = context.state.facet(editor_1.languageName)[0] === 'json';
36
+ const isJSON = context.state.facet(editor_1.languageName)[0] === 'json';
37
+ const shouldAlwaysEscapeProperty = isJSON;
34
38
  if (isJSONPropertyName(token) || isJavaScriptPropertyName(token)) {
35
39
  const prefix = context.state
36
40
  .sliceDoc(token.from, context.pos)
@@ -55,6 +59,27 @@ const createDocumentAutocompleter = (fields) => {
55
59
  filter: false,
56
60
  };
57
61
  }
62
+ if (!isJSON && token.type.name !== 'String' && (0, utils_1.isPropertyValue)(token)) {
63
+ const prefix = context.state.sliceDoc(token.from, context.pos);
64
+ if (!prefix) {
65
+ return null;
66
+ }
67
+ return {
68
+ from: token.from,
69
+ to: token.to,
70
+ options: bsonCompletions
71
+ .filter((completion) => {
72
+ return completion.value
73
+ .toLowerCase()
74
+ .startsWith(prefix.toLowerCase());
75
+ })
76
+ .map((completion) => {
77
+ // bson constructors are expressions, never quoted like a field name
78
+ return (0, utils_1.mapMongoDBCompletionToCodemirrorCompletion)(completion, 'never');
79
+ }),
80
+ filter: false,
81
+ };
82
+ }
58
83
  return (0, utils_1.completeWordsInString)(context);
59
84
  };
60
85
  };
@@ -0,0 +1,21 @@
1
+ import type { EditorRef } from '../types';
2
+ import type { Annotation } from './../editor';
3
+ import type { LintConfig } from '../linter';
4
+ export type SafeIntegerViolation = {
5
+ from: number;
6
+ to: number;
7
+ acceptsStringArgument: boolean;
8
+ };
9
+ type SafeIntegerLinterOptions = LintConfig & {
10
+ editorRef?: React.RefObject<EditorRef>;
11
+ onFixViolation?: (source: string) => string;
12
+ onViolationFixed: () => void;
13
+ externalAnnotations?: React.RefObject<Annotation[]>;
14
+ };
15
+ export declare function useSafeIntegerLinter({ editorRef, onFixViolation, onViolationFixed, externalAnnotations, lintDelay, tooltipExitDelay, theme, }: SafeIntegerLinterOptions): {
16
+ safeIntegerLinter: import("@codemirror/state").Extension;
17
+ violations: SafeIntegerViolation[];
18
+ onFixViolations: () => void;
19
+ };
20
+ export {};
21
+ //# sourceMappingURL=use-safe-integer-linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-safe-integer-linter.d.ts","sourceRoot":"","sources":["../../src/codemirror/use-safe-integer-linter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAK5C,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IAIX,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,KAAK,wBAAwB,GAAG,UAAU,GAAG;IAC3C,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;CACrD,CAAC;AAuGF,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,cAAsC,EACtC,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,gBAAgB,EAChB,KAAK,GACN,EAAE,wBAAwB;;;;EAgG1B"}
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSafeIntegerLinter = useSafeIntegerLinter;
4
+ const react_1 = require("react");
5
+ const compass_components_1 = require("@mongodb-js/compass-components");
6
+ const linter_1 = require("../linter");
7
+ const lint_tooltip_exit_delay_1 = require("../lint-tooltip-exit-delay");
8
+ const defaultOnFixViolation = (source) => `Long("${source}")`;
9
+ const VIOLATION_MESSAGE = 'Exceeds safe integer range.';
10
+ // Constructors that accept a string and use the value. Anything else
11
+ // either changes meaning (`Date`) or still rounds the value (`Int32`,
12
+ // `Double`), so those get wrapped instead.
13
+ const STRING_ARGUMENT_CONSTRUCTORS = new Set([
14
+ 'Long',
15
+ 'NumberLong',
16
+ 'Int64',
17
+ 'Decimal128',
18
+ 'NumberDecimal',
19
+ ]);
20
+ function isUnsafeInteger(str) {
21
+ if (!/^-?\d+$/.test(str)) {
22
+ return false;
23
+ }
24
+ try {
25
+ const num = BigInt(str);
26
+ return (num > BigInt(Number.MAX_SAFE_INTEGER) ||
27
+ num < BigInt(Number.MIN_SAFE_INTEGER));
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ // A leading `-` is a unary expression around the literal rather than part of
34
+ // it, so it has to be pulled into the violation to fix `-123...` as
35
+ // `Long("-123...")` rather than `-Long("123...")`.
36
+ function negationOperator(node, doc) {
37
+ const operator = node.parent?.name === 'UnaryExpression' ? node.parent.firstChild : null;
38
+ return operator?.name === 'ArithOp' &&
39
+ doc.sliceString(operator.from, operator.to) === '-'
40
+ ? operator
41
+ : null;
42
+ }
43
+ function isStringConstructorArgument(node, doc) {
44
+ if (node.parent?.name !== 'ArgList') {
45
+ return false;
46
+ }
47
+ const callee = node.parent.prevSibling;
48
+ return (callee?.name === 'VariableName' &&
49
+ STRING_ARGUMENT_CONSTRUCTORS.has(doc.sliceString(callee.from, callee.to)));
50
+ }
51
+ function unsafeIntegerViolation(node, doc) {
52
+ if (!isUnsafeInteger(doc.sliceString(node.from, node.to))) {
53
+ return null;
54
+ }
55
+ const literal = negationOperator(node, doc)?.parent ?? node;
56
+ return {
57
+ from: literal.from,
58
+ to: literal.to,
59
+ acceptsStringArgument: isStringConstructorArgument(literal, doc),
60
+ };
61
+ }
62
+ function sameViolations(a, b) {
63
+ return (a.length === b.length &&
64
+ a.every((v, i) => v.from === b[i].from &&
65
+ v.to === b[i].to &&
66
+ v.acceptsStringArgument === b[i].acceptsStringArgument));
67
+ }
68
+ function applyFix(violation, source, { onFixViolation, onViolationFixed }) {
69
+ // The violation can span whitespace between a sign and its digits (`- 123`).
70
+ const literal = source.replace(/\s+/g, '');
71
+ onViolationFixed();
72
+ return violation.acceptsStringArgument
73
+ ? `"${literal}"`
74
+ : onFixViolation(literal);
75
+ }
76
+ function useSafeIntegerLinter({ editorRef, onFixViolation = defaultOnFixViolation, onViolationFixed, externalAnnotations, lintDelay, tooltipExitDelay, theme, }) {
77
+ const [violations, setViolations] = (0, react_1.useState)([]);
78
+ const optionsRef = (0, compass_components_1.useCurrentValueRef)({
79
+ onFixViolation,
80
+ onViolationFixed,
81
+ externalAnnotations,
82
+ });
83
+ const violationsRef = (0, compass_components_1.useCurrentValueRef)(violations);
84
+ const safeIntegerLinter = (0, react_1.useMemo)(() => {
85
+ return (0, linter_1.createCodemirrorLinter)((tree, view) => {
86
+ const violations = [];
87
+ tree.iterate({
88
+ enter: (node) => {
89
+ // Warn on any bare number literal, including one passed as a
90
+ // numeric argument to a constructor like `Long(123...)`: the
91
+ // literal is parsed as a JS double and loses precision before the
92
+ // constructor sees it.
93
+ if (node.name !== 'Number') {
94
+ return;
95
+ }
96
+ const violation = unsafeIntegerViolation(node.node, view.state.doc);
97
+ if (violation) {
98
+ violations.push(violation);
99
+ }
100
+ },
101
+ });
102
+ // Only update state when the violations actually changed, otherwise
103
+ // every lint pass re-renders the consumer with a new array identity.
104
+ if (!sameViolations(violationsRef.current, violations)) {
105
+ violationsRef.current = violations;
106
+ setViolations(violations);
107
+ }
108
+ const annotations = violations.map((violation) => {
109
+ const { from, to } = violation;
110
+ return {
111
+ from,
112
+ to,
113
+ severity: 'error',
114
+ message: VIOLATION_MESSAGE,
115
+ actions: [
116
+ {
117
+ name: 'Convert to Long',
118
+ apply: (view, from, to) => {
119
+ view.dispatch({
120
+ changes: {
121
+ from,
122
+ to,
123
+ insert: applyFix(violation, view.state.sliceDoc(from, to), optionsRef.current),
124
+ },
125
+ });
126
+ },
127
+ },
128
+ ],
129
+ };
130
+ });
131
+ return [
132
+ ...annotations.map(lint_tooltip_exit_delay_1.wrapLinterAnnotation),
133
+ ...(optionsRef.current.externalAnnotations?.current ?? []),
134
+ ];
135
+ }, { lintDelay, theme, tooltipExitDelay });
136
+ }, [lintDelay, theme, tooltipExitDelay]);
137
+ const onFixViolations = (0, react_1.useCallback)(() => {
138
+ const editor = editorRef?.current?.editor;
139
+ if (!editor || violations.length === 0) {
140
+ return;
141
+ }
142
+ editor.dispatch({
143
+ changes: violations.map((violation) => {
144
+ const { from, to } = violation;
145
+ return {
146
+ from,
147
+ to,
148
+ insert: applyFix(violation, editor.state.sliceDoc(from, to), optionsRef.current),
149
+ };
150
+ }),
151
+ });
152
+ setViolations([]);
153
+ }, [violations, editorRef]);
154
+ return { safeIntegerLinter, violations, onFixViolations };
155
+ }
package/dist/editor.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { KeyBinding } from '@codemirror/view';
3
3
  import { placeholder as codemirrorPlaceholder, EditorView } from '@codemirror/view';
4
+ import { syntaxTree } from '@codemirror/language';
4
5
  import type { Diagnostic } from '@codemirror/lint';
5
6
  import type { CompletionSource } from '@codemirror/autocomplete';
6
7
  import type { Extension } from '@codemirror/state';
@@ -33,6 +34,7 @@ export declare const editorPalette: {
33
34
  readonly autocompleteBorderColor: "#E8EDEB";
34
35
  readonly autocompleteMatchColor: "#00A35C";
35
36
  readonly autocompleteSelectedBackgroundColor: "#E8EDEB";
37
+ readonly linkColor: "#016BF8";
36
38
  };
37
39
  readonly dark: {
38
40
  readonly color: string;
@@ -57,14 +59,19 @@ export declare const editorPalette: {
57
59
  readonly autocompleteBorderColor: "#5C6C75";
58
60
  readonly autocompleteMatchColor: "#F9FBFA";
59
61
  readonly autocompleteSelectedBackgroundColor: "#3D4F58";
62
+ readonly linkColor: "#0498EC";
60
63
  };
61
64
  };
62
65
  declare const highlightStyles: {
63
66
  readonly light: HighlightStyle;
64
67
  readonly dark: HighlightStyle;
65
68
  };
66
- type EditorLanguage = 'json' | 'javascript' | 'javascript-expression';
67
- export type Annotation = Pick<Diagnostic, 'from' | 'to' | 'severity' | 'message'>;
69
+ export type EditorLanguage = 'json' | 'javascript' | 'javascript-expression';
70
+ /**
71
+ * *Note*: Action only works when linting has been enabled
72
+ */
73
+ export type Annotation = Pick<Diagnostic, 'from' | 'to' | 'severity' | 'message' | 'actions' | 'renderMessage'>;
74
+ export type Linter = (tree: ReturnType<typeof syntaxTree>, view: EditorView) => readonly Annotation[];
68
75
  type EditorProps = {
69
76
  language?: EditorLanguage;
70
77
  onChangeText?: (text: string, event?: any) => void;
@@ -83,6 +90,7 @@ type EditorProps = {
83
90
  'data-testid'?: string;
84
91
  annotations?: Annotation[];
85
92
  completer?: CompletionSource;
93
+ linter?: Extension;
86
94
  customExtensions?: Extension[];
87
95
  minLines?: number;
88
96
  maxLines?: number;
@@ -102,7 +110,7 @@ export declare const languages: Record<EditorLanguage, () => LanguageSupport>;
102
110
  export declare const languageName: Facet<EditorLanguage, readonly EditorLanguage[]>;
103
111
  declare const BaseEditor: React.ForwardRefExoticComponent<EditorProps & React.RefAttributes<EditorRef>>;
104
112
  export type { EditorView, KeyBinding as Command };
105
- type InlineEditorProps = Omit<EditorProps, 'text' | 'showLineNumbers' | 'showFoldGutter' | 'showAnnotationsGutter' | 'showScroll' | 'highlightActiveLine' | 'minLines' | 'annotations'> & ({
113
+ type InlineEditorProps = Omit<EditorProps, 'text' | 'showLineNumbers' | 'showFoldGutter' | 'showScroll' | 'highlightActiveLine' | 'minLines' | 'annotations'> & ({
106
114
  text: string;
107
115
  initialText?: never;
108
116
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAEL,WAAW,IAAI,qBAAqB,EAMpC,UAAU,EACX,MAAM,kBAAkB,CAAC;AAqB1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAwBjE,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,KAAK,EAA4B,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,eAAe,EAEf,cAAc,EACf,MAAM,sBAAsB,CAAC;AAK9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA+EzC,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEnD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDhB,CAAC;AAsVX,QAAA,MAAM,eAAe;;;CAGX,CAAC;AAGX,KAAK,cAAc,GAAG,MAAM,GAAG,YAAY,GAAG,uBAAuB,CAAC;AAEtE,MAAM,MAAM,UAAU,GAAG,IAAI,CAC3B,UAAU,EACV,MAAM,GAAG,IAAI,GAAG,UAAU,GAAG,SAAS,CACvC,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACnD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC5D,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC5D,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,gBAAgB,CAAC,EAAE,SAAS,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACjC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,CACA;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,KAAK,CAAA;CAAE,GACrC;IAAE,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CACxC,GACC,IAAI,CACF,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAC/B,IAAI,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CACtD,CAAC;AAsBJ,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,eAAe,CAM1D,CAAC;AAEX,eAAO,MAAM,YAAY,kDAAmC,CAAC;AAuF7D,QAAA,MAAM,UAAU,+EAuiBd,CAAC;AAmGH,YAAY,EAAE,UAAU,EAAE,UAAU,IAAI,OAAO,EAAE,CAAC;AAElD,KAAK,iBAAiB,GAAG,IAAI,CAC3B,WAAW,EACT,MAAM,GACN,iBAAiB,GACjB,gBAAgB,GAChB,uBAAuB,GACvB,YAAY,GACZ,qBAAqB,GACrB,UAAU,GACV,aAAa,CAChB,GACC,CACI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,KAAK,CAAA;CAAE,GACrC;IAAE,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CACxC,CAAC;AAQJ,QAAA,MAAM,YAAY,qFAiBjB,CAAC;AA2BF,KAAK,oBAAoB,GAAG,WAAW,GAAG;IACxC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,eAAe,wFA8GpB,CAAC;AAEF;;;;;;;GAOG;AACH,iBAAe,wBAAwB,CACrC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,EAChC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;;GAOG;AACH,iBAAS,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAS1E;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,OAAO,EAAE,YAAY,IAAI,sBAAsB,EAAE,CAAC;AAClD,OAAO,EAAE,eAAe,IAAI,yBAAyB,EAAE,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,CAAC;AACpC,YAAY,EAAE,gBAAgB,IAAI,SAAS,EAAE,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.tsx"],"names":[],"mappings":"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"}
package/dist/editor.js CHANGED
@@ -142,6 +142,7 @@ exports.editorPalette = {
142
142
  autocompleteBorderColor: compass_components_1.palette.gray.light2,
143
143
  autocompleteMatchColor: compass_components_1.palette.green.dark1,
144
144
  autocompleteSelectedBackgroundColor: compass_components_1.palette.gray.light2,
145
+ linkColor: compass_components_1.palette.blue.base,
145
146
  },
146
147
  dark: {
147
148
  color: compass_components_1.codePalette.dark[3],
@@ -167,6 +168,7 @@ exports.editorPalette = {
167
168
  autocompleteBorderColor: compass_components_1.palette.gray.dark1,
168
169
  autocompleteMatchColor: compass_components_1.palette.gray.light3,
169
170
  autocompleteSelectedBackgroundColor: compass_components_1.palette.gray.dark2,
171
+ linkColor: compass_components_1.palette.blue.light1,
170
172
  },
171
173
  };
172
174
  const cmFontStyles = {
@@ -405,6 +407,29 @@ function getStylesForTheme(theme) {
405
407
  '& .cm-tooltip .completion-info p:last-child': {
406
408
  marginBottom: 0,
407
409
  },
410
+ // Hide the inline underline @codemirror/lint error
411
+ '& .cm-lintRange-error': {
412
+ backgroundImage: 'none',
413
+ },
414
+ '& .cm-lintPoint::after': {
415
+ display: 'none',
416
+ },
417
+ '.cm-diagnosticAction': {
418
+ background: 'none',
419
+ display: 'inline',
420
+ margin: '0 0 0 8px',
421
+ padding: '0',
422
+ border: 'none',
423
+ color: exports.editorPalette[theme].linkColor,
424
+ cursor: 'pointer',
425
+ },
426
+ '& .cm-diagnosticAction:focus-visible': {
427
+ outline: 'none',
428
+ boxShadow: `0 0 0 2px ${compass_components_1.palette.blue.light1}`,
429
+ },
430
+ '& .cm-diagnosticAction:hover': {
431
+ textDecoration: 'underline',
432
+ },
408
433
  '& .cm-widgetBuffer': {
409
434
  // Default is text-top which causes weird 1px added to the line height
410
435
  // when widget (in our case this is placeholder widget) is shown in the
@@ -419,6 +444,9 @@ const themeStyles = {
419
444
  };
420
445
  // Base theme for autocomplete hover - applies to document root for tooltips
421
446
  const autocompleteHoverStyles = view_1.EditorView.baseTheme({
447
+ '.cm-tooltip': {
448
+ maxWidth: 'min(90vw, 500px)',
449
+ },
422
450
  '&light .cm-tooltip.cm-tooltip-autocomplete ul li:hover': {
423
451
  color: exports.editorPalette.light.autocompleteColor,
424
452
  backgroundColor: exports.editorPalette.light.autocompleteSelectedBackgroundColor,
@@ -578,7 +606,7 @@ function useCodemirrorExtensionCompartment(fn, value, editorViewRef) {
578
606
  }, value);
579
607
  return extensionCompartment;
580
608
  }
581
- const BaseEditor = react_1.default.forwardRef(function BaseEditor({ initialText: _initialText, text, onChangeText, language = 'json', showLineNumbers = true, showFoldGutter = true, showAnnotationsGutter = true, showScroll = true, highlightActiveLine: shouldHighlightActiveLine = true, annotations, completer, customExtensions, darkMode: _darkMode, disabled = false, className, readOnly = false, onLoad = () => {
609
+ const BaseEditor = react_1.default.forwardRef(function BaseEditor({ initialText: _initialText, text, onChangeText, language = 'json', showLineNumbers = true, showFoldGutter = true, showAnnotationsGutter = true, showScroll = true, highlightActiveLine: shouldHighlightActiveLine = true, annotations, completer, linter, customExtensions, darkMode: _darkMode, disabled = false, className, readOnly = false, onLoad = () => {
582
610
  /**/
583
611
  }, onFocus = () => {
584
612
  /**/
@@ -722,6 +750,9 @@ const BaseEditor = react_1.default.forwardRef(function BaseEditor({ initialText:
722
750
  })
723
751
  : [];
724
752
  }, completer, editorViewRef);
753
+ const linterExtension = useCodemirrorExtensionCompartment(() => {
754
+ return linter ? linter : [];
755
+ }, linter, editorViewRef);
725
756
  const placeholderExtension = useCodemirrorExtensionCompartment(() => {
726
757
  return placeholder ? (0, view_1.placeholder)(placeholder) : [];
727
758
  }, placeholder, editorViewRef);
@@ -771,6 +802,7 @@ const BaseEditor = react_1.default.forwardRef(function BaseEditor({ initialText:
771
802
  (0, language_1.bracketMatching)(),
772
803
  (0, autocomplete_1.closeBrackets)(),
773
804
  autocompletionExtension,
805
+ linterExtension,
774
806
  languageExtension,
775
807
  (0, language_2.syntaxHighlighting)(highlightStyles['light']),
776
808
  (0, language_2.syntaxHighlighting)(highlightStyles['dark']),
@@ -802,11 +834,14 @@ const BaseEditor = react_1.default.forwardRef(function BaseEditor({ initialText:
802
834
  ...autocomplete_1.completionKeymap,
803
835
  ...tabKeymap,
804
836
  ]),
805
- // Supply the document body as the tooltip parent
806
- // because we are using containment contexts for container
807
- // queries which offset things otherwise.
837
+ // Supply the tooltip parent explicitly because we are using
838
+ // containment contexts for container queries which offset things
839
+ // otherwise. When the editor is rendered inside a modal (a native
840
+ // <dialog> promoted to the top layer via showModal), the tooltip
841
+ // must be parented to that dialog so it renders in the same top
842
+ // layer instead of behind the modal.
808
843
  (0, view_1.tooltips)({
809
- parent: document.body,
844
+ parent: domNode.closest('dialog') ?? document.body,
810
845
  }),
811
846
  editableExtension,
812
847
  readOnlyExtension,
@@ -882,6 +917,7 @@ const BaseEditor = react_1.default.forwardRef(function BaseEditor({ initialText:
882
917
  readOnlyExtension,
883
918
  themeConfigExtension,
884
919
  autocompletionExtension,
920
+ linterExtension,
885
921
  lineHeightExtension,
886
922
  activeLineExtension,
887
923
  placeholderExtension,
@@ -1055,13 +1091,17 @@ const prettify = (editorView) => {
1055
1091
  }
1056
1092
  return false;
1057
1093
  };
1058
- const inlineStyles = (0, compass_components_1.css)({
1094
+ const inlineStylesLightMode = (0, compass_components_1.css)({
1059
1095
  '& .cm-editor': {
1060
- backgroundColor: 'transparent',
1096
+ backgroundColor: compass_components_1.palette.white,
1097
+ },
1098
+ '& .cm-gutters': {
1099
+ backgroundColor: `${compass_components_1.palette.white} !important`,
1061
1100
  },
1062
1101
  });
1063
- const InlineEditor = react_1.default.forwardRef(function InlineEditor({ className, ...props }, forwardRef) {
1064
- return (react_1.default.createElement(BaseEditor, { ref: forwardRef, maxLines: 10, showFoldGutter: false, showLineNumbers: false, showAnnotationsGutter: false, showScroll: false, highlightActiveLine: false, className: (0, compass_components_1.cx)(inlineStyles, className), language: "javascript-expression", ...props }));
1102
+ const InlineEditor = react_1.default.forwardRef(function InlineEditor({ className, showAnnotationsGutter, ...props }, forwardRef) {
1103
+ const darkMode = (0, compass_components_1.useDarkMode)();
1104
+ return (react_1.default.createElement(BaseEditor, { ref: forwardRef, maxLines: 10, showFoldGutter: false, showLineNumbers: false, showAnnotationsGutter: Boolean(showAnnotationsGutter), showScroll: false, highlightActiveLine: false, className: (0, compass_components_1.cx)(!darkMode && inlineStylesLightMode, className), language: "javascript-expression", ...props }));
1065
1105
  });
1066
1106
  exports.CodemirrorInlineEditor = InlineEditor;
1067
1107
  const multilineEditorContainerStyle = (0, compass_components_1.css)({
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { prettify } from './prettify';
3
3
  export type { FormatOptions } from './prettify';
4
4
  export { CodemirrorInlineEditor, CodemirrorMultilineEditor, setCodemirrorEditorValue, getCodemirrorEditorValue, } from './editor';
5
5
  export type { EditorView, Command, Annotation, Completer } from './editor';
6
+ export type { Extension } from '@codemirror/state';
6
7
  export type { Action } from './action-button';
7
8
  export { createDocumentAutocompleter } from './codemirror/document-autocompleter';
8
9
  export { createValidationAutocompleter } from './codemirror/validation-autocompleter';
@@ -14,4 +15,5 @@ export { createQueryHistoryAutocompleter, type SavedQuery, } from './codemirror/
14
15
  export { createQueryWithHistoryAutocompleter } from './codemirror/query-autocompleter-with-history';
15
16
  export { useJsonSchemaAutocompleter } from './use-json-schema-autocompleter';
16
17
  export type { JsonSchemaAutocompleterResult } from './use-json-schema-autocompleter';
18
+ export { useSafeIntegerLinter } from './codemirror/use-safe-integer-linter';
17
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC3E,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AACxF,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EACL,+BAA+B,EAC/B,KAAK,UAAU,GAChB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,YAAY,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AACxF,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EACL,+BAA+B,EAC/B,KAAK,UAAU,GAChB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,YAAY,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useJsonSchemaAutocompleter = exports.createQueryWithHistoryAutocompleter = exports.createQueryHistoryAutocompleter = exports.createSearchIndexAutocompleter = exports.createAggregationAutocompleter = exports.createStageAutocompleter = exports.createQueryAutocompleter = exports.createValidationAutocompleter = exports.createDocumentAutocompleter = exports.getCodemirrorEditorValue = exports.setCodemirrorEditorValue = exports.CodemirrorMultilineEditor = exports.CodemirrorInlineEditor = exports.prettify = void 0;
3
+ exports.useSafeIntegerLinter = exports.useJsonSchemaAutocompleter = exports.createQueryWithHistoryAutocompleter = exports.createQueryHistoryAutocompleter = exports.createSearchIndexAutocompleter = exports.createAggregationAutocompleter = exports.createStageAutocompleter = exports.createQueryAutocompleter = exports.createValidationAutocompleter = exports.createDocumentAutocompleter = exports.getCodemirrorEditorValue = exports.setCodemirrorEditorValue = exports.CodemirrorMultilineEditor = exports.CodemirrorInlineEditor = exports.prettify = void 0;
4
4
  var prettify_1 = require("./prettify");
5
5
  Object.defineProperty(exports, "prettify", { enumerable: true, get: function () { return prettify_1.prettify; } });
6
6
  var editor_1 = require("./editor");
@@ -26,3 +26,5 @@ var query_autocompleter_with_history_1 = require("./codemirror/query-autocomplet
26
26
  Object.defineProperty(exports, "createQueryWithHistoryAutocompleter", { enumerable: true, get: function () { return query_autocompleter_with_history_1.createQueryWithHistoryAutocompleter; } });
27
27
  var use_json_schema_autocompleter_1 = require("./use-json-schema-autocompleter");
28
28
  Object.defineProperty(exports, "useJsonSchemaAutocompleter", { enumerable: true, get: function () { return use_json_schema_autocompleter_1.useJsonSchemaAutocompleter; } });
29
+ var use_safe_integer_linter_1 = require("./codemirror/use-safe-integer-linter");
30
+ Object.defineProperty(exports, "useSafeIntegerLinter", { enumerable: true, get: function () { return use_safe_integer_linter_1.useSafeIntegerLinter; } });
@@ -0,0 +1,7 @@
1
+ import { type Extension } from '@codemirror/state';
2
+ import type { Annotation } from './editor';
3
+ export declare const TOOLTIP_DATA_ATTR = "data-codemirror-linter";
4
+ export declare function wrapLinterAnnotation(annotation: Annotation): Annotation;
5
+ export declare const TOOLTIP_SELECTOR = ".cm-diagnostic:has([data-codemirror-linter=true])";
6
+ export declare function lintTooltipExitDelay(tooltipExitDelay?: number): Extension;
7
+ //# sourceMappingURL=lint-tooltip-exit-delay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint-tooltip-exit-delay.d.ts","sourceRoot":"","sources":["../src/lint-tooltip-exit-delay.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAcvE;AAED,eAAO,MAAM,gBAAgB,sDAAoD,CAAC;AAGlF,wBAAgB,oBAAoB,CAClC,gBAAgB,GAAE,MAAmC,GACpD,SAAS,CAwEX"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TOOLTIP_SELECTOR = exports.TOOLTIP_DATA_ATTR = void 0;
4
+ exports.wrapLinterAnnotation = wrapLinterAnnotation;
5
+ exports.lintTooltipExitDelay = lintTooltipExitDelay;
6
+ const view_1 = require("@codemirror/view");
7
+ const state_1 = require("@codemirror/state");
8
+ const delayedHide = state_1.Annotation.define();
9
+ const DEFAULT_TOOLTIP_EXIT_DELAY = 300;
10
+ exports.TOOLTIP_DATA_ATTR = 'data-codemirror-linter';
11
+ function wrapLinterAnnotation(annotation) {
12
+ return {
13
+ ...annotation,
14
+ renderMessage: (view) => {
15
+ const wrapper = document.createElement('span');
16
+ wrapper.setAttribute(exports.TOOLTIP_DATA_ATTR, 'true');
17
+ if (annotation.renderMessage) {
18
+ wrapper.appendChild(annotation.renderMessage(view));
19
+ }
20
+ else {
21
+ wrapper.textContent = annotation.message;
22
+ }
23
+ return wrapper;
24
+ },
25
+ };
26
+ }
27
+ exports.TOOLTIP_SELECTOR = `.cm-diagnostic:has([${exports.TOOLTIP_DATA_ATTR}=true])`;
28
+ const HOVER_SELECTOR = `${exports.TOOLTIP_SELECTOR}, .cm-lint-marker`;
29
+ function lintTooltipExitDelay(tooltipExitDelay = DEFAULT_TOOLTIP_EXIT_DELAY) {
30
+ let editorView;
31
+ let pendingTimeout;
32
+ let hideEffects;
33
+ const clearPendingTimeout = () => {
34
+ clearTimeout(pendingTimeout);
35
+ pendingTimeout = undefined;
36
+ };
37
+ const hideTooltip = () => {
38
+ pendingTimeout = undefined;
39
+ const effects = hideEffects;
40
+ hideEffects = undefined;
41
+ if (effects) {
42
+ editorView?.dispatch({ effects, annotations: delayedHide.of(true) });
43
+ }
44
+ };
45
+ const scheduleHide = () => {
46
+ clearPendingTimeout();
47
+ pendingTimeout = setTimeout(hideTooltip, tooltipExitDelay);
48
+ };
49
+ const onMouseMove = (event) => {
50
+ if (!hideEffects) {
51
+ return;
52
+ }
53
+ const target = event.target;
54
+ if (target?.closest?.(HOVER_SELECTOR)) {
55
+ // Pointer came back in time, keep the tooltip open until it leaves again.
56
+ clearPendingTimeout();
57
+ }
58
+ else if (!pendingTimeout) {
59
+ scheduleHide();
60
+ }
61
+ };
62
+ return [
63
+ view_1.ViewPlugin.define((view) => {
64
+ editorView = view;
65
+ // Listening on the window rather than through `domEventHandlers`: neither
66
+ // the gutter marker nor the tooltip is part of the editor content DOM.
67
+ window.addEventListener('mousemove', onMouseMove);
68
+ return {
69
+ destroy() {
70
+ window.removeEventListener('mousemove', onMouseMove);
71
+ clearPendingTimeout();
72
+ hideEffects = undefined;
73
+ editorView = undefined;
74
+ },
75
+ };
76
+ }),
77
+ state_1.EditorState.transactionFilter.of((tr) => {
78
+ if (tr.annotation(delayedHide) || tr.docChanged || !tr.effects.length) {
79
+ return tr;
80
+ }
81
+ const before = tr.startState.facet(view_1.showTooltip);
82
+ const stillShown = new Set(tr.state.facet(view_1.showTooltip).filter(Boolean));
83
+ const hidesTooltip = before.some((tooltip) => tooltip && !stillShown.has(tooltip));
84
+ if (!hidesTooltip || !document.querySelector(exports.TOOLTIP_SELECTOR)) {
85
+ return tr;
86
+ }
87
+ hideEffects = tr.effects;
88
+ scheduleHide();
89
+ return [];
90
+ }),
91
+ ];
92
+ }
@@ -0,0 +1,14 @@
1
+ import { syntaxTree } from '@codemirror/language';
2
+ import type { Annotation } from './editor';
3
+ import { EditorView } from '@codemirror/view';
4
+ import type { Extension } from '@codemirror/state';
5
+ export type LintConfig = {
6
+ lintDelay?: number;
7
+ tooltipExitDelay?: number;
8
+ theme?: {
9
+ spec: Parameters<typeof EditorView.theme>[0];
10
+ options?: Parameters<typeof EditorView.theme>[1];
11
+ };
12
+ };
13
+ export declare function createCodemirrorLinter(diagnosticsFn: (tree: ReturnType<typeof syntaxTree>, view: EditorView) => Annotation[], config?: LintConfig): Extension;
14
+ //# sourceMappingURL=linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linter.d.ts","sourceRoot":"","sources":["../src/linter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOnD,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAI1B,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KAClD,CAAC;CACH,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,CACb,IAAI,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EACnC,IAAI,EAAE,UAAU,KACb,UAAU,EAAE,EACjB,MAAM,CAAC,EAAE,UAAU,GAClB,SAAS,CAgBX"}
package/dist/linter.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCodemirrorLinter = createCodemirrorLinter;
4
+ const lint_1 = require("@codemirror/lint");
5
+ const language_1 = require("@codemirror/language");
6
+ const view_1 = require("@codemirror/view");
7
+ const lint_tooltip_exit_delay_1 = require("./lint-tooltip-exit-delay");
8
+ // Do not show inline (on-hover) tooltips for linting errors,
9
+ // we will show them in the gutter instead
10
+ const noInlineTooltips = () => [];
11
+ function createCodemirrorLinter(diagnosticsFn, config) {
12
+ const lintExtension = (0, lint_1.linter)((view) => diagnosticsFn((0, language_1.syntaxTree)(view.state), view), {
13
+ delay: config?.lintDelay ?? 500,
14
+ tooltipFilter: noInlineTooltips,
15
+ });
16
+ const extensions = [
17
+ lintExtension,
18
+ (0, lint_tooltip_exit_delay_1.lintTooltipExitDelay)(config?.tooltipExitDelay),
19
+ ];
20
+ if (config?.theme) {
21
+ extensions.push(view_1.EditorView.theme(config.theme.spec, config.theme.options));
22
+ }
23
+ return extensions;
24
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"use-json-schema-autocompleter.d.ts","sourceRoot":"","sources":["../src/use-json-schema-autocompleter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAQnD,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,0BAA0B,CAAC;AAU7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkM3C,MAAM,MAAM,6BAA6B,GAAG;IAC1C,uDAAuD;IACvD,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACxC,sFAAsF;IACtF,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,iDAAiD;IACjD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,IAAI,EAAE,MAAM,GACX,6BAA6B,CA8U/B"}
1
+ {"version":3,"file":"use-json-schema-autocompleter.d.ts","sourceRoot":"","sources":["../src/use-json-schema-autocompleter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAQnD,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,0BAA0B,CAAC;AAU7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkM3C,MAAM,MAAM,6BAA6B,GAAG;IAC1C,uDAAuD;IACvD,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACxC,sFAAsF;IACtF,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,iDAAiD;IACjD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,IAAI,EAAE,MAAM,GACX,6BAA6B,CA6U/B"}
@@ -430,11 +430,12 @@ function useJsonSchemaAutocompleter(schema, text) {
430
430
  aborted = true;
431
431
  };
432
432
  }, [schema, text, editorConfig.extensions.length]);
433
- // Compute hasErrors from annotations - both error and warning severity block validation
433
+ // Compute hasErrors from annotations - only error severity blocks validation.
434
434
  // Note: vscode-json-languageservice reports schema violations (missing required fields,
435
- // type mismatches, etc.) as warnings, so we include them in validation blocking
435
+ // type mismatches, etc.) as warnings and only malformed JSON syntax as an error, so
436
+ // schema violations are surfaced as annotations without blocking the consumer's action.
436
437
  const hasErrors = (0, react_1.useMemo)(() => {
437
- return annotations.some((a) => a.severity === 'error' || a.severity === 'warning');
438
+ return annotations.some((a) => a.severity === 'error');
438
439
  }, [annotations]);
439
440
  return {
440
441
  completer: editorConfig.completer,
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "email": "compass@mongodb.com"
14
14
  },
15
15
  "homepage": "https://github.com/mongodb-js/compass",
16
- "version": "0.70.0",
16
+ "version": "0.71.0",
17
17
  "repository": {
18
18
  "type": "git",
19
19
  "url": "https://github.com/mongodb-js/compass.git"
@@ -46,10 +46,10 @@
46
46
  "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ."
47
47
  },
48
48
  "devDependencies": {
49
- "@mongodb-js/eslint-config-compass": "^1.4.25",
50
- "@mongodb-js/mocha-config-compass": "^1.8.0",
49
+ "@mongodb-js/eslint-config-compass": "^1.4.26",
50
+ "@mongodb-js/mocha-config-compass": "^1.8.1",
51
51
  "@mongodb-js/prettier-config-compass": "^1.2.9",
52
- "@mongodb-js/testing-library-compass": "^1.6.0",
52
+ "@mongodb-js/testing-library-compass": "^1.7.0",
53
53
  "@mongodb-js/tsconfig-compass": "^1.3.1",
54
54
  "@types/chai": "^4.2.21",
55
55
  "@types/hast": "^3.0.4",
@@ -73,14 +73,14 @@
73
73
  "@codemirror/state": "^6.5.2",
74
74
  "@codemirror/view": "^6.38.0",
75
75
  "@lezer/highlight": "^1.2.1",
76
- "@mongodb-js/compass-components": "^1.68.0",
77
- "@mongodb-js/mongodb-constants": "^0.33.0",
76
+ "@mongodb-js/compass-components": "^1.69.0",
77
+ "@mongodb-js/mongodb-constants": "^0.34.8",
78
78
  "hast": "^0.0.2",
79
79
  "json-schema": "^0.4.0",
80
- "mongodb-query-parser": "^4.7.14",
80
+ "mongodb-query-parser": "^5.0.5",
81
81
  "polished": "^4.2.2",
82
82
  "prettier": "^2.7.1",
83
- "react": "^17.0.2",
83
+ "react": "^18.3.1",
84
84
  "rehype-sanitize": "^5.0.1",
85
85
  "rehype-stringify": "^9.0.4",
86
86
  "remark-parse": "^10.0.0",
@@ -89,5 +89,5 @@
89
89
  "vscode-json-languageservice": "^5.7.2",
90
90
  "vscode-languageserver-textdocument": "^1.0.12"
91
91
  },
92
- "gitHead": "b56c594288a4ee443a43a8907867401768ea5955"
92
+ "gitHead": "18b9284c2de5c1daef72e6fa187efb016f597539"
93
93
  }