@owlmeans/client-panel 0.1.18-rc.6 → 0.1.18-rc.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +63 -4
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/client-panel/SKILL.md +157 -11
  4. package/build/auth/i18n/fr.json +56 -0
  5. package/build/auth/i18n.js +10 -8
  6. package/build/auth/i18n.js.map +1 -1
  7. package/build/auth/index.d.ts +1 -0
  8. package/build/auth/index.d.ts.map +1 -1
  9. package/build/auth/index.js +1 -0
  10. package/build/auth/index.js.map +1 -1
  11. package/build/auth/login/index.d.ts +5 -0
  12. package/build/auth/login/index.d.ts.map +1 -0
  13. package/build/auth/login/index.js +4 -0
  14. package/build/auth/login/index.js.map +1 -0
  15. package/build/auth/login/model.d.ts +10 -0
  16. package/build/auth/login/model.d.ts.map +1 -0
  17. package/build/auth/login/model.js +88 -0
  18. package/build/auth/login/model.js.map +1 -0
  19. package/build/auth/login/provider/consts.local.d.ts +3 -0
  20. package/build/auth/login/provider/consts.local.d.ts.map +1 -0
  21. package/build/auth/login/provider/consts.local.js +3 -0
  22. package/build/auth/login/provider/consts.local.js.map +1 -0
  23. package/build/auth/login/provider-config.d.ts +37 -0
  24. package/build/auth/login/provider-config.d.ts.map +1 -0
  25. package/build/auth/login/provider-config.js +2 -0
  26. package/build/auth/login/provider-config.js.map +1 -0
  27. package/build/auth/login/provider.d.ts +5 -0
  28. package/build/auth/login/provider.d.ts.map +1 -0
  29. package/build/auth/login/provider.js +55 -0
  30. package/build/auth/login/provider.js.map +1 -0
  31. package/build/auth/login/types.d.ts +103 -0
  32. package/build/auth/login/types.d.ts.map +1 -0
  33. package/build/auth/login/types.js +2 -0
  34. package/build/auth/login/types.js.map +1 -0
  35. package/build/components/index.d.ts +1 -0
  36. package/build/components/index.d.ts.map +1 -1
  37. package/build/components/index.js +1 -0
  38. package/build/components/index.js.map +1 -1
  39. package/build/components/nav/helper.d.ts +13 -0
  40. package/build/components/nav/helper.d.ts.map +1 -0
  41. package/build/components/nav/helper.js +99 -0
  42. package/build/components/nav/helper.js.map +1 -0
  43. package/build/components/nav/index.d.ts +4 -0
  44. package/build/components/nav/index.d.ts.map +1 -0
  45. package/build/components/nav/index.js +3 -0
  46. package/build/components/nav/index.js.map +1 -0
  47. package/build/components/nav/label.d.ts +4 -0
  48. package/build/components/nav/label.d.ts.map +1 -0
  49. package/build/components/nav/label.js +12 -0
  50. package/build/components/nav/label.js.map +1 -0
  51. package/build/components/nav/types.d.ts +88 -0
  52. package/build/components/nav/types.d.ts.map +1 -0
  53. package/build/components/nav/types.js +2 -0
  54. package/build/components/nav/types.js.map +1 -0
  55. package/build/consts.local.d.ts +43 -0
  56. package/build/consts.local.d.ts.map +1 -0
  57. package/build/consts.local.js +11 -0
  58. package/build/consts.local.js.map +1 -0
  59. package/build/i18n.d.ts +2 -0
  60. package/build/i18n.d.ts.map +1 -0
  61. package/build/i18n.js +6 -0
  62. package/build/i18n.js.map +1 -0
  63. package/build/index.d.ts +1 -0
  64. package/build/index.d.ts.map +1 -1
  65. package/build/index.js +1 -0
  66. package/build/index.js.map +1 -1
  67. package/package.json +17 -16
  68. package/src/auth/i18n/fr.json +56 -0
  69. package/src/auth/i18n.ts +10 -8
  70. package/src/auth/index.ts +1 -1
  71. package/src/auth/login/index.ts +4 -0
  72. package/src/auth/login/model.ts +102 -0
  73. package/src/auth/login/provider/consts.local.ts +2 -0
  74. package/src/auth/login/provider-config.ts +38 -0
  75. package/src/auth/login/provider.ts +65 -0
  76. package/src/auth/login/types.ts +110 -0
  77. package/src/components/index.ts +1 -0
  78. package/src/components/nav/helper.ts +118 -0
  79. package/src/components/nav/index.ts +4 -0
  80. package/src/components/nav/label.ts +20 -0
  81. package/src/components/nav/types.ts +92 -0
  82. package/src/consts.local.ts +10 -0
  83. package/src/i18n.ts +6 -0
  84. package/src/index.ts +2 -0
  85. package/build/.gitkeep +0 -0
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # @owlmeans/client-panel
2
2
 
