@bpmn-io/feel-lint
Advanced tools
Comparing version 1.2.0 to 1.3.0
@@ -5,2 +5,7 @@ import { parser } from 'lezer-feel'; | ||
/** | ||
* @typedef {import('@lezer/common').Tree} Tree | ||
* @typedef {import('@codemirror/lint').Diagnostic} LintMessage | ||
*/ | ||
/** | ||
* Create an array of syntax errors in the given tree. | ||
@@ -59,11 +64,125 @@ * | ||
/** | ||
* Generates lint messages for the given syntax tree. | ||
* @typedef {object} Context | ||
* @property {function} report | ||
* @property {(from: number, to: number) => string} readContent | ||
* @property {(from: number, to: number, content: string) => void} updateContent | ||
*/ | ||
const RULE_NAME = 'first-item'; | ||
var firstItem = { | ||
create(/** @type {Context} */ context) { | ||
return { | ||
enter(node) { | ||
if (node.name !== 'FilterExpression') { | ||
return; | ||
} | ||
const content = context.readContent(node.from, node.to); | ||
if (zeroIndexPattern().test(content)) { | ||
const { | ||
from, | ||
to | ||
} = node; | ||
context.report({ | ||
from, | ||
to, | ||
message: 'First item is accessed via [1]', | ||
severity: 'error', | ||
type: RULE_NAME, | ||
actions: [ | ||
{ | ||
name: 'fix', | ||
apply(_, start = from, end = to) { | ||
context.updateContent(start, end, content.replace(zeroIndexPattern(), '[1]')); | ||
} | ||
} | ||
] | ||
}); | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
function zeroIndexPattern() { | ||
return /\[\s*0\s*\]$/; | ||
} | ||
/** | ||
* @typedef {import('@lezer/common').Tree} Tree | ||
* @typedef {import('@codemirror/lint').Diagnostic} LintMessage | ||
* @typedef {import('./index').LintAllContext} LintAllContext | ||
*/ | ||
const RULES = [ | ||
firstItem | ||
]; | ||
/** | ||
* Create an array of messages reported from rules in the given tree. | ||
* | ||
* @param {Tree} syntaxTree | ||
* @param {LintAllContext} context | ||
* @returns {LintMessage[]} array of syntax errors | ||
*/ | ||
function lintRules(context) { | ||
const { | ||
readContent, | ||
syntaxTree, | ||
updateContent | ||
} = context; | ||
const lintMessages = []; | ||
const ruleContext = { | ||
readContent, | ||
report: message => { | ||
lintMessages.push(message); | ||
}, | ||
updateContent | ||
}; | ||
const rules = RULES.map(rule => rule.create(ruleContext)); | ||
syntaxTree.iterate({ | ||
enter: ref => { | ||
for (const rule of rules) { | ||
rule.enter && rule.enter(ref); | ||
} | ||
}, | ||
leave: ref => { | ||
for (const rule of rules) { | ||
rule.leave && rule.leave(ref); | ||
} | ||
} | ||
}); | ||
return lintMessages; | ||
} | ||
/** | ||
* @typedef {import('@lezer/common').Tree} Tree | ||
* @typedef {import('@codemirror/lint').Diagnostic} LintMessage | ||
*/ | ||
/** | ||
* @typedef {object} LintAllContext | ||
* @property {Tree} syntaxTree | ||
* @property {(from: number, to: number) => string} readContent | ||
* @property {(from: number, to: number, content: string) => void} updateContent | ||
*/ | ||
/** | ||
* Generates lint messages for the given context. | ||
* | ||
* @param {LintAllContext} context | ||
* @returns {LintMessage[]} array of all lint messages | ||
*/ | ||
function lintAll(syntaxTree) { | ||
function lintAll(context) { | ||
const lintMessages = [ | ||
...lintSyntax(syntaxTree) | ||
...lintSyntax(context.syntaxTree), | ||
...lintRules(context) | ||
]; | ||
@@ -84,4 +203,11 @@ | ||
const lintMessages = lintAll(syntaxTree); | ||
const lintMessages = lintAll({ | ||
syntaxTree, | ||
readContent: (from, to) => expression.slice(from, to), | ||
updateContent: (from, to, content) => { | ||
// not implemented | ||
} | ||
}); | ||
return lintMessages; | ||
@@ -93,4 +219,3 @@ } | ||
* | ||
* @param {EditorView} editorView | ||
* @returns {Source} CodeMirror linting source | ||
* @returns {import('@codemirror/lint').LintSource} CodeMirror linting source | ||
*/ | ||
@@ -106,3 +231,9 @@ const cmFeelLinter = () => editorView => { | ||
const messages = lintAll(tree); | ||
const messages = lintAll({ | ||
syntaxTree: tree, | ||
readContent: (from, to) => editorView.state.sliceDoc(from, to), | ||
updateContent: (from, to, content) => editorView.dispatch({ | ||
changes: { from, to, insert: content } | ||
}) | ||
}); | ||
@@ -109,0 +240,0 @@ return messages.map(message => ({ |
@@ -7,2 +7,7 @@ 'use strict'; | ||
/** | ||
* @typedef {import('@lezer/common').Tree} Tree | ||
* @typedef {import('@codemirror/lint').Diagnostic} LintMessage | ||
*/ | ||
/** | ||
* Create an array of syntax errors in the given tree. | ||
@@ -61,11 +66,125 @@ * | ||
/** | ||
* Generates lint messages for the given syntax tree. | ||
* @typedef {object} Context | ||
* @property {function} report | ||
* @property {(from: number, to: number) => string} readContent | ||
* @property {(from: number, to: number, content: string) => void} updateContent | ||
*/ | ||
const RULE_NAME = 'first-item'; | ||
var firstItem = { | ||
create(/** @type {Context} */ context) { | ||
return { | ||
enter(node) { | ||
if (node.name !== 'FilterExpression') { | ||
return; | ||
} | ||
const content = context.readContent(node.from, node.to); | ||
if (zeroIndexPattern().test(content)) { | ||
const { | ||
from, | ||
to | ||
} = node; | ||
context.report({ | ||
from, | ||
to, | ||
message: 'First item is accessed via [1]', | ||
severity: 'error', | ||
type: RULE_NAME, | ||
actions: [ | ||
{ | ||
name: 'fix', | ||
apply(_, start = from, end = to) { | ||
context.updateContent(start, end, content.replace(zeroIndexPattern(), '[1]')); | ||
} | ||
} | ||
] | ||
}); | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
function zeroIndexPattern() { | ||
return /\[\s*0\s*\]$/; | ||
} | ||
/** | ||
* @typedef {import('@lezer/common').Tree} Tree | ||
* @typedef {import('@codemirror/lint').Diagnostic} LintMessage | ||
* @typedef {import('./index').LintAllContext} LintAllContext | ||
*/ | ||
const RULES = [ | ||
firstItem | ||
]; | ||
/** | ||
* Create an array of messages reported from rules in the given tree. | ||
* | ||
* @param {Tree} syntaxTree | ||
* @param {LintAllContext} context | ||
* @returns {LintMessage[]} array of syntax errors | ||
*/ | ||
function lintRules(context) { | ||
const { | ||
readContent, | ||
syntaxTree, | ||
updateContent | ||
} = context; | ||
const lintMessages = []; | ||
const ruleContext = { | ||
readContent, | ||
report: message => { | ||
lintMessages.push(message); | ||
}, | ||
updateContent | ||
}; | ||
const rules = RULES.map(rule => rule.create(ruleContext)); | ||
syntaxTree.iterate({ | ||
enter: ref => { | ||
for (const rule of rules) { | ||
rule.enter && rule.enter(ref); | ||
} | ||
}, | ||
leave: ref => { | ||
for (const rule of rules) { | ||
rule.leave && rule.leave(ref); | ||
} | ||
} | ||
}); | ||
return lintMessages; | ||
} | ||
/** | ||
* @typedef {import('@lezer/common').Tree} Tree | ||
* @typedef {import('@codemirror/lint').Diagnostic} LintMessage | ||
*/ | ||
/** | ||
* @typedef {object} LintAllContext | ||
* @property {Tree} syntaxTree | ||
* @property {(from: number, to: number) => string} readContent | ||
* @property {(from: number, to: number, content: string) => void} updateContent | ||
*/ | ||
/** | ||
* Generates lint messages for the given context. | ||
* | ||
* @param {LintAllContext} context | ||
* @returns {LintMessage[]} array of all lint messages | ||
*/ | ||
function lintAll(syntaxTree) { | ||
function lintAll(context) { | ||
const lintMessages = [ | ||
...lintSyntax(syntaxTree) | ||
...lintSyntax(context.syntaxTree), | ||
...lintRules(context) | ||
]; | ||
@@ -86,4 +205,11 @@ | ||
const lintMessages = lintAll(syntaxTree); | ||
const lintMessages = lintAll({ | ||
syntaxTree, | ||
readContent: (from, to) => expression.slice(from, to), | ||
updateContent: (from, to, content) => { | ||
// not implemented | ||
} | ||
}); | ||
return lintMessages; | ||
@@ -95,4 +221,3 @@ } | ||
* | ||
* @param {EditorView} editorView | ||
* @returns {Source} CodeMirror linting source | ||
* @returns {import('@codemirror/lint').LintSource} CodeMirror linting source | ||
*/ | ||
@@ -108,3 +233,9 @@ const cmFeelLinter = () => editorView => { | ||
const messages = lintAll(tree); | ||
const messages = lintAll({ | ||
syntaxTree: tree, | ||
readContent: (from, to) => editorView.state.sliceDoc(from, to), | ||
updateContent: (from, to, content) => editorView.dispatch({ | ||
changes: { from, to, insert: content } | ||
}) | ||
}); | ||
@@ -111,0 +242,0 @@ return messages.map(message => ({ |
{ | ||
"name": "@bpmn-io/feel-lint", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Linter for FEEL expressions.", | ||
@@ -12,2 +12,3 @@ "source": "lib/index.js", | ||
"scripts": { | ||
"start": "SINGLE_START=editor npm run dev", | ||
"all": "run-s lint test build", | ||
@@ -47,11 +48,13 @@ "build": "rollup -c --bundleConfigAsCjs", | ||
"devDependencies": { | ||
"@codemirror/state": "^6.2.1", | ||
"@codemirror/view": "^6.14.0", | ||
"@rollup/plugin-commonjs": "^25.0.5", | ||
"chai": "^4.3.6", | ||
"eslint": "^8.44.0", | ||
"@codemirror/lang-json": "^6.0.1", | ||
"@codemirror/lint": "^6.8.1", | ||
"@codemirror/state": "^6.4.0", | ||
"@codemirror/view": "^6.23.0", | ||
"@rollup/plugin-commonjs": "^26.0.0", | ||
"chai": "^4.5.0", | ||
"eslint": "^8.56.0", | ||
"eslint-plugin-bpmn-io": "^1.0.0", | ||
"karma": "^6.4.1", | ||
"karma-chrome-launcher": "^3.1.1", | ||
"karma-coverage": "^2.2.0", | ||
"karma": "^6.4.2", | ||
"karma-chrome-launcher": "^3.2.0", | ||
"karma-coverage": "^2.2.1", | ||
"karma-debug-launcher": "^0.0.5", | ||
@@ -63,14 +66,14 @@ "karma-env-preprocessor": "^0.1.1", | ||
"lang-feel": "^2.0.0", | ||
"mocha": "^10.0.0", | ||
"npm-run-all": "^4.1.5", | ||
"puppeteer": "^18.0.5", | ||
"rollup": "^3.29.4", | ||
"sinon": "^14.0.0", | ||
"mocha": "^10.7.3", | ||
"npm-run-all2": "^6.0.0", | ||
"puppeteer": "^23.1.1", | ||
"rollup": "^4.9.6", | ||
"sinon": "^17.0.1", | ||
"sinon-chai": "^3.7.0", | ||
"webpack": "^5.74.0" | ||
"webpack": "^5.89.0" | ||
}, | ||
"dependencies": { | ||
"@codemirror/language": "^6.8.0", | ||
"@codemirror/language": "^6.10.0", | ||
"lezer-feel": "^1.2.3" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14772
398
24
1
Updated@codemirror/language@^6.10.0