@boopkit/cap-web 0.5.1 → 0.5.3
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 +2 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +22 -0
- package/dist/helpers.js.map +1 -1
- package/dist/view-engine.d.ts +6 -0
- package/dist/view-engine.d.ts.map +1 -1
- package/dist/view-engine.js +10 -1
- package/dist/view-engine.js.map +1 -1
- package/package.json +1 -1
- package/scaffold/reference/web-ui.ref.md +1 -0
- package/skills/boop-web-web-ui-design/SKILL.md +1 -0
package/README.md
CHANGED
|
@@ -43,6 +43,8 @@ app.use(pageRoutes); // order 50 — mount the example pages
|
|
|
43
43
|
|
|
44
44
|
Order numbers are the `preRoutes` phase ordering; other capabilities slot themselves around these (for example, `cap-api`'s error handler mounts after route handlers).
|
|
45
45
|
|
|
46
|
+
`configureViewEngine(app, options?)` takes `viewsDir`, `layoutsDir`, `defaultLayout`, and `compilerOptions` (forwarded to Handlebars). It defaults `preventIndent: true` so a standalone partial's call-site indentation is never applied to interpolated values — which would otherwise corrupt user text inside `<textarea>`/`<pre>`. Override any Handlebars compile option via `compilerOptions`, e.g. `configureViewEngine(app, { compilerOptions: { preventIndent: false } })`.
|
|
47
|
+
|
|
46
48
|
### Skills installed
|
|
47
49
|
|
|
48
50
|
- `design.web-ui-design.skill.md` — teaches agents the semantic-CSS convention and view-rendering patterns used in boop web apps.
|
package/dist/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAiG3D,CAAC"}
|
package/dist/helpers.js
CHANGED
|
@@ -43,6 +43,28 @@ exports.helpers = {
|
|
|
43
43
|
return str;
|
|
44
44
|
return str.slice(0, len) + '…';
|
|
45
45
|
},
|
|
46
|
+
/**
|
|
47
|
+
* URL-encode a value for a query parameter: {{urlencode next}}
|
|
48
|
+
*
|
|
49
|
+
* Handlebars escapes an interpolated value for HTML, which is not the same as
|
|
50
|
+
* escaping it for a URL. `href="?next={{next}}"` with a return path of
|
|
51
|
+
* `/a&b=c` renders `next=/a&b=c`, and the browser reads that as
|
|
52
|
+
* `next=/a` plus a stray `b=c` — the visitor lands on the wrong page. Any
|
|
53
|
+
* template that interpolates a value into a query string needs this helper.
|
|
54
|
+
*
|
|
55
|
+
* This *encodes*; it does not sanitise. Deciding whether a return path is
|
|
56
|
+
* acceptable belongs to whatever gates it (cap-oauth-client's
|
|
57
|
+
* `validateReturnPath`, say) — stripping characters here would put a second,
|
|
58
|
+
* quietly divergent copy of that judgement in the view layer.
|
|
59
|
+
*
|
|
60
|
+
* The result is deliberately not a SafeString: `encodeURIComponent` leaves
|
|
61
|
+
* only alphanumerics and `-_.!~*'()%`, of which Handlebars escapes just the
|
|
62
|
+
* apostrophe, and `'` decodes back to `'` before the browser parses the
|
|
63
|
+
* URL. So the value round-trips, and the attribute keeps its HTML escaping.
|
|
64
|
+
*/
|
|
65
|
+
urlencode: (value) => typeof value === 'string' || typeof value === 'number'
|
|
66
|
+
? encodeURIComponent(String(value))
|
|
67
|
+
: '',
|
|
46
68
|
/** Uppercase: {{upper text}} */
|
|
47
69
|
upper: (str) => (typeof str === 'string' ? str.toUpperCase() : ''),
|
|
48
70
|
/** Lowercase: {{lower text}} */
|
package/dist/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,4DAAoC;AACpC,mCAAgC;AAEhC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE5C,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAa,EAAE,QAAiB;IAC9D,MAAM,GAAG,GAAG,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;IAC/B,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;QACjG,IAAI,CAAC;YACH,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,wBAAwB,GAAG,MAAM,CAAC;QAC3C,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,eAAe,QAAQ,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACU,QAAA,OAAO,GAA4C;IAC9D,uCAAuC;IACvC,EAAE,EAAE,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;IAEvC,mCAAmC;IACnC,IAAI,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,6CAA6C;IAC7C,QAAQ,EAAE,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;QACrC,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;QAClC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;IACjC,CAAC;IAED,gCAAgC;IAChC,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1E,gCAAgC;IAChC,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1E,uGAAuG;IACvG,WAAW,EAAE,CAAC,KAAa,EAAE,OAAa,EAAE,EAAE;QAC5C,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,GAAG,CAAC;QAC9B,MAAM,IAAI,GAA6B;YACrC,KAAK,EAAE,UAAU;YACjB,QAAQ,EAAE,KAAK;SAChB,CAAC;QACF,MAAM,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC;QACvC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,wBAAwB,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,qBAAqB,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,uDAAuD;IACvD,WAAW,EAAE,CAAC,KAAa,EAAE,EAAE;QAC7B,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,KAAK,CAAC;QAChC,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;QAC1B,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,KAAK,KAAK,CAAC;YAAE,MAAM,GAAG,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI;YAAE,MAAM,GAAG,CAAC,CAAC;QACxC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG;YAAE,MAAM,GAAG,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE;YACnC,KAAK,EAAE,SAAS;YAChB,qBAAqB,EAAE,MAAM;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,IAAmB,EAAE,EAAE;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE;YACtC,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,SAAS;SAChB,CAAC,CAAC;IACL,CAAC;IAED,kFAAkF;IAClF,QAAQ,EAAE,UAAU,OAAY;QAC9B,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACxD,OAAO,IAAI,oBAAU,CAAC,UAAU,CAAC,eAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAW,CAAC,CAAC;IAC1E,CAAC;IAED,oGAAoG;IACpG,IAAI,EAAE,CAAC,IAAY,EAAE,KAAa,EAAE,OAAa,EAAE,EAAE;QACnD,MAAM,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC;QACtC,OAAO,IAAI,oBAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,IAAI,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpF,CAAC;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/view-engine.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ export interface ViewEngineOptions {
|
|
|
6
6
|
layoutsDir?: string;
|
|
7
7
|
/** Name of the default layout file (without extension). Defaults to `'main'`. */
|
|
8
8
|
defaultLayout?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Handlebars compiler options, forwarded to express-handlebars (and on to
|
|
11
|
+
* `Handlebars.compile`). Merged over the defaults below, so any key you set
|
|
12
|
+
* here wins — including turning `preventIndent` back off if you need it.
|
|
13
|
+
*/
|
|
14
|
+
compilerOptions?: CompileOptions;
|
|
9
15
|
}
|
|
10
16
|
/**
|
|
11
17
|
* Configure Handlebars as the view engine for an Express app.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-engine.d.ts","sourceRoot":"","sources":["../src/view-engine.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAOvC,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"view-engine.d.ts","sourceRoot":"","sources":["../src/view-engine.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAOvC,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,eAAe,CAAC,EAAE,cAAc,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,iBAAsB,GAAG,IAAI,CA4BvF"}
|
package/dist/view-engine.js
CHANGED
|
@@ -19,12 +19,21 @@ const helpers_1 = require("./helpers");
|
|
|
19
19
|
* string, math, array, etc.) plus custom formatting helpers.
|
|
20
20
|
*/
|
|
21
21
|
function configureViewEngine(app, options = {}) {
|
|
22
|
-
const { viewsDir = path_1.default.join(process.cwd(), 'views'), layoutsDir = path_1.default.join(process.cwd(), 'views', 'layouts'), defaultLayout = 'main', } = options;
|
|
22
|
+
const { viewsDir = path_1.default.join(process.cwd(), 'views'), layoutsDir = path_1.default.join(process.cwd(), 'views', 'layouts'), defaultLayout = 'main', compilerOptions, } = options;
|
|
23
23
|
app.engine('hbs', (0, express_handlebars_1.engine)({
|
|
24
24
|
extname: '.hbs',
|
|
25
25
|
helpers: helpers_1.helpers,
|
|
26
26
|
layoutsDir,
|
|
27
27
|
defaultLayout,
|
|
28
|
+
// Default `preventIndent: true`. Handlebars otherwise indents a standalone
|
|
29
|
+
// partial's output by the indentation of its call site, applied to every
|
|
30
|
+
// line of the rendered output — including interpolated values. That is
|
|
31
|
+
// harmless in collapsible markup, but inside a whitespace-significant
|
|
32
|
+
// element (<textarea>, <pre>) it corrupts the user's text, and once the
|
|
33
|
+
// form posts that value back the corruption is stored. Partial indentation
|
|
34
|
+
// only tidied generated HTML that nothing consumes, so opt every consumer
|
|
35
|
+
// out by default; a caller can override via `compilerOptions`. (boop-rv7)
|
|
36
|
+
compilerOptions: { preventIndent: true, ...compilerOptions },
|
|
28
37
|
}));
|
|
29
38
|
app.set('view engine', 'hbs');
|
|
30
39
|
app.set('views', viewsDir);
|
package/dist/view-engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-engine.js","sourceRoot":"","sources":["../src/view-engine.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"view-engine.js","sourceRoot":"","sources":["../src/view-engine.ts"],"names":[],"mappings":";;;;;AAgCA,kDA4BC;AA5DD,gDAAwB;AACxB,4DAAoC;AACpC,2DAA4C;AAE5C,4EAAmD;AACnD,uCAAoC;AAEpC,iFAAiF;AACjF,IAAA,4BAAiB,EAAC,EAAE,UAAU,EAAE,oBAAU,EAAE,CAAC,CAAC;AAiB9C;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAAC,GAAY,EAAE,UAA6B,EAAE;IAC/E,MAAM,EACJ,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,EAC5C,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,EACzD,aAAa,GAAG,MAAM,EACtB,eAAe,GAChB,GAAG,OAAO,CAAC;IAEZ,GAAG,CAAC,MAAM,CACR,KAAK,EACL,IAAA,2BAAM,EAAC;QACL,OAAO,EAAE,MAAM;QACf,OAAO,EAAP,iBAAO;QACP,UAAU;QACV,aAAa;QACb,2EAA2E;QAC3E,yEAAyE;QACzE,uEAAuE;QACvE,sEAAsE;QACtE,wEAAwE;QACxE,2EAA2E;QAC3E,0EAA0E;QAC1E,0EAA0E;QAC1E,eAAe,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,eAAe,EAAE;KAC7D,CAAC,CACH,CAAC;IACF,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC9B,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
|
package/package.json
CHANGED
|
@@ -35,6 +35,7 @@ Handlebars via `express-handlebars`. Templates in `views/`, layouts in `views/la
|
|
|
35
35
|
|--------|---------|
|
|
36
36
|
| `json` | JSON stringify with formatting |
|
|
37
37
|
| `truncate` | Truncate string with ellipsis |
|
|
38
|
+
| `urlencode` | Percent-encode a value for a query parameter: `href="/signup?next={{urlencode next}}"`. Handlebars escapes for HTML, not for a URL, so a value interpolated straight into a query string is truncated at its first `&`. |
|
|
38
39
|
| `fmt_dollars` | Currency formatting |
|
|
39
40
|
| `fmt_percent` | Percentage formatting |
|
|
40
41
|
| `fmt_date` | Human-readable date (e.g., "March 28, 2026") |
|
|
@@ -96,6 +96,7 @@ When considering whether to reuse existing components:
|
|
|
96
96
|
- `icon` — inline SVG icon from heroicons: `{{icon "user" "24/outline"}}` or with CSS class: `{{icon "check" "24/solid" class="w-5 h-5 text-green-600"}}`. Styles: `24/outline`, `24/solid`, `20/solid`, `16/solid`. Icons are read from `node_modules/heroicons/` and cached.
|
|
97
97
|
- `json` — JSON stringify: `{{json obj}}`
|
|
98
98
|
- `truncate` — truncate string: `{{truncate text 100}}`
|
|
99
|
+
- `urlencode` — percent-encode a value for a query parameter: `<a href="/signup?next={{urlencode next}}">`. Handlebars escapes an interpolated value for HTML, not for a URL, so `?next={{next}}` renders a return path of `/a&b=c` as `next=/a&b=c` and the browser reads `next=/a`. Use this helper for **every** value that lands in a query string; it encodes rather than validates, so whatever gates the value keeps doing that job.
|
|
99
100
|
- `upper` / `lower` — case conversion
|
|
100
101
|
- `eq` — strict equality check (also available from handlebars-helpers)
|
|
101
102
|
|