3
- Schema-driven React form components with react-hook-form integration, i18n, and action buttons.
3
+ Schema-driven React form components with react-hook-form integration, i18n, action buttons, and the
4
+ headless navigation model.
4
5
 
5
6
  ## Overview
6
7
 
@@ -9,12 +10,13 @@ Schema-driven React form components with react-hook-form integration, i18n, and
9
10
  - `InputCtrl` — labeled input field component backed by react-hook-form
10
11
  - `useFormRef()` — hook to get a ref for programmatic form operations
11
12
  - `FormOnSubmit` — type for form submission handler functions
13
+ - `usePanelNav()` — the model behind a two-layer navigation menu (no JSX)
12
14
  - Platform-agnostic: used by React web and React Native frontends
13
15
 
14
16
  ## Installation
15
17
 
16
18
  ```bash
17
- bun add @owlmeans/client-panel
19
+ bun add @owlmeans/client-panel@^0.1.18-rc.60
18
20
  ```
19
21
 
20
22
  ## Usage
@@ -24,12 +26,13 @@ A complete form with submit and cancel actions:
24
26
  ```typescript
25
27
  import { ClientForm, InputCtrl, ActionCtrl, useFormRef } from '@owlmeans/client-panel'
26
28
  import type { FormOnSubmit } from '@owlmeans/client-panel'
29
+ import { appProtocols } from 'my-app-common'
27
30
 
28
31
  function CreateProjectForm() {
29
32
  const formRef = useFormRef()
30
33
 
31
34
  const onSubmit: FormOnSubmit<CreateProject> = async (data) => {
32
- await ctx.module<ClientModule<Project>>('project-create').call({ body: data })
35
+ await ctx.entrypoint(appProtocols.api.project.create).call({ body: data })
33
36
  }
34
37
 
35
38
  return (
@@ -81,6 +84,62 @@ type FormOnSubmit<T> = (data: T) => void | Promise<void>
81
84
 
82
85
  Derives default form values from an AJV schema's `default` fields.
83
86
 
87
+ ## Navigation model
88
+
89
+ Navigation is declared as data and rendered by the platform package
90
+ (`@owlmeans/web-panel` ships `NavLayout` / `TopNav` / `SideNav` / `Footer`). This package holds only
91
+ the model, so both levels of the menu agree on what is active.
92
+
93
+ ```typescript
94
+ import { usePanelNav } from '@owlmeans/client-panel'
95
+ import type { PanelNavConfig } from '@owlmeans/client-panel'
96
+
97
+ const config: PanelNavConfig = {
98
+ sections: [
99
+ { name: 'home', label: 'Home', items: [{ alias: HOME, label: 'Overview' }] },
100
+ { name: 'demo', items: [{ alias: web.session }, { alias: web.about }] },
101
+ ],
102
+ }
103
+
104
+ const model = usePanelNav(config)
105
+ ```
106
+
107
+ ### Types
108
+
109
+ - `PanelNavItem` — `{ alias, label?, Icon?, hidden? }`; one screen, addressed by entrypoint alias,
110
+ never by URL.
111
+ - `PanelNavSection` — `{ name, label?, items, hidden? }`; the first menu level. Pressing it goes to
112
+ the first visible item.
113
+ - `PanelNavConfig` — `{ sections }`.
114
+ - `PanelNavLink` — `{ alias? | href?, label?, open? }`; a footer link.
115
+ - `NavTranslate` — `(key, defaultValue) => string`.
116
+
117
+ ### `usePanelNav(config): PanelNavModel`
118
+
119
+ Returns `sections` (with `hidden` filtered out), `current` (the active screen's alias or null),
120
+ `active` (its section), `showSide`, `isSectionActive` / `isItemActive`, `goSection` / `goItem`
121
+ (each returning a handler), and `hrefOf(target)`.
122
+
123
+ - `showSide` is false when the active section holds a single screen — that is where the "one screen,
124
+ no second level" rule lives; a renderer asks the model rather than counting items.
125
+ - The current screen resolves from the router's `location.state.alias` when present, and otherwise
126
+ from the pathname matched against entrypoint paths — exact first, then longest prefix.
127
+ Both are needed: `state` is `window.history.state`, so it is empty on a hard load or deep link. A
128
+ screen listed in no section finds its section by walking its declared `parent` upward.
129
+ - `hrefOf` resolves a real URL synchronously so a menu entry can be a proper link (focusable,
130
+ keyboard-operable, openable in a new tab). It returns `undefined` for a path carrying route
131
+ parameters.
132
+
133
+ ### `navLabelHelper.resolveNavLabel(translate, label, key, alias)`
134
+
135
+ Resolves a label as literal `label` → `translate(key, defaultNavLabel(alias))` → the humanized
136
+ alias. `translate` always reaches a component as a **prop**, defaulting to `navLabelHelper.defaultNavTranslate`
137
+ (which returns the fallback) — a menu must never read an i18n context implicitly, because an app
138
+ mounted without an i18n provider throws inside render and blanks the page. `navLabelHelper.defaultNavLabel`
139
+ humanizes the last alias segment
140
+ (`my-app:web:user-list` → `User list`). Default key families are `nav.<section>` and
141
+ `modules.<alias>`.
142
+
84
143
  ## Related Packages
85
144
 
86
145
  - [`@owlmeans/client`](../client) — `useContext`, `useNavigate` used within form components
@@ -94,7 +153,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
94
153
  your project's skill store (`.agents/skills/`):
95
154
 
96
155
  ```sh
