mikel 0.36.0 → 0.38.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.
package/README.md CHANGED
@@ -732,9 +732,9 @@ console.log(result); // --> "Users: John Doe and Alice Smith"
732
732
 
733
733
  ### Subexpressions
734
734
 
735
- > Added in `v0.30.0`.
735
+ > Added in `v0.30.0`. Supported in helpers and partials in `v0.37.0`.
736
736
 
737
- Subexpressions allow you to evaluate a function call inside another function call. They are written using parentheses, and can be used anywhere a normal function argument is allowed. Example:
737
+ Subexpressions allow you to evaluate a function call inside another function call, helpers, or partials. They are written using parentheses, and can be used anywhere a normal function argument is allowed. Example:
738
738
 
739
739
  ```hbs
740
740
  {{=sum (sum 3 4) 3}}
@@ -751,6 +751,18 @@ Result:
751
751
  10
752
752
  ```
753
753
 
754
+ Subexpressions can be used in helpers also:
755
+
756
+ ```hbs
757
+ {{#sayHello name=(concat "John" "Doe")}}{{/sayHello}}
758
+ ```
759
+
760
+ And in partials:
761
+
762
+ ```hbs
763
+ {{>heading text=(concat "Hello" "World")}}
764
+ ```
765
+
754
766
  #### Nested subexpressions
755
767
 
756
768
  Subexpressions can be nested to any depth:
@@ -783,8 +795,7 @@ You can reference variables or paths normally:
783
795
 
784
796
  #### Limitations
785
797
 
786
- - Subexpressions are currently supported **only for functions** (`{{=...}}`).
787
- - Subexpressions inside helper arguments are not yet supported.
798
+ - Subexpressions are currently supported in **functions** (`{{=...}}`), **helpers** (`{{# ...}}`), and **partials** (`{{> ...}}`).
788
799
  - Parentheses must be balanced; malformed expressions will throw an error.
789
800
 
790
801
 
package/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export type MikelHelper = (params: {
12
12
  fn: MikelHelperCallback;
13
13
  }) => string;
14
14
 
15
- export type MikelPartial = {
15
+ export type MikelPartial = string | {
16
16
  body: string;
17
17
  data: Record<string, any>;
18
18
  };
@@ -28,7 +28,7 @@ export type MikelState = Record<string, string>;
28
28
 
29
29
  export type MikelOptions = {
30
30
  helpers?: Record<string, MikelHelper>;
31
- partials?: Record<string, string | MikelPartial>;
31
+ partials?: Record<string, MikelPartial>;
32
32
  functions?: Record<string, MikelFunction>;
33
33
  };
34
34
 
@@ -52,7 +52,7 @@ export type Mikel = {
52
52
  removeHelper(name: string): void;
53
53
  addFunction(name: string, fn: MikelFunction): void;
54
54
  removeFunction(name: string): void;
55
- addPartial(name: string, partial: string | MikelPartial): void;
55
+ addPartial(name: string, partial: MikelPartial): void;
56
56
  removePartial(name: string): void;
57
57
  };
58
58
 
package/index.js CHANGED
@@ -29,8 +29,8 @@ const untokenize = (ts = [], s = "{{", e = "}}") => {
29
29
  // @description tokenize args
30
30
  const tokenizeArgs = (str = "", tokens = [], strings = []) => {
31
31
  let current = "", depth = 0;
32
- // 1. replace strings
33
- str = str.replace(/"([^"\\]|\\.)*"/g, (match) => {
32
+ // 1. replace strings in single/double quotes
33
+ str = str.replace(/("([^"\\]|\\.)*"|'([^'\\]|\\.)*')/g, (match) => {
34
34
  const id = `__STR${strings.length}__`;
35
35
  strings.push(match);
36
36
  return id;
@@ -100,8 +100,9 @@ const parse = (v, data = {}, state = {}, fns = {}) => {
100
100
  if (v.startsWith("(") && v.endsWith(")")) {
101
101
  return evaluateExpression(v.slice(1, -1).trim(), data, state, fns);
102
102
  }
103
- if ((v.startsWith(`"`) && v.endsWith(`"`)) || /^-?\d+\.?\d*$/.test(v) || v === "true" || v === "false" || v === "null") {
104
- return JSON.parse(v);
103
+ if ((v.startsWith(`"`) && v.endsWith(`"`)) || (v.startsWith(`'`) && v.endsWith(`'`)) || /^-?\d+\.?\d*$/.test(v) || v === "true" || v === "false" || v === "null") {
104
+ const normalized = (v.startsWith(`'`) && v.endsWith(`'`)) ? `"${v.slice(1, -1).replace(/"/g, '\\"')}"` : v;
105
+ return JSON.parse(normalized);
105
106
  }
106
107
  return (v || "").startsWith("@") ? get(state, v.slice(1)) : get(data, v || ".");
107
108
  };
@@ -130,7 +131,7 @@ const compile = (ctx, tokens, output, data, state, index = 0, section = "") => {
130
131
  output.push(tokens[i]);
131
132
  }
132
133
  else if (tokens[i].startsWith("#") && typeof ctx.helpers[tokens[i].slice(1).trim().split(" ")[0]] === "function") {
133
- const [t, args, opt] = parseArgs(tokens[i].slice(1), data, state);
134
+ const [t, args, opt] = parseArgs(tokens[i].slice(1), data, state, ctx.functions);
134
135
  const j = i + 1;
135
136
  i = findClosingToken(tokens, j, t);
136
137
  output.push(ctx.helpers[t]({
@@ -173,7 +174,7 @@ const compile = (ctx, tokens, output, data, state, index = 0, section = "") => {
173
174
  }
174
175
  }
175
176
  else if (tokens[i].startsWith(">")) {
176
- const [t, args, opt] = parseArgs(tokens[i].replace(/^>{1,2}/, ""), data, state);
177
+ const [t, args, opt] = parseArgs(tokens[i].replace(/^>{1,2}/, ""), data, state, ctx.functions);
177
178
  const j = i + 1, blockContent = []; // to store partial block content
178
179
  if (tokens[i].startsWith(">>")) {
179
180
  i = compile(ctx, tokens, blockContent, data, state, i + 1, t);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mikel",
3
3
  "description": "Micro templating library with zero dependencies",
4
- "version": "0.36.0",
4
+ "version": "0.38.0",
5
5
  "type": "module",
6
6
  "author": {
7
7
  "name": "Josemi Juanes",