workers-mini-admin 0.1.1 → 0.2.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 +33 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +2 -2
- package/dist/auth.js.map +1 -1
- package/dist/css.d.ts +1 -1
- package/dist/css.d.ts.map +1 -1
- package/dist/css.js +1 -1
- package/dist/css.js.map +1 -1
- package/dist/form.d.ts +60 -11
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +258 -35
- package/dist/form.js.map +1 -1
- package/dist/handler.d.ts +8 -8
- package/dist/handler.d.ts.map +1 -1
- package/dist/html.d.ts +2 -2
- package/dist/html.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/list-script.d.ts +5 -0
- package/dist/list-script.d.ts.map +1 -0
- package/dist/list-script.js +106 -0
- package/dist/list-script.js.map +1 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -66,6 +66,37 @@ export default {
|
|
|
66
66
|
};
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
### Declarative fields
|
|
70
|
+
|
|
71
|
+
Supported field types: `text`, `url`, `password`, `number`, `textarea`, `select`, `radio`, `checkbox`, `fieldset`, `row`, `list`, and trusted `html`.
|
|
72
|
+
|
|
73
|
+
**Hints:** `hint` is escaped plain text. Use `hintHtml` for trusted HTML (e.g. `<code>`). If both are set, `hintHtml` wins. For arbitrary in-form markup, use `{ type: 'html', html: '…' }`.
|
|
74
|
+
|
|
75
|
+
**Scalar attrs:** text/url/password support `pattern`, `maxlength`, `minlength`, `autocomplete`, and `spellcheck` (text only). Textareas support `maxlength`, `minlength`, `autocomplete`, and `spellcheck`. Numbers keep `min` / `max` / `step` and also accept `autocomplete`.
|
|
76
|
+
|
|
77
|
+
**Compact rows:** `{ type: 'row', fields: […] }` lays short fields side-by-side (reuses `.row` CSS).
|
|
78
|
+
|
|
79
|
+
**Repeatable lists:**
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
{
|
|
83
|
+
type: 'list',
|
|
84
|
+
name: 'feeds',
|
|
85
|
+
legend: 'Feed sources',
|
|
86
|
+
minItems: 1,
|
|
87
|
+
maxItems: 8,
|
|
88
|
+
itemFields: [
|
|
89
|
+
{ type: 'text', name: 'label', label: 'Label', required: true },
|
|
90
|
+
{ type: 'url', name: 'url', label: 'URL', required: true },
|
|
91
|
+
],
|
|
92
|
+
values: [{ label: 'Example', url: 'https://example.com/feed.xml' }],
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Form control names are `listName_index_fieldName` (e.g. `feeds_0_url`). `parseAdminForm` returns `values.feeds` as an array of row objects. A small add/remove script is injected automatically when the form contains a list.
|
|
97
|
+
|
|
98
|
+
Stay on Fields for login + KV settings + repeatable lists. Use `body` / `routes` / `extraCss` for live previews and other client-heavy UIs.
|
|
99
|
+
|
|
69
100
|
### Mount path / reverse proxy
|
|
70
101
|
|
|
71
102
|
`basePath` defaults to `"/admin"`. Use `""` or `"/"` when the admin is the site root (e.g. `admin.example.com`):
|
|
@@ -153,8 +184,8 @@ You can still wire auth and chrome yourself (`isAuthenticated`, `loginResponse`,
|
|
|
153
184
|
| Export | Role |
|
|
154
185
|
| ------------------------------------ | ---------------------------------------------------- |
|
|
155
186
|
| `createAdmin` | Auth router + form page with configurable `basePath` |
|
|
156
|
-
| `adminForm` / `Field` | Declarative form HTML
|
|
157
|
-
| `formText` / `parseAdminForm` | FormData helpers
|
|
187
|
+
| `adminForm` / `Field` | Declarative form HTML (incl. `list`, `row`) |
|
|
188
|
+
| `formText` / `parseAdminForm` | FormData helpers (lists → row arrays) |
|
|
158
189
|
| `escapeHtml` | Safe HTML text interpolation |
|
|
159
190
|
| `hexSha256` / `timingSafeEqual` | Cookie token helpers |
|
|
160
191
|
| `isAuthenticated` | Cookie or `Authorization: Bearer` check |
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAS7D;AAED,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,MAA4B,EACxC,IAAI,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAS7D;AAED,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,MAA4B,EACxC,IAAI,SAAM,GACT,MAAM,CAGR;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC,OAAO,CAAC,CAkBlB;AAMD,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoBpB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,QAAQ,CAoBX"}
|
package/dist/auth.js
CHANGED
|
@@ -19,7 +19,7 @@ export function timingSafeEqual(a, b) {
|
|
|
19
19
|
export const DEFAULT_COOKIE_NAME = 'admin_auth';
|
|
20
20
|
export function adminAuthCookie(token, isSecure, maxAge, cookieName = DEFAULT_COOKIE_NAME, path = '/') {
|
|
21
21
|
const secureFlag = isSecure ? 'Secure; ' : '';
|
|
22
|
-
return `${cookieName}=${token}; HttpOnly; ${secureFlag}SameSite=Lax; Max-Age=${maxAge}; Path=${path}`;
|
|
22
|
+
return `${cookieName}=${token}; HttpOnly; ${secureFlag}SameSite=Lax; Max-Age=${String(maxAge)}; Path=${path}`;
|
|
23
23
|
}
|
|
24
24
|
export async function isAuthenticated(request, secret, cookieName = DEFAULT_COOKIE_NAME) {
|
|
25
25
|
const auth = request.headers.get('Authorization');
|
|
@@ -29,7 +29,7 @@ export async function isAuthenticated(request, secret, cookieName = DEFAULT_COOK
|
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
const cookie = request.headers.get('Cookie')
|
|
32
|
+
const cookie = request.headers.get('Cookie') ?? '';
|
|
33
33
|
const match = new RegExp(String.raw `(?:^|;\s*)${escapeRegExp(cookieName)}=([^;]+)`).exec(cookie);
|
|
34
34
|
if (!match) {
|
|
35
35
|
return false;
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE7E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAc;IAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CACvC,SAAS,EACT,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CACjC,CAAC;IACF,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;SAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9C,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAEhD,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,QAAiB,EACjB,MAAc,EACd,aAAqB,mBAAmB,EACxC,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/css.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** Generated by scripts/embed-css.mjs — edit src/shared.css instead. */
|
|
2
|
-
export declare const SHARED_CSS = "* {\n box-sizing: border-box;\n}\n\n.admin-body {\n font-family:\n system-ui,\n -apple-system,\n 'Segoe UI',\n sans-serif;\n margin: 0;\n line-height: 1.45;\n color: #1a1a1a;\n background: #e4e6eb;\n min-height: 100vh;\n text-size-adjust: 100%;\n}\n\n.page-shell {\n max-width: 40rem;\n margin: 0 auto;\n padding: 0.75rem 1rem 2rem;\n}\n\n@media (width >= 640px) {\n .page-shell {\n padding: 1rem 1.25rem 2rem;\n }\n}\n\n.page-header {\n margin-bottom: 1rem;\n}\n\n.page-header h1 {\n font-size: clamp(1.25rem, 4vw, 1.5rem);\n margin: 0 0 0.5rem;\n}\n\n.panel-card {\n background: #fff;\n border-radius: 12px;\n padding: 1rem 1rem 1.25rem;\n box-shadow: 0 1px 3px rgb(0 0 0 / 7%);\n margin-bottom: 1rem;\n}\n\nlabel {\n display: block;\n margin-top: 1rem;\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.mode-row label {\n margin-top: 0;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.row {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.row label {\n flex: 1;\n min-width: min(100%, 5.5rem);\n margin-top: 0;\n}\n\n@media (width <= 480px) {\n .row {\n flex-direction: column;\n }\n\n .row label {\n min-width: 100%;\n }\n}\n\nlabel:first-of-type,\n.panel-card > label:first-child {\n margin-top: 0;\n}\n\ninput[type='text'],\ninput[type='password'],\ninput[type='url'],\ninput[type='number'],\ntextarea,\nselect {\n width: 100%;\n padding: 0.55rem 0.65rem;\n font: inherit;\n border: 1px solid #c5c9d0;\n border-radius: 8px;\n background: #fafbfc;\n}\n\ntextarea {\n min-height: 5.5rem;\n resize: vertical;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n outline: 2px solid #90cdf4;\n outline-offset: 1px;\n border-color: #3182ce;\n}\n\n.hint {\n font-size: 0.82rem;\n color: #4a5568;\n font-weight: normal;\n}\n\n.actions {\n margin-top: 1.5rem;\n display: flex;\n gap: 0.75rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.btn-primary {\n padding: 0.6rem 1.1rem;\n border: none;\n border-radius: 8px;\n background: #2d3748;\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n min-height: 44px;\n}\n\n.btn-primary:active {\n opacity: 0.94;\n}\n\n.btn-ghost {\n padding: 0.5rem 0.75rem;\n border: none;\n background: transparent;\n color: #4a5568;\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n min-height: 44px;\n}\n\n.ok {\n color: #276749;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.flash-err {\n color: #c53030;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.warn {\n color: #c05600;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.err {\n color: #b00;\n margin-bottom: 1rem;\n font-size: 0.95rem;\n}\n\n.btn-secondary {\n padding: 0.5rem 0.85rem;\n border: 1px solid #cbd5e0;\n border-radius: 8px;\n background: #f7fafc;\n font: inherit;\n cursor: pointer;\n min-height: 44px;\n font-size: 0.9rem;\n}\n\n.btn-secondary:active {\n background: #edf2f7;\n}\n\nfieldset {\n border: 1px solid #d8dee6;\n padding: 0.75rem 1rem;\n margin-top: 1rem;\n border-radius: 8px;\n background: #fafbfc;\n}\n\nlegend {\n padding: 0 0.35rem;\n font-weight: 600;\n}\n\n.mode-row {\n display: flex;\n flex-wrap: wrap;\n gap: 0.75rem 1.25rem;\n margin-top: 0.5rem;\n}\n\n.mode-row input {\n width: auto;\n margin: 0;\n}\n\n.checkbox-row {\n margin-top: 1rem;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.checkbox-row input {\n width: auto;\n margin: 0;\n}\n\n.login-shell {\n max-width: 24rem;\n margin: 0 auto;\n padding: 1.25rem;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.login-shell .panel-card {\n width: 100%;\n margin: 0;\n}\n\n.login-shell button {\n width: 100%;\n}";
|
|
2
|
+
export declare const SHARED_CSS = "* {\n box-sizing: border-box;\n}\n\n.admin-body {\n font-family:\n system-ui,\n -apple-system,\n 'Segoe UI',\n sans-serif;\n margin: 0;\n line-height: 1.45;\n color: #1a1a1a;\n background: #e4e6eb;\n min-height: 100vh;\n text-size-adjust: 100%;\n}\n\n.page-shell {\n max-width: 40rem;\n margin: 0 auto;\n padding: 0.75rem 1rem 2rem;\n}\n\n@media (width >= 640px) {\n .page-shell {\n padding: 1rem 1.25rem 2rem;\n }\n}\n\n.page-header {\n margin-bottom: 1rem;\n}\n\n.page-header h1 {\n font-size: clamp(1.25rem, 4vw, 1.5rem);\n margin: 0 0 0.5rem;\n}\n\n.panel-card {\n background: #fff;\n border-radius: 12px;\n padding: 1rem 1rem 1.25rem;\n box-shadow: 0 1px 3px rgb(0 0 0 / 7%);\n margin-bottom: 1rem;\n}\n\nlabel {\n display: block;\n margin-top: 1rem;\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.mode-row label {\n margin-top: 0;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.row {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.row label {\n flex: 1;\n min-width: min(100%, 5.5rem);\n margin-top: 0;\n}\n\n@media (width <= 480px) {\n .row {\n flex-direction: column;\n }\n\n .row label {\n min-width: 100%;\n }\n}\n\nlabel:first-of-type,\n.panel-card > label:first-child {\n margin-top: 0;\n}\n\ninput[type='text'],\ninput[type='password'],\ninput[type='url'],\ninput[type='number'],\ntextarea,\nselect {\n width: 100%;\n padding: 0.55rem 0.65rem;\n font: inherit;\n border: 1px solid #c5c9d0;\n border-radius: 8px;\n background: #fafbfc;\n}\n\ntextarea {\n min-height: 5.5rem;\n resize: vertical;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n outline: 2px solid #90cdf4;\n outline-offset: 1px;\n border-color: #3182ce;\n}\n\n.hint {\n font-size: 0.82rem;\n color: #4a5568;\n font-weight: normal;\n}\n\n.actions {\n margin-top: 1.5rem;\n display: flex;\n gap: 0.75rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.btn-primary {\n padding: 0.6rem 1.1rem;\n border: none;\n border-radius: 8px;\n background: #2d3748;\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n min-height: 44px;\n}\n\n.btn-primary:active {\n opacity: 0.94;\n}\n\n.btn-ghost {\n padding: 0.5rem 0.75rem;\n border: none;\n background: transparent;\n color: #4a5568;\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n min-height: 44px;\n}\n\n.ok {\n color: #276749;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.flash-err {\n color: #c53030;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.warn {\n color: #c05600;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.err {\n color: #b00;\n margin-bottom: 1rem;\n font-size: 0.95rem;\n}\n\n.btn-secondary {\n padding: 0.5rem 0.85rem;\n border: 1px solid #cbd5e0;\n border-radius: 8px;\n background: #f7fafc;\n font: inherit;\n cursor: pointer;\n min-height: 44px;\n font-size: 0.9rem;\n}\n\n.btn-secondary:active {\n background: #edf2f7;\n}\n\nfieldset {\n border: 1px solid #d8dee6;\n padding: 0.75rem 1rem;\n margin-top: 1rem;\n border-radius: 8px;\n background: #fafbfc;\n}\n\nlegend {\n padding: 0 0.35rem;\n font-weight: 600;\n}\n\n.mode-row {\n display: flex;\n flex-wrap: wrap;\n gap: 0.75rem 1.25rem;\n margin-top: 0.5rem;\n}\n\n.mode-row input {\n width: auto;\n margin: 0;\n}\n\n.checkbox-row {\n margin-top: 1rem;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.checkbox-row input {\n width: auto;\n margin: 0;\n}\n\n.list-field {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.list-field > legend {\n margin-bottom: 0.25rem;\n}\n\n.list-item {\n margin-top: 0;\n}\n\n.list-item > label:first-of-type,\n.list-item > .row:first-child label {\n margin-top: 0;\n}\n\n.list-item-actions {\n margin-top: 0.75rem;\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n.list-add {\n align-self: flex-start;\n}\n\n.list-add:disabled,\n.list-item-remove:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.login-shell {\n max-width: 24rem;\n margin: 0 auto;\n padding: 1.25rem;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.login-shell .panel-card {\n width: 100%;\n margin: 0;\n}\n\n.login-shell button {\n width: 100%;\n}";
|
|
3
3
|
//# sourceMappingURL=css.d.ts.map
|
package/dist/css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,UAAU,svIAAsvI,CAAC"}
|
package/dist/css.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** Generated by scripts/embed-css.mjs — edit src/shared.css instead. */
|
|
2
|
-
export const SHARED_CSS = "* {\n box-sizing: border-box;\n}\n\n.admin-body {\n font-family:\n system-ui,\n -apple-system,\n 'Segoe UI',\n sans-serif;\n margin: 0;\n line-height: 1.45;\n color: #1a1a1a;\n background: #e4e6eb;\n min-height: 100vh;\n text-size-adjust: 100%;\n}\n\n.page-shell {\n max-width: 40rem;\n margin: 0 auto;\n padding: 0.75rem 1rem 2rem;\n}\n\n@media (width >= 640px) {\n .page-shell {\n padding: 1rem 1.25rem 2rem;\n }\n}\n\n.page-header {\n margin-bottom: 1rem;\n}\n\n.page-header h1 {\n font-size: clamp(1.25rem, 4vw, 1.5rem);\n margin: 0 0 0.5rem;\n}\n\n.panel-card {\n background: #fff;\n border-radius: 12px;\n padding: 1rem 1rem 1.25rem;\n box-shadow: 0 1px 3px rgb(0 0 0 / 7%);\n margin-bottom: 1rem;\n}\n\nlabel {\n display: block;\n margin-top: 1rem;\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.mode-row label {\n margin-top: 0;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.row {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.row label {\n flex: 1;\n min-width: min(100%, 5.5rem);\n margin-top: 0;\n}\n\n@media (width <= 480px) {\n .row {\n flex-direction: column;\n }\n\n .row label {\n min-width: 100%;\n }\n}\n\nlabel:first-of-type,\n.panel-card > label:first-child {\n margin-top: 0;\n}\n\ninput[type='text'],\ninput[type='password'],\ninput[type='url'],\ninput[type='number'],\ntextarea,\nselect {\n width: 100%;\n padding: 0.55rem 0.65rem;\n font: inherit;\n border: 1px solid #c5c9d0;\n border-radius: 8px;\n background: #fafbfc;\n}\n\ntextarea {\n min-height: 5.5rem;\n resize: vertical;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n outline: 2px solid #90cdf4;\n outline-offset: 1px;\n border-color: #3182ce;\n}\n\n.hint {\n font-size: 0.82rem;\n color: #4a5568;\n font-weight: normal;\n}\n\n.actions {\n margin-top: 1.5rem;\n display: flex;\n gap: 0.75rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.btn-primary {\n padding: 0.6rem 1.1rem;\n border: none;\n border-radius: 8px;\n background: #2d3748;\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n min-height: 44px;\n}\n\n.btn-primary:active {\n opacity: 0.94;\n}\n\n.btn-ghost {\n padding: 0.5rem 0.75rem;\n border: none;\n background: transparent;\n color: #4a5568;\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n min-height: 44px;\n}\n\n.ok {\n color: #276749;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.flash-err {\n color: #c53030;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.warn {\n color: #c05600;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.err {\n color: #b00;\n margin-bottom: 1rem;\n font-size: 0.95rem;\n}\n\n.btn-secondary {\n padding: 0.5rem 0.85rem;\n border: 1px solid #cbd5e0;\n border-radius: 8px;\n background: #f7fafc;\n font: inherit;\n cursor: pointer;\n min-height: 44px;\n font-size: 0.9rem;\n}\n\n.btn-secondary:active {\n background: #edf2f7;\n}\n\nfieldset {\n border: 1px solid #d8dee6;\n padding: 0.75rem 1rem;\n margin-top: 1rem;\n border-radius: 8px;\n background: #fafbfc;\n}\n\nlegend {\n padding: 0 0.35rem;\n font-weight: 600;\n}\n\n.mode-row {\n display: flex;\n flex-wrap: wrap;\n gap: 0.75rem 1.25rem;\n margin-top: 0.5rem;\n}\n\n.mode-row input {\n width: auto;\n margin: 0;\n}\n\n.checkbox-row {\n margin-top: 1rem;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.checkbox-row input {\n width: auto;\n margin: 0;\n}\n\n.login-shell {\n max-width: 24rem;\n margin: 0 auto;\n padding: 1.25rem;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.login-shell .panel-card {\n width: 100%;\n margin: 0;\n}\n\n.login-shell button {\n width: 100%;\n}";
|
|
2
|
+
export const SHARED_CSS = "* {\n box-sizing: border-box;\n}\n\n.admin-body {\n font-family:\n system-ui,\n -apple-system,\n 'Segoe UI',\n sans-serif;\n margin: 0;\n line-height: 1.45;\n color: #1a1a1a;\n background: #e4e6eb;\n min-height: 100vh;\n text-size-adjust: 100%;\n}\n\n.page-shell {\n max-width: 40rem;\n margin: 0 auto;\n padding: 0.75rem 1rem 2rem;\n}\n\n@media (width >= 640px) {\n .page-shell {\n padding: 1rem 1.25rem 2rem;\n }\n}\n\n.page-header {\n margin-bottom: 1rem;\n}\n\n.page-header h1 {\n font-size: clamp(1.25rem, 4vw, 1.5rem);\n margin: 0 0 0.5rem;\n}\n\n.panel-card {\n background: #fff;\n border-radius: 12px;\n padding: 1rem 1rem 1.25rem;\n box-shadow: 0 1px 3px rgb(0 0 0 / 7%);\n margin-bottom: 1rem;\n}\n\nlabel {\n display: block;\n margin-top: 1rem;\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.mode-row label {\n margin-top: 0;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.row {\n display: flex;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.row label {\n flex: 1;\n min-width: min(100%, 5.5rem);\n margin-top: 0;\n}\n\n@media (width <= 480px) {\n .row {\n flex-direction: column;\n }\n\n .row label {\n min-width: 100%;\n }\n}\n\nlabel:first-of-type,\n.panel-card > label:first-child {\n margin-top: 0;\n}\n\ninput[type='text'],\ninput[type='password'],\ninput[type='url'],\ninput[type='number'],\ntextarea,\nselect {\n width: 100%;\n padding: 0.55rem 0.65rem;\n font: inherit;\n border: 1px solid #c5c9d0;\n border-radius: 8px;\n background: #fafbfc;\n}\n\ntextarea {\n min-height: 5.5rem;\n resize: vertical;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n outline: 2px solid #90cdf4;\n outline-offset: 1px;\n border-color: #3182ce;\n}\n\n.hint {\n font-size: 0.82rem;\n color: #4a5568;\n font-weight: normal;\n}\n\n.actions {\n margin-top: 1.5rem;\n display: flex;\n gap: 0.75rem;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.btn-primary {\n padding: 0.6rem 1.1rem;\n border: none;\n border-radius: 8px;\n background: #2d3748;\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n min-height: 44px;\n}\n\n.btn-primary:active {\n opacity: 0.94;\n}\n\n.btn-ghost {\n padding: 0.5rem 0.75rem;\n border: none;\n background: transparent;\n color: #4a5568;\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n min-height: 44px;\n}\n\n.ok {\n color: #276749;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.flash-err {\n color: #c53030;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.warn {\n color: #c05600;\n margin: 0 0 0.75rem;\n font-weight: 600;\n}\n\n.err {\n color: #b00;\n margin-bottom: 1rem;\n font-size: 0.95rem;\n}\n\n.btn-secondary {\n padding: 0.5rem 0.85rem;\n border: 1px solid #cbd5e0;\n border-radius: 8px;\n background: #f7fafc;\n font: inherit;\n cursor: pointer;\n min-height: 44px;\n font-size: 0.9rem;\n}\n\n.btn-secondary:active {\n background: #edf2f7;\n}\n\nfieldset {\n border: 1px solid #d8dee6;\n padding: 0.75rem 1rem;\n margin-top: 1rem;\n border-radius: 8px;\n background: #fafbfc;\n}\n\nlegend {\n padding: 0 0.35rem;\n font-weight: 600;\n}\n\n.mode-row {\n display: flex;\n flex-wrap: wrap;\n gap: 0.75rem 1.25rem;\n margin-top: 0.5rem;\n}\n\n.mode-row input {\n width: auto;\n margin: 0;\n}\n\n.checkbox-row {\n margin-top: 1rem;\n font-weight: normal;\n display: flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.checkbox-row input {\n width: auto;\n margin: 0;\n}\n\n.list-field {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.list-field > legend {\n margin-bottom: 0.25rem;\n}\n\n.list-item {\n margin-top: 0;\n}\n\n.list-item > label:first-of-type,\n.list-item > .row:first-child label {\n margin-top: 0;\n}\n\n.list-item-actions {\n margin-top: 0.75rem;\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n.list-add {\n align-self: flex-start;\n}\n\n.list-add:disabled,\n.list-item-remove:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.login-shell {\n max-width: 24rem;\n margin: 0 auto;\n padding: 1.25rem;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.login-shell .panel-card {\n width: 100%;\n margin: 0;\n}\n\n.login-shell button {\n width: 100%;\n}";
|
|
3
3
|
//# sourceMappingURL=css.js.map
|
package/dist/css.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css.js","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"css.js","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,mvIAAmvI,CAAC"}
|
package/dist/form.d.ts
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface FieldOption {
|
|
2
2
|
value: string;
|
|
3
3
|
label: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
4
|
+
}
|
|
5
|
+
interface FieldBase {
|
|
6
6
|
label?: string;
|
|
7
|
+
/**
|
|
8
|
+
Plain-text hint (escaped). Ignored when `hintHtml` is set.
|
|
9
|
+
*/
|
|
7
10
|
hint?: string;
|
|
11
|
+
/**
|
|
12
|
+
Trusted HTML hint. Prefer this over `hint` when both are set.
|
|
13
|
+
*/
|
|
14
|
+
hintHtml?: string;
|
|
8
15
|
required?: boolean;
|
|
9
16
|
placeholder?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
17
|
+
}
|
|
18
|
+
interface TextInputAttributes {
|
|
19
|
+
pattern?: string;
|
|
20
|
+
maxlength?: number;
|
|
21
|
+
minlength?: number;
|
|
22
|
+
autocomplete?: string;
|
|
23
|
+
spellcheck?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export type TextField = FieldBase & TextInputAttributes & {
|
|
12
26
|
type: 'text' | 'url' | 'password';
|
|
13
27
|
name: string;
|
|
14
28
|
value?: string;
|
|
@@ -20,11 +34,16 @@ export type NumberField = FieldBase & {
|
|
|
20
34
|
min?: number;
|
|
21
35
|
max?: number;
|
|
22
36
|
step?: number | string;
|
|
37
|
+
autocomplete?: string;
|
|
23
38
|
};
|
|
24
39
|
export type TextareaField = FieldBase & {
|
|
25
40
|
type: 'textarea';
|
|
26
41
|
name: string;
|
|
27
42
|
value?: string;
|
|
43
|
+
maxlength?: number;
|
|
44
|
+
minlength?: number;
|
|
45
|
+
autocomplete?: string;
|
|
46
|
+
spellcheck?: boolean;
|
|
28
47
|
};
|
|
29
48
|
export type SelectField = FieldBase & {
|
|
30
49
|
type: 'select';
|
|
@@ -47,17 +66,46 @@ export type CheckboxField = FieldBase & {
|
|
|
47
66
|
checked?: boolean;
|
|
48
67
|
value?: string;
|
|
49
68
|
};
|
|
50
|
-
export
|
|
69
|
+
export interface FieldsetField {
|
|
51
70
|
type: 'fieldset';
|
|
52
71
|
legend: string;
|
|
53
72
|
hint?: string;
|
|
73
|
+
hintHtml?: string;
|
|
54
74
|
fields: Field[];
|
|
55
|
-
}
|
|
56
|
-
export
|
|
75
|
+
}
|
|
76
|
+
export interface HtmlField {
|
|
57
77
|
type: 'html';
|
|
58
78
|
html: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
Side-by-side layout for short related fields (e.g. day · month · year).
|
|
82
|
+
*/
|
|
83
|
+
export interface RowField {
|
|
84
|
+
type: 'row';
|
|
85
|
+
fields: Field[];
|
|
86
|
+
}
|
|
87
|
+
export type ListItemValue = Record<string, string | boolean>;
|
|
88
|
+
/**
|
|
89
|
+
Repeatable group of fields. Form names use `listName_index_fieldName`.
|
|
90
|
+
*/
|
|
91
|
+
export interface ListField {
|
|
92
|
+
type: 'list';
|
|
93
|
+
name: string;
|
|
94
|
+
legend?: string;
|
|
95
|
+
hint?: string;
|
|
96
|
+
hintHtml?: string;
|
|
97
|
+
/**
|
|
98
|
+
Template fields for each row (scalars, row, fieldset, html — not nested list).
|
|
99
|
+
*/
|
|
100
|
+
itemFields: Field[];
|
|
101
|
+
values: ListItemValue[];
|
|
102
|
+
minItems?: number;
|
|
103
|
+
maxItems?: number;
|
|
104
|
+
addLabel?: string;
|
|
105
|
+
removeLabel?: string;
|
|
106
|
+
}
|
|
107
|
+
export type Field = TextField | NumberField | TextareaField | SelectField | RadioField | CheckboxField | FieldsetField | HtmlField | RowField | ListField;
|
|
108
|
+
export type ParsedAdminForm = Record<string, string | boolean | ListItemValue[]>;
|
|
61
109
|
export declare function adminForm(options: {
|
|
62
110
|
action: string;
|
|
63
111
|
fields: Field[];
|
|
@@ -68,7 +116,8 @@ export declare function adminForm(options: {
|
|
|
68
116
|
export declare function formText(form: FormData, name: string): string;
|
|
69
117
|
/**
|
|
70
118
|
Named scalar values from a form matching the field schema (checkbox → boolean).
|
|
119
|
+
List fields become arrays of row objects keyed by `list.name`.
|
|
71
120
|
*/
|
|
72
|
-
export declare function parseAdminForm(form: FormData, fields: Field[]):
|
|
121
|
+
export declare function parseAdminForm(form: FormData, fields: Field[]): ParsedAdminForm;
|
|
73
122
|
export {};
|
|
74
123
|
//# sourceMappingURL=form.d.ts.map
|
package/dist/form.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"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"}
|
package/dist/form.js
CHANGED
|
@@ -1,13 +1,106 @@
|
|
|
1
1
|
import { escapeHtml } from './escape.js';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { LIST_FIELD_SCRIPT } from './list-script.js';
|
|
3
|
+
function optionalAttribute(name, value) {
|
|
4
|
+
return value === undefined || value === ''
|
|
5
|
+
? ''
|
|
6
|
+
: ` ${name}="${escapeHtml(String(value))}"`;
|
|
4
7
|
}
|
|
5
|
-
function
|
|
6
|
-
|
|
8
|
+
function spellcheckAttribute(value) {
|
|
9
|
+
if (value === undefined) {
|
|
10
|
+
return '';
|
|
11
|
+
}
|
|
12
|
+
const spellcheckValue = value ? 'true' : 'false';
|
|
13
|
+
return ` spellcheck="${spellcheckValue}"`;
|
|
14
|
+
}
|
|
15
|
+
function hintMarkup(hint, hintHtml, isBlock = false) {
|
|
16
|
+
if (hintHtml) {
|
|
17
|
+
return isBlock
|
|
18
|
+
? `<p class="hint">${hintHtml}</p>`
|
|
19
|
+
: ` <span class="hint">${hintHtml}</span>`;
|
|
20
|
+
}
|
|
21
|
+
if (hint) {
|
|
22
|
+
return isBlock
|
|
23
|
+
? `<p class="hint">${escapeHtml(hint)}</p>`
|
|
24
|
+
: ` <span class="hint">${escapeHtml(hint)}</span>`;
|
|
25
|
+
}
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
function optionalHint(hint, hintHtml) {
|
|
29
|
+
return hintMarkup(hint, hintHtml, false);
|
|
30
|
+
}
|
|
31
|
+
function labelHtml(id, label, hint, hintHtml) {
|
|
32
|
+
return `<label for="${escapeHtml(id)}">${escapeHtml(label)}${optionalHint(hint, hintHtml)}</label>`;
|
|
7
33
|
}
|
|
8
34
|
function requiredAttribute(required) {
|
|
9
35
|
return required ? ' required' : '';
|
|
10
36
|
}
|
|
37
|
+
function withNamePrefix(field, prefix) {
|
|
38
|
+
if (field.type === 'html') {
|
|
39
|
+
return field;
|
|
40
|
+
}
|
|
41
|
+
if (field.type === 'fieldset') {
|
|
42
|
+
return {
|
|
43
|
+
...field,
|
|
44
|
+
fields: field.fields.map((child) => withNamePrefix(child, prefix)),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (field.type === 'row') {
|
|
48
|
+
return {
|
|
49
|
+
...field,
|
|
50
|
+
fields: field.fields.map((child) => withNamePrefix(child, prefix)),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (field.type === 'list') {
|
|
54
|
+
return field;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
...field,
|
|
58
|
+
name: `${prefix}${field.name}`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function applyListItemValues(field, values) {
|
|
62
|
+
if (field.type === 'html') {
|
|
63
|
+
return field;
|
|
64
|
+
}
|
|
65
|
+
if (field.type === 'fieldset' || field.type === 'row') {
|
|
66
|
+
return {
|
|
67
|
+
...field,
|
|
68
|
+
fields: field.fields.map((child) => applyListItemValues(child, values)),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (field.type === 'list') {
|
|
72
|
+
return field;
|
|
73
|
+
}
|
|
74
|
+
if (field.type === 'checkbox') {
|
|
75
|
+
const raw = values[field.name];
|
|
76
|
+
const expected = field.value ?? 'on';
|
|
77
|
+
return {
|
|
78
|
+
...field,
|
|
79
|
+
checked: raw === true ||
|
|
80
|
+
(typeof raw === 'string' && ['true', expected].includes(raw)),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (isValueField(field)) {
|
|
84
|
+
const raw = values[field.name];
|
|
85
|
+
return {
|
|
86
|
+
...field,
|
|
87
|
+
value: typeof raw === 'string' || typeof raw === 'number' ? raw : '',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return field;
|
|
91
|
+
}
|
|
92
|
+
function emptyItemValues(itemFields) {
|
|
93
|
+
const values = {};
|
|
94
|
+
walkScalarFields(itemFields, (field) => {
|
|
95
|
+
if (field.type === 'checkbox') {
|
|
96
|
+
values[field.name] = false;
|
|
97
|
+
}
|
|
98
|
+
else if (isValueField(field)) {
|
|
99
|
+
values[field.name] = '';
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return values;
|
|
103
|
+
}
|
|
11
104
|
function renderField(field) {
|
|
12
105
|
switch (field.type) {
|
|
13
106
|
case 'html': {
|
|
@@ -16,6 +109,12 @@ function renderField(field) {
|
|
|
16
109
|
case 'fieldset': {
|
|
17
110
|
return renderFieldset(field);
|
|
18
111
|
}
|
|
112
|
+
case 'row': {
|
|
113
|
+
return renderRow(field);
|
|
114
|
+
}
|
|
115
|
+
case 'list': {
|
|
116
|
+
return renderList(field);
|
|
117
|
+
}
|
|
19
118
|
case 'radio': {
|
|
20
119
|
return renderRadio(field);
|
|
21
120
|
}
|
|
@@ -37,9 +136,7 @@ function renderField(field) {
|
|
|
37
136
|
}
|
|
38
137
|
}
|
|
39
138
|
function renderFieldset(field) {
|
|
40
|
-
const hint = field.hint
|
|
41
|
-
? `<p class="hint">${escapeHtml(field.hint)}</p>`
|
|
42
|
-
: '';
|
|
139
|
+
const hint = hintMarkup(field.hint, field.hintHtml, true);
|
|
43
140
|
const inner = field.fields.map((child) => renderField(child)).join('\n');
|
|
44
141
|
return `<fieldset>
|
|
45
142
|
<legend>${escapeHtml(field.legend)}</legend>
|
|
@@ -47,9 +144,53 @@ function renderFieldset(field) {
|
|
|
47
144
|
${inner}
|
|
48
145
|
</fieldset>`;
|
|
49
146
|
}
|
|
147
|
+
function renderRow(field) {
|
|
148
|
+
const inner = field.fields.map((child) => renderField(child)).join('\n');
|
|
149
|
+
return `<div class="row">
|
|
150
|
+
${inner}
|
|
151
|
+
</div>`;
|
|
152
|
+
}
|
|
153
|
+
function renderListItem(list, index, values) {
|
|
154
|
+
const prefix = `${list.name}_${String(index)}_`;
|
|
155
|
+
const prepared = list.itemFields.map((child) => withNamePrefix(applyListItemValues(child, values), prefix));
|
|
156
|
+
const inner = prepared.map((child) => renderField(child)).join('\n');
|
|
157
|
+
const itemRemoveText = list.removeLabel ?? 'Remove';
|
|
158
|
+
return `<fieldset class="list-item" data-list-index="${String(index)}">
|
|
159
|
+
${inner}
|
|
160
|
+
<div class="list-item-actions">
|
|
161
|
+
<button type="button" class="btn-secondary list-item-remove">${escapeHtml(itemRemoveText)}</button>
|
|
162
|
+
</div>
|
|
163
|
+
</fieldset>`;
|
|
164
|
+
}
|
|
165
|
+
function renderList(field) {
|
|
166
|
+
const minItems = field.minItems ?? 0;
|
|
167
|
+
const rows = field.values.length > 0
|
|
168
|
+
? field.values
|
|
169
|
+
: Array.from({ length: minItems }, () => emptyItemValues(field.itemFields));
|
|
170
|
+
const items = rows
|
|
171
|
+
.map((values, index) => renderListItem(field, index, values))
|
|
172
|
+
.join('\n');
|
|
173
|
+
const templateValues = emptyItemValues(field.itemFields);
|
|
174
|
+
const templateItem = renderListItem(field, 0, templateValues);
|
|
175
|
+
const hint = hintMarkup(field.hint, field.hintHtml, true);
|
|
176
|
+
const legend = field.legend
|
|
177
|
+
? `<legend>${escapeHtml(field.legend)}</legend>`
|
|
178
|
+
: '';
|
|
179
|
+
const listAddText = field.addLabel ?? 'Add';
|
|
180
|
+
const maxAttribute = field.maxItems === undefined
|
|
181
|
+
? ''
|
|
182
|
+
: ` data-max-items="${String(field.maxItems)}"`;
|
|
183
|
+
return `<fieldset class="list-field" data-list-name="${escapeHtml(field.name)}" data-min-items="${String(minItems)}"${maxAttribute}>
|
|
184
|
+
${legend}
|
|
185
|
+
${hint}
|
|
186
|
+
${items}
|
|
187
|
+
<template class="list-item-template">${templateItem}</template>
|
|
188
|
+
<button type="button" class="btn-secondary list-add">${escapeHtml(listAddText)}</button>
|
|
189
|
+
</fieldset>`;
|
|
190
|
+
}
|
|
50
191
|
function renderRadio(field) {
|
|
51
192
|
const legend = field.label
|
|
52
|
-
? `<legend>${escapeHtml(field.label)}${optionalHint(field.hint)}</legend>`
|
|
193
|
+
? `<legend>${escapeHtml(field.label)}${optionalHint(field.hint, field.hintHtml)}</legend>`
|
|
53
194
|
: '';
|
|
54
195
|
const options = field.options
|
|
55
196
|
.map((option) => {
|
|
@@ -71,21 +212,25 @@ function renderCheckbox(field) {
|
|
|
71
212
|
const value = field.value ?? 'on';
|
|
72
213
|
return `<label class="checkbox-row" for="${escapeHtml(id)}">
|
|
73
214
|
<input id="${escapeHtml(id)}" type="checkbox" name="${escapeHtml(field.name)}" value="${escapeHtml(value)}"${checked}>
|
|
74
|
-
${escapeHtml(field.label ?? field.name)}${optionalHint(field.hint)}
|
|
215
|
+
${escapeHtml(field.label ?? field.name)}${optionalHint(field.hint, field.hintHtml)}
|
|
75
216
|
</label>`;
|
|
76
217
|
}
|
|
77
218
|
function renderTextarea(field) {
|
|
78
219
|
const id = field.name;
|
|
79
|
-
const label = field.label
|
|
220
|
+
const label = field.label
|
|
221
|
+
? labelHtml(id, field.label, field.hint, field.hintHtml)
|
|
222
|
+
: '';
|
|
80
223
|
const placeholder = field.placeholder
|
|
81
224
|
? ` placeholder="${escapeHtml(field.placeholder)}"`
|
|
82
225
|
: '';
|
|
83
226
|
return `${label}
|
|
84
|
-
<textarea id="${escapeHtml(id)}" name="${escapeHtml(field.name)}"${placeholder}${requiredAttribute(field.required)}>${escapeHtml(field.value ?? '')}</textarea>`;
|
|
227
|
+
<textarea id="${escapeHtml(id)}" name="${escapeHtml(field.name)}"${placeholder}${optionalAttribute('maxlength', field.maxlength)}${optionalAttribute('minlength', field.minlength)}${optionalAttribute('autocomplete', field.autocomplete)}${spellcheckAttribute(field.spellcheck)}${requiredAttribute(field.required)}>${escapeHtml(field.value ?? '')}</textarea>`;
|
|
85
228
|
}
|
|
86
229
|
function renderSelect(field) {
|
|
87
230
|
const id = field.name;
|
|
88
|
-
const label = field.label
|
|
231
|
+
const label = field.label
|
|
232
|
+
? labelHtml(id, field.label, field.hint, field.hintHtml)
|
|
233
|
+
: '';
|
|
89
234
|
const options = field.options
|
|
90
235
|
.map((option) => {
|
|
91
236
|
const selected = option.value === (field.value ?? '') ? ' selected' : '';
|
|
@@ -99,9 +244,11 @@ function renderSelect(field) {
|
|
|
99
244
|
}
|
|
100
245
|
function renderNumber(field) {
|
|
101
246
|
const id = field.name;
|
|
102
|
-
const label = field.label
|
|
103
|
-
|
|
104
|
-
|
|
247
|
+
const label = field.label
|
|
248
|
+
? labelHtml(id, field.label, field.hint, field.hintHtml)
|
|
249
|
+
: '';
|
|
250
|
+
const min = field.min === undefined ? '' : ` min="${String(field.min)}"`;
|
|
251
|
+
const max = field.max === undefined ? '' : ` max="${String(field.max)}"`;
|
|
105
252
|
const step = field.step === undefined ? '' : ` step="${escapeHtml(String(field.step))}"`;
|
|
106
253
|
const placeholder = field.placeholder
|
|
107
254
|
? ` placeholder="${escapeHtml(field.placeholder)}"`
|
|
@@ -110,28 +257,46 @@ function renderNumber(field) {
|
|
|
110
257
|
? ` value="${escapeHtml(String(field.value))}"`
|
|
111
258
|
: '';
|
|
112
259
|
return `${label}
|
|
113
|
-
<input id="${escapeHtml(id)}" name="${escapeHtml(field.name)}" type="number"${value}${min}${max}${step}${placeholder}${requiredAttribute(field.required)}>`;
|
|
260
|
+
<input id="${escapeHtml(id)}" name="${escapeHtml(field.name)}" type="number"${value}${min}${max}${step}${placeholder}${optionalAttribute('autocomplete', field.autocomplete)}${requiredAttribute(field.required)}>`;
|
|
114
261
|
}
|
|
115
262
|
function renderTextInput(field) {
|
|
116
263
|
const id = field.name;
|
|
117
|
-
const label = field.label
|
|
264
|
+
const label = field.label
|
|
265
|
+
? labelHtml(id, field.label, field.hint, field.hintHtml)
|
|
266
|
+
: '';
|
|
118
267
|
const placeholder = field.placeholder
|
|
119
268
|
? ` placeholder="${escapeHtml(field.placeholder)}"`
|
|
120
269
|
: '';
|
|
121
270
|
const value = field.value === undefined ? '' : ` value="${escapeHtml(field.value)}"`;
|
|
271
|
+
const spellcheck = field.type === 'text' ? spellcheckAttribute(field.spellcheck) : '';
|
|
122
272
|
return `${label}
|
|
123
|
-
<input id="${escapeHtml(id)}" name="${escapeHtml(field.name)}" type="${field.type}"${value}${placeholder}${requiredAttribute(field.required)}>`;
|
|
273
|
+
<input id="${escapeHtml(id)}" name="${escapeHtml(field.name)}" type="${field.type}"${value}${placeholder}${optionalAttribute('pattern', field.pattern)}${optionalAttribute('maxlength', field.maxlength)}${optionalAttribute('minlength', field.minlength)}${optionalAttribute('autocomplete', field.autocomplete)}${spellcheck}${requiredAttribute(field.required)}>`;
|
|
274
|
+
}
|
|
275
|
+
function hasListField(fields) {
|
|
276
|
+
for (const field of fields) {
|
|
277
|
+
if (field.type === 'list') {
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
if ((field.type === 'fieldset' || field.type === 'row') &&
|
|
281
|
+
hasListField(field.fields)) {
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return false;
|
|
124
286
|
}
|
|
125
287
|
export function adminForm(options) {
|
|
126
288
|
const { action, fields, method = 'post', submitLabel = 'Save', id } = options;
|
|
127
289
|
const idAttribute = id ? ` id="${escapeHtml(id)}"` : '';
|
|
128
290
|
const body = fields.map((field) => renderField(field)).join('\n');
|
|
291
|
+
const script = hasListField(fields)
|
|
292
|
+
? `\n<script>${LIST_FIELD_SCRIPT}</script>`
|
|
293
|
+
: '';
|
|
129
294
|
return `<form method="${method}" action="${escapeHtml(action)}"${idAttribute}>
|
|
130
295
|
${body}
|
|
131
296
|
<div class="actions">
|
|
132
297
|
<button type="submit" class="btn-primary">${escapeHtml(submitLabel)}</button>
|
|
133
298
|
</div>
|
|
134
|
-
</form
|
|
299
|
+
</form>${script}`;
|
|
135
300
|
}
|
|
136
301
|
export function formText(form, name) {
|
|
137
302
|
const value = form.get(name);
|
|
@@ -149,35 +314,93 @@ const VALUE_FIELD_TYPES = new Set([
|
|
|
149
314
|
function isValueField(field) {
|
|
150
315
|
return VALUE_FIELD_TYPES.has(field.type);
|
|
151
316
|
}
|
|
152
|
-
function walkScalarFields(fields,
|
|
317
|
+
function walkScalarFields(fields, visit) {
|
|
153
318
|
for (const field of fields) {
|
|
154
|
-
if (field.type === 'html') {
|
|
319
|
+
if (field.type === 'html' || field.type === 'list') {
|
|
155
320
|
continue;
|
|
156
321
|
}
|
|
157
|
-
if (field.type === 'fieldset') {
|
|
158
|
-
walkScalarFields(field.fields,
|
|
322
|
+
if (field.type === 'fieldset' || field.type === 'row') {
|
|
323
|
+
walkScalarFields(field.fields, visit);
|
|
159
324
|
continue;
|
|
160
325
|
}
|
|
161
|
-
|
|
326
|
+
visit(field);
|
|
162
327
|
}
|
|
163
328
|
}
|
|
329
|
+
function walkLists(fields, out) {
|
|
330
|
+
for (const field of fields) {
|
|
331
|
+
if (field.type === 'list') {
|
|
332
|
+
out.push(field);
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
if (field.type === 'fieldset' || field.type === 'row') {
|
|
336
|
+
walkLists(field.fields, out);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function isNamedScalarField(field) {
|
|
341
|
+
return field.type === 'checkbox' || isValueField(field);
|
|
342
|
+
}
|
|
343
|
+
function isCheckboxChecked(form, field, name) {
|
|
344
|
+
const raw = form.get(name);
|
|
345
|
+
const expected = field.value ?? 'on';
|
|
346
|
+
return typeof raw === 'string' && raw === expected;
|
|
347
|
+
}
|
|
348
|
+
function collectListIndices(form, listName) {
|
|
349
|
+
const indices = new Set();
|
|
350
|
+
const prefix = `${listName}_`;
|
|
351
|
+
for (const key of form.keys()) {
|
|
352
|
+
if (!key.startsWith(prefix)) {
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
const rest = key.slice(prefix.length);
|
|
356
|
+
const underscore = rest.indexOf('_');
|
|
357
|
+
if (underscore <= 0) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
const indexPart = rest.slice(0, underscore);
|
|
361
|
+
if (!/^\d+$/.test(indexPart)) {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
indices.add(Number(indexPart));
|
|
365
|
+
}
|
|
366
|
+
return [...indices].toSorted((a, b) => a - b);
|
|
367
|
+
}
|
|
368
|
+
function parseListField(form, list) {
|
|
369
|
+
const indices = collectListIndices(form, list.name);
|
|
370
|
+
return indices.map((index) => {
|
|
371
|
+
const row = {};
|
|
372
|
+
walkScalarFields(list.itemFields, (field) => {
|
|
373
|
+
if (!isNamedScalarField(field)) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const name = `${list.name}_${String(index)}_${field.name}`;
|
|
377
|
+
row[field.name] =
|
|
378
|
+
field.type === 'checkbox'
|
|
379
|
+
? isCheckboxChecked(form, field, name)
|
|
380
|
+
: formText(form, name);
|
|
381
|
+
});
|
|
382
|
+
return row;
|
|
383
|
+
});
|
|
384
|
+
}
|
|
164
385
|
/**
|
|
165
386
|
Named scalar values from a form matching the field schema (checkbox → boolean).
|
|
387
|
+
List fields become arrays of row objects keyed by `list.name`.
|
|
166
388
|
*/
|
|
167
389
|
export function parseAdminForm(form, fields) {
|
|
168
|
-
const scalars = [];
|
|
169
|
-
walkScalarFields(fields, scalars);
|
|
170
390
|
const result = {};
|
|
171
|
-
|
|
172
|
-
if (field
|
|
173
|
-
|
|
174
|
-
const expected = field.value ?? 'on';
|
|
175
|
-
result[field.name] = typeof raw === 'string' && raw === expected;
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
if (isValueField(field)) {
|
|
179
|
-
result[field.name] = formText(form, field.name);
|
|
391
|
+
walkScalarFields(fields, (field) => {
|
|
392
|
+
if (!isNamedScalarField(field)) {
|
|
393
|
+
return;
|
|
180
394
|
}
|
|
395
|
+
result[field.name] =
|
|
396
|
+
field.type === 'checkbox'
|
|
397
|
+
? isCheckboxChecked(form, field, field.name)
|
|
398
|
+
: formText(form, field.name);
|
|
399
|
+
});
|
|
400
|
+
const lists = [];
|
|
401
|
+
walkLists(fields, lists);
|
|
402
|
+
for (const list of lists) {
|
|
403
|
+
result[list.name] = parseListField(form, list);
|
|
181
404
|
}
|
|
182
405
|
return result;
|
|
183
406
|
}
|
package/dist/form.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA8EzC,SAAS,YAAY,CAAC,IAAwB;IAC5C,OAAO,IAAI,CAAC,CAAC,CAAC,uBAAuB,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,SAAS,CAAC,EAAU,EAAE,KAAa,EAAE,IAAa;IACzD,OAAO,eAAe,UAAU,CAAC,EAAE,CAAC,KAAK,UAAU,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;AAC5F,CAAC;AAED,SAAS,iBAAiB,CAAC,QAA6B;IACtD,OAAO,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,KAAY;IAC/B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAoB;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI;QACrB,CAAC,CAAC,mBAAmB,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM;QACjD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzE,OAAO;YACG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;IAChC,IAAI;IACJ,KAAK;YACG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,KAAiB;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK;QACxB,CAAC,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW;QAC1E,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;SAC1B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,MAAM,EAAE,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,eAAe,UAAU,CAAC,EAAE,CAAC,gBAAgB,UAAU,CAAC,EAAE,CAAC,wBAAwB,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;IAC7O,CAAC,CAAC;SACD,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClB,OAAO;IACL,MAAM;;MAEJ,OAAO;;YAED,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,KAAoB;IAC1C,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC;IAClC,OAAO,oCAAoC,UAAU,CAAC,EAAE,CAAC;eAC5C,UAAU,CAAC,EAAE,CAAC,2BAA2B,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,KAAK,CAAC,IAAI,OAAO;IAClH,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC;SAC3D,CAAC;AACV,CAAC;AAED,SAAS,cAAc,CAAC,KAAoB;IAC1C,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW;QACnC,CAAC,CAAC,iBAAiB,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG;QACnD,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,GAAG,KAAK;gBACD,UAAU,CAAC,EAAE,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,aAAa,CAAC;AACjK,CAAC;AAED,SAAS,YAAY,CAAC,KAAkB;IACtC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;SAC1B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,kBAAkB,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,QAAQ,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;IACvG,CAAC,CAAC;SACD,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClB,OAAO,GAAG,KAAK;cACH,UAAU,CAAC,EAAE,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC;MAC5F,OAAO;YACD,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CAAC,KAAkB;IACtC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,GAAG,CAAC;IACjE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,GAAG,CAAC;IACjE,MAAM,IAAI,GACR,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;IAC9E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW;QACnC,CAAC,CAAC,iBAAiB,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG;QACnD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,KAAK,GACT,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE;QAC7C,CAAC,CAAC,WAAW,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG;QAC/C,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,GAAG,KAAK;aACJ,UAAU,CAAC,EAAE,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;AAC5J,CAAC;AAED,SAAS,eAAe,CAAC,KAAgB;IACvC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW;QACnC,CAAC,CAAC,iBAAiB,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG;QACnD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,KAAK,GACT,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;IACzE,OAAO,GAAG,KAAK;aACJ,UAAU,CAAC,EAAE,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,IAAI,IAAI,KAAK,GAAG,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;AAChJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAMzB;IACC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IAC9E,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,OAAO,iBAAiB,MAAM,aAAa,UAAU,CAAC,MAAM,CAAC,IAAI,WAAW;EAC5E,IAAI;;gDAE0C,UAAU,CAAC,WAAW,CAAC;;QAE/D,CAAC;AACT,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAc,EAAE,IAAY;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAKD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAgB;IAC/C,MAAM;IACN,KAAK;IACL,UAAU;IACV,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,OAAO;CACR,CAAC,CAAC;AAEH,SAAS,YAAY,CAAC,KAAY;IAChC,OAAO,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAe,EAAE,GAAY;IACrD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9B,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACpC,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;EAEE;AACF,MAAM,UAAU,cAAc,CAC5B,IAAc,EACd,MAAe;IAEf,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,MAAM,GAAqC,EAAE,CAAC;IACpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,CAAC;YACjE,SAAS;QACX,CAAC;QACD,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../src/form.ts"],"names":[],"mappings":"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"}
|
package/dist/handler.d.ts
CHANGED
|
@@ -28,10 +28,10 @@ export type AdminRenderResult = {
|
|
|
28
28
|
body: string;
|
|
29
29
|
fields?: undefined;
|
|
30
30
|
});
|
|
31
|
-
export
|
|
31
|
+
export interface AdminSaveResult {
|
|
32
32
|
flash?: string;
|
|
33
|
-
}
|
|
34
|
-
export
|
|
33
|
+
}
|
|
34
|
+
export interface AdminRouteContext<Env = unknown> {
|
|
35
35
|
request: Request;
|
|
36
36
|
env: Env;
|
|
37
37
|
url: URL;
|
|
@@ -42,8 +42,8 @@ export type AdminRouteContext<Env = unknown> = {
|
|
|
42
42
|
*/
|
|
43
43
|
path: string;
|
|
44
44
|
requireAuth: () => Promise<Response | undefined>;
|
|
45
|
-
}
|
|
46
|
-
export
|
|
45
|
+
}
|
|
46
|
+
export interface CreateAdminOptions<Env = unknown> {
|
|
47
47
|
/**
|
|
48
48
|
Mount path. `""` or `"/"` = site root; default `"/admin"`.
|
|
49
49
|
*/
|
|
@@ -72,9 +72,9 @@ export type CreateAdminOptions<Env = unknown> = {
|
|
|
72
72
|
*/
|
|
73
73
|
routes?: Record<string, (context: AdminRouteContext<Env>) => Response | Promise<Response>>;
|
|
74
74
|
disabledMessage?: string;
|
|
75
|
-
}
|
|
76
|
-
export
|
|
75
|
+
}
|
|
76
|
+
export interface AdminHandler<Env = unknown> {
|
|
77
77
|
fetch: (request: Request, env: Env) => Promise<Response | undefined>;
|
|
78
|
-
}
|
|
78
|
+
}
|
|
79
79
|
export declare function createAdmin<Env = unknown>(options: CreateAdminOptions<Env>): AdminHandler<Env>;
|
|
80
80
|
//# sourceMappingURL=handler.d.ts.map
|
package/dist/handler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,WAAW,CAAC;AAGnB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;MAEE;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;MAEE;IACF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;MAEE;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;MAEE;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,GAAG,CACF;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,CAC7E,CAAC;AAEF,MAAM,
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,WAAW,CAAC;AAGnB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;MAEE;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;MAEE;IACF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;MAEE;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;MAEE;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,GAAG,CACF;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,CAC7E,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB,CAAC,GAAG,GAAG,OAAO;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB;;MAEE;IACF,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,kBAAkB,CAAC,GAAG,GAAG,OAAO;IAC/C;;MAEE;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;MAEE;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,OAAO,EAAE;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,EAAE,GAAG,CAAC;QACT,GAAG,EAAE,GAAG,CAAC;KACV,KAAK,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACrD,IAAI,EAAE,CAAC,OAAO,EAAE;QACd,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,EAAE,GAAG,CAAC;QACT,GAAG,EAAE,GAAG,CAAC;QACT,IAAI,EAAE,QAAQ,CAAC;KAChB,KAAK,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD;;;MAGE;IACF,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN,CAAC,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAClE,CAAC;IACF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY,CAAC,GAAG,GAAG,OAAO;IACzC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;CACtE;AA4BD,wBAAgB,WAAW,CAAC,GAAG,GAAG,OAAO,EACvC,OAAO,EAAE,kBAAkB,CAAC,GAAG,CAAC,GAC/B,YAAY,CAAC,GAAG,CAAC,CAwJnB"}
|
package/dist/html.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ Allow only simple CSS lengths for shellMaxWidth (no injection).
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function isSafeCssLength(value: string): boolean;
|
|
16
16
|
export declare function resolveFlashClass(flash: string, tone?: FlashTone): 'ok' | 'warn' | 'flash-err';
|
|
17
|
-
export
|
|
17
|
+
export interface AdminPageOptions {
|
|
18
18
|
title: string;
|
|
19
19
|
body: string;
|
|
20
20
|
flash?: string;
|
|
@@ -42,6 +42,6 @@ export type AdminPageOptions = {
|
|
|
42
42
|
Attributes merged onto `<body>` (values escaped).
|
|
43
43
|
*/
|
|
44
44
|
bodyAttrs?: Record<string, string>;
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
export declare function adminPage(options: AdminPageOptions): string;
|
|
47
47
|
//# sourceMappingURL=html.d.ts.map
|
package/dist/html.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,QAAQ,CAKzD;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAClC,QAAQ,CAUV;AAKD,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAKhE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CA+BT;AAED;;EAEE;AACF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,SAAS,GACf,IAAI,GAAG,MAAM,GAAG,WAAW,CAO7B;AAaD,MAAM,
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,QAAQ,CAKzD;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAClC,QAAQ,CAUV;AAKD,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAKhE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CA+BT;AAED;;EAEE;AACF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,SAAS,GACf,IAAI,GAAG,MAAM,GAAG,WAAW,CAO7B;AAaD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;MAEE;IACF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;MAEE;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;MAEE;IACF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;MAGE;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;MAEE;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAgD3D"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { adminAuthCookie, DEFAULT_COOKIE_NAME, hexSha256, isAuthenticated, loginResponse, logoutResponse, timingSafeEqual, } from './auth.js';
|
|
2
2
|
export { SHARED_CSS } from './css.js';
|
|
3
|
-
export { adminForm, formText, parseAdminForm, type CheckboxField, type Field, type FieldOption, type FieldsetField, type HtmlField, type NumberField, type RadioField, type SelectField, type TextareaField, type TextField, } from './form.js';
|
|
3
|
+
export { adminForm, formText, parseAdminForm, type CheckboxField, type Field, type FieldOption, type FieldsetField, type HtmlField, type ListField, type ListItemValue, type NumberField, type ParsedAdminForm, type RadioField, type RowField, type SelectField, type TextareaField, type TextField, } from './form.js';
|
|
4
4
|
export { createAdmin, type AdminHandler, type AdminRenderResult, type AdminRouteContext, type AdminSaveResult, type CreateAdminOptions, } from './handler.js';
|
|
5
5
|
export { adminDisabledResponse, adminPage, escapeHtml, html, isSafeCssLength, loginPageHtml, redirect, resolveFlashClass, type AdminPageOptions, type FlashTone, } from './html.js';
|
|
6
6
|
export { cookiePathForBase, joinBasePath, normalizeBasePath, normalizePathname, relativeToBase, resolveBasePath, } from './path.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EACL,SAAS,EACT,QAAQ,EACR,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,EACrB,SAAS,EACT,UAAU,EACV,IAAI,EACJ,eAAe,EACf,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,SAAS,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EACL,SAAS,EACT,QAAQ,EACR,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,EACrB,SAAS,EACT,UAAU,EACV,IAAI,EACJ,eAAe,EACf,aAAa,EACb,QAAQ,EACR,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,SAAS,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EACL,SAAS,EACT,QAAQ,EACR,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EACL,SAAS,EACT,QAAQ,EACR,cAAc,GAef,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,WAAW,GAMZ,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,EACrB,SAAS,EACT,UAAU,EACV,IAAI,EACJ,eAAe,EACf,aAAa,EACb,QAAQ,EACR,iBAAiB,GAGlB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Client script for `type: 'list'` add/remove. Injected once when a form contains a list.
|
|
3
|
+
*/
|
|
4
|
+
export declare const LIST_FIELD_SCRIPT = "(function () {\n function escapeRegExp(value) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n\n function reindexItem(item, index, listName) {\n var nextPrefix = listName + '_' + index + '_';\n var nameRe = new RegExp('^' + escapeRegExp(listName) + '_\\\\d+_');\n item.setAttribute('data-list-index', String(index));\n item.querySelectorAll('[name]').forEach(function (el) {\n var name = el.getAttribute('name');\n if (!name || !nameRe.test(name)) return;\n var fieldName = name.replace(nameRe, '');\n el.setAttribute('name', nextPrefix + fieldName);\n if (el.id && nameRe.test(el.id)) {\n el.id = nextPrefix + fieldName;\n }\n });\n item.querySelectorAll('[for]').forEach(function (el) {\n var forId = el.getAttribute('for');\n if (!forId || !nameRe.test(forId)) return;\n var fieldName = forId.replace(nameRe, '');\n el.setAttribute('for', nextPrefix + fieldName);\n });\n }\n\n function reindexAll(list) {\n var listName = list.getAttribute('data-list-name');\n var items = list.querySelectorAll(':scope > .list-item');\n items.forEach(function (item, index) {\n reindexItem(item, index, listName);\n });\n updateButtons(list);\n }\n\n function updateButtons(list) {\n var minItems = Number(list.getAttribute('data-min-items') || '0');\n var maxItems = list.getAttribute('data-max-items');\n var max = maxItems === null || maxItems === '' ? Infinity : Number(maxItems);\n var items = list.querySelectorAll(':scope > .list-item');\n var count = items.length;\n items.forEach(function (item) {\n var remove = item.querySelector('.list-item-remove');\n if (remove) remove.disabled = count <= minItems;\n });\n var add = list.querySelector(':scope > .list-add');\n if (add) add.disabled = count >= max;\n }\n\n function clearItemValues(item) {\n item.querySelectorAll('input, textarea, select').forEach(function (el) {\n if (el.type === 'checkbox' || el.type === 'radio') {\n el.checked = false;\n } else if (el.tagName === 'SELECT') {\n el.selectedIndex = 0;\n } else {\n el.value = '';\n }\n });\n }\n\n document.addEventListener('click', function (event) {\n var target = event.target;\n if (!(target instanceof Element)) return;\n\n var addBtn = target.closest('.list-add');\n if (addBtn) {\n var list = addBtn.closest('.list-field');\n if (!list) return;\n event.preventDefault();\n var maxItems = list.getAttribute('data-max-items');\n var max = maxItems === null || maxItems === '' ? Infinity : Number(maxItems);\n var items = list.querySelectorAll(':scope > .list-item');\n if (items.length >= max) return;\n var template = list.querySelector(':scope > template.list-item-template');\n var source = template\n ? template.content.querySelector('.list-item')\n : items[items.length - 1];\n if (!source) return;\n var clone = source.cloneNode(true);\n clearItemValues(clone);\n list.insertBefore(clone, template || addBtn);\n reindexAll(list);\n return;\n }\n\n var removeBtn = target.closest('.list-item-remove');\n if (removeBtn) {\n var item = removeBtn.closest('.list-item');\n var listEl = removeBtn.closest('.list-field');\n if (!item || !listEl) return;\n event.preventDefault();\n var minItems = Number(listEl.getAttribute('data-min-items') || '0');\n var count = listEl.querySelectorAll(':scope > .list-item').length;\n if (count <= minItems) return;\n item.remove();\n reindexAll(listEl);\n }\n });\n\n document.querySelectorAll('.list-field').forEach(updateButtons);\n})();";
|
|
5
|
+
//# sourceMappingURL=list-script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-script.d.ts","sourceRoot":"","sources":["../src/list-script.ts"],"names":[],"mappings":"AAAA;;EAEE;AACF,eAAO,MAAM,iBAAiB,wrHAqGxB,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Client script for `type: 'list'` add/remove. Injected once when a form contains a list.
|
|
3
|
+
*/
|
|
4
|
+
export const LIST_FIELD_SCRIPT = `(function () {
|
|
5
|
+
function escapeRegExp(value) {
|
|
6
|
+
return value.replace(/[.*+?^\${}()|[\\]\\\\]/g, '\\\\$&');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function reindexItem(item, index, listName) {
|
|
10
|
+
var nextPrefix = listName + '_' + index + '_';
|
|
11
|
+
var nameRe = new RegExp('^' + escapeRegExp(listName) + '_\\\\d+_');
|
|
12
|
+
item.setAttribute('data-list-index', String(index));
|
|
13
|
+
item.querySelectorAll('[name]').forEach(function (el) {
|
|
14
|
+
var name = el.getAttribute('name');
|
|
15
|
+
if (!name || !nameRe.test(name)) return;
|
|
16
|
+
var fieldName = name.replace(nameRe, '');
|
|
17
|
+
el.setAttribute('name', nextPrefix + fieldName);
|
|
18
|
+
if (el.id && nameRe.test(el.id)) {
|
|
19
|
+
el.id = nextPrefix + fieldName;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
item.querySelectorAll('[for]').forEach(function (el) {
|
|
23
|
+
var forId = el.getAttribute('for');
|
|
24
|
+
if (!forId || !nameRe.test(forId)) return;
|
|
25
|
+
var fieldName = forId.replace(nameRe, '');
|
|
26
|
+
el.setAttribute('for', nextPrefix + fieldName);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function reindexAll(list) {
|
|
31
|
+
var listName = list.getAttribute('data-list-name');
|
|
32
|
+
var items = list.querySelectorAll(':scope > .list-item');
|
|
33
|
+
items.forEach(function (item, index) {
|
|
34
|
+
reindexItem(item, index, listName);
|
|
35
|
+
});
|
|
36
|
+
updateButtons(list);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function updateButtons(list) {
|
|
40
|
+
var minItems = Number(list.getAttribute('data-min-items') || '0');
|
|
41
|
+
var maxItems = list.getAttribute('data-max-items');
|
|
42
|
+
var max = maxItems === null || maxItems === '' ? Infinity : Number(maxItems);
|
|
43
|
+
var items = list.querySelectorAll(':scope > .list-item');
|
|
44
|
+
var count = items.length;
|
|
45
|
+
items.forEach(function (item) {
|
|
46
|
+
var remove = item.querySelector('.list-item-remove');
|
|
47
|
+
if (remove) remove.disabled = count <= minItems;
|
|
48
|
+
});
|
|
49
|
+
var add = list.querySelector(':scope > .list-add');
|
|
50
|
+
if (add) add.disabled = count >= max;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function clearItemValues(item) {
|
|
54
|
+
item.querySelectorAll('input, textarea, select').forEach(function (el) {
|
|
55
|
+
if (el.type === 'checkbox' || el.type === 'radio') {
|
|
56
|
+
el.checked = false;
|
|
57
|
+
} else if (el.tagName === 'SELECT') {
|
|
58
|
+
el.selectedIndex = 0;
|
|
59
|
+
} else {
|
|
60
|
+
el.value = '';
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
document.addEventListener('click', function (event) {
|
|
66
|
+
var target = event.target;
|
|
67
|
+
if (!(target instanceof Element)) return;
|
|
68
|
+
|
|
69
|
+
var addBtn = target.closest('.list-add');
|
|
70
|
+
if (addBtn) {
|
|
71
|
+
var list = addBtn.closest('.list-field');
|
|
72
|
+
if (!list) return;
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
var maxItems = list.getAttribute('data-max-items');
|
|
75
|
+
var max = maxItems === null || maxItems === '' ? Infinity : Number(maxItems);
|
|
76
|
+
var items = list.querySelectorAll(':scope > .list-item');
|
|
77
|
+
if (items.length >= max) return;
|
|
78
|
+
var template = list.querySelector(':scope > template.list-item-template');
|
|
79
|
+
var source = template
|
|
80
|
+
? template.content.querySelector('.list-item')
|
|
81
|
+
: items[items.length - 1];
|
|
82
|
+
if (!source) return;
|
|
83
|
+
var clone = source.cloneNode(true);
|
|
84
|
+
clearItemValues(clone);
|
|
85
|
+
list.insertBefore(clone, template || addBtn);
|
|
86
|
+
reindexAll(list);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var removeBtn = target.closest('.list-item-remove');
|
|
91
|
+
if (removeBtn) {
|
|
92
|
+
var item = removeBtn.closest('.list-item');
|
|
93
|
+
var listEl = removeBtn.closest('.list-field');
|
|
94
|
+
if (!item || !listEl) return;
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
var minItems = Number(listEl.getAttribute('data-min-items') || '0');
|
|
97
|
+
var count = listEl.querySelectorAll(':scope > .list-item').length;
|
|
98
|
+
if (count <= minItems) return;
|
|
99
|
+
item.remove();
|
|
100
|
+
reindexAll(listEl);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
document.querySelectorAll('.list-field').forEach(updateButtons);
|
|
105
|
+
})();`;
|
|
106
|
+
//# sourceMappingURL=list-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-script.js","sourceRoot":"","sources":["../src/list-script.ts"],"names":[],"mappings":"AAAA;;EAEE;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAqG3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workers-mini-admin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Tiny single-user admin for Cloudflare Workers: cookie/Bearer auth, declarative forms, configurable mount",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,22 +30,22 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@eslint/js": "^10.0.1",
|
|
34
33
|
"eslint": "^10.12.0",
|
|
35
|
-
"eslint-config-
|
|
36
|
-
"eslint-config-narwhal": "^1.0.2",
|
|
34
|
+
"eslint-config-narwhal": "^2.1.1",
|
|
37
35
|
"husky": "^9.1.7",
|
|
38
36
|
"lint-staged": "^17.6.0",
|
|
39
37
|
"prettier": "^3.9.9",
|
|
40
38
|
"stylelint": "^17.16.0",
|
|
41
39
|
"stylelint-config-standard": "^40.0.0",
|
|
42
40
|
"typescript": "^6.0.3",
|
|
43
|
-
"typescript-eslint": "^8.71.0",
|
|
44
41
|
"wrangler": "^4.147.0"
|
|
45
42
|
},
|
|
46
43
|
"engines": {
|
|
47
44
|
"node": ">=24"
|
|
48
45
|
},
|
|
46
|
+
"devEngines": {
|
|
47
|
+
"node": "26"
|
|
48
|
+
},
|
|
49
49
|
"publishConfig": {
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|