From a08b1cc7a9fc77be646b6bf4c79b8c6c64839b74 Mon Sep 17 00:00:00 2001 From: NeaByteLab <209737579+NeaByteLab@users.noreply.github.com> Date: Sat, 20 Jun 2026 20:38:57 +0700 Subject: [PATCH] refactor(editor): remove bundled editor extension - Remove editor README and packaged VSIX - Remove language configuration, package manifest, and snippets - Remove tmLanguage grammar for dve files --- editor/README.md | 97 --------- editor/dve/README.md | 250 ------------------------ editor/dve/dve-language-0.1.0.vsix | Bin 7364 -> 0 bytes editor/dve/language-configuration.json | 19 -- editor/dve/package.json | 45 ----- editor/dve/snippets/dve.code-snippets | 61 ------ editor/dve/syntaxes/dve.tmLanguage.json | 141 ------------- 7 files changed, 613 deletions(-) delete mode 100644 editor/README.md delete mode 100644 editor/dve/README.md delete mode 100644 editor/dve/dve-language-0.1.0.vsix delete mode 100644 editor/dve/language-configuration.json delete mode 100644 editor/dve/package.json delete mode 100644 editor/dve/snippets/dve.code-snippets delete mode 100644 editor/dve/syntaxes/dve.tmLanguage.json diff --git a/editor/README.md b/editor/README.md deleted file mode 100644 index 600d266..0000000 --- a/editor/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# Editor Tooling - -Editor support for Deserve, including syntax highlighting for Deserve View Engine (DVE) templates. - -## Table of Contents - -- [DVE (Deserve View Engine)](#dve-deserve-view-engine) -- [Example: Use DVE in Deserve](#example-use-dve-in-deserve) - - [Project Structure](#project-structure) - - [1) Add Templates](#1-add-templates) - - [2) Configure Router](#2-configure-router) - - [3) Render in a Route](#3-render-in-a-route) -- [Syntax Highlighting (Cursor / VS Code / Trae)](#syntax-highlighting-cursor--vs-code--trae) - -## DVE (Deserve View Engine) - -DVE is Deserve's built-in view engine for rendering `.dve` templates. - -## Example: Use DVE in Deserve - -### Project Structure - -``` -. -├── main.ts -├── routes/ -│ └── index.ts -└── views/ - ├── index.dve - └── partials/ - └── header.dve -``` - -### 1) Add Templates - -Create `views/index.dve`: - -```txt -{{> partials/header.dve}} -Hello {{ user?.name ?? 'Guest' }}. -``` - -Create `views/partials/header.dve`: - -```txt -

Welcome