97
- npx @owlmeans/agent-skills
156
+ npx @owlmeans/agent-skills@^0.1.18-rc.52
98
157
  ```
99
158
 
100
159
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/client-panel",
4
- "version": "0.1.18-rc.6",
5
- "generatedAt": "2026-08-18T14:48:00.543Z",
4
+ "version": "0.1.18-rc.60",
5
+ "generatedAt": "2026-10-08T21:27:54.316Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: client-panel
3
- description: How to use @owlmeans/client-panel — reusable cross-platform UI panel + form components (auth screens, layouts) shared by web-panel and native-panel. Auto-invoked when importing panel components.
3
+ description: How to use @owlmeans/client-panel — reusable cross-platform UI panel + form components (auth screens, layouts) and the headless navigation model (usePanelNav) shared by web-panel and native-panel. Auto-invoked when importing panel components or building a navigation menu.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,30 +8,176 @@ user-invocable: false
8
8
  # @owlmeans/client-panel
9
9
 
10
10
  **Layer:** Client
11
- **Install:** `"@owlmeans/client-panel": "^0.1.18-rc.6"` in `dependencies`
11
+ **Install:** `"@owlmeans/client-panel": "^0.1.18-rc.60"` in `dependencies`
12
12
 
13
13
  ## Key Exports
14
14
 
15
+ Everything below is a **root** export — this package has no `./components` or `./helpers`
16
+ subpath. Only auth is split out (see below).
17
+
18
+ Importing the root also registers the package-owned seven-language `client-panel` bundle. Its
19
+ generic `buttons.submit` fallback is always available after an application imports any root form
20
+ controller; apps may override it through their own `buttons` resource.
21
+
15
22
  | Export | Description |
16
23
  |--------|-------------|
17
- | `components` submodule | Cross-platform panel/form components |
18
- | `helpers` submodule | Layout / form helpers |
24
+ | `ClientForm` | The form model: `react-hook-form` + an AJV resolver with `coerceTypes` and `ajv-formats`, publishing a `FormContext` and a loader toggle |
25
+ | `FormContext` / `useClientFormContext` | That context, and the hook a renderer reads it with |
26
+ | `useFormI18n()` / `useFormError(name, error?)` | The form's `t`, and a field error resolved to a message — `<field>.errors.<type>` → `errors.<type>` → `lib:errors.<type>`, or `<field>.error` → `lib:errors.form-field` when the error carries no type |
27
+ | `useFormRef<T>()` | The `MutableRefObject<FormRef>` a caller holds to drive a form from outside: `form`, `update`, `loader`, `error` |
28
+ | `InputCtrl` | The headless field controller — resolves `label`/`placeholder`/`hint` from the form namespace when passed `true`, and calls the platform `render` |
29
+ | `ActionCtrl` | The headless submit/action controller — three-tier label lookup (form namespace, the app's `buttons` section, then `client-panel`'s), the loader flag, and the bound `action` |
30
+ | `schemaToFormDefault(schema)` | Initial values derived from an AJV schema, which is what `ClientForm` uses when no `defaults` are given |
31
+ | `PanelContext` / `usePanelHelper()` | Inject `resource`, `ns`, `prefix` or `suppress` into a sub-tree; the parent's values are inherited and overridden field by field |
32
+ | `usePanelI18n(name?, override?)` / `usePanelError(name, error?)` | The panel's `t`, and a `ResilientError` resolved through it |
33
+ | `useStatusMessage(opts)` | `{ message, variant, ok }` for a status surface — a marshalled error's `:` is rewritten to `.` before lookup, so a key written with a colon never matches |
34
+ | `usePanelLayout()` / `useLayoutTitle(name?, alias?)` / `prepareLayoutTitle(title)` | The entrypoint the current layout is rendering, and its translated title |
35
+ | `BlockScaling` | `Full` / `Half` / `Wide` — the sizing vocabulary both platform families render |
36
+ | `usePanelNav(config)` | Headless navigation model behind a two-layer menu |
37
+ | `navLabelHelper` → `.resolveNavLabel`, `.defaultNavLabel`, `.defaultNavTranslate` | Label resolution helpers |
38
+ | `PanelNavConfig`, `PanelNavSection`, `PanelNavItem`, `PanelNavLink`, `PanelNavModel`, `NavTranslate` | Navigation types |
39
+ | `FormProps`, `FormRef`, `FormOnSubmit`, `TFormContext`, `FormFieldProps`, `FormActionProps`, `FormActionRenderArgs`, `InputControllerProps`, `TPanelContext`, `StatusOptions` | The model shapes a renderer is written against |
19
40
 
20
41
  ## Subpath Exports
21
42
 
22
- - `./auth` — auth-related panel components
23
- - `./auth/plugins` — pluggable auth panel pieces
43
+ - `./auth` — `useLoginMethods`, `loginProviderHelper` and the login model types
44
+ (`LoginMethodsModel`, `LoginTermsModel`, `LoginCreditModel`, `LoginProviderConfig`,
45
+ `LoginProviderModel`, `LoginProviderPlacement`, `UseLoginMethodsOptions`). Importing it also
46
+ registers this package's own seven-language `client-panel-auth` bundle and the
47
+ `LoginScreenConfig.provider` augmentation of `@owlmeans/config` by side effect.
48
+ - `./auth/plugins` — the shapes an auth UI plugin is written against: `Ed22519BasicAuthUIPluginForm`
49
+ and its `Ed22519BasicAuthUIPluginFormSchema`.
50
+
51
+ `useLoginMethods` is the headless model behind a sign-in screen: which methods are offered, whether
52
+ the terms are confirmed, what the credit line says, and a `select` that is deliberately NOT async
53
+ (the flow may have to open a window inside the click). The rendering lives in `web-panel` — the
54
+ same split the form and navigation models already use. See `login-methods`.
55
+
56
+ `LoginTermsModel.terms` carries `documents` and `notices` (each `ResolvedTermsDocument[]` from
57
+ `@owlmeans/client-auth/login`) rather than a flat `urls: { terms, privacy, cookies? }` — that field
58
+ is gone; nothing in the repo read it outside this model and its one renderer, so it was dropped
59
+ rather than kept alongside the replacement. It also carries `revisedAt?` and `version`. A renderer
60
+ turns `documents`/`notices` into markup with `loginTermsHelper.termsSentence`
61
+ (`@owlmeans/client-auth/login`), never by re-deriving link/label pairs itself.
62
+
63
+ `LoginTermsModel.deferred` mirrors `loginTermsHelper.termsDeferred(ctx)`: true once a registered,
64
+ bound `LoginStep` confirms the terms instead of this screen. `LoginMethodsModel.blocked` folds it in
65
+ (`required && !deferred && !accepted`) — a renderer never blocks on `required`/`accepted` alone, or
66
+ it would re-block a screen whose confirmation moved elsewhere.
67
+
68
+ ### The provider disclosure — `LoginMethodsModel.provider`
69
+
70
+ A sign-in screen that a third party runs for an application (a generated target signing people in
71
+ through the platform's IAM) names both parties: who signs the person in, and on behalf of which
72
+ product. The rules live here, headless, so every renderer discloses the same thing:
73
+
74
+ - **Config** — `cfg.security.auth.login.provider?: LoginProviderConfig`
75
+ (`{ name, operator?, info?, placement?: 'top' | 'inline' }`), declared onto `@owlmeans/config`'s
76
+ `LoginScreenConfig` by module augmentation in `auth/login/provider-config.ts` (the
77
+ `client-auth/login/terms-config.ts` pattern), never by editing `@owlmeans/config`. The `./auth`
78
+ barrel re-exports it, so any import of `@owlmeans/client-panel/auth` loads the field; a program
79
+ that builds the literal without one adds `import type {} from '@owlmeans/client-panel/auth'`.
80
+ - **Model** — `loginProviderHelper.resolve(cfg, brand)` → `LoginProviderModel { name, operator,
81
+ product, info: string | null, placement }` or `null`. Null unless the provider `name` AND the
82
+ product (`cfg.brand.name`) are set — a relationship with one party missing is never shown. Blank
83
+ strings are unset (build-time env arrives as `''`); `operator` defaults to `name`; `placement` to
84
+ `'inline'` (anything but `'top'` is inline); `info` survives only as an absolute `http(s)` URL or
85
+ a root-relative path (`//host` and `/\` are refused). `useLoginMethods().provider` carries it.
86
+ - **Copy** — `loginProviderHelper.fill(template, model)` puts `{{provider}}`, `{{operator}}` and
87
+ `{{product}}` into an ALREADY-TRANSLATED sentence in one pass; names never travel as i18next
88
+ params. The keys (`login.provider.*`) and the markup belong to `web-panel`.
89
+ - The disclosure is independent of the credit line: `credit.poweredBy: false` never hides who
90
+ signs a person in.
24
91
 
