@wix/himalaya-cli 0.1432.0 → 0.1433.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/dist/cli.mjs +856 -417
- package/guides/base44-app-to-himi-app.md +75 -29
- package/guides/base44-entities.md +0 -1
- package/guides/himi-json-output.md +18 -0
- package/package.json +2 -2
|
@@ -61,8 +61,8 @@ whose `Task` entity anyone may read and write:
|
|
|
61
61
|
|
|
62
62
|
| Tab | Screen | Worker | Pattern it shows |
|
|
63
63
|
|---|---|---|---|
|
|
64
|
-
| Tasks | `b44_tasks` | `
|
|
65
|
-
| (pushed) | `b44_task` | `task` | read one row by its id (a nav param), edit, delete then go back |
|
|
64
|
+
| Tasks | `b44_tasks` | `b44-task-list` | **generated** by `himi base44 screens`: list, create, delete; loading / empty / error / ready; pull to refresh |
|
|
65
|
+
| (pushed) | `b44_task` | `b44-task` | **generated**: read one row by its id (a nav param), edit, delete then go back |
|
|
66
66
|
| Functions | `b44_functions` | `functions` | `functions.invoke(name, payload)` with the reply and the error painted |
|
|
67
67
|
| Account | `b44_account` | `account` | Native Google sign-in (requires tenant app-link associations), email + password and emailed-code sign-in, register, reset, profile, sign out |
|
|
68
68
|
|
|
@@ -89,10 +89,14 @@ Turn the book's entities and functions into an adopted declaration, then wire it
|
|
|
89
89
|
himi base44 adopt --content . --book ../.himi/base44-book --write # the book step 1 wrote, one level up → base44-entities.ts (never overwrites)
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
+
The starter's `config.ts` declares the sample `Task` as a local `const base44Entities = [...]`.
|
|
93
|
+
Delete that declaration, then import yours in its place (keeping both fails with "Identifier
|
|
94
|
+
'base44Entities' has already been declared"):
|
|
95
|
+
|
|
92
96
|
```ts
|
|
93
97
|
import { base44Entities, base44Functions } from "./base44-entities.js";
|
|
94
98
|
// …
|
|
95
|
-
base44: { appId:
|
|
99
|
+
base44: { appId: base44AppId, entities: base44Entities, functions: base44Functions },
|
|
96
100
|
```
|
|
97
101
|
|
|
98
102
|
`himi validate` then lints the declaration (`pass: "base44"`), and `himi base44 entities query`
|
|
@@ -112,15 +116,21 @@ until you do. See [`base44-sdk`](base44-sdk.md#typed-rows).
|
|
|
112
116
|
|
|
113
117
|
## 3. Plan the screens from the book
|
|
114
118
|
|
|
119
|
+
`himi base44 screens` (step 4) applies the rules below for you, so this step is about choosing
|
|
120
|
+
**what to declare**: which entities, in what order (with up to three entities each gets a tab; with
|
|
121
|
+
four or more, the first two get tabs and the rest go under More), which fields and which `rls`. The rules describe what the generator emits. Read them to predict the result, and to
|
|
122
|
+
know what to customise afterwards.
|
|
123
|
+
|
|
115
124
|
Write `.himi/screen-plan.md` before editing code. For each entity in `book.entities`:
|
|
116
125
|
|
|
117
126
|
1. **Decide whether it gets a tab.** An entity that a top-level route reads (`routes[].entities`)
|
|
118
127
|
and that a user browses gets a tab. A child entity (one whose rows only make sense under a
|
|
119
128
|
parent, such as `OrderItem` under `Order`) gets a section on the parent's detail screen
|
|
120
129
|
instead. Keep to 3–5 tabs. Account always takes one when the app is not public (step 5).
|
|
121
|
-
2. **Pick the list row.** The title is the
|
|
122
|
-
`title`, `name` or `label`. The subtitle is
|
|
123
|
-
number). Never put a long text field in a
|
|
130
|
+
2. **Pick the list row.** The title is the entity's `displayField` if it declares one, else the
|
|
131
|
+
first `required` string field, preferring one named `title`, `name` or `label`. The subtitle is
|
|
132
|
+
one or two short fields (a status `enum`, a date, a number). Never put a long text field in a
|
|
133
|
+
row.
|
|
124
134
|
3. **Pick the detail and form fields** from each field's JSON Schema type:
|
|
125
135
|
|
|
126
136
|
| Field (`type` / `format` / `enum`) | Detail shows | Form control |
|
|
@@ -129,20 +139,28 @@ Write `.himi/screen-plan.md` before editing code. For each entity in `book.entit
|
|
|
129
139
|
| `string` + long text (`description`, `notes`, `body`, …) | `Text` with `maxLines` | `TextField` with `multilineMaxLines` |
|
|
130
140
|
| `string` + `enum` | `Badge` / `Text` | `SegmentedControl` (≤ 4 values) or `Picker` |
|
|
131
141
|
| `string` + `format: date` / `date-time` | formatted `Text` | `DatePicker` |
|
|
132
|
-
| `string` + `format: email` / `uri` | `Text
|
|
142
|
+
| `string` + `format: email` / `uri` | `Text` (the generator does not make it tappable yet) | `TextField` with `keyboard: "email"` / `"url"` |
|
|
133
143
|
| `string` holding an image URL (`image`, `photo`, `avatar`, `*_url`) | `Image` | read-only, see [file upload](#what-the-sdk-cannot-do) |
|
|
134
144
|
| `number` / `integer` | `Text` (with unit) | `Stepper` (small ranges) or numeric `TextField` |
|
|
135
145
|
| `boolean` | `Badge` or `Text` | `Toggle` |
|
|
136
|
-
| `array` of strings |
|
|
137
|
-
| `object` / nested `array` of objects | a sub-section of rows | none
|
|
146
|
+
| `array` of strings | comma-joined `Text` | `ChipsInput` |
|
|
147
|
+
| `object` / nested `array` of objects | its JSON as `Text` (a sub-section of rows is yours to build) | none. Edit it on the web app |
|
|
138
148
|
| built-ins `id`, `created_date`, `updated_date`, `created_by` | "Created …" metadata row | never editable |
|
|
139
149
|
|
|
140
150
|
4. **Respect the entity's rules.** `rls` (and field-level `rls`) decide what the signed-in user
|
|
141
|
-
may do.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
may do. Declare the `rls` `BOOK.md` lists for the entity. The generator gates each write
|
|
152
|
+
control on its operation's rule (falling back to the entity-level `write` rule):
|
|
153
|
+
|
|
154
|
+
| Rule | Control |
|
|
155
|
+
|---|---|
|
|
156
|
+
| `false`, or absent | not emitted at all |
|
|
157
|
+
| `true` | always shown |
|
|
158
|
+
| exactly `{ "created_by": "{{user.email}}" }` or `{ "created_by_id": "{{user.id}}" }` | shown only on the signed-in user's own rows |
|
|
159
|
+
| any other condition | shown only when signed in |
|
|
160
|
+
|
|
161
|
+
A field whose field-level `rls.write` is not `true` is read-only in the form. The gate is
|
|
162
|
+
advisory: a denied call still fails with Base44's message, and every screen paints that error
|
|
163
|
+
rather than swallowing it.
|
|
146
164
|
5. **Use the sample rows** (`sampleRows`, already redacted) to size rows and choose the subtitle,
|
|
147
165
|
never as data the app ships.
|
|
148
166
|
|
|
@@ -151,22 +169,48 @@ Compose each screen with [`designing-himi-screens`](designing-himi-screens.md)
|
|
|
151
169
|
|
|
152
170
|
## 4. Build one list + detail per entity
|
|
153
171
|
|
|
154
|
-
|
|
172
|
+
Declare the entity, then generate its screens:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
himi base44 adopt --content . --book ../.himi/base44-book --write # or declare by hand (step 2)
|
|
176
|
+
himi base44 screens --content . --json
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
For each entity in `config.ts` `base44.entities`, `himi base44 screens` writes a list screen
|
|
180
|
+
(`b44_<plural>`, e.g. `b44_projects`) and a detail screen (`b44_<name>`, e.g. `b44_project`):
|
|
181
|
+
|
|
182
|
+
- `tier5-src/_shared/b44-<entity>-plan.ts`: the plan (row title and subtitle, facts, form
|
|
183
|
+
controls, write gates) the rules in step 3 produce. The list, the detail and the descriptors all
|
|
184
|
+
read it, so this is the file to customise.
|
|
185
|
+
- `tier5-src/b44-<entity>-list/index.ts` and `tier5-src/b44-<entity>/index.ts`: one-line worker
|
|
186
|
+
entries over the template's shared engine (`_shared/entity-list.ts`, `_shared/entity-detail.ts`).
|
|
187
|
+
Each entity gets its own bundle and service, so two entity tabs never share state.
|
|
188
|
+
- `dev/entities.generated.ts` and `config.entities.generated.ts`: the screen registrations and the
|
|
189
|
+
`linkableScreens` / `tabBar` items. `dev/index.ts` and `config.ts` already import them.
|
|
190
|
+
|
|
191
|
+
The first three entities in config order get a tab, in front of Functions and Account. With more,
|
|
192
|
+
the last entity slot becomes a generated `b44_more` screen listing the rest, so the bar never has
|
|
193
|
+
more than five items. Ids pluralise naively (`Category` → `b44_categories`, `Person` →
|
|
194
|
+
`b44_persons`); give the entity a `title` for the visible name. Two entities that would share an id
|
|
195
|
+
are refused with `code: "entity_id_collision"`.
|
|
196
|
+
|
|
197
|
+
Re-running is safe. Each generated file starts with
|
|
198
|
+
`// @generated by himi base44 screens — sha256:<hash>`:
|
|
199
|
+
|
|
200
|
+
- an unchanged config reports every file `unchanged` and writes nothing;
|
|
201
|
+
- a generated file you edited by hand (its body no longer matches the hash) is reported
|
|
202
|
+
`skipped-edited` and left alone, and the command still exits 0. Pass `--force` to overwrite it;
|
|
203
|
+
- files for an entity you removed from `config.ts` are reported in `orphaned[]` and never deleted.
|
|
204
|
+
|
|
205
|
+
`--dry-run` reports the same outcomes without writing. Failures carry a top-level `code`
|
|
206
|
+
(`no_entities_block`, `entity_id_collision`, `content_dir_not_base44_starter`), per
|
|
207
|
+
[`himi-json-output`](himi-json-output.md). The generator never calls Base44.
|
|
155
208
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
guard, and `derive()` producing the `hide*` flags.
|
|
160
|
-
- `tier5-src/project/index.ts` from `tier5-src/task/index.ts`. `inputId()` reads the row id from
|
|
161
|
-
the nav param, `get(id)` loads it, and `remove` returns `navigate(…, { presentation: "back" })`
|
|
162
|
-
from the action the host dispatched.
|
|
163
|
-
- In `dev/index.ts`, a `projects()` and a `project()` builder (copy `tasks()` and `task()`), each
|
|
164
|
-
bound with `bundle: "<worker dir>"` and `declaredCapabilities: ["base44"]`. Register both in
|
|
165
|
-
`screens.exact` and the tab root in `seed.screens`.
|
|
166
|
-
- In `config.ts`, a `linkableScreens` entry for each (the detail with `paramKeys: ["id"]` and its
|
|
167
|
-
list as `parentScreenId`) and a `tabBar` item for the list.
|
|
209
|
+
To change a screen beyond what the plan expresses (a filtered list, a child section, a custom
|
|
210
|
+
action), edit its generated entry or plan. The edit makes the file `skipped-edited`, so the
|
|
211
|
+
generator leaves it alone from then on.
|
|
168
212
|
|
|
169
|
-
The calls a worker
|
|
213
|
+
The calls the engine makes (and a customised worker can make), all on `entities("<Name>")`:
|
|
170
214
|
|
|
171
215
|
| Need | Call |
|
|
172
216
|
|---|---|
|
|
@@ -187,7 +231,9 @@ Rules that keep it correct:
|
|
|
187
231
|
`$item.openLabel`. `himi validate` flags this as an error.
|
|
188
232
|
- **Every write re-lists**, and a failed write keeps the list on screen with the error above it.
|
|
189
233
|
Only a failed *first* list is the error state.
|
|
190
|
-
-
|
|
234
|
+
- Replace the sample `Task` declaration with your own entities and re-run `himi base44 screens`.
|
|
235
|
+
The home screen is the first entity's list. The generator reports the sample's files as
|
|
236
|
+
`orphaned`; delete them by hand.
|
|
191
237
|
|
|
192
238
|
## 5. Auth: the Account tab
|
|
193
239
|
|
|
@@ -147,4 +147,3 @@ Failure codes are listed in [`himi-json-output`](himi-json-output.md#himi-base44
|
|
|
147
147
|
full-set sync, which is why it is a separate, deliberate step.
|
|
148
148
|
- **Typed clients and hermetic test data**: `entities<"X">()` typed from the declaration, with
|
|
149
149
|
`seed` rows as mocks.
|
|
150
|
-
- **Generated screens**: list and detail screens per declared entity.
|
|
@@ -249,6 +249,24 @@ branch on them without parsing prose:
|
|
|
249
249
|
- `source_unavailable`: the project download (the eject read) failed, so no drift was
|
|
250
250
|
computed. Row counts still ran; `sourceRead` is `"unavailable"` and `sourceError` says why.
|
|
251
251
|
|
|
252
|
+
## `himi base44 screens` codes
|
|
253
|
+
|
|
254
|
+
`himi base44 screens` (#4560, [base44-app-to-himi-app](base44-app-to-himi-app.md)) generates one
|
|
255
|
+
list + detail screen per declared `base44.entities` entity. Failures print `ok: false` and `code`
|
|
256
|
+
on stderr (exit 1):
|
|
257
|
+
|
|
258
|
+
- `content_dir_not_base44_starter`: the directory lacks the shared engine the generated files
|
|
259
|
+
import (`missing[]` names the files). Scaffold with `himi init --template base44-starter`.
|
|
260
|
+
- `no_entities_block`: `config.ts` declares no `base44.entities`, so there is nothing to generate.
|
|
261
|
+
- `entity_id_collision`: two entities would generate the same screen id (or one would shadow
|
|
262
|
+
`b44_functions` / `b44_account` / `b44_more`); `entity`, `screenId` and `with` name the clash.
|
|
263
|
+
- `config_unloadable` / `invalid_config`: as for `himi base44 entities` above.
|
|
264
|
+
|
|
265
|
+
On success (`ok: true`, stdout, exit 0) `files[]` gives every generated path with its `outcome`:
|
|
266
|
+
`written`, `unchanged`, or `skipped-edited` (the file was edited by hand and was left alone; pass
|
|
267
|
+
`--force` to overwrite it). A skipped file is not a failure. `orphaned[]`, when present, lists
|
|
268
|
+
generated files for entities no longer declared. They are never deleted.
|
|
269
|
+
|
|
252
270
|
## Follow-ups
|
|
253
271
|
|
|
254
272
|
- Migrate failure envelopes in subcommands other than `push`, keeping this contract.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1433.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"artifactId": "himalaya-cli"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
"falconPackageHash": "
|
|
74
|
+
"falconPackageHash": "f0352e9dd51208b098564413b02976840565ff1539e321ae4ea327f5"
|
|
75
75
|
}
|