-``` - -### 2) Configure Router - -Enable DVE by setting `viewsDir` when the router is created. - -```ts -import { Router } from '@neabyte/deserve' - -const router = new Router({ - routesDir: './routes', - viewsDir: './views' -}) - -await router.serve(8000) -``` - -### 3) Render in a Route - -Create `routes/index.ts`: - -```ts -import type { Context } from '@neabyte/deserve' - -export async function GET(ctx: Context) { - return await ctx.render('index', { user: { name: 'Nea' } }) -} -``` - -Run the server and open `http://localhost:8000` to see the rendered page. - -## Syntax Highlighting (Cursor / VS Code / Trae) - -Deserve ships a local DVE extension package at `editor/dve/dve-language-0.1.0.vsix`. - -Install it with an editor CLI: - -```bash -# Trae -trae --install-extension ./dve/dve-language-0.1.0.vsix --force - -# VS Code -code --install-extension ./dve/dve-language-0.1.0.vsix --force - -# Cursor -cursor --install-extension ./dve/dve-language-0.1.0.vsix --force -``` - -After installing, reload the editor window and open any `.dve` file, where HTML stays the base syntax with the embedded DVE tags highlighted on top. - -- **DVE syntax reference**: See [`editor/dve/README.md`](dve/README.md) diff --git a/editor/dve/README.md b/editor/dve/README.md deleted file mode 100644 index 9b0bd66..0000000 --- a/editor/dve/README.md +++ /dev/null @@ -1,250 +0,0 @@ -# DVE Grammar - -A short, friendly tour of the Deserve `.dve` template syntax that reads from top to bottom, so the first open of a `.dve` file feels easy instead of intimidating. - -- **Editor tooling overview**: See [`editor/README.md`](../README.md) - -## Table of Contents - -- [Install Local VSIX](#install-local-vsix) -- [Start Here](#start-here) -- [Variables](#variables) -- [Raw Output (Unescaped)](#raw-output-unescaped) -- [Include](#include) -- [If / Else](#if--else) -- [Each](#each) -- [Each Metadata](#each-metadata) -- [Expressions](#expressions) -- [Operator Reference](#operator-reference) -- [Snippets](#snippets) -- [Advanced Examples](#advanced-examples) -- [What DVE Does Not Do](#what-dve-does-not-do) -- [Editor Scope Mapping](#editor-scope-mapping) - -## Install Local VSIX - -This folder ships a prebuilt VSIX package, so nothing needs to be built first: - -```txt -dve-language-0.1.0.vsix -``` - -Install it from this directory with an editor CLI: - -```bash -# VS Code -code --install-extension ./dve-language-0.1.0.vsix --force - -# Cursor -cursor --install-extension ./dve-language-0.1.0.vsix --force - -# Trae -trae --install-extension ./dve-language-0.1.0.vsix --force -``` - -Reload the editor after installing, and since DVE builds on HTML syntax the `.dve` files keep full HTML highlighting with the template tags layered on top. - -## Start Here - -The whole language comes down to two tags, and once those land the rest is just small variations. - -A `{{ ... }}` tag **shows a value** while a `{{#... }} ... {{/... }}` tag wraps a **block** like an if or a loop, and everything further down builds on those two shapes. - -```txt -Hello {{ user?.name ?? 'Guest' }}. -{{#if user?.isAdmin}}ADMIN{{else}}USER{{/if}} -``` - -## Variables - -A value wrapped in double braces is printed onto the page, and DVE escapes HTML by default so user input can never sneak in markup or open an injection hole. - -```txt -Hello {{ name }}. -``` - -## Raw Output (Unescaped) - -Triple braces print the value as-is with no escaping, which is meant only for HTML that is already known to be safe. - -```txt -{{{ trustedHtml }}} -``` - -## Include - -A repeated piece of markup can live in its own file and get pulled in with an include, where the path is resolved relative to the configured `viewsDir`. - -```txt -{{> partials/header.dve}} -``` - -## If / Else - -An `#if` block renders its body only when the condition is truthy and an optional `else` covers the other case, and every `#if` must be closed with a matching `/if` or DVE reports the block as unclosed. - -```txt -{{#if ok}}YES{{else}}NO{{/if}} -``` - -## Each - -An `#each` block walks an array and `as` names the current item, and leaving the name out falls back to `item`. - -```txt -{{#each items as item}}{{ item }},{{/each}} -``` - -## Each Metadata - -Inside an `#each` block four helpers are available for free, so the loop position never has to be tracked by hand: - -- `@index` — current position, starting at 0 -- `@first` — true on the first item -- `@last` — true on the last item -- `@length` — total number of items - -```txt -{{#each items as item}}({{ @index }}/{{ @length }} {{#if @first}}F{{else}}-{{/if}}{{#if @last}}L{{else}}-{{/if}}={{ item }});{{/each}} -``` - -## Expressions - -Any `{{ ... }}` tag accepts a small JavaScript-like expression, so a value can be read, given a fallback, compared, or run through a little math all in one place. - -```txt -Hello {{ user?.name ?? 'Guest' }}. -Total {{ price * quantity }} -{{#if age >= 18}}Adult{{else}}Minor{{/if}} -``` - -A few behaviours worth knowing: - -- A dotted path like `user.profile.name` reads nested values, and missing data along the way resolves to `undefined` -- Both `.` and `?.` return `undefined` when the object is missing, so a deep lookup never throws -- Strings use `"double"` or `'single'` quotes and understand the `\n`, `\t`, `\r` escapes -- Numbers can be decimals or exponents like `2.5` or `1e3` - -## Operator Reference - -Everything DVE understands, lowest precedence at the top down to highest at the bottom, and anything not on this list is rejected by the parser on purpose. - -| Group | Operators | Example | -| -------------- | --------------------------------------------------- | -------------------------- | -| Ternary | `? :` | `{{ ok ? 'yes' : 'no' }}` | -| Nullish | `??` | `{{ name ?? 'Guest' }}` | -| Logical OR | `\|\|` | `{{ a \|\| b }}` | -| Logical AND | `&&` | `{{ a && b }}` | -| Equality | `===` `!==` `==` `!=` | `{{ role === 'admin' }}` | -| Relational | `>` `<` `>=` `<=` | `{{ age >= 18 }}` | -| Additive | `+` `-` | `{{ a + b }}` | -| Multiplicative | `*` `/` `%` | `{{ total % 2 }}` | -| Unary | `!` `+` `-` | `{{ !done }}` | -| Member | `.` `?.` | `{{ user?.profile.name }}` | -| Grouping | `( )` | `{{ (a + b) * c }}` | -| Literals | numbers, strings, `true` `false` `null` `undefined` | `{{ 1 + 2 * 3 }}` | - -## Snippets - -Type a prefix and press Tab to drop in the syntax that is easiest to forget. - -| Prefix | Inserts | -| ---------- | ------------------------------------- | -| `dve` | `{{ value }}` | -| `dveraw` | `{{{ html }}}` | -| `dveinc` | `{{> partials/header.dve }}` | -| `dveif` | `{{#if}} ... {{else}} ... {{/if}}` | -| `dveifn` | multi-line `{{#if}}` block | -| `dveeach` | `{{#each items as item}}` block | -| `dveeachm` | `#each` block with `@index`/`@length` | -| `dvetern` | `{{ cond ? yes : no }}` | -| `dvedef` | `{{ value ?? 'fallback' }}` | -| `dveopt` | `{{ user?.name ?? 'Guest' }}` | -| `dvecmt` | `` | - -## Advanced Examples - -### Layout + Partial Composition - -`views/layout.dve`: - -```txt - - - {{> partials/header.dve}} -
- {{{ bodyHtml }}} -
- {{> partials/footer.dve}} - - -``` - -`views/partials/header.dve`: - -```txt -
-