25
92
  ## Usage
26
93
 
27
94
  ```typescript
28
- import { Panel } from '@owlmeans/client-panel'
29
- import { LoginPanel } from '@owlmeans/client-panel/auth'
95
+ import { ClientForm, InputCtrl, useFormRef, PanelContext } from '@owlmeans/client-panel'
96
+ import { useLoginMethods } from '@owlmeans/client-panel/auth'
97
+ ```
98
+
99
+ Nothing here renders. A platform package supplies the JSX, and `@owlmeans/web-panel` re-exports
100
+ this package's whole root surface (`export * from '@owlmeans/client-panel'`), so an application can
101
+ reach any of it through the platform package it already imports.
102
+
103
+ The split is not uniform, and the difference matters when reading a screen:
104
+
105
+ - **The navigation model is wrapped.** `usePanelNav` has no renderer here; `TopNav`, `SideNav` and
106
+ `NavLayout` in `@owlmeans/web-panel` are its only rendering, and an app calls those.
107
+ - **The form controllers are used directly.** `ClientForm`, `InputCtrl` and `ActionCtrl` are not
108
+ wrapped by any platform package: `@owlmeans/web-panel`'s `Form` builds its own `useForm` +
109
+ `ajvResolver` and takes only `FormContext` and `schemaToFormDefault` from here, its `TextInput`
110
+ drives `react-hook-form`'s `Controller` itself, and its buttons call `handleSubmit` themselves.
111
+ An application that wants a form laid out its own way imports the three from this package: it
112
+ puts its fields inside `ClientForm` and writes the `render` callbacks `InputCtrl` and `ActionCtrl`
113
+ take.
114
+
115
+ Read the contracts from the controller you actually use — they differ. `InputCtrl` resolves
116
+ `label`/`placeholder`/`hint` only from a boolean `true` and **drops a string**, while
117
+ `@owlmeans/web-panel`'s `TextInput` honours a string verbatim.
118
+
119
+ ## Navigation model — `usePanelNav`
120
+
121
+ The **model lives here, the JSX lives in the platform package.** `usePanelNav` is headless and
122
+ cross-platform; `@owlmeans/web-panel` renders it as `TopNav`/`SideNav`/`NavLayout`. Never put a
123
+ rendered menu in this package, and never re-derive active state in a renderer.
124
+
125
+ Navigation is declared as data. A **section** is the first menu level; its **items** are the screens
126
+ the second level offers while that section is active. An item addresses a frontend entrypoint by
127
+ `alias` and never carries a URL — the router resolves it, so a path that changes shape stays correct
128
+ everywhere it is rendered.
129
+
130
+ ```ts
131
+ import { usePanelNav } from '@owlmeans/client-panel'
132
+ import type { PanelNavConfig } from '@owlmeans/client-panel'
133
+
134
+ const config: PanelNavConfig = {
135
+ sections: [
136
+ { name: 'home', label: 'Home', items: [{ alias: HOME, label: 'Overview' }] },
137
+ { name: 'demo', items: [{ alias: web.session }, { alias: web.about }] },
138
+ ],
139
+ }
140
+
141
+ const model = usePanelNav(config)
30
142
  ```
