@botlr/cli 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/CHANGELOG.md +30 -0
- package/README.md +109 -6
- package/dist/cli.js +688 -143
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +202 -6
- package/dist/index.js +568 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @botlr/cli
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Prop types from the dashboard's schema, and a warning when the code and the dashboard disagree about the props.
|
|
8
|
+
|
|
9
|
+
- `pull` writes `<name>.props.ts` next to the manifest: `export interface <ExportName>Props { ... }` generated from the section definition's props schema as the dashboard stores it (`definition.schema` in the pull response), in both the field DSL and the older FormBuilder format. `required: true` makes a property non-optional; a `select` with plain or `{ value }` options becomes a union of literals; asset and reference types become `string | Record<string, unknown>`; types the CLI does not know become `unknown`. The file carries a "generated, do not edit" header and is left alone when its text is unchanged. `--no-types` on a pull, or `"types": false` in `botlr.config.json`, turns it off.
|
|
10
|
+
- `push` and `sections status` warn when the manifest has a `schema` object (the props the code expects, field DSL only) and its keys differ from the definition's schema on the server: props the code expects that the dashboard does not define, and props the dashboard defines that the code does not list. The warning only reports; the dashboard owns the schema. The manifest's `schema` is otherwise a seed for `push --create`.
|
|
11
|
+
- `sections init` fills `schema` from the zod object a component's `XDefinition.schema` points at when it can read it (field names, a best-effort type, `required` unless optional or defaulted); otherwise it leaves `schema` out.
|
|
12
|
+
- `@botlr/sdk`: `SectionManifest.schema`, the `SectionSchemaField`, `SectionFieldSchema`, `SectionFormBuilderNode`, `SectionFormBuilderSchema` and `SectionSchema` types, and the `isFieldSchema` / `isFormBuilderSchema` guards. `SectionDefinition.schema` is typed as `SectionSchema | Record<string, unknown>`.
|
|
13
|
+
|
|
14
|
+
- Pull writes manifests in a fixed key order and keeps the section registry up to date.
|
|
15
|
+
|
|
16
|
+
- `<name>.botlr.json` is always written as 2-space JSON with `section`, `framework`, `entry`, `exportName`, `files`, `title`, `description`, `category`, `icon`, `dependencies`, then unknown keys alphabetically (`dependencies` lists `npm` before `internal`, nested objects sorted). The server stores manifests as jsonb, which forgets key order, so a pull right after a push no longer shows up as a change in git. A pull also leaves the manifest file alone when it already holds the same data.
|
|
17
|
+
- After a pull, when `publisher-section-registry.ts` (or the file named by the new `registryFile` config key, relative to `sectionsDir`) exists, the CLI adds `import { <exportName> } from "./<entry>";` after the last import and `"<name>": <exportName>,` as the last registry entry, keeping existing entries and formatting. Already-registered sections leave the file untouched; `--no-registry` skips the step; a missing registry prints a one-line notice.
|
|
18
|
+
- `sections init` reads the registry from `registryFile` too.
|
|
19
|
+
- The lock stays one entry per section name per app (documented; `--dir` shares it). `pulledAt` is now kept when the same scope, version and hash land again, so re-pulling does not rewrite the lock.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
- @botlr/sdk@0.4.0
|
|
25
|
+
|
|
26
|
+
## 0.1.2
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [e3ff8e7]
|
|
31
|
+
- @botlr/sdk@0.3.0
|
|
32
|
+
|
|
3
33
|
## 0.1.1
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -17,10 +17,17 @@ pnpm add -D @botlr/cli
|
|
|
17
17
|
"baseUrl": "https://api.botlr.io",
|
|
18
18
|
"appId": "00000000-0000-0000-0000-000000000000",
|
|
19
19
|
"framework": "react-next",
|
|
20
|
-
"sectionsDir": "components/sections"
|
|
20
|
+
"sectionsDir": "components/sections",
|
|
21
|
+
"registryFile": "publisher-section-registry.ts",
|
|
22
|
+
"types": true
|
|
21
23
|
}
|
|
22
24
|
```
|
|
23
25
|
|
|
26
|
+
`registryFile` is optional and relative to `sectionsDir`; it names the
|
|
27
|
+
component registry `pull` keeps up to date and `sections init` reads.
|
|
28
|
+
`types` (default true) makes `pull` write `<name>.props.ts` from the
|
|
29
|
+
definition's props schema; `false` turns it off for the app.
|
|
30
|
+
|
|
24
31
|
Environment: `BOTLR_API_KEY` (site token, for pull/list/status) and
|
|
25
32
|
`BOTLR_PAT` (personal access token with `write:sections`, for push).
|
|
26
33
|
`BOTLR_BASE_URL`, `BOTLR_APP_ID`, `BOTLR_FRAMEWORK` and `BOTLR_SECTIONS_DIR`
|
|
@@ -29,7 +36,7 @@ override the file; `--framework` and `--dir` override both.
|
|
|
29
36
|
## Commands
|
|
30
37
|
|
|
31
38
|
```
|
|
32
|
-
botlr pull <name...> | --all [--framework react-next] [--dir components/sections] [--version N] [--shared] [--force]
|
|
39
|
+
botlr pull <name...> | --all [--framework react-next] [--dir components/sections] [--version N] [--shared] [--force] [--no-registry] [--no-types]
|
|
33
40
|
botlr push <name> [-m msg] [--shared] [--create] [--force]
|
|
34
41
|
botlr sections list
|
|
35
42
|
botlr sections status [name...] [--offline]
|
|
@@ -39,16 +46,112 @@ botlr sections init [--force] [--dry-run]
|
|
|
39
46
|
- `pull` writes every file of the section under `sectionsDir`, plus
|
|
40
47
|
`<name>.botlr.json` (the manifest, never holding version or hash) and the
|
|
41
48
|
lock entry in `.botlr/sections.lock.json`. A section whose local files
|
|
42
|
-
changed since the last pull is skipped unless `--force`.
|
|
49
|
+
changed since the last pull is skipped unless `--force`. When the registry
|
|
50
|
+
file exists, `pull` also adds `import { <exportName> } from "./<entry>";`
|
|
51
|
+
and `"<name>": <exportName>,` to it, keeping what is there; a section that
|
|
52
|
+
is already registered leaves the file untouched, and `--no-registry` skips
|
|
53
|
+
this step. Without a registry file the pull prints a one-line notice.
|
|
54
|
+
A pull also writes `<name>.props.ts` from the definition's props schema
|
|
55
|
+
(see "Prop types" below) unless `--no-types` or `"types": false`.
|
|
43
56
|
- `push` reads the manifest and its files, hashes them, and pushes with
|
|
44
57
|
`baseVersion` from the lock so a stale checkout gets a conflict instead of
|
|
45
58
|
overwriting someone's version. `--force` omits `baseVersion`. `--create`
|
|
46
|
-
adds the section definition when the dashboard does not know it yet
|
|
59
|
+
adds the section definition when the dashboard does not know it yet,
|
|
60
|
+
seeded with the manifest's `schema` when it has one. After the push the
|
|
61
|
+
CLI warns when the manifest's `schema` and the definition's schema list
|
|
62
|
+
different props (see "Schema drift" below).
|
|
47
63
|
- `sections status` compares the local content hash with the lock and the
|
|
48
64
|
server's latest: `clean`, `modified`, `behind`, `diverged`, or
|
|
49
|
-
`untracked` for a manifest with no lock entry.
|
|
65
|
+
`untracked` for a manifest with no lock entry. For manifests that carry a
|
|
66
|
+
`schema`, it also fetches the definition and prints the drift warning
|
|
67
|
+
(not with `--offline`).
|
|
50
68
|
- `sections init` derives first manifests from a satellite app's
|
|
51
69
|
`publisher-section-registry.ts` and the `XDefinition` exports next to each
|
|
52
|
-
component.
|
|
70
|
+
component. When the definition's `schema` points at a `z.object({...})`
|
|
71
|
+
in the same file, the manifest gets a `schema` with the field names and a
|
|
72
|
+
best-effort type (`z.string()` → `text`, `z.number()` → `number`,
|
|
73
|
+
`z.boolean()` → `boolean`, `z.enum([...])` → `select` with options,
|
|
74
|
+
`z.array(...)` → `array`, `z.object`/`z.record` → `json`,
|
|
75
|
+
`z.union([z.string(), z.any()])` → `asset`; `required` unless
|
|
76
|
+
`.optional()`, `.nullable()` or `.default(...)`). Fields it cannot read are
|
|
77
|
+
left out, and so is `schema` when nothing could be read. Review them, then
|
|
78
|
+
`botlr push <name> --create` per section.
|
|
79
|
+
|
|
80
|
+
## Prop types
|
|
81
|
+
|
|
82
|
+
The dashboard owns a section definition's props schema. `pull` turns it
|
|
83
|
+
into TypeScript so a component does not have to repeat it in zod:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
// components/sections/hero.props.ts (generated, do not edit)
|
|
87
|
+
export interface HeroProps {
|
|
88
|
+
/** Heading */
|
|
89
|
+
heading: string;
|
|
90
|
+
subheading?: string;
|
|
91
|
+
alignment?: "left" | "center" | "right";
|
|
92
|
+
image?: string | Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The interface is named after the manifest's `exportName` (else a
|
|
97
|
+
PascalCase of the slug) plus `Props`. Field types map as follows: text,
|
|
98
|
+
textarea, markdown, richtext, string, email, tel, url, icon, color, date,
|
|
99
|
+
datetime → `string`; number, integer, currency → `number`; boolean →
|
|
100
|
+
`boolean`; select → a union of the option values (`options` as plain values
|
|
101
|
+
or `{ value }` objects), else `string`, and an array of that with
|
|
102
|
+
`multiple`; multiselect, tags → `string[]`; array, list, repeater →
|
|
103
|
+
`unknown[]`; json, jsonb, object → `Record<string, unknown>`; asset,
|
|
104
|
+
asset-picker-*, media, document, page, reference, relation,
|
|
105
|
+
entity_reference, app_instance, forum_thread → `string | Record<string,
|
|
106
|
+
unknown>`; anything else → `unknown`. `required: true` makes the property
|
|
107
|
+
non-optional. The older FormBuilder format (`{ nodes: [...] }`) is walked
|
|
108
|
+
the same way, with groups flattened and repeater items typed from their
|
|
109
|
+
`fields`. A definition without fields yields `Record<string, unknown>`. The
|
|
110
|
+
file is rewritten only when its text changes. Import the type in the
|
|
111
|
+
component:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import type { HeroProps } from "./hero.props";
|
|
115
|
+
export function Hero(props: HeroProps) { ... }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Schema drift
|
|
119
|
+
|
|
120
|
+
A manifest may carry a `schema` object in the field DSL (the same shape the
|
|
121
|
+
dashboard stores): the props the code expects. The CLI never writes it to
|
|
122
|
+
the server's definition except as the seed for `push --create`. On `push`
|
|
123
|
+
and `sections status` it compares that object's keys with the definition's
|
|
124
|
+
schema and warns:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
warning: props schema of 'hero' differs between the code and the dashboard
|
|
128
|
+
the code expects props the dashboard does not define: ctaLink
|
|
129
|
+
the dashboard defines props the code does not list: image
|
|
130
|
+
the dashboard owns the schema: edit it there, or update 'schema' in hero.botlr.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The warning changes nothing; fix the schema in the dashboard, pull to
|
|
134
|
+
refresh `<name>.props.ts`, and update the manifest's `schema` (or drop it)
|
|
135
|
+
when the code catches up.
|
|
136
|
+
|
|
137
|
+
## Manifest format
|
|
138
|
+
|
|
139
|
+
The CLI always writes `<name>.botlr.json` the same way: 2-space JSON with
|
|
140
|
+
the keys `section`, `framework`, `entry`, `exportName`, `files`, `title`,
|
|
141
|
+
`description`, `category`, `icon`, `dependencies`, `schema` in that order,
|
|
142
|
+
then any other keys alphabetically; inside `dependencies`, `npm` before `internal`,
|
|
143
|
+
with package names sorted. The server stores manifests as jsonb and does not
|
|
144
|
+
keep key order, so this normalization is what makes a pull right after a
|
|
145
|
+
push produce no diff. A pull leaves a manifest file alone when the local
|
|
146
|
+
file already says the same thing, whatever its formatting.
|
|
147
|
+
|
|
148
|
+
## The lock file
|
|
149
|
+
|
|
150
|
+
`.botlr/sections.lock.json` has one entry per section name for the whole
|
|
151
|
+
app, next to `botlr.config.json`. It is not keyed by directory: `--dir`
|
|
152
|
+
points a command at another sections directory but records into the same
|
|
153
|
+
lock, so a section name means one thing per app. `pulledAt` is when the
|
|
154
|
+
recorded version first landed locally; pulling the same version again keeps
|
|
155
|
+
it, so a no-op pull does not touch the lock file either.
|
|
53
156
|
|
|
54
157
|
Commit the manifests and the lock file; keep `BOTLR_PAT` out of the repo.
|