@ofidj/generator-fidj 3.10.2 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,19 +51,35 @@ one.
51
51
  - `--logo <image>` and `--favicon <image>`: the app's own marks, copied into `public/brand/`. The logo sits beside the app name at the top of the sign-in panel; the favicon goes in the browser tab. Both fall back to the Fidj mark, so neither is ever blank. Accepts `.png`, `.svg`, `.gif`, `.jpg`, `.webp` or `.ico` under 512KB — an animated GIF works as a logo, and as a favicon in the browsers that animate one.
52
52
  - `--api-endpoint`: select the API (default: hosted sandbox).
53
53
  - `--sdk-path` or `FIDJ_SDK_DIR`: use a built local SDK during coordinated development.
54
+ - `--entry-path` or `FIDJ_ENTRY_DIR`: same, for a built local `@ofidj/entry` — the sign-in and account screens, the agreement and the design system. Point it at that package's `dist`, as with the SDK.
54
55
  - `--local` or `FIDJ_LOCAL=true`: use the loopback API/console. Test credentials stay in the validation guide, outside the content app UI. Supply the matching local app ID; `FIDJ_APP_ID` can override it.
55
56
  - `--replace`: regenerate only a destination containing `.fidj-generated`; unmarked projects are protected.
56
57
 
57
- The generated shell paints from one design system: `src/tokens.css` holds every
58
- colour, family and radius, and `src/style.css` may not introduce a literal of
59
- its own. Fonts are self-hosted under `public/fonts` and served from the build
60
- manifest, so a generated site stays statically hostable and makes no
61
- third-party request on sign-in. fidj-app consumes the same tokens, which is why
62
- a style change lands here first.
58
+ **The entry is a dependency, not a copy.** `@ofidj/entry` carries the sign-in
59
+ and account screens, the service agreement, the provider window, the version
60
+ badge and the design system; the generated app imports them the way it imports
61
+ the SDK. They used to be files in this template, which meant the only way to
62
+ ship a fix was to regenerate every app — and meant Fidj's own console had to be
63
+ generated to reach them. A style change now lands in that package, and this
64
+ template is what remains genuinely the generator's: the shells that hold the
65
+ screens, the content app and the Notes app.
66
+
67
+ This is an architecture boundary, not only a packaging detail: never copy a
68
+ credential, signup, recovery or agreement component into a generated output.
69
+ The template may compose a shell and call `@ofidj/entry` after dynamic rendering,
70
+ but the markup rules and browser behavior such as password reveal belong in
71
+ `fidj-entry`. A fix there must reach Fidj, mleweb and newly generated apps
72
+ without maintaining parallel component implementations.
73
+
74
+ The design system is `@ofidj/entry`'s `tokens.css` — every colour, family and
75
+ radius — and its `style.css`, which may not introduce a literal of its own.
76
+ Fonts are self-hosted under `public/fonts` and served from the build manifest,
77
+ so a generated site stays statically hostable and makes no third-party request
78
+ on sign-in.
63
79
 
64
80
  Generation writes `.env.example`, `.env` and public `app.config.json`. Static configuration is embedded at build time: regenerate/rebuild when changing endpoints. Notes server configuration is read at runtime. Do not place secrets in any public configuration or content input.
65
81
 
66
- For unpublished coordinated changes, build the sibling SDK and pass `--sdk-path` with its absolute `dist` path. Committed templates use registry dependency `@ofidj/node ^3.7.3`; a registry-only install is not validated until coordinated versions are published.
82
+ For unpublished coordinated changes, build the sibling SDK and entry packages and pass `--sdk-path` and `--entry-path` with their absolute `dist` paths. Committed templates name registry ranges for both; a registry-only install is not validated until coordinated versions are published.
67
83
 
68
84
  Every generated app carries a fixed bottom-right badge naming the Fidj it runs:
69
85
  `fidj@<version>`, taken from the SDK it was generated with — the `--sdk-path`
@@ -106,10 +122,11 @@ The generated content app opens on `/#/signin`. Sign in, or choose **Enter anony
106
122
  is the one control on the screen wearing `--fidj-accent`, because it is the one
107
123
  that belongs to Fidj rather than to the app — and it is the path where the app
108
124
  never sees a password. An app generated with `--signin both` keeps its own
109
- email-and-password form under an *Inline form* disclosure, with its service
110
- agreement: opening it folds the Fidj door away, because the two are alternatives
111
- rather than a list. That agreement gates the app's own door and nothing else, so
112
- an agreement that fails to load never shuts the Fidj door.
125
+ email-and-password form under an *Inline form* disclosure: opening it folds the
126
+ Fidj door away, because the two are alternatives rather than a list. Whichever
127
+ door is taken runs the same two screens — credentials, with the verification
128
+ wait appearing beneath them on the create path, and then the agreement — so the
129
+ button is a shortcut to the flow, not a different one.
113
130
 