31
143
 
32
- `@owlmeans/web-panel` re-exports these and provides the Material-UI implementations.
144
+ `PanelNavModel` carries `sections` (with `hidden` filtered out), `current` (the active screen's
145
+ alias, or null), `active` (its section), `showSide`, `isSectionActive` / `isItemActive`,
146
+ `goSection` / `goItem` (each returning a handler), and `hrefOf`.
147
+
148
+ - **`showSide` owns the one-screen rule.** It is false when the active section holds a single
149
+ screen — a second level offering the page you are already on is noise. A renderer asks the model;
150
+ it does not count items itself.
151
+ - **Label resolution never touches i18n implicitly.** `NavTranslate` is a
152
+ `(key, defaultValue) => string` **prop**, defaulting to `navLabelHelper.defaultNavTranslate`,
153
+ which returns the fallback. An app mounted without an i18n provider (`renderApp` from
154
+ `@owlmeans/web-client` mounts none) crashes if a menu reaches for the panel i18n context: the hook
155
+ dereferences `i18n.options` on the empty object `react-i18next` returns without an instance, and a
156
+ throw inside render blanks the whole app.
157
+ `navLabelHelper.resolveNavLabel(translate, label, key, alias)` applies the order — literal `label`
158
+ → `translate(key, humanized)` → `.defaultNavLabel(alias)`, which humanizes the last alias segment
159
+ (`my-app:web:user-list` → `User list`). Default key families: `nav.<name>` for sections,
160
+ `modules.<alias>` for items and footer links.
161
+ - **Resolving the current screen needs two sources.** The router's `location.state.alias` is
162
+ authoritative but is `window.history.state`, so it is null until the first in-app navigation — on
163
+ a hard page load or a deep link a menu keyed on it alone highlights nothing, on exactly the entry
164
+ that matters most. The pathname is the fallback: entrypoint paths are matched exactly
165
+ first, then by longest prefix, so a detail screen under a listed one still belongs to its section.
166
+ A screen listed in no section resolves its section by walking `route.route.parent` upward.
167
+ - **`hrefOf` gives a menu entry a real URL**, resolved synchronously from
168
+ `context.entrypoint(protocol).path()` — a protocol composes its path from its own declaration and
169
+ its ancestors', so matching one is a lookup rather than a guess. It returns undefined for a path
170
+ carrying route parameters (`:id`) — there is no honest URL for a screen whose address is not
171
+ known yet. A protocol the app never bound resolves to null and is skipped rather than taking the
172
+ menu down.
33
173
 
