Skip to content

Commit

Permalink
feat(editor): Migrate codemirror-lang-n8n-expression into this mono…
Browse files Browse the repository at this point in the history
…repo (no-changelog) (#9087)

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
  • Loading branch information
netroy and ivov committed May 10, 2024
1 parent aa397b9 commit 2445205
Show file tree
Hide file tree
Showing 19 changed files with 499 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/units-tests-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,4 @@ jobs:
if: ${{ inputs.collectCoverage == 'true' }}
uses: codecov/codecov-action@v3
with:
files: packages/@n8n/chat/coverage/cobertura-coverage.xml,packages/@n8n/nodes-langchain/coverage/cobertura-coverage.xml,packages/@n8n/permissions/coverage/cobertura-coverage.xml,packages/@n8n/client-oauth2/coverage/cobertura-coverage.xml,packages/cli/coverage/cobertura-coverage.xml,packages/core/coverage/cobertura-coverage.xml,packages/design-system/coverage/cobertura-coverage.xml,packages/editor-ui/coverage/cobertura-coverage.xml,packages/nodes-base/coverage/cobertura-coverage.xml,packages/workflow/coverage/cobertura-coverage.xml
files: packages/@n8n/chat/coverage/cobertura-coverage.xml,packages/@n8n/nodes-langchain/coverage/cobertura-coverage.xml,packages/@n8n/permissions/coverage/cobertura-coverage.xml,packages/@n8n/client-oauth2/coverage/cobertura-coverage.xml,packages/cli/coverage/cobertura-coverage.xml,packages/core/coverage/cobertura-coverage.xml,packages/design-system/coverage/cobertura-coverage.xml,packages/@n8n/codemirror-lang/coverage/cobertura-coverage.xml,packages/editor-ui/coverage/cobertura-coverage.xml,packages/nodes-base/coverage/cobertura-coverage.xml,packages/workflow/coverage/cobertura-coverage.xml
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"scripts": {
"preinstall": "node scripts/block-npm-install.js",
"build": "turbo run build",
"build:backend": "pnpm --filter=!@n8n/chat --filter=!n8n-design-system --filter=!n8n-editor-ui build",
"build:frontend": "pnpm --filter=@n8n/chat --filter=n8n-design-system --filter=n8n-editor-ui build",
"build:backend": "pnpm --filter=!@n8n/chat --filter=!@n8n/codemirror-lang --filter=!n8n-design-system --filter=!n8n-editor-ui build",
"build:frontend": "pnpm --filter=@n8n/chat --filter=@n8n/codemirror-lang --filter=n8n-design-system --filter=n8n-editor-ui build",
"typecheck": "turbo run typecheck",
"dev": "turbo run dev --parallel --filter=!n8n-design-system --filter=!@n8n/chat",
"dev:ai": "turbo run dev --parallel --filter=@n8n/nodes-langchain --filter=n8n --filter=n8n-core",
Expand All @@ -26,9 +26,9 @@
"start:tunnel": "./packages/cli/bin/n8n start --tunnel",
"start:windows": "cd packages/cli/bin && n8n",
"test": "turbo run test",
"test:backend": "pnpm --filter=!@n8n/chat --filter=!n8n-design-system --filter=!n8n-editor-ui --filter=!n8n-nodes-base --filter=!@n8n/n8n-nodes-langchain test",
"test:backend": "pnpm --filter=!@n8n/chat --filter=!@n8n/codemirror-lang --filter=!n8n-design-system --filter=!n8n-editor-ui --filter=!n8n-nodes-base test --filter=!@n8n/n8n-nodes-langchain test",
"test:nodes": "pnpm --filter=n8n-nodes-base --filter=@n8n/n8n-nodes-langchain test",
"test:frontend": "pnpm --filter=@n8n/chat --filter=n8n-design-system --filter=n8n-editor-ui test",
"test:frontend": "pnpm --filter=@n8n/chat --filter=@n8n/codemirror-lang --filter=n8n-design-system --filter=n8n-editor-ui test",
"watch": "turbo run watch --parallel",
"webhook": "./packages/cli/bin/n8n webhook",
"worker": "./packages/cli/bin/n8n worker",
Expand Down
14 changes: 14 additions & 0 deletions packages/@n8n/codemirror-lang/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const sharedOptions = require('@n8n_io/eslint-config/shared');

/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/base'],

...sharedOptions(__dirname),

ignorePatterns: [
'src/expressions/grammar*.ts'
]
};
5 changes: 5 additions & 0 deletions packages/@n8n/codemirror-lang/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# @n8n/codemirror-lang

Language support package for CodeMirror 6 in n8n

[n8n Expression Language support](./src/expressions/README.md)
2 changes: 2 additions & 0 deletions packages/@n8n/codemirror-lang/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** @type {import('jest').Config} */
module.exports = require('../../../jest.config');
37 changes: 37 additions & 0 deletions packages/@n8n/codemirror-lang/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@n8n/codemirror-lang",
"version": "0.3.0",
"description": "Language support package for CodeMirror 6 in n8n",
"private": true,
"sideEffects": false,
"main": "dist/index.js",
"module": "src/index.ts",
"types": "dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.js",
"import": "./src/index.ts",
"types": "./dist/index.d.ts"
},
"./*": "./*"
},
"scripts": {
"clean": "rimraf dist .turbo",
"typecheck": "tsc --noEmit",
"generate:expressions:grammar": "lezer-generator --typeScript --output src/expressions/grammar.ts src/expressions/expressions.grammar",
"generate": "pnpm generate:expressions:grammar && pnpm format",
"build": "tsc -p tsconfig.build.json",
"test": "jest",
"lint": "eslint . --ext .ts --quiet",
"lintfix": "eslint . --ext .ts --fix",
"format": "prettier --write --ignore-path ../../.prettierignore src test"
},
"peerDependencies": {
"@codemirror/language": "*",
"@lezer/highlight": "*",
"@lezer/lr": "^1.4.0"
},
"devDependencies": {
"@lezer/generator": "^1.7.0"
}
}
26 changes: 26 additions & 0 deletions packages/@n8n/codemirror-lang/src/expressions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# n8n Expression language support