{{ title ?? 'Untitled' }}

- {{#if user?.name}}

Hello {{ user.name }}.

{{else}}

Hello Guest.

{{/if}} -
-``` - -### Lists With Conditional Blocks - -```txt -{{#if items?.length ?? 0}} - -{{else}} -

No items.

-{{/if}} -``` - -### Nested Each (Matrix-Style) - -```txt - - {{#each rows as row}} - - {{#each row as cell}} - - {{/each}} - - {{/each}} -
{{ cell }}
-``` - -## What DVE Does Not Do - -DVE stays small on purpose so a template can never run arbitrary code, and these limits are the safety boundary rather than missing features: - -- No function or method calls -- No array indexing like `items[0]` -- No assignment or variable declarations -- No regular expressions or arbitrary JavaScript - -Two guardrails also stop runaway templates, where include nesting is capped at 64 levels deep and a single `#each` is capped at 100,000 iterations, and crossing either one raises a clear error instead of hanging. - -Anything that needs real logic belongs in the route handler, where the finished value gets computed and then passed into the template. - -## Editor Scope Mapping - -| Syntax | Scope | -| ---------------------------------- | ------------------------------------------------------- | -| `{{` `}}` `{{{` `}}}` | `meta.tag.output.dve` / `meta.tag.raw.dve` | -| `#if` `#each` `else` `/if` `/each` | `keyword.control.dve` | -| `>` (include) | `keyword.control.include.dve` | -| `as` (in #each) | `keyword.operator.as.dve` | -| Include path | `string.unquoted.path.dve` | -| `true` `false` `null` `undefined` | `constant.language.dve` | -| Numbers (incl. `1e3`) | `constant.numeric.dve` | -| `"..."` `'...'` | `string.quoted.double.dve` / `string.quoted.single.dve` | -| Operators `?.` `===` `??` etc. | `keyword.operator.dve` | -| Identifiers / variables | `variable.other.dve` | -| Item name in #each | `variable.parameter.dve` | diff --git a/editor/dve/dve-language-0.1.0.vsix b/editor/dve/dve-language-0.1.0.vsix deleted file mode 100644 index a729a0dd3114f0f52c7afda1414965d3505c67df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7364 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 G)&BuGn@C*% diff --git a/editor/dve/language-configuration.json b/editor/dve/language-configuration.json deleted file mode 100644 index ae56a0e..0000000 --- a/editor/dve/language-configuration.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "comments": {}, - "brackets": [ - ["{{", "}}"], - ["{{{", "}}}"] - ], - "autoClosingPairs": [ - { "open": "{{", "close": "}}" }, - { "open": "{{{", "close": "}}}" }, - { "open": "\"", "close": "\"", "notIn": ["string"] }, - { "open": "'", "close": "'", "notIn": ["string"] } - ], - "surroundingPairs": [ - ["{{", "}}"], - ["{{{", "}}}"], - ["\"", "\""], - ["'", "'"] - ] -} diff --git a/editor/dve/package.json b/editor/dve/package.json deleted file mode 100644 index 1bcaa23..0000000 --- a/editor/dve/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "dve-language", - "displayName": "DVE Template Language", - "description": "Syntax highlighting for Deserve (.dve) templates", - "version": "0.1.0", - "publisher": "neabyte", - "engines": { - "vscode": "^1.74.0" - }, - "categories": [ - "Programming Languages" - ], - "contributes": { - "languages": [ - { - "id": "dve", - "aliases": [ - "DVE", - "dve" - ], - "extensions": [ - ".dve" - ], - "configuration": "./language-configuration.json" - } - ], - "snippets": [ - { - "language": "dve", - "path": "./snippets/dve.code-snippets" - } - ], - "grammars": [ - { - "language": "dve", - "scopeName": "text.html.dve", - "path": "./syntaxes/dve.tmLanguage.json", - "embeddedLanguages": { - "meta.embedded.line.dve": "dve", - "meta.embedded.block.dve": "dve" - } - } - ] - } -} diff --git a/editor/dve/snippets/dve.code-snippets b/editor/dve/snippets/dve.code-snippets deleted file mode 100644 index 44899f3..0000000 --- a/editor/dve/snippets/dve.code-snippets +++ /dev/null @@ -1,61 +0,0 @@ -{ - "DVE: Tag": { - "prefix": "dve", - "body": ["{{ ${1:value} }}"], - "description": "Insert DVE tag: {{ value }}" - }, - "DVE: Raw Tag": { - "prefix": "dveraw", - "body": ["{{{ ${1:html} }}}"], - "description": "Insert DVE raw tag: {{{ html }}}" - }, - "DVE: Include": { - "prefix": "dveinc", - "body": ["{{> ${1:partials/header.dve} }}"], - "description": "Insert DVE include: {{> path }}" - }, - "DVE: If / Else": { - "prefix": "dveif", - "body": ["{{#if ${1:condition}}}${2:then}{{else}}${3:else}{{/if}}"], - "description": "Insert DVE if/else block" - }, - "DVE: If": { - "prefix": "dveifn", - "body": ["{{#if ${1:condition}}}", " ${2:then}", "{{/if}}"], - "description": "Insert DVE if block (multi-line)" - }, - "DVE: Each": { - "prefix": "dveeach", - "body": ["{{#each ${1:items} as ${2:item}}}", " ${3:{{ item }}}", "{{/each}}"], - "description": "Insert DVE each block" - }, - "DVE: Each (With Meta)": { - "prefix": "dveeachm", - "body": [ - "{{#each ${1:items} as ${2:item}}}", - " ({{ @index }}/{{ @length }}) ${3:{{ item }}}", - "{{/each}}" - ], - "description": "Insert DVE each block with @index/@length" - }, - "DVE: Ternary": { - "prefix": "dvetern", - "body": ["{{ ${1:condition} ? ${2:yes} : ${3:no} }}"], - "description": "Insert DVE ternary: {{ cond ? yes : no }}" - }, - "DVE: Default (Nullish)": { - "prefix": "dvedef", - "body": ["{{ ${1:value} ?? ${2:'fallback'} }}"], - "description": "Insert DVE nullish default: {{ value ?? 'fallback' }}" - }, - "DVE: Optional Chain": { - "prefix": "dveopt", - "body": ["{{ ${1:user}?.${2:name} ?? ${3:'Guest'} }}"], - "description": "Insert DVE optional chain: {{ user?.name ?? 'Guest' }}" - }, - "DVE: Comment (HTML)": { - "prefix": "dvecmt", - "body": [""], - "description": "Insert HTML comment inside template" - } -} diff --git a/editor/dve/syntaxes/dve.tmLanguage.json b/editor/dve/syntaxes/dve.tmLanguage.json deleted file mode 100644 index ac7e8db..0000000 --- a/editor/dve/syntaxes/dve.tmLanguage.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "DVE", - "scopeName": "text.html.dve", - "fileTypes": ["dve"], - "patterns": [{ "include": "#dve-tags" }, { "include": "text.html.basic" }], - "repository": { - "dve-tags": { - "patterns": [ - { "include": "#dve-raw-tag" }, - { "include": "#dve-include-tag" }, - { "include": "#dve-block-tag" }, - { "include": "#dve-output-tag" } - ] - }, - "dve-raw-tag": { - "begin": "\\{\\{\\{", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.dve" } - }, - "end": "\\}\\}\\}", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.dve" } - }, - "name": "meta.embedded.line.dve meta.tag.raw.dve", - "contentName": "meta.expression.dve", - "patterns": [{ "include": "#expression" }] - }, - "dve-include-tag": { - "begin": "\\{\\{\\s*(>)", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.dve" }, - "1": { "name": "keyword.control.include.dve" } - }, - "end": "\\}\\}", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.dve" } - }, - "name": "meta.embedded.line.dve meta.tag.include.dve", - "patterns": [{ "include": "#path" }] - }, - "dve-block-tag": { - "begin": "\\{\\{\\s*(#if|#each|else|/if|/each)\\b", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.dve" }, - "1": { "name": "keyword.control.dve" } - }, - "end": "\\}\\}", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.dve" } - }, - "name": "meta.embedded.block.dve meta.tag.block.dve", - "patterns": [ - { - "match": "\\b(as)\\s+([a-zA-Z_$][a-zA-Z0-9_$]*)", - "captures": { - "1": { "name": "keyword.operator.as.dve" }, - "2": { "name": "variable.parameter.dve" } - } - }, - { "include": "#expression" } - ] - }, - "dve-output-tag": { - "begin": "\\{\\{", - "beginCaptures": { - "0": { "name": "punctuation.section.embedded.begin.dve" } - }, - "end": "\\}\\}", - "endCaptures": { - "0": { "name": "punctuation.section.embedded.end.dve" } - }, - "name": "meta.embedded.line.dve meta.tag.output.dve", - "contentName": "meta.expression.dve", - "patterns": [{ "include": "#expression" }] - }, - "expression": { - "patterns": [ - { "include": "#string-double" }, - { "include": "#string-single" }, - { "include": "#number" }, - { "include": "#literal" }, - { "include": "#operator" }, - { "include": "#identifier" } - ] - }, - "path": { - "match": "[@a-zA-Z0-9_$./\\\\-]+\\.dve|[@a-zA-Z_$][a-zA-Z0-9_$.]*", - "name": "string.unquoted.path.dve" - }, - "string-double": { - "begin": "\"", - "end": "\"", - "name": "string.quoted.double.dve", - "patterns": [ - { - "match": "\\\\.", - "name": "constant.character.escape.dve" - } - ] - }, - "string-single": { - "begin": "'", - "end": "'", - "name": "string.quoted.single.dve", - "patterns": [ - { - "match": "\\\\.", - "name": "constant.character.escape.dve" - } - ] - }, - "number": { - "match": "\\b[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?\\b", - "name": "constant.numeric.dve" - }, - "literal": { - "match": "\\b(true|false|null|undefined)\\b", - "name": "constant.language.dve" - }, - "operator": { - "match": "\\?\\.|===|!==|==|!=|&&|\\|\\||\\?\\?|>=|<=|[?.!:()+\\-*/%<>]", - "name": "keyword.operator.dve" - }, - "identifier": { - "match": "\\b([a-zA-Z_$@][a-zA-Z0-9_$]*)\\b", - "name": "variable.other.dve" - } - }, - "injections": { - "L:text.html.dve - (meta.embedded.line.dve | meta.embedded.block.dve)": { - "patterns": [{ "include": "#dve-tags" }] - }, - "L:text.html.basic": { - "patterns": [{ "include": "#dve-tags" }] - }, - "L:string.quoted.double.html, L:string.quoted.single.html": { - "patterns": [{ "include": "#dve-tags" }] - } - } -}