@sungen/driver-db 3.2.24-beta.6 → 3.2.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sungen/driver-db",
3
- "version": "3.2.24-beta.6",
3
+ "version": "3.2.25",
4
4
  "description": "Sungen DB capability (Data Driver) — the @query annotation, query catalog, declarative DB steps, and the specs/db.ts runtime template. Plugs into @sun-asterisk/sungen via the capability SPI.",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -23,7 +23,7 @@
23
23
  "author": "eqe team (engineer & quality) — Sun Asterisk",
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
- "@sun-asterisk/sungen": "3.2.24-beta.6"
26
+ "@sun-asterisk/sungen": "3.2.25"
27
27
  },
28
28
  "files": [
29
29
  "dist",
@@ -44,6 +44,36 @@ const reNoRowMasked = /see\s+\[~\]\s+no\s+row\s+where\b/i;
44
44
  // `see [Cart badge] contains "count is high"`) claim this priority-60 pattern away from the UI drivers.
45
45
  const reCountMasked = /see\s+\[~\](?:\s+where\s+.+?)?\s+count\s+is\b/i;
46
46
 
47
+ /**
48
+ * `{{var}}` EMBEDDED in a quoted literal — test-data keys/paths only; `{{$...}}`
49
+ * dynamic tokens have no test-data key (a get() call would throw at runtime)
50
+ * and stay literal text. Twin of the core expect-patterns helper — these
51
+ * pattern modules are deliberately self-contained per driver.
52
+ */
53
+ const RE_EMBEDDED_VAR = /\{\{\s*([\w.[\]*-]+?)\s*\}\}/g;
54
+
55
+ /** Escape static literal text for a template-literal context. */
56
+ const escapeForTemplate = (s: string): string =>
57
+ s.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
58
+
59
+ /**
60
+ * Render a quoted literal's BODY as a JS expression. Quoting expresses STRING
61
+ * intent, so embedded/whole vars read through get() (string), unlike the bare
62
+ * `{{var}}` token below which keeps raw() native-type binding for filters.
63
+ */
64
+ function literalExpr(text: string): string {
65
+ const vars = [...text.matchAll(RE_EMBEDDED_VAR)];
66
+ if (vars.length === 0) return JSON.stringify(text);
67
+ if (vars.length === 1 && vars[0][0] === text) return `testData.get(${JSON.stringify(vars[0][1])})`;
68
+ let out = '';
69
+ let last = 0;
70
+ for (const m of vars) {
71
+ out += escapeForTemplate(text.slice(last, m.index!)) + `\${testData.get(${JSON.stringify(m[1])})}`;
72
+ last = m.index! + m[0].length;
73
+ }
74
+ return `\`${out + escapeForTemplate(text.slice(last))}\``;
75
+ }
76
+
47
77
  /** Render a value token (`{{var}}` | "literal" | 'literal' | number) as a JS expression. */
48
78
  function valueExpr(token: string): string {
49
79
  const t = token.trim();
@@ -52,7 +82,7 @@ function valueExpr(token: string): string {
52
82
  // match a stringified number); the expected-column compare stringifies both sides anyway.
53
83
  if (v) return `testData.raw(${JSON.stringify(v[1])})`;
54
84
  const q = t.match(/^["'](.*)["']$/);
55
- if (q) return JSON.stringify(q[1]);
85
+ if (q) return literalExpr(q[1]);
56
86
  if (/^-?\d+(?:\.\d+)?$/.test(t)) return t;
57
87
  return JSON.stringify(t);
58
88
  }