ventojs 1.15.0 → 2.0.0-canary.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.
Files changed (184) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +2 -0
  3. package/browser.js +19 -0
  4. package/{esm/src → core}/environment.js +17 -16
  5. package/{esm/src → core}/errors.js +0 -8
  6. package/{esm/src → core}/js.js +23 -15
  7. package/core/reserved.js +63 -0
  8. package/{esm/src → core}/tokenizer.js +0 -1
  9. package/highlightjs-vento.js +24 -0
  10. package/{esm/src/loader.js → loaders/file.js} +4 -1
  11. package/loaders/memory.js +24 -0
  12. package/loaders/url.js +28 -0
  13. package/{esm/bare.js → mod.js} +7 -2
  14. package/package.json +144 -57
  15. package/{esm/plugins → plugins}/auto_trim.js +0 -1
  16. package/{esm/plugins → plugins}/echo.js +0 -1
  17. package/{esm/plugins → plugins}/escape.js +0 -1
  18. package/{esm/plugins → plugins}/export.js +0 -1
  19. package/{esm/plugins → plugins}/for.js +1 -2
  20. package/{esm/plugins → plugins}/function.js +0 -1
  21. package/{esm/plugins → plugins}/if.js +0 -1
  22. package/{esm/plugins → plugins}/import.js +0 -1
  23. package/{esm/plugins → plugins}/include.js +1 -2
  24. package/{esm/plugins → plugins}/js.js +0 -1
  25. package/{esm/plugins → plugins}/layout.js +0 -1
  26. package/plugins/mod.js +30 -0
  27. package/{esm/plugins → plugins}/set.js +4 -4
  28. package/{esm/plugins → plugins}/trim.js +0 -1
  29. package/{esm/plugins → plugins}/unescape.js +0 -1
  30. package/prism-vento.js +26 -0
  31. package/types/browser.d.ts +8 -0
  32. package/{esm/src → types/core}/environment.d.ts +2 -4
  33. package/{esm/src → types/core}/errors.d.ts +0 -6
  34. package/types/core/js.d.ts +11 -0
  35. package/types/core/reserved.d.ts +2 -0
  36. package/{esm/src → types/core}/tokenizer.d.ts +0 -2
  37. package/{esm/src/loader.d.ts → types/loaders/file.d.ts} +5 -4
  38. package/types/loaders/memory.d.ts +11 -0
  39. package/{esm/src/url_loader.d.ts → types/loaders/url.d.ts} +5 -4
  40. package/{esm/bare.d.ts → types/mod.d.ts} +1 -3
  41. package/{esm → types}/plugins/auto_trim.d.ts +2 -4
  42. package/types/plugins/echo.d.ts +2 -0
  43. package/types/plugins/escape.d.ts +2 -0
  44. package/types/plugins/export.d.ts +2 -0
  45. package/types/plugins/for.d.ts +2 -0
  46. package/types/plugins/function.d.ts +2 -0
  47. package/types/plugins/if.d.ts +2 -0
  48. package/types/plugins/import.d.ts +2 -0
  49. package/types/plugins/include.d.ts +2 -0
  50. package/types/plugins/js.d.ts +2 -0
  51. package/types/plugins/layout.d.ts +2 -0
  52. package/types/plugins/mod.d.ts +2 -0
  53. package/types/plugins/set.d.ts +2 -0
  54. package/types/plugins/trim.d.ts +4 -0
  55. package/types/plugins/unescape.d.ts +2 -0
  56. package/esm/_dnt.polyfills.d.ts +0 -12
  57. package/esm/_dnt.polyfills.d.ts.map +0 -1
  58. package/esm/_dnt.polyfills.js +0 -15
  59. package/esm/_dnt.shims.d.ts +0 -2
  60. package/esm/_dnt.shims.d.ts.map +0 -1
  61. package/esm/_dnt.shims.js +0 -57
  62. package/esm/_dnt.test_polyfills.d.ts.map +0 -1
  63. package/esm/_dnt.test_shims.d.ts.map +0 -1
  64. package/esm/bare.d.ts.map +0 -1
  65. package/esm/deps/deno.land/std@0.224.0/assert/_constants.d.ts.map +0 -1
  66. package/esm/deps/deno.land/std@0.224.0/assert/assert_equals.d.ts.map +0 -1
  67. package/esm/deps/deno.land/std@0.224.0/assert/assert_is_error.d.ts.map +0 -1
  68. package/esm/deps/deno.land/std@0.224.0/assert/assert_throws.d.ts.map +0 -1
  69. package/esm/deps/deno.land/std@0.224.0/assert/assertion_error.d.ts.map +0 -1
  70. package/esm/deps/deno.land/std@0.224.0/assert/equal.d.ts.map +0 -1
  71. package/esm/deps/deno.land/std@0.224.0/collections/_utils.d.ts.map +0 -1
  72. package/esm/deps/deno.land/std@0.224.0/collections/deep_merge.d.ts.map +0 -1
  73. package/esm/deps/deno.land/std@0.224.0/fmt/colors.d.ts.map +0 -1
  74. package/esm/deps/deno.land/std@0.224.0/front_matter/_formats.d.ts.map +0 -1
  75. package/esm/deps/deno.land/std@0.224.0/front_matter/create_extractor.d.ts.map +0 -1
  76. package/esm/deps/deno.land/std@0.224.0/front_matter/json.d.ts.map +0 -1
  77. package/esm/deps/deno.land/std@0.224.0/front_matter/mod.d.ts.map +0 -1
  78. package/esm/deps/deno.land/std@0.224.0/front_matter/test.d.ts.map +0 -1
  79. package/esm/deps/deno.land/std@0.224.0/front_matter/toml.d.ts.map +0 -1
  80. package/esm/deps/deno.land/std@0.224.0/front_matter/yaml.d.ts.map +0 -1
  81. package/esm/deps/deno.land/std@0.224.0/internal/diff.d.ts.map +0 -1
  82. package/esm/deps/deno.land/std@0.224.0/internal/format.d.ts.map +0 -1
  83. package/esm/deps/deno.land/std@0.224.0/internal/mod.d.ts.map +0 -1
  84. package/esm/deps/deno.land/std@0.224.0/toml/_parser.d.ts.map +0 -1
  85. package/esm/deps/deno.land/std@0.224.0/toml/parse.d.ts.map +0 -1
  86. package/esm/deps/deno.land/std@0.224.0/yaml/_error.d.ts.map +0 -1
  87. package/esm/deps/deno.land/std@0.224.0/yaml/_loader/loader.d.ts.map +0 -1
  88. package/esm/deps/deno.land/std@0.224.0/yaml/_loader/loader_state.d.ts.map +0 -1
  89. package/esm/deps/deno.land/std@0.224.0/yaml/_mark.d.ts.map +0 -1
  90. package/esm/deps/deno.land/std@0.224.0/yaml/_state.d.ts.map +0 -1
  91. package/esm/deps/deno.land/std@0.224.0/yaml/_type/binary.d.ts.map +0 -1
  92. package/esm/deps/deno.land/std@0.224.0/yaml/_type/bool.d.ts.map +0 -1
  93. package/esm/deps/deno.land/std@0.224.0/yaml/_type/float.d.ts.map +0 -1
  94. package/esm/deps/deno.land/std@0.224.0/yaml/_type/function.d.ts.map +0 -1
  95. package/esm/deps/deno.land/std@0.224.0/yaml/_type/int.d.ts.map +0 -1
  96. package/esm/deps/deno.land/std@0.224.0/yaml/_type/map.d.ts.map +0 -1
  97. package/esm/deps/deno.land/std@0.224.0/yaml/_type/merge.d.ts.map +0 -1
  98. package/esm/deps/deno.land/std@0.224.0/yaml/_type/mod.d.ts.map +0 -1
  99. package/esm/deps/deno.land/std@0.224.0/yaml/_type/nil.d.ts.map +0 -1
  100. package/esm/deps/deno.land/std@0.224.0/yaml/_type/omap.d.ts.map +0 -1
  101. package/esm/deps/deno.land/std@0.224.0/yaml/_type/pairs.d.ts.map +0 -1
  102. package/esm/deps/deno.land/std@0.224.0/yaml/_type/regexp.d.ts.map +0 -1
  103. package/esm/deps/deno.land/std@0.224.0/yaml/_type/seq.d.ts.map +0 -1
  104. package/esm/deps/deno.land/std@0.224.0/yaml/_type/set.d.ts.map +0 -1
  105. package/esm/deps/deno.land/std@0.224.0/yaml/_type/str.d.ts.map +0 -1
  106. package/esm/deps/deno.land/std@0.224.0/yaml/_type/timestamp.d.ts.map +0 -1
  107. package/esm/deps/deno.land/std@0.224.0/yaml/_type/undefined.d.ts.map +0 -1
  108. package/esm/deps/deno.land/std@0.224.0/yaml/_utils.d.ts.map +0 -1
  109. package/esm/deps/deno.land/std@0.224.0/yaml/parse.d.ts.map +0 -1
  110. package/esm/deps/deno.land/std@0.224.0/yaml/schema/core.d.ts.map +0 -1
  111. package/esm/deps/deno.land/std@0.224.0/yaml/schema/default.d.ts.map +0 -1
  112. package/esm/deps/deno.land/std@0.224.0/yaml/schema/extended.d.ts.map +0 -1
  113. package/esm/deps/deno.land/std@0.224.0/yaml/schema/failsafe.d.ts.map +0 -1
  114. package/esm/deps/deno.land/std@0.224.0/yaml/schema/json.d.ts.map +0 -1
  115. package/esm/deps/deno.land/std@0.224.0/yaml/schema/mod.d.ts.map +0 -1
  116. package/esm/deps/deno.land/std@0.224.0/yaml/schema.d.ts.map +0 -1
  117. package/esm/deps/deno.land/std@0.224.0/yaml/type.d.ts.map +0 -1
  118. package/esm/deps/jsr.io/@davidbonnet/astring/1.8.6/src/astring.d.ts +0 -110
  119. package/esm/deps/jsr.io/@davidbonnet/astring/1.8.6/src/astring.d.ts.map +0 -1
  120. package/esm/deps/jsr.io/@davidbonnet/astring/1.8.6/src/astring.js +0 -1159
  121. package/esm/deps.d.ts +0 -5
  122. package/esm/deps.d.ts.map +0 -1
  123. package/esm/deps.js +0 -3
  124. package/esm/mod.d.ts +0 -9
  125. package/esm/mod.d.ts.map +0 -1
  126. package/esm/mod.js +0 -36
  127. package/esm/package.json +0 -3
  128. package/esm/plugins/auto_trim.d.ts.map +0 -1
  129. package/esm/plugins/echo.d.ts +0 -4
  130. package/esm/plugins/echo.d.ts.map +0 -1
  131. package/esm/plugins/escape.d.ts +0 -4
  132. package/esm/plugins/escape.d.ts.map +0 -1
  133. package/esm/plugins/export.d.ts +0 -4
  134. package/esm/plugins/export.d.ts.map +0 -1
  135. package/esm/plugins/for.d.ts +0 -4
  136. package/esm/plugins/for.d.ts.map +0 -1
  137. package/esm/plugins/function.d.ts +0 -4
  138. package/esm/plugins/function.d.ts.map +0 -1
  139. package/esm/plugins/if.d.ts +0 -4
  140. package/esm/plugins/if.d.ts.map +0 -1
  141. package/esm/plugins/import.d.ts +0 -4
  142. package/esm/plugins/import.d.ts.map +0 -1
  143. package/esm/plugins/include.d.ts +0 -4
  144. package/esm/plugins/include.d.ts.map +0 -1
  145. package/esm/plugins/js.d.ts +0 -4
  146. package/esm/plugins/js.d.ts.map +0 -1
  147. package/esm/plugins/layout.d.ts +0 -4
  148. package/esm/plugins/layout.d.ts.map +0 -1
  149. package/esm/plugins/set.d.ts +0 -4
  150. package/esm/plugins/set.d.ts.map +0 -1
  151. package/esm/plugins/trim.d.ts +0 -6
  152. package/esm/plugins/trim.d.ts.map +0 -1
  153. package/esm/plugins/unescape.d.ts +0 -4
  154. package/esm/plugins/unescape.d.ts.map +0 -1
  155. package/esm/src/environment.d.ts.map +0 -1
  156. package/esm/src/errors.d.ts.map +0 -1
  157. package/esm/src/js.d.ts +0 -12
  158. package/esm/src/js.d.ts.map +0 -1
  159. package/esm/src/loader.d.ts.map +0 -1
  160. package/esm/src/tokenizer.d.ts.map +0 -1
  161. package/esm/src/transformer.d.ts +0 -3
  162. package/esm/src/transformer.d.ts.map +0 -1
  163. package/esm/src/transformer.js +0 -219
  164. package/esm/src/url_loader.d.ts.map +0 -1
  165. package/esm/src/url_loader.js +0 -19
  166. package/esm/test/auto_trim.test.d.ts.map +0 -1
  167. package/esm/test/comment.test.d.ts.map +0 -1
  168. package/esm/test/compile.test.d.ts.map +0 -1
  169. package/esm/test/echo.test.d.ts.map +0 -1
  170. package/esm/test/escape.test.d.ts.map +0 -1
  171. package/esm/test/for.test.d.ts.map +0 -1
  172. package/esm/test/function.test.d.ts.map +0 -1
  173. package/esm/test/if.test.d.ts.map +0 -1
  174. package/esm/test/import.test.d.ts.map +0 -1
  175. package/esm/test/include.test.d.ts.map +0 -1
  176. package/esm/test/js.test.d.ts.map +0 -1
  177. package/esm/test/layout.test.d.ts.map +0 -1
  178. package/esm/test/print.test.d.ts.map +0 -1
  179. package/esm/test/safe.test.d.ts.map +0 -1
  180. package/esm/test/set.test.d.ts.map +0 -1
  181. package/esm/test/tokenizer.test.d.ts.map +0 -1
  182. package/esm/test/unescape.test.d.ts.map +0 -1
  183. package/esm/test/utils.d.ts.map +0 -1
  184. package/esm/test/with.test.d.ts.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## 2.0.0 - Unreleased