114
131
  Pressing it opens Fidj in a browser window of its own rather than navigating
115
132
  away. Fidj's screens are served from another origin and refuse to be framed, so
@@ -161,11 +178,26 @@ A compatible issuer, REST API and registered callback without a fragment are pre
161
178
 
162
179
  ## Required service agreement
163
180
 
164
- All generated sign-in and account-creation forms (content, composed Fidj and
165
- Notes) share an unchecked required agreement checkbox. Both submit buttons stay
166
- disabled until it is checked. Reading the agreement opens an in-app dialog;
167
- failed agreement loading keeps sign-in blocked. Anonymous entry, when enabled,
168
- is not a login and does not record agreement acceptance.
181
+ [The workspace README](../README.md#entry-one-flow-the-same-everywhere) defines
182
+ the flow every Fidj sign-in surface follows, and this generator owns the
183
+ implementation the others render. In short: the first screen asks for an email,
184
+ a password, **Sign in** and **Create an account**, and gates neither; creating an
185
+ account grows a verification wait beneath that same form rather than replacing
186
+ it; and the agreement is its own screen, shown whenever the version recorded for
187
+ this person and this app is not the current one, with its submit button
188
+ read-only until the box is ticked.
189
+
190
+ The agreement screen's markup, its loading and its disabled-button rule live in
191
+ `@ofidj/entry` — one implementation for the app's own form, the composed Fidj
192
+ console and the Fidj-hosted consent page of the beta OIDC provider — so an owner
193
+ who publishes a new version changes one thing and every surface asks again.
194
+ Anonymous entry, when enabled, is not a login and records no acceptance.
195
+
196
+ Both generated entries render this. The content app and the Notes starter lost
197
+ their checkbox beside the credentials and their local gate; each calls `login`,
198
+ and the API's `409 agreement_required` is what puts the agreement screen on
199
+ screen, carrying the version it compared against. `--signin button` delegates
200
+ the whole question to Fidj and never had one.
169
201
 
170
202
  The text and version come from the app's public API metadata, not copied generator
171
203
  settings. The API records acceptance before issuing the app token, preserves
@@ -9,6 +9,7 @@ try {
9
9
  "api-endpoint": { type: "string" },
10
10
  "oidc-issuer": { type: "string" },
11
11
  "sdk-path": { type: "string" },
12
+ "entry-path": { type: "string" },
12
13
  title: { type: "string" },
13
14
  welcome: { type: "string" },
14
15
  description: { type: "string" },
@@ -39,6 +40,7 @@ try {
39
40
  apiEndpoint: values["api-endpoint"],
40
41
  oidcIssuer: values["oidc-issuer"],
41
42
  sdkPath: values["sdk-path"] || process.env.FIDJ_SDK_DIR,
43
+ entryPath: values["entry-path"] || process.env.FIDJ_ENTRY_DIR,
42
44
  title: values.title,
43
45
  welcome: values.welcome,
44
46
  description: values.description,
@@ -9,6 +9,7 @@ const TEXT_OPTIONS = [
9
9
  "api-endpoint",
10
10
  "oidc-issuer",
11
11
  "sdk-path",
12
+ "entry-path",
12
13
  "title",
13
14
  "welcome",
14
15
  "description",
@@ -99,6 +100,7 @@ module.exports = class extends Generator {
99
100
  moduleEntry: this.options["module-entry"],
100
101
  domain: this.options.domain,
101
102
  sdkPath: this.options["sdk-path"] || process.env.FIDJ_SDK_DIR,
103
+ entryPath: this.options["entry-path"] || process.env.FIDJ_ENTRY_DIR,
102
104
  oidcIssuer: this.options["oidc-issuer"],
103
105
  local: this.options.local || process.env.FIDJ_LOCAL === "true",
104
106
  replace: this.options.replace,
@@ -15,7 +15,8 @@
15
15
  "privacy:rehearse": "npm run build && node --test test/server.test.mjs"
16
16
  },
17
17
  "dependencies": {
18
- "@ofidj/node": "^3.10.0"
18
+ "@ofidj/entry": "^3.13.0",
19
+ "@ofidj/node": "^3.13.0"
19
20
  },
20
21
  "devDependencies": {
21
22
  "@types/node": "^22.0.0",
@@ -342,7 +342,8 @@ if (require.main === module) {
342
342
  localDemo:
343
343
  process.env.LOCAL_DEMO === "true" &&
344
344
  host === "127.0.0.1" &&
345
- ["localhost", "127.0.0.1"].includes(api.hostname),
345
+ (["localhost", "127.0.0.1"].includes(api.hostname) ||
346
+ api.hostname.endsWith(".localhost")),
346
347
  };
347
348
  createApp(settings, {
348
349
  dataDir: process.env.FIDJ_DATA_DIR,