openModal()}>
+
{/if}
diff --git a/src/utils/errors/MetaBindErrors.ts b/src/utils/errors/MetaBindErrors.ts
index 0e444777..2ed004bc 100644
--- a/src/utils/errors/MetaBindErrors.ts
+++ b/src/utils/errors/MetaBindErrors.ts
@@ -13,12 +13,14 @@ export enum ErrorType {
JS = 'MB_JS_ERROR',
EXPRESSION = 'MB_EXPRESSION_ERROR',
PUBLISH = 'MB_PUBLISH_ERROR',
+ VALIDATION = 'MB_VALIDATION_ERROR',
OTHER = 'OTHER',
}
export abstract class MetaBindError extends Error {
abstract getErrorType(): ErrorType;
+
errorLevel: ErrorLevel;
effect: string;
cause: string | Error;
@@ -35,7 +37,7 @@ export abstract class MetaBindError extends Error {
this.updateMessage();
}
- private updateMessage(): void {
+ protected updateMessage(): void {
if (this.cause instanceof Error) {
this.message = `[${this.getErrorType()}] "${this.effect}" caused by error "${this.cause.message}"`;
} else {
@@ -60,6 +62,12 @@ export class MetaBindParsingError extends MetaBindError {
}
}
+export class MetaBindValidationError extends MetaBindError {
+ public getErrorType(): ErrorType {
+ return ErrorType.VALIDATION;
+ }
+}
+
export class MetaBindBindTargetError extends MetaBindError {
public getErrorType(): ErrorType {
return ErrorType.BIND_TARGET;
diff --git a/styles.css b/styles.css
index 5c285c68..ede587c6 100644
--- a/styles.css
+++ b/styles.css
@@ -179,3 +179,43 @@ code.meta-bind-plugin-error {
.meta-bind-error-collection > svg.lucide-info {
color: var(--text-normal);
}
+
+.mb-list-input {
+ display: flex;
+ gap: var(--size-4-2);
+}
+
+.mb-list-input > div:has(> input) {
+ flex-grow: 1;
+}
+
+.mb-list-empty {
+ color: var(--text-faint);
+}
+
+.mb-list-items {
+ margin-bottom: var(--size-4-4);
+ display: flex;
+ flex-direction: column;
+ gap: var(--size-4-2);
+}
+
+.mb-list-item {
+ display: flex;
+}
+
+.mb-list-item > span {
+ flex-grow: 1;
+}
+
+.meta-bind-pre {
+ overflow-x: scroll;
+}
+
+.meta-bind-pre > code {
+ white-space: pre;
+}
+
+.meta-bind-error-collection-modal {
+ width: 80%;
+}
diff --git a/tests/DateParser.test.ts b/tests/DateParser.test.ts
index 205a0c2c..733c512a 100644
--- a/tests/DateParser.test.ts
+++ b/tests/DateParser.test.ts
@@ -1,3 +1,7 @@
+test('placeholder', () => {
+ expect(true).toEqual(true);
+});
+
/*
import {Date, DateParser} from '../src/parsers/DateParser';
diff --git a/tests/InputFieldDeclarationParser.test.ts b/tests/InputFieldDeclarationParser.test.ts
index 16bccfd4..2c76ce4b 100644
--- a/tests/InputFieldDeclarationParser.test.ts
+++ b/tests/InputFieldDeclarationParser.test.ts
@@ -1,11 +1,9 @@
-import { InputFieldArgumentContainer } from '../src/inputFieldArguments/InputFieldArgumentContainer';
-import { InputFieldArgumentType, InputFieldDeclaration, InputFieldDeclarationParser, InputFieldType } from '../src/parsers/InputFieldDeclarationParser';
import { MetaBindParsingError } from '../src/utils/errors/MetaBindErrors';
-// test('placeholder', () => {
-// expect(true).toEqual(true);
-// });
-//
+test('placeholder', () => {
+ expect(true).toEqual(true);
+});
+
// describe('apply template', () => {
// test('found', () => {
// InputFieldDeclarationParser.templates = [
diff --git a/tests/ParserUtils.test.ts b/tests/ParserUtils.test.ts
index e1930652..80772915 100644
--- a/tests/ParserUtils.test.ts
+++ b/tests/ParserUtils.test.ts
@@ -90,7 +90,9 @@ describe('getInBetween', () => {
expect(ParserUtils.getInBetween('aa[a]sda]', new EnclosingPair('[', ']'))).toEqual('a');
expect(ParserUtils.getInBetween('aa[a]sd[a]', new EnclosingPair('[', ']'))).toEqual(['a', 'a']);
expect(ParserUtils.getInBetween('aa[a[sd]a]', new EnclosingPair('[', ']'))).toEqual('a[sd]a');
- expect(ParserUtils.getInBetween('slider(addLabels, minValue(10), maxValue(60))', new EnclosingPair('(', ')'))).toEqual('addLabels, minValue(10), maxValue(60)');
+ expect(ParserUtils.getInBetween('slider(addLabels, minValue(10), maxValue(60))', new EnclosingPair('(', ')'))).toEqual(
+ 'addLabels, minValue(10), maxValue(60)'
+ );
});
test('multi length opening and single closing strings', () => {
diff --git a/tests/__snapshots__/InputFieldParser.test.ts.snap b/tests/__snapshots__/InputFieldParser.test.ts.snap
new file mode 100644
index 00000000..18bfd757
--- /dev/null
+++ b/tests/__snapshots__/InputFieldParser.test.ts.snap
@@ -0,0 +1,784 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ast parser tests complex closure test 2 1`] = `
+ParsingTree {
+ "children": [
+ PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "hello world",
+ "range": {
+ "from": 0,
+ "to": 10,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ PT_Closure {
+ "children": [
+ PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "this is a message to all people",
+ "range": {
+ "from": 12,
+ "to": 42,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ ],
+ "endLiteral": PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "]",
+ "range": {
+ "from": 43,
+ "to": 43,
+ },
+ "type": "]",
+ },
+ "type": "LITERAL",
+ },
+ "startLiteral": PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "[",
+ "range": {
+ "from": 11,
+ "to": 11,
+ },
+ "type": "[",
+ },
+ "type": "LITERAL",
+ },
+ "str": "hello world[this is a message to all people]test(a)b",
+ "type": "CLOSURE",
+ },
+ PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "test",
+ "range": {
+ "from": 44,
+ "to": 47,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ PT_Closure {
+ "children": [
+ PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "a",
+ "range": {
+ "from": 49,
+ "to": 49,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ ],
+ "endLiteral": PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": ")",
+ "range": {
+ "from": 50,
+ "to": 50,
+ },
+ "type": ")",
+ },
+ "type": "LITERAL",
+ },
+ "startLiteral": PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "(",
+ "range": {
+ "from": 48,
+ "to": 48,
+ },
+ "type": "(",
+ },
+ "type": "LITERAL",
+ },
+ "str": "hello world[this is a message to all people]test(a)b",
+ "type": "CLOSURE",
+ },
+ PT_Literal {
+ "str": "hello world[this is a message to all people]test(a)b",
+ "token": {
+ "literal": "b",
+ "range": {
+ "from": 51,
+ "to": 51,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ ],
+ "str": "hello world[this is a message to all people]test(a)b",
+ "tokens": [
+ {
+ "literal": "hello world",
+ "range": {
+ "from": 0,
+ "to": 10,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "[",
+ "range": {
+ "from": 11,
+ "to": 11,
+ },
+ "type": "[",
+ },
+ {
+ "literal": "this is a message to all people",
+ "range": {
+ "from": 12,
+ "to": 42,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "]",
+ "range": {
+ "from": 43,
+ "to": 43,
+ },
+ "type": "]",
+ },
+ {
+ "literal": "test",
+ "range": {
+ "from": 44,
+ "to": 47,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "(",
+ "range": {
+ "from": 48,
+ "to": 48,
+ },
+ "type": "(",
+ },
+ {
+ "literal": "a",
+ "range": {
+ "from": 49,
+ "to": 49,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": ")",
+ "range": {
+ "from": 50,
+ "to": 50,
+ },
+ "type": ")",
+ },
+ {
+ "literal": "b",
+ "range": {
+ "from": 51,
+ "to": 51,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 52,
+ "to": 52,
+ },
+ "type": "__EOF__",
+ },
+ ],
+ "type": "ROOT",
+}
+`;
+
+exports[`ast parser tests simple closure test 1`] = `
+ParsingTree {
+ "children": [
+ PT_Literal {
+ "str": "hello world(this is a message to all people)",
+ "token": {
+ "literal": "hello world",
+ "range": {
+ "from": 0,
+ "to": 10,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ PT_Closure {
+ "children": [
+ PT_Literal {
+ "str": "hello world(this is a message to all people)",
+ "token": {
+ "literal": "this is a message to all people",
+ "range": {
+ "from": 12,
+ "to": 42,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ ],
+ "endLiteral": PT_Literal {
+ "str": "hello world(this is a message to all people)",
+ "token": {
+ "literal": ")",
+ "range": {
+ "from": 43,
+ "to": 43,
+ },
+ "type": ")",
+ },
+ "type": "LITERAL",
+ },
+ "startLiteral": PT_Literal {
+ "str": "hello world(this is a message to all people)",
+ "token": {
+ "literal": "(",
+ "range": {
+ "from": 11,
+ "to": 11,
+ },
+ "type": "(",
+ },
+ "type": "LITERAL",
+ },
+ "str": "hello world(this is a message to all people)",
+ "type": "CLOSURE",
+ },
+ ],
+ "str": "hello world(this is a message to all people)",
+ "tokens": [
+ {
+ "literal": "hello world",
+ "range": {
+ "from": 0,
+ "to": 10,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "(",
+ "range": {
+ "from": 11,
+ "to": 11,
+ },
+ "type": "(",
+ },
+ {
+ "literal": "this is a message to all people",
+ "range": {
+ "from": 12,
+ "to": 42,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": ")",
+ "range": {
+ "from": 43,
+ "to": 43,
+ },
+ "type": ")",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 44,
+ "to": 44,
+ },
+ "type": "__EOF__",
+ },
+ ],
+ "type": "ROOT",
+}
+`;
+
+exports[`ast parser tests simple input field declaration 1 1`] = `
+ParsingTree {
+ "children": [
+ PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "INPUT",
+ "range": {
+ "from": 0,
+ "to": 4,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ PT_Closure {
+ "children": [
+ PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "text",
+ "range": {
+ "from": 6,
+ "to": 9,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": ":",
+ "range": {
+ "from": 10,
+ "to": 10,
+ },
+ "type": ":",
+ },
+ "type": "LITERAL",
+ },
+ PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "nested",
+ "range": {
+ "from": 11,
+ "to": 16,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ PT_Closure {
+ "children": [
+ PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "object",
+ "range": {
+ "from": 19,
+ "to": 24,
+ },
+ "type": "WORD",
+ },
+ "type": "LITERAL",
+ },
+ ],
+ "endLiteral": PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "]",
+ "range": {
+ "from": 26,
+ "to": 26,
+ },
+ "type": "]",
+ },
+ "type": "LITERAL",
+ },
+ "startLiteral": PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "[",
+ "range": {
+ "from": 17,
+ "to": 17,
+ },
+ "type": "[",
+ },
+ "type": "LITERAL",
+ },
+ "str": "INPUT[text:nested['object']]",
+ "type": "CLOSURE",
+ },
+ ],
+ "endLiteral": PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "]",
+ "range": {
+ "from": 27,
+ "to": 27,
+ },
+ "type": "]",
+ },
+ "type": "LITERAL",
+ },
+ "startLiteral": PT_Literal {
+ "str": "INPUT[text:nested['object']]",
+ "token": {
+ "literal": "[",
+ "range": {
+ "from": 5,
+ "to": 5,
+ },
+ "type": "[",
+ },
+ "type": "LITERAL",
+ },
+ "str": "INPUT[text:nested['object']]",
+ "type": "CLOSURE",
+ },
+ ],
+ "str": "INPUT[text:nested['object']]",
+ "tokens": [
+ {
+ "literal": "INPUT",
+ "range": {
+ "from": 0,
+ "to": 4,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "[",
+ "range": {
+ "from": 5,
+ "to": 5,
+ },
+ "type": "[",
+ },
+ {
+ "literal": "text",
+ "range": {
+ "from": 6,
+ "to": 9,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": ":",
+ "range": {
+ "from": 10,
+ "to": 10,
+ },
+ "type": ":",
+ },
+ {
+ "literal": "nested",
+ "range": {
+ "from": 11,
+ "to": 16,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "[",
+ "range": {
+ "from": 17,
+ "to": 17,
+ },
+ "type": "[",
+ },
+ {
+ "literal": "object",
+ "range": {
+ "from": 19,
+ "to": 24,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "]",
+ "range": {
+ "from": 26,
+ "to": 26,
+ },
+ "type": "]",
+ },
+ {
+ "literal": "]",
+ "range": {
+ "from": 27,
+ "to": 27,
+ },
+ "type": "]",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 28,
+ "to": 28,
+ },
+ "type": "__EOF__",
+ },
+ ],
+ "type": "ROOT",
+}
+`;
+
+exports[`ast parser tests unclosed closure test 1`] = `
+"[MB_PARSING_ERROR] "failed to parse" caused by "Encountered invalid token. Active closure is not the closure that this token closes. You probably forgot a ')' somewhere in font of this token."
+hello world[this is a message to all (people]test)b
+ ^
+"
+`;
+
+exports[`tokenizer tests tokenize all simple tokens 1`] = `
+[
+ {
+ "literal": "(",
+ "range": {
+ "from": 0,
+ "to": 0,
+ },
+ "type": "(",
+ },
+ {
+ "literal": ")",
+ "range": {
+ "from": 1,
+ "to": 1,
+ },
+ "type": ")",
+ },
+ {
+ "literal": "[",
+ "range": {
+ "from": 2,
+ "to": 2,
+ },
+ "type": "[",
+ },
+ {
+ "literal": "]",
+ "range": {
+ "from": 3,
+ "to": 3,
+ },
+ "type": "]",
+ },
+ {
+ "literal": ":",
+ "range": {
+ "from": 4,
+ "to": 4,
+ },
+ "type": ":",
+ },
+ {
+ "literal": "#",
+ "range": {
+ "from": 5,
+ "to": 5,
+ },
+ "type": "#",
+ },
+ {
+ "literal": ",",
+ "range": {
+ "from": 6,
+ "to": 6,
+ },
+ "type": ",",
+ },
+ {
+ "literal": ".",
+ "range": {
+ "from": 7,
+ "to": 7,
+ },
+ "type": ".",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 8,
+ "to": 8,
+ },
+ "type": "__EOF__",
+ },
+]
+`;
+
+exports[`tokenizer tests tokenize complex quotes 1`] = `
+[
+ {
+ "literal": "hello world",
+ "range": {
+ "from": 0,
+ "to": 10,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "(",
+ "range": {
+ "from": 11,
+ "to": 11,
+ },
+ "type": "(",
+ },
+ {
+ "literal": "this is a message to all people []",
+ "range": {
+ "from": 13,
+ "to": 46,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": " test ",
+ "range": {
+ "from": 48,
+ "to": 53,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "[",
+ "range": {
+ "from": 54,
+ "to": 54,
+ },
+ "type": "[",
+ },
+ {
+ "literal": "]",
+ "range": {
+ "from": 55,
+ "to": 55,
+ },
+ "type": "]",
+ },
+ {
+ "literal": " ",
+ "range": {
+ "from": 56,
+ "to": 56,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": ":",
+ "range": {
+ "from": 58,
+ "to": 58,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": ")",
+ "range": {
+ "from": 60,
+ "to": 60,
+ },
+ "type": ")",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 61,
+ "to": 61,
+ },
+ "type": "__EOF__",
+ },
+]
+`;
+
+exports[`tokenizer tests tokenize simple mix of tokens and words 1`] = `
+[
+ {
+ "literal": "hello world",
+ "range": {
+ "from": 0,
+ "to": 10,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "(",
+ "range": {
+ "from": 11,
+ "to": 11,
+ },
+ "type": "(",
+ },
+ {
+ "literal": "this is a message to all people",
+ "range": {
+ "from": 12,
+ "to": 42,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": ")",
+ "range": {
+ "from": 43,
+ "to": 43,
+ },
+ "type": ")",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 44,
+ "to": 44,
+ },
+ "type": "__EOF__",
+ },
+]
+`;
+
+exports[`tokenizer tests tokenize simple quotes 1`] = `
+[
+ {
+ "literal": "hello world(this is a message to all people)",
+ "range": {
+ "from": 1,
+ "to": 44,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 46,
+ "to": 46,
+ },
+ "type": "__EOF__",
+ },
+]
+`;
+
+exports[`tokenizer tests tokenize simple word 1`] = `
+[
+ {
+ "literal": "hello world",
+ "range": {
+ "from": 0,
+ "to": 10,
+ },
+ "type": "WORD",
+ },
+ {
+ "literal": "eof",
+ "range": {
+ "from": 11,
+ "to": 11,
+ },
+ "type": "__EOF__",
+ },
+]
+`;
diff --git a/tsconfig.json b/tsconfig.json
index 4eab46a5..600a1e60 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,7 +12,8 @@
"importHelpers": true,
"isolatedModules": true,
"lib": ["DOM", "ES5", "ES6", "ES7", "Es2021"],
- "types": ["svelte", "node", "jest"]
+ "types": ["svelte", "node", "jest"],
+ "allowSyntheticDefaultImports": true
},
"include": ["**/*.ts", "node_modules/obsidian/publish.d.ts"]
}