8
+ Vento 2.0 is now dependency-free and compatible with browsers without requiring a build process.
9
+
10
+ ### Added
11
+ - Build-less browser support.
12
+ - `plugins/mod.ts` module to register all default plugins easily.
13
+
14
+ ### Changed
15
+ - Renamed `src` directory to `core`.
16
+ - Moved all loaders to the `loaders` root directory.
17
+ - Implemented a different approach to resolve the variables without using `meriyah` to analyze the code. [#128]
18
+
19
+ ### Removed
20
+ - Deprecated option `useWith`.
21
+ - All extenal dependencies (`meriyah`, `estree`, etc).
22
+ - `bare.ts` file since now it's useless.
23
+
24
+ [#128]: https://github.com/ventojs/vento/issues/128
package/README.md CHANGED
@@ -20,6 +20,8 @@ Nunjucks, Liquid, Mustache, and EJS.
20
20
  ## Features
21
21
 
22
22
  - Minimal, fast runtime. 🔥
23
+ - No dependencies.
24
+ - Compatible with browsers and JS runtimes (Deno, Node, Bun, etc).
23
25
  - Ergonomic by design. All tags and outputs are written with `{{` and `}}`.
24
26
  - Write JavaScript anywhere. `{{ await user.getName() }}` is real JS executed at
25
27
  runtime.
package/browser.js ADDED
@@ -0,0 +1,19 @@
1
+ import { Environment } from "./core/environment.js";
2
+ import { UrlLoader } from "./loaders/url.js";
3
+ import defaultPlugins from "./plugins/mod.js";
4
+ export default function (options) {
5
+ // Determine the loader based on the includes option
6
+ const loader = options.includes instanceof URL
7
+ ? new UrlLoader(options.includes)
8
+ : options.includes;
9
+ // Create a new Environment instance with the provided options
10
+ const env = new Environment({
11
+ loader,
12
+ dataVarname: options.dataVarname || "it",
13
+ autoescape: options.autoescape ?? false,
14
+ autoDataVarname: options.autoDataVarname ?? true,
15
+ });
16
+ // Register the default plugins
17
+ env.use(defaultPlugins());
18
+ return env;
19
+ }
@@ -1,8 +1,6 @@
1
- import "../_dnt.polyfills.js";
2
- import * as dntShim from "../_dnt.shims.js";
1
+ import iterateTopLevel from "./js.js";
3
2
  import tokenize from "./tokenizer.js";
4
- import { transformTemplateCode } from "./transformer.js";
5
- import { TemplateError, TransformError } from "./errors.js";
3
+ import { TemplateError } from "./errors.js";
6
4
  export class Environment {
7
5
  cache = new Map();
8
6
  options;
@@ -47,14 +45,16 @@ export class Environment {
47
45
  let code = this.compileTokens(tokens).join("\n");
48
46
  const { dataVarname, autoDataVarname } = this.options;
49
47
  if (autoDataVarname) {
50
- try {
51
- code = transformTemplateCode(code, dataVarname);
52
- }
53
- catch (cause) {
54
- if (cause instanceof TransformError) {
55
- throw new TemplateError(path, source, cause.position, cause);
56
- }
57
- throw new Error(`Unknown error while transforming ${path}`, { cause });
48
+ const generator = iterateTopLevel(code);
49
+ const [, , variables] = generator.next().value;
50
+ while (!generator.next().done)
51
+ ;
52
+ variables.delete(dataVarname);
53
+ if (variables.size > 0) {
54
+ code = `
55
+ var {${[...variables].join(",")}} = ${dataVarname};
56
+ {\n${code}\n}
57
+ `;
58
58
  }
59
59
  }
60
60
  const constructor = new Function("__file", "__env", "__defaults", "__err", `return${sync ? "" : " async"} function (${dataVarname}) {
@@ -65,7 +65,7 @@ export class Environment {
65
65
  ${code}
66
66
  return __exports;
67
67
  } catch (cause) {
68
- const template = __env.cache.get(__file);
68
+ const template = ${sync ? "" : "await"} __env.cache.get(__file);
69
69
  throw new __err(__file, template?.source, __pos, cause);
70
70
  }
71
71
  }
@@ -171,14 +171,15 @@ export class Environment {
171
171
  }
172
172
  }
173
173
  function isGlobal(name) {
174
- // @ts-ignore TS doesn't know about globalThis
175
- if (Object.hasOwn(dntShim.dntGlobalThis, name)) {
174
+ if (name == "name")
175
+ return false;
176
+ if (Object.hasOwn(globalThis, name)) {
176
177
  return true;
177
178
  }
178
179
  if (name.includes(".")) {
179
180
  const [obj, prop] = name.split(".");
180
181
  // @ts-ignore TS doesn't know about globalThis
181
- return Object.hasOwn(dntShim.dntGlobalThis[obj], prop);
182
+ return Object.hasOwn(globalThis[obj], prop);
182
183
  }
183
184
  }
184
185
  // deno-lint-ignore no-explicit-any
@@ -1,4 +1,3 @@
1
- import "../_dnt.polyfills.js";
2
1
  class VentoBaseError extends Error {
3
2
  name = this.constructor.name;
4
3
  }
@@ -14,13 +13,6 @@ export class TemplateError extends VentoBaseError {
14
13
  this.position = position;
15
14
  }
16
15
  }
17
- export class TransformError extends VentoBaseError {
18
- position;
19
- constructor(message, position = 0, cause) {
20
- super(message, { cause });
21
- this.position = position;
22
- }
23
- }
24
16
  /** Returns the number and code of the errored line */
25
17
  export function errorLine(source, position) {
26
18
  let line = 1;
@@ -1,17 +1,19 @@
1
- import "../_dnt.polyfills.js";
1
+ import reserved from "./reserved.js";
2
2
  const TEMPLATE_PART = /[`}](?:\\?[^])*?(?:`|\${)/y;
3
3
  const REGEX_LITERAL_START = /(?<=[(=:,?&!]\s*)\//y;
4
- const STOPPING_POINT = /['"`{}[\]/|]/g;
4
+ const STOPPING_POINT = /['"`{}[\]/|]|((?<!\.\??)\b[a-zA-Z_]\w+)/g;
5
5
  /**
6
- * This function iterates over the top-level scope of a JavaScript source code string.
7
- * It yields pairs of the index and the type of each top-level element found.
6
+ * This function iterates over the top-level scope of a JavaScript source code
7
+ * string. It yields pairs of the index and the type of each top-level element
8
+ * found.
8
9
  *
9
10
  * @example `{ foo: { bar: 1 } }` will yield:
10
- * - [0, "{"] for the opening brace
11
- * - [18, "}"] for the closing brace
12
- * - [18, ""] for the end of the string
11
+ * - [0, "{", Set[]] for the first opening brace
12
+ * - [18, "}", Set['foo', 'bar']] for the _second_ closing brace
13
+ * - [18, "", Set['foo', 'bar']] for the end of the string
13
14
  */
14
15
  export default function* iterateTopLevel(source, start = 0) {
16
+ const variables = new Set();
15
17
  let cursor = start;
16
18
  let depth = -1;
17
19
  const brackets = [];
@@ -25,7 +27,13 @@ export default function* iterateTopLevel(source, start = 0) {
25
27
  break parsing;
26
28
  }
27
29
  cursor = match.index;
28
- const [stop] = match;
30
+ const [stop, variable] = match;
31
+ if (variable) {
32
+ cursor += variable.length;
33
+ if (!reserved.has(variable))
34
+ variables.add(variable);
35
+ continue;
36
+ }
29
37
  // Check the type of the stopping point.
30
38
  switch (stop) {
31
39
  case "|": {
@@ -33,7 +41,7 @@ export default function* iterateTopLevel(source, start = 0) {
33
41
  // It's a pipe `|>` in the top-level scope
34
42
  if (depth < 0 && source[cursor] === ">") {
35
43
  cursor++;
36
- yield [cursor - 2, "|>"];
44
+ yield [cursor - 2, "|>", variables];
37
45
  }
38
46
  break;
39
47
  }
@@ -58,7 +66,7 @@ export default function* iterateTopLevel(source, start = 0) {
58
66
  case "{": {
59
67
  // It's an opening brace: yield if it's in the top-level scope.
60
68
  if (depth < 0)
61
- yield [cursor, "{"];
69
+ yield [cursor, "{", variables];
62
70
  cursor++;
63
71
  // Handle `{}`
64
72
  if (source[cursor] == "}")
@@ -71,7 +79,7 @@ export default function* iterateTopLevel(source, start = 0) {
71
79
  case "[": {
72
80
  // It's an opening brace: yield if it's in the top-level scope.
73
81
  if (depth < 0)
74
- yield [cursor, "["];
82
+ yield [cursor, "[", variables];
75
83
  cursor++;
76
84
  // Handle `[]`
77
85
  if (source[cursor] == "]")
@@ -87,7 +95,7 @@ export default function* iterateTopLevel(source, start = 0) {
87
95
  depth--;
88
96
  // Yield if it's in the top-level scope.
89
97
  if (depth < 0)
90
- yield [cursor, "]"];
98
+ yield [cursor, "]", variables];
91
99
  cursor++;
92
100
  break;
93
101
  }
@@ -97,13 +105,13 @@ export default function* iterateTopLevel(source, start = 0) {
97
105
  depth--;
98
106
  // Yield if it's in the top-level scope.
99
107
  if (depth < 0)
100
- yield [cursor, "}"];
108
+ yield [cursor, "}", variables];
101
109
  cursor++;
102
110
  break;
103
111
  }
104
112
  // If it doesn't match, but we're in the top-level scope, yield anyway.
105
113
  if (depth < 0) {
106
- yield [cursor, "}"];
114
+ yield [cursor, "}", variables];
107
115
  cursor++;
108
116
  break;
109
117
  }
@@ -179,5 +187,5 @@ export default function* iterateTopLevel(source, start = 0) {
179
187
  }
180
188
  }
181
189
  }
182
- return [max, ""];
190
+ return [max, "", variables];
183
191
  }
@@ -0,0 +1,63 @@
1
+ const variables = new Set([
2
+ // Words reserved by Vento, used internally. In general, don't use variable
3
+ // names starting with two underscores to be future-proof and avoid clashes.
4
+ "__file",
5
+ "__env",
6
+ "__defaults",
7
+ "__err",
8
+ "__exports",
9
+ "__pos",
10
+ "__tmp",
11
+ // JS reserved words, and some "dangerous" words like `let`, `async`, `of` or
12
+ // `undefined`, which aren't technically reserved but don't name your
13
+ // variables that.
14
+ "async",
15
+ "await",
16
+ "break",
17
+ "case",
18
+ "catch",
19
+ "class",
20
+ "const",
21
+ "continue",
22
+ "debugger",
23
+ "default",
24
+ "delete",
25
+ "do",
26
+ "else",
27
+ "enum",
28
+ "export",
29
+ "extends",
30
+ "false",
31
+ "finally",
32
+ "for",
33
+ "function",
34
+ "if",
35
+ "import",
36
+ "in",
37
+ "instanceof",
38
+ "let",
39
+ "new",
40
+ "null",
41
+ "of",
42
+ "return",
43
+ "super",
44
+ "switch",
45
+ "this",
46
+ "throw",
47
+ "true",
48
+ "try",
49
+ "typeof",
50
+ "undefined",
51
+ "var",
52
+ "void",
53
+ "while",
54
+ "with",
55
+ "yield",
56
+ // Variables that are already defined globally
57
+ ...Object.getOwnPropertyNames(globalThis),
58
+ ]);
59
+ // Remove `name` from the reserved variables
60
+ // because it's widely used in templates
61
+ // and it can cause issues if it's reserved.
62
+ variables.delete("name");
63
+ export default variables;
@@ -1,4 +1,3 @@
1
- import "../_dnt.polyfills.js";
2
1
  import iterateTopLevel from "./js.js";
3
2
  export default function tokenize(source) {
4
3
  const tokens = [];
@@ -0,0 +1,24 @@
1
+ /** @type LanguageFn */
2
+ export default function (hljs) {
3
+ return {
4
+ name: "vento",
5
+ subLanguage: "xml",
6
+ contains: [
7
+ hljs.COMMENT("{{#", "#}}"),
8
+ {
9
+ begin: "{{[-]?",
10
+ end: "[-]?}}",
11
+ subLanguage: "javascript",
12
+ excludeBegin: true,
13
+ excludeEnd: true,
14
+ },
15
+ {
16
+ begin: "^---\n",
17
+ end: "\n---\n",
18
+ subLanguage: "yaml",
19
+ excludeBegin: true,
20
+ excludeEnd: true,
21
+ },
22
+ ],
23
+ };
24
+ }
@@ -1,7 +1,10 @@
1
- import "../_dnt.polyfills.js";
2
1
  import path from "node:path";
3
2
  import fs from "node:fs/promises";
4
3
  import process from "node:process";
4
+ /**
5
+ * Vento file loader for loading templates from the file system.
6
+ * Used by JS runtimes like Node, Deno, and Bun.
7
+ */
5
8
  export class FileLoader {
6
9
  #root;
7
10
  constructor(root = process.cwd()) {
@@ -0,0 +1,24 @@
1
+ import path from "node:path";
2
+ /**
3
+ * Vento loader for loading templates from an in-memory object.
4
+ * Used for testing or in-memory operations.
5
+ */
6
+ export class MemoryLoader {
7
+ files = {};
8
+ constructor(files) {
9
+ this.files = files;
10
+ }
11
+ load(file) {
12
+ if (!(file in this.files)) {
13
+ throw new Error(`File not found: ${file}`);
14
+ }
15
+ const source = this.files[file];
16
+ return Promise.resolve({ source });
17
+ }
18
+ resolve(from, file) {
19
+ if (file.startsWith(".")) {
20
+ return path.join(path.dirname(from), file).replace(/\\/g, "/");
21
+ }
22
+ return path.join("/", file).replace(/\\/g, "/");
23
+ }
24
+ }
package/loaders/url.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Vento URL loader for loading templates from a URL.
3
+ * Used by browser environments.
4
+ */
5
+ export class UrlLoader {
6
+ #root;
7
+ constructor(root) {
8
+ this.#root = root;
9
+ }
10
+ async load(file) {
11
+ const url = new URL(join(this.#root.pathname, file), this.#root);
12
+ const source = await (await fetch(url)).text();
13
+ return { source };
14
+ }
15
+ resolve(from, file) {
16
+ if (file.startsWith(".")) {
17
+ return join("/", dirname(from), file);
18
+ }
19
+ return join("/", file);
20
+ }
21
+ }
22
+ function join(...parts) {
23
+ return parts.join("/").replace(/\/+/g, "/");
24
+ }
25
+ function dirname(path) {
26
+ const lastSlash = path.lastIndexOf("/");
27
+ return lastSlash === -1 ? "." : path.slice(0, lastSlash);
28
+ }
@@ -1,14 +1,19 @@
1
- import { Environment } from "./src/environment.js";
2
- import { FileLoader } from "./src/loader.js";
1
+ import { Environment } from "./core/environment.js";
2
+ import { FileLoader } from "./loaders/file.js";
3
+ import defaultPlugins from "./plugins/mod.js";
3
4
  export default function (options = {}) {
5
+ // Determine the loader based on the includes option
4
6
  const loader = typeof options.includes === "object"
5
7
  ? options.includes
6
8
  : new FileLoader(options.includes);
9
+ // Create a new Environment instance with the provided options
7
10
  const env = new Environment({
8
11
  loader,
9
12
  dataVarname: options.dataVarname || "it",
10
13
  autoescape: options.autoescape ?? false,
11
14
  autoDataVarname: options.autoDataVarname ?? true,
12
15
  });
16
+ // Register the default plugins
17
+ env.use(defaultPlugins());
13
18
  return env;
14
19
  }
package/package.json CHANGED
@@ -1,92 +1,179 @@
1
1
  {
2
2
  "name": "ventojs",
3
- "version": "1.15.0",
3
+ "version": "2.0.0-canary.0",
4
4
  "description": "🌬 A minimal but powerful template engine",
5
- "homepage": "https://vento.js.org/",
6
- "repository": "github:oscarotero/vento",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ventojs/vento.git"
9
+ },
10
+ "keywords": [
11
+ "template engine"
12
+ ],
13
+ "author": "Óscar Otero",
7
14
  "license": "MIT",
8
- "bugs": "https://github.com/oscarotero/vento/issues",
9
- "module": "./esm/mod.js",
15
+ "bugs": {
16
+ "url": "https://github.com/ventojs/vento/issues"
17
+ },
18
+ "homepage": "https://vento.js.org/",
10
19
  "exports": {
11
20
  ".": {
12
- "import": "./esm/mod.js"
13
- },
14
- "./src/environment.js": {
15
- "import": "./esm/src/environment.js"
16
- },
17
- "./src/errors.js": {
18
- "import": "./esm/src/errors.js"
19
- },
20
- "./src/js.js": {
21
- "import": "./esm/src/js.js"
22
- },
23
- "./src/loader.js": {
24
- "import": "./esm/src/loader.js"
25
- },
26
- "./src/tokenizer.js": {
27
- "import": "./esm/src/tokenizer.js"
28
- },
29
- "./src/transformer.js": {
30
- "import": "./esm/src/transformer.js"
31
- },
32
- "./src/url_loader.js": {
33
- "import": "./esm/src/url_loader.js"
21
+ "import": {
22
+ "types": "./types/mod.d.ts",
23
+ "default": "./mod.js"
24
+ }
25
+ },
26
+ "./browser.js": {
27
+ "import": {
28
+ "types": "./types/browser.d.ts",
29
+ "default": "./browser.js"
30
+ }
31
+ },
32
+ "./core/environment.js": {
33
+ "import": {
34
+ "types": "./types/core/environment.d.ts",
35
+ "default": "./core/environment.js"
36
+ }
37
+ },
38
+ "./core/errors.js": {
39
+ "import": {
40
+ "types": "./types/core/errors.d.ts",
41
+ "default": "./core/errors.js"
42
+ }
43
+ },
44
+ "./core/js.js": {
45
+ "import": {
46
+ "types": "./types/core/js.d.ts",
47
+ "default": "./core/js.js"
48
+ }
49
+ },
50
+ "./core/reserved.js": {
51
+ "import": {
52
+ "types": "./types/core/reserved.d.ts",
53
+ "default": "./core/reserved.js"
54
+ }
55
+ },
56
+ "./core/tokenizer.js": {
57
+ "import": {
58
+ "types": "./types/core/tokenizer.d.ts",
59
+ "default": "./core/tokenizer.js"
60
+ }
61
+ },
62
+ "./highlightjs-vento.js": "./highlightjs-vento.js",
63
+ "./loaders/file.js": {
64
+ "import": {
65
+ "types": "./types/loaders/file.d.ts",
66
+ "default": "./loaders/file.js"
67
+ }
68
+ },
69
+ "./loaders/memory.js": {
70
+ "import": {
71
+ "types": "./types/loaders/memory.d.ts",
72
+ "default": "./loaders/memory.js"
73
+ }
74
+ },
75
+ "./loaders/url.js": {
76
+ "import": {
77
+ "types": "./types/loaders/url.d.ts",
78
+ "default": "./loaders/url.js"
79
+ }
80
+ },
81
+ "./mod.js": {
82
+ "import": {
83
+ "types": "./types/mod.d.ts",
84
+ "default": "./mod.js"
85
+ }
34
86
  },
35
87
  "./plugins/auto_trim.js": {
36
- "import": "./esm/plugins/auto_trim.js"
88
+ "import": {
89
+ "types": "./types/plugins/auto_trim.d.ts",
90
+ "default": "./plugins/auto_trim.js"
91
+ }
37
92
  },
38
93
  "./plugins/echo.js": {
39
- "import": "./esm/plugins/echo.js"
94
+ "import": {
95
+ "types": "./types/plugins/echo.d.ts",
96
+ "default": "./plugins/echo.js"
97
+ }
40
98
  },
41
99
  "./plugins/escape.js": {
42
- "import": "./esm/plugins/escape.js"
100
+ "import": {
101
+ "types": "./types/plugins/escape.d.ts",
102
+ "default": "./plugins/escape.js"
103
+ }
43
104
  },
44
105
  "./plugins/export.js": {
45
- "import": "./esm/plugins/export.js"
106
+ "import": {
107
+ "types": "./types/plugins/export.d.ts",
108
+ "default": "./plugins/export.js"
109
+ }
46
110
  },
47
111
  "./plugins/for.js": {
48
- "import": "./esm/plugins/for.js"
112
+ "import": {
113
+ "types": "./types/plugins/for.d.ts",
114
+ "default": "./plugins/for.js"
115
+ }
49
116
  },
50
117
  "./plugins/function.js": {
51
- "import": "./esm/plugins/function.js"
118
+ "import": {
119
+ "types": "./types/plugins/function.d.ts",
120
+ "default": "./plugins/function.js"
121
+ }
52
122
  },
53
123
  "./plugins/if.js": {
54
- "import": "./esm/plugins/if.js"
124
+ "import": {
125
+ "types": "./types/plugins/if.d.ts",
126
+ "default": "./plugins/if.js"
127
+ }
55
128
  },
56
129
  "./plugins/import.js": {
57
- "import": "./esm/plugins/import.js"
130
+ "import": {
131
+ "types": "./types/plugins/import.d.ts",
132
+ "default": "./plugins/import.js"
133
+ }
58
134
  },
59
135
  "./plugins/include.js": {
60
- "import": "./esm/plugins/include.js"
136
+ "import": {
137
+ "types": "./types/plugins/include.d.ts",
138
+ "default": "./plugins/include.js"
139
+ }
61
140
  },
62
141
  "./plugins/js.js": {
63
- "import": "./esm/plugins/js.js"
142
+ "import": {
143
+ "types": "./types/plugins/js.d.ts",
144
+ "default": "./plugins/js.js"
145
+ }
64
146
  },
65
147
  "./plugins/layout.js": {
66
- "import": "./esm/plugins/layout.js"
148
+ "import": {
149
+ "types": "./types/plugins/layout.d.ts",
150
+ "default": "./plugins/layout.js"
151
+ }
152
+ },
153
+ "./plugins/mod.js": {
154
+ "import": {
155
+ "types": "./types/plugins/mod.d.ts",
156
+ "default": "./plugins/mod.js"
157
+ }
67
158
  },
68
159
  "./plugins/set.js": {
69
- "import": "./esm/plugins/set.js"
160
+ "import": {
161
+ "types": "./types/plugins/set.d.ts",
162
+ "default": "./plugins/set.js"
163
+ }
70
164
  },
71
165
  "./plugins/trim.js": {
72
- "import": "./esm/plugins/trim.js"
166
+ "import": {
167
+ "types": "./types/plugins/trim.d.ts",
168
+ "default": "./plugins/trim.js"
169
+ }
73
170
  },
74
171
  "./plugins/unescape.js": {
75
- "import": "./esm/plugins/unescape.js"
76
- }
77
- },
78
- "scripts": {
79
- "test": "node test_runner.js"
80
- },
81
- "dependencies": {
82
- "estree-walker": "3.0.3",
83
- "meriyah": "6.0.5"
84
- },
85
- "devDependencies": {
86
- "@types/node": "^20.9.0",
87
- "picocolors": "^1.0.0",
88
- "@deno/shim-deno": "~0.18.0",
89
- "@types/estree": "1.0.5"
90
- },
91
- "_generatedBy": "dnt@dev"
172
+ "import": {
173
+ "types": "./types/plugins/unescape.d.ts",
174
+ "default": "./plugins/unescape.js"
175
+ }
176
+ },
177
+ "./prism-vento.js": "./prism-vento.js"
178
+ }
92
179
  }
@@ -1,4 +1,3 @@
1
- import "../_dnt.polyfills.js";
2
1
  export const defaultTags = [
3
2
  ">",
4
3
  "#",
@@ -1,4 +1,3 @@
1
- import "../_dnt.polyfills.js";
2
1
  export default function () {
3
2
  return (env) => {
4
3
  env.tags.push(echoTag);