34
174
  ## Depends On
35
175
 
36
- - `@owlmeans/client`, `@owlmeans/client-auth`, `@owlmeans/client-i18n`
37
- - `react` (peer)
176
+ - `@owlmeans/client`, `@owlmeans/client-i18n`, `@owlmeans/client-entrypoint`, `@owlmeans/client-route`,
177
+ `@owlmeans/entrypoint`, `@owlmeans/error`, `@hookform/resolvers`
178
+ - Peers (host-provided): `react`, `react-hook-form`, `ajv`, `@owlmeans/auth`, `@owlmeans/client-auth`,
179
+ `@owlmeans/config`, `@owlmeans/i18n`, `@owlmeans/router`. No platform UI library — that is the
180
+ point of the split. (`@owlmeans/auth` and `@owlmeans/client-auth` are marked optional.)
181
+ - `ajv-formats` is imported at module scope by `ClientForm` but is declared in no dependency section
182
+ of the manifest, which lists `ajv` alone. An install that does not otherwise pull it in fails at
183
+ import time, so declare `ajv-formats` next to `ajv` in the consuming application.
@@ -0,0 +1,56 @@
1
+ {
2
+ "basic-ed25519": {
3
+ "entityId": {
4
+ "label": "Identifiant de l’organisation"
5
+ },
6
+ "address": {
7
+ "label": "DID de l’utilisateur"
8
+ },
9
+ "privateKey": {
10
+ "label": "Clé privée"
11
+ },
12
+ "submit": "S’authentifier"
13
+ },
14
+ "re-captcha": {
15
+ "guideline": "Nous devons vérifier que vous n’êtes pas un robot. Cliquez dans la case blanche ci-dessous pour prouver que vous êtes humain."
16
+ },
17
+ "wallet-provider": {
18
+ "pin": {
19
+ "loading": "Chargement…",
20
+ "guideline": "Utilisez ce code PIN avec toute ressource prenant en charge l’autorisation par portefeuille"
21
+ }
22
+ },
23
+ "wallet-consumer": {
24
+ "pin": {
25
+ "label": "Code PIN",
26
+ "hint": "Scannez le code QR ou générez un code PIN avec votre application OwlMeans ID"
27
+ },
28
+ "submit": "Continuer avec le PIN"
29
+ },
30
+ "oidp-auth": {
31
+ "reset": "Réinitialiser",
32
+ "error": {
33
+ "socket": {
34
+ "timeout": {
35
+ "rely": "La fenêtre d’authentification a expiré. Actualisez la page pour réessayer."
36
+ }
37
+ }
38
+ }
39
+ },
40
+ "oidp-create-id": {
41
+ "error": {
42
+ "socket": {
43
+ "timeout": {
44
+ "call": "Délai d’action dépassé. Pour des raisons de sécurité, les actions d’authentification sont limitées dans le temps. Réessayez.",
45
+ "rely": "Le code d’authentification a expiré. Réessayez."
46
+ }
47
+ },
48
+ "auth": {
49
+ "authorization": {
50
+ "sequence": "Le processus d’authentification a été interrompu par l’application d’authentification utilisée."
51
+ }
52
+ }
53
+ },
54
+ "reset": "Actualiser"
55
+ }
56
+ }
@@ -1,4 +1,4 @@
1
- import { addI18nLib } from '@owlmeans/i18n';
1
+ import { i18nHelper } from '@owlmeans/i18n';
2
2
  import en from './i18n/en.json' with { type: 'json' };
3
3
  import pl from './i18n/pl.json' with { type: 'json' };
4
4
  import ru from './i18n/ru.json' with { type: 'json' };
@@ -6,11 +6,13 @@ import be from './i18n/be.json' with { type: 'json' };
6
6
  import uk from './i18n/uk.json' with { type: 'json' };
7
7
  import es from './i18n/es.json' with { type: 'json' };
8
8
  import de from './i18n/de.json' with { type: 'json' };