## Usage

```js
import { parserWithMetaData as n8nParser } from '@n8n/codemirror-lang';
import { LanguageSupport, LRLanguage } from '@codemirror/language';
import { parseMixed } from '@lezer/common';
import { parser as jsParser } from '@lezer/javascript';

const n8nPlusJsParser = n8nParser.configure({
wrap: parseMixed((node) => {
if (node.type.isTop) return null;

return node.name === 'Resolvable'
? { parser: jsParser, overlay: (node) => node.type.name === 'Resolvable' }
: null;
}),
});

const n8nLanguage = LRLanguage.define({ parser: n8nPlusJsParser });

export function n8nExpressionLanguageSupport() {
return new LanguageSupport(n8nLanguage);
}
```
21 changes: 21 additions & 0 deletions packages/@n8n/codemirror-lang/src/expressions/expressions.grammar
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@top Program { entity* }

entity { Plaintext | Resolvable }

@tokens {
Plaintext { ![{] Plaintext? | "{" (@eof | ![{] Plaintext?) }

OpenMarker[closedBy="CloseMarker"] { "{{" }

CloseMarker[openedBy="OpenMarker"] { "}}" }

Resolvable {
OpenMarker resolvableChar* CloseMarker
}

resolvableChar { unicodeChar | "}" ![}] | "\\}}" }

unicodeChar { $[\u0000-\u007C] | $[\u007E-\u1FFF] | $[\u20A0-\u20CF] | $[\u{1F300}-\u{1F64F}] }
}

@detectDelim
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
export const Program = 1,
Plaintext = 2,
Resolvable = 3;
18 changes: 18 additions & 0 deletions packages/@n8n/codemirror-lang/src/expressions/grammar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
import { LRParser } from '@lezer/lr';

export const parser = LRParser.deserialize({
version: 14,
states: "nQQOPOOOOOO'#Cb'#CbOOOO'#C`'#C`QQOPOOOOOO-E6^-E6^",
stateData: 'Y~OQPORPO~O',
goto: 'bVPPPPWP^QRORSRTQOR',
nodeNames: '⚠ Program Plaintext Resolvable',
maxTerm: 6,
skippedNodes: [0],
repeatNodeCount: 1,
tokenData:
"&U~RTO#ob#o#p!h#p;'Sb;'S;=`!]<%lOb~gTQ~O#ob#o#pv#p;'Sb;'S;=`!]<%lOb~yUO#ob#p;'Sb;'S;=`!]<%l~b~Ob~~!c~!`P;=`<%lb~!hOQ~~!kVO#ob#o#p#Q#p;'Sb;'S;=`!]<%l~b~Ob~~!c~#TWO#O#Q#O#P#m#P#q#Q#q#r%Z#r$IS#Q$Lj$Ml#Q;(b;(c%x;(c;(d&O~#pWO#O#Q#O#P#m#P#q#Q#q#r$Y#r$IS#Q$Lj$Ml#Q;(b;(c%x;(c;(d&O~$]TO#q#Q#q#r$l#r;'S#Q;'S;=`%r<%lO#Q~$qWR~O#O#Q#O#P#m#P#q#Q#q#r%Z#r$IS#Q$Lj$Ml#Q;(b;(c%x;(c;(d&O~%^TO#q#Q#q#r%m#r;'S#Q;'S;=`%r<%lO#Q~%rOR~~%uP;=`<%l#Q~%{P;NQ<%l#Q~&RP;=`;JY#Q",
tokenizers: [0],
topRules: { Program: [0, 1] },
tokenPrec: 0,
});
28 changes: 28 additions & 0 deletions packages/@n8n/codemirror-lang/src/expressions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { LRLanguage, LanguageSupport, foldNodeProp, foldInside } from '@codemirror/language';
import { styleTags, tags as t } from '@lezer/highlight';
import { parser } from './grammar';

export const parserWithMetaData = parser.configure({
props: [
foldNodeProp.add({
Application: foldInside,
}),
styleTags({
OpenMarker: t.brace,
CloseMarker: t.brace,
Plaintext: t.content,
Resolvable: t.string,
}),
],
});

export const n8nLanguage = LRLanguage.define({
parser: parserWithMetaData,
languageData: {
commentTokens: { line: ';' },
},
});

export function n8nExpression() {
return new LanguageSupport(n8nLanguage);
}
1 change: 1 addition & 0 deletions packages/@n8n/codemirror-lang/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { parserWithMetaData, n8nLanguage } from './expressions';

0 comments on commit 2445205

Please sign in to comment.