9
- addI18nLib('en', 'client-panel-auth', en);
10
- addI18nLib('pl', 'client-panel-auth', pl);
11
- addI18nLib('ru', 'client-panel-auth', ru);
12
- addI18nLib('be', 'client-panel-auth', be);
13
- addI18nLib('uk', 'client-panel-auth', uk);
14
- addI18nLib('es', 'client-panel-auth', es);
15
- addI18nLib('de', 'client-panel-auth', de);
9
+ import fr from './i18n/fr.json' with { type: 'json' };
10
+ i18nHelper.addI18nLib('en', 'client-panel-auth', en);
11
+ i18nHelper.addI18nLib('pl', 'client-panel-auth', pl);
12
+ i18nHelper.addI18nLib('ru', 'client-panel-auth', ru);
13
+ i18nHelper.addI18nLib('be', 'client-panel-auth', be);
14
+ i18nHelper.addI18nLib('uk', 'client-panel-auth', uk);
15
+ i18nHelper.addI18nLib('es', 'client-panel-auth', es);
16
+ i18nHelper.addI18nLib('de', 'client-panel-auth', de);
17
+ i18nHelper.addI18nLib('fr', 'client-panel-auth', fr);
16
18
  //# sourceMappingURL=i18n.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../../src/auth/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAErD,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACzC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACzC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACzC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACzC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACzC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACzC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../../src/auth/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAErD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACpD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACpD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACpD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACpD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACpD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACpD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACpD,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAA"}
@@ -1,2 +1,3 @@
1
1
  export * from './i18n.js';
2
+ export * from './login/index.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA"}
@@ -1,2 +1,3 @@
1
1
  export * from './i18n.js';
2
+ export * from './login/index.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export type * from './types.js';
2
+ export * from './model.js';
3
+ export * from './provider.js';
4
+ export * from './provider-config.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/login/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './model.js';
2
+ export * from './provider.js';
3
+ export * from './provider-config.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/login/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { LoginMethodsModel, UseLoginMethodsOptions } from './types.js';
2
+ /**
3
+ * Everything a sign-in screen needs, with no opinion about how it looks.
4
+ *
5
+ * Headless and cross-platform, like `usePanelNav`: the rules about what may be offered, what must
6
+ * be confirmed first, what the credit line says and who is disclosed as signing the person in are
7
+ * the same on every platform, and only the rendering differs. A renderer that re-derives any of them will drift from the one that does not.
8
+ */
9
+ export declare const useLoginMethods: (opts?: UseLoginMethodsOptions) => LoginMethodsModel;
10
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/auth/login/model.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAG3E;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,UAAW,sBAAsB,KAAG,iBAsF/D,CAAA"}
@@ -0,0 +1,88 @@
1
+ import { useCallback, useMemo, useState } from 'react';
2
+ import { useContext, useNavigate } from '@owlmeans/client';
3
+ import { resolveCredit, LoginOutcome, LOGIN_SERVICE, loginMethodsHelper, loginTermsHelper } from '@owlmeans/client-auth/login';
4
+ import { loginProviderHelper } from './provider.js';
5
+ /**
6
+ * Everything a sign-in screen needs, with no opinion about how it looks.
7
+ *
8
+ * Headless and cross-platform, like `usePanelNav`: the rules about what may be offered, what must
9
+ * be confirmed first, what the credit line says and who is disclosed as signing the person in are
10
+ * the same on every platform, and only the rendering differs. A renderer that re-derives any of them will drift from the one that does not.
11
+ */
12
+ export const useLoginMethods = (opts) => {
13
+ const context = useContext();
14
+ const nav = useNavigate();
15
+ const login = context.service(LOGIN_SERVICE);
16
+ const cfg = opts?.config ?? context.cfg.security?.auth?.login;
17
+ const brand = context.cfg.brand;
18
+ const resolved = useMemo(() => loginTermsHelper.resolveTerms(opts?.terms ?? cfg?.terms), [opts?.terms, cfg]);
19
+ const credit = useMemo(() => resolveCredit(cfg?.credit, brand, context.cfg.service), [cfg, brand, context]);
20
+ const provider = useMemo(() => loginProviderHelper.resolve(cfg?.provider, brand), [cfg, brand]);
21
+ const [accepted, setAccepted] = useState(() => loginTermsHelper.termsAccepted(resolved));
22
+ const [attempted, setAttempted] = useState(false);
23
+ const [busy, setBusy] = useState(null);
24
+ const [outcome, setOutcome] = useState(null);
25
+ const [error, setError] = useState(null);
26
+ const env = login.env();
27
+ const all = login.methods({
28
+ context, env,
29
+ navigate: (alias, params) => { nav.go(alias, params != null ? { params } : undefined); },
30
+ });
31
+ const methods = typeof opts?.methods === 'function'
32
+ ? opts.methods(all)
33
+ : opts?.methods ?? all;
34
+ const deferred = loginTermsHelper.termsDeferred(context);
35
+ const blocked = resolved != null && resolved.required && !deferred && !accepted;
36
+ const select = useCallback((method) => {
37
+ if (blocked) {
38
+ // Nothing starts, and no window opens. The screen renders the reason instead — which is why
39
+ // a control must never be `disabled`: a disabled control swallows the click and says nothing.
40
+ setAttempted(true);
41
+ return;
42
+ }
43
+ setBusy(method.id);
44
+ setError(null);
45
+ void method.start({
46
+ context, env,
47
+ navigate: (alias, params) => { nav.go(alias, params != null ? { params } : undefined); },
48
+ }).then(result => {
49
+ setOutcome(result);
50
+ // `Redirected` means the browser is leaving; keeping the control busy is honest there.
51
+ if (result !== LoginOutcome.Redirected) {
52
+ setBusy(null);
53
+ }
54
+ }).catch((e) => {
55
+ setError(e.message);
56
+ setOutcome(LoginOutcome.Failed);
57
+ setBusy(null);
58
+ });
59
+ }, [blocked, context, env, nav]);
60
+ const accept = useCallback((value) => {
61
+ setAccepted(value);
62
+ setAttempted(false);
63
+ loginTermsHelper.acceptTerms(resolved, value);
64
+ }, [resolved]);
65
+ return {
66
+ methods,
67
+ primary: loginMethodsHelper.primaryLoginMethod(methods),
68
+ terms: {
69
+ required: resolved?.required ?? false,
70
+ accepted: resolved == null ? true : accepted,
71
+ deferred,
72
+ attempted,
73
+ documents: resolved?.documents ?? [],
74
+ notices: resolved?.notices ?? [],
75
+ ...(resolved?.revisedAt != null ? { revisedAt: resolved.revisedAt } : {}),
76
+ version: resolved?.version ?? '',
77
+ accept,
78
+ },
79
+ credit,
80
+ provider,
81
+ blocked,
82
+ busy,
83
+ outcome,
84
+ error,
85
+ select,
86
+ };
87
+ };
88
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/auth/login/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** The names a provider sentence may carry, matched in one pass. */
2
+ export declare const PROVIDER_PLACEHOLDER: RegExp;
3
+ //# sourceMappingURL=consts.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../../../../src/auth/login/provider/consts.local.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,eAAO,MAAM,oBAAoB,QAAyC,CAAA"}
@@ -0,0 +1,3 @@
1
+ /** The names a provider sentence may carry, matched in one pass. */
2
+ export const PROVIDER_PLACEHOLDER = /\{\{(provider|operator|product)\}\}/g;
3
+ //# sourceMappingURL=consts.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../../../../src/auth/login/provider/consts.local.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,sCAAsC,CAAA"}
@@ -0,0 +1,37 @@
1
+ import type { LoginProviderConfig } from './types.js';
2
+ /**
3
+ * `LoginScreenConfig.provider`, added by TypeScript module augmentation rather than by editing
4
+ * `@owlmeans/config` itself.
5
+ *
6
+ * `@owlmeans/config` has roughly 85 dependents, and every one of them sits in the same release
7
+ * closure — a config bump ripples through every package that pins a range against it, whether or
8
+ * not it touches sign-in. The field below is read by exactly one consumer family (the sign-in
9
+ * screen's headless model here and its renderers), so it is declared here instead, merged onto the
10
+ * base interface by TypeScript's own declaration merging — the pattern
11
+ * `@owlmeans/client-auth/login`'s `terms-config.ts` set.
12
+ *
13
+ * This file must be part of whatever a consumer's own compilation actually loads, or the merge
14
+ * never happens — an ambient augmentation applies only once the compiler has read the file that
15
+ * declares it. `@owlmeans/client-panel/auth`'s barrel re-exports this module for exactly that
16
+ * reason, so ANY import from `@owlmeans/client-panel/auth` pulls this augmentation into that
17
+ * program. An app that builds its `security.auth.login` literal in a file that imports nothing from
18
+ * it (a config file importing only `@owlmeans/config`) still benefits as long as some other file in
19
+ * the same `tsc` program does; if none does, add `import type {} from '@owlmeans/client-panel/auth'`
20
+ * to the file building the literal — an import with an empty type list, kept only to pull this
21
+ * file into that program's graph.
22
+ *
23
+ * `export {}` below is required, not decorative: without at least one top-level import/export this
24
+ * file is a SCRIPT to TypeScript, not a MODULE, and `declare module '@owlmeans/config'` inside a
25
+ * script augments the global scope instead of merging onto the named module's exports.
26
+ */
27
+ declare module '@owlmeans/config' {
28
+ interface LoginScreenConfig {
29
+ /**
30
+ * Who signs a person in on this application's behalf — an identity service the application
31
+ * does not itself run. Absent, the screen discloses nothing and renders exactly as before.
32
+ */
33
+ provider?: LoginProviderConfig;
34
+ }
35
+ }
36
+ export {};
37
+ //# sourceMappingURL=provider-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-config.d.ts","sourceRoot":"","sources":["../../../src/auth/login/provider-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,QAAQ,kBAAkB,CAAC;IAChC,UAAU,iBAAiB;QACzB;;;WAGG;QACH,QAAQ,CAAC,EAAE,mBAAmB,CAAA;KAC/B;CACF;AAED,OAAO,EAAG,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-config.js","sourceRoot":"","sources":["../../../src/auth/login/provider-config.ts"],"names":[],"mappings":""}