@botlr/cli 0.1.2 → 0.3.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 +39 -0
- package/README.md +154 -8
- package/dist/cli.js +902 -138
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +303 -6
- package/dist/index.js +719 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { SectionSourceScope, SectionManifest, SectionSourceFileInput, SectionSourceScopeSummary, SectionSourceSummary, BotlrClient } from '@botlr/sdk';
|
|
1
|
+
import { SectionSourceScope, SectionManifest, SectionSourceFileInput, SectionSourceScopeSummary, SectionSourceSummary, SectionFieldSchema, SectionSchemaField, SectionFormBuilderNode, SectionSchema, SectionSchemaFormat, BotlrClient } from '@botlr/sdk';
|
|
2
2
|
|
|
3
3
|
declare const CONFIG_FILE = "botlr.config.json";
|
|
4
4
|
declare const DEFAULT_FRAMEWORK = "react-next";
|
|
5
5
|
declare const DEFAULT_SECTIONS_DIR = "components/sections";
|
|
6
|
+
declare const DEFAULT_REGISTRY_FILE = "publisher-section-registry.ts";
|
|
6
7
|
/** `botlr.config.json` */
|
|
7
8
|
interface BotlrCliConfigFile {
|
|
8
9
|
baseUrl?: string;
|
|
9
10
|
appId?: string;
|
|
10
11
|
framework?: string;
|
|
11
12
|
sectionsDir?: string;
|
|
13
|
+
/** Registry file `pull` keeps up to date, relative to `sectionsDir`. Default `publisher-section-registry.ts`. */
|
|
14
|
+
registryFile?: string;
|
|
15
|
+
/** Write `<name>.props.ts` after a pull. Default true; `false` turns it off (`--no-types` does per call). */
|
|
16
|
+
types?: boolean;
|
|
12
17
|
}
|
|
13
18
|
interface ResolvedConfig {
|
|
14
19
|
/** Directory holding `botlr.config.json` (or the cwd when there is none). Paths resolve against it. */
|
|
@@ -19,6 +24,10 @@ interface ResolvedConfig {
|
|
|
19
24
|
framework: string;
|
|
20
25
|
/** Absolute path of the sections directory. */
|
|
21
26
|
sectionsDir: string;
|
|
27
|
+
/** Absolute path of the registry file (`sectionsDir/publisher-section-registry.ts` by default); it may not exist. */
|
|
28
|
+
registryFile: string;
|
|
29
|
+
/** Whether `pull` writes `<name>.props.ts` from the definition's schema. */
|
|
30
|
+
types: boolean;
|
|
22
31
|
/** Site token, `BOTLR_API_KEY`. */
|
|
23
32
|
apiKey: string | undefined;
|
|
24
33
|
/** Personal access token, `BOTLR_PAT`. */
|
|
@@ -52,11 +61,25 @@ interface LockEntry {
|
|
|
52
61
|
framework: string;
|
|
53
62
|
version: number;
|
|
54
63
|
contentHash: string;
|
|
55
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* ISO timestamp of the pull or push that first put this version here. A
|
|
66
|
+
* pull that lands the same scope, version and hash again keeps it, so
|
|
67
|
+
* re-pulling does not touch the lock file.
|
|
68
|
+
*/
|
|
56
69
|
pulledAt: string;
|
|
57
70
|
}
|
|
58
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* `.botlr/sections.lock.json`: one entry per section name, for the whole
|
|
73
|
+
* app. The lock is not keyed by directory: `--dir` points a command at
|
|
74
|
+
* another sections directory but still records into this one lock, so a
|
|
75
|
+
* section name means one thing per app whichever directory holds it.
|
|
76
|
+
*/
|
|
59
77
|
type SectionsLock = Record<string, LockEntry>;
|
|
78
|
+
/**
|
|
79
|
+
* The entry to record after a pull or push: `fresh` with the previous
|
|
80
|
+
* `pulledAt` kept when scope, framework, version and hash are unchanged.
|
|
81
|
+
*/
|
|
82
|
+
declare function nextLockEntry(previous: LockEntry | undefined, fresh: LockEntry): LockEntry;
|
|
60
83
|
declare function lockPath(root: string): string;
|
|
61
84
|
declare function readLock(root: string): Promise<SectionsLock>;
|
|
62
85
|
declare function writeLock(root: string, lock: SectionsLock): Promise<void>;
|
|
@@ -71,8 +94,32 @@ declare function manifestPath(sectionsDir: string, name: string): string;
|
|
|
71
94
|
declare function listManifests(sectionsDir: string): Promise<string[]>;
|
|
72
95
|
declare function readManifest(sectionsDir: string, name: string): Promise<SectionManifest>;
|
|
73
96
|
declare function validateManifest(value: unknown, where?: string): SectionManifest;
|
|
74
|
-
/**
|
|
97
|
+
/** Top-level manifest keys in the order the CLI writes them; anything else follows alphabetically. */
|
|
98
|
+
declare const MANIFEST_KEY_ORDER: readonly ["section", "framework", "entry", "exportName", "files", "title", "description", "category", "icon", "dependencies", "schema"];
|
|
99
|
+
/**
|
|
100
|
+
* The manifest with pull state removed and keys in a fixed order: the known
|
|
101
|
+
* keys first (`MANIFEST_KEY_ORDER`), then unknown keys alphabetically;
|
|
102
|
+
* `dependencies` lists `npm` before `internal`, and every nested object is
|
|
103
|
+
* sorted alphabetically. Arrays keep their order. The server stores
|
|
104
|
+
* manifests as jsonb, which forgets key order, so this is what makes a pull
|
|
105
|
+
* after a push write the same bytes.
|
|
106
|
+
*/
|
|
107
|
+
declare function normalizeManifest(manifest: SectionManifest): SectionManifest;
|
|
108
|
+
/** The exact text `writeManifest` writes: normalized, 2-space JSON, trailing newline. */
|
|
109
|
+
declare function formatManifest(manifest: SectionManifest): string;
|
|
110
|
+
/** True when two manifests hold the same data, whatever their key order or formatting. */
|
|
111
|
+
declare function manifestsEqual(a: SectionManifest, b: SectionManifest): boolean;
|
|
112
|
+
/** Write `<name>.botlr.json` without any pull state, in the CLI's fixed key order. */
|
|
75
113
|
declare function writeManifest(sectionsDir: string, name: string, manifest: SectionManifest): Promise<string>;
|
|
114
|
+
/**
|
|
115
|
+
* Like `writeManifest`, but leaves the file alone when it already holds the
|
|
116
|
+
* same manifest (compared after normalization, so a hand-formatted file that
|
|
117
|
+
* says the same thing is not rewritten). Returns whether the file changed.
|
|
118
|
+
*/
|
|
119
|
+
declare function writeManifestIfChanged(sectionsDir: string, name: string, manifest: SectionManifest): Promise<{
|
|
120
|
+
file: string;
|
|
121
|
+
changed: boolean;
|
|
122
|
+
}>;
|
|
76
123
|
/** The files a manifest lists, read from `sectionsDir`, in manifest order. */
|
|
77
124
|
declare function readSectionFiles(sectionsDir: string, manifest: SectionManifest): Promise<SectionSourceFileInput[]>;
|
|
78
125
|
/** Write pulled files under `sectionsDir`, creating sub-directories. */
|
|
@@ -99,6 +146,7 @@ declare function computeStatus({ localHash, lock, remote }: StatusInput): Sectio
|
|
|
99
146
|
/** The server summary that corresponds to a lock entry's scope. */
|
|
100
147
|
declare function remoteForLock(summary: SectionSourceSummary | undefined, lock: LockEntry | undefined): SectionSourceScopeSummary | null | undefined;
|
|
101
148
|
|
|
149
|
+
/** @deprecated use `DEFAULT_REGISTRY_FILE` from config; the path is configurable as `registryFile`. */
|
|
102
150
|
declare const REGISTRY_FILE = "publisher-section-registry.ts";
|
|
103
151
|
interface RegistryEntry {
|
|
104
152
|
slug: string;
|
|
@@ -114,9 +162,24 @@ interface DefinitionMeta {
|
|
|
114
162
|
category?: string;
|
|
115
163
|
description?: string;
|
|
116
164
|
icon?: string;
|
|
165
|
+
/** The identifier `schema:` refers to, for example `HeroSchema`. */
|
|
166
|
+
schemaName?: string;
|
|
117
167
|
}
|
|
118
168
|
/** Scalar fields of an `export const XDefinition = { ... }` block, when the file has one. */
|
|
119
169
|
declare function parseDefinition(source: string): DefinitionMeta | null;
|
|
170
|
+
/**
|
|
171
|
+
* A best-effort field DSL entry for one zod expression, or null when the
|
|
172
|
+
* expression is not one the CLI understands. `.optional()`, `.nullable()`,
|
|
173
|
+
* `.nullish()` and `.default(...)` make the field optional; anything else is
|
|
174
|
+
* required.
|
|
175
|
+
*/
|
|
176
|
+
declare function zodFieldToSchemaField(expr: string): SectionSchemaField | null;
|
|
177
|
+
/**
|
|
178
|
+
* The field DSL for `export const <schemaName> = z.object({ ... })` in a
|
|
179
|
+
* component source, from the fields the CLI can read; null when the schema
|
|
180
|
+
* is not found or no field could be read.
|
|
181
|
+
*/
|
|
182
|
+
declare function parseZodSchema(source: string, schemaName: string): SectionFieldSchema | null;
|
|
120
183
|
/** Module specifiers a source file imports, split into relative and package imports. */
|
|
121
184
|
declare function parseImports(source: string): {
|
|
122
185
|
internal: string[];
|
|
@@ -132,12 +195,171 @@ interface DeriveOptions {
|
|
|
132
195
|
framework: string;
|
|
133
196
|
/** npm dependency ranges to record, usually from the app's package.json. */
|
|
134
197
|
npmVersions?: Record<string, string>;
|
|
198
|
+
/** Registry file to read; `sectionsDir/publisher-section-registry.ts` by default. */
|
|
199
|
+
registryFile?: string;
|
|
135
200
|
}
|
|
136
201
|
/** One manifest per registry entry whose component file exists. */
|
|
137
202
|
declare function deriveManifests(sectionsDir: string, options: DeriveOptions): Promise<DerivedManifest[]>;
|
|
138
203
|
/** `dependencies` + `devDependencies` of the nearest package.json above `dir`, for version ranges. */
|
|
139
204
|
declare function readNpmVersions(dir: string): Promise<Record<string, string>>;
|
|
140
|
-
|
|
205
|
+
/** Whether the registry file exists (`sectionsDir/publisher-section-registry.ts`, or `registryFile` when given). */
|
|
206
|
+
declare function hasRegistry(sectionsDir: string, registryFile?: string): Promise<boolean>;
|
|
207
|
+
|
|
208
|
+
interface RegistryAddition {
|
|
209
|
+
slug: string;
|
|
210
|
+
exportName: string;
|
|
211
|
+
/** Module specifier to import from, for example `./markdown`. */
|
|
212
|
+
importPath: string;
|
|
213
|
+
}
|
|
214
|
+
interface RegistryEditResult {
|
|
215
|
+
source: string;
|
|
216
|
+
/** True when an import or a map entry was appended. */
|
|
217
|
+
changed: boolean;
|
|
218
|
+
addedImport: boolean;
|
|
219
|
+
addedEntry: boolean;
|
|
220
|
+
}
|
|
221
|
+
/** `./markdown` for a registry at `sectionsDir` and an entry `markdown.tsx`; `./parts/x` for `parts/x.tsx`. */
|
|
222
|
+
declare function importPathFor(registryFile: string, entryFile: string): string;
|
|
223
|
+
/**
|
|
224
|
+
* Return `source` with `import { exportName } from "importPath";` added after
|
|
225
|
+
* the last import and `slug: exportName,` added as the last entry of the
|
|
226
|
+
* registry object. Each is skipped when it is already there. Quote style,
|
|
227
|
+
* semicolons, indentation and trailing commas follow the surrounding code.
|
|
228
|
+
*/
|
|
229
|
+
declare function addRegistryEntry(source: string, addition: RegistryAddition): RegistryEditResult;
|
|
230
|
+
interface RegistryUpdate {
|
|
231
|
+
/** Absolute path of the registry file. */
|
|
232
|
+
file: string;
|
|
233
|
+
/** False when nothing was added or the registry could not be updated. */
|
|
234
|
+
changed: boolean;
|
|
235
|
+
addedImport?: boolean;
|
|
236
|
+
addedEntry?: boolean;
|
|
237
|
+
/** Why nothing was written, for the user. */
|
|
238
|
+
notice?: string;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Add the pulled section to the registry file, when there is one. Returns a
|
|
242
|
+
* notice instead of throwing when the registry is missing or the manifest has
|
|
243
|
+
* no `exportName`, since a pull should still succeed.
|
|
244
|
+
*/
|
|
245
|
+
declare function registerSection(sectionsDir: string, registryFile: string, manifest: SectionManifest): Promise<RegistryUpdate>;
|
|
246
|
+
|
|
247
|
+
declare const PROPS_SUFFIX = ".props.ts";
|
|
248
|
+
/** One property of the generated interface. */
|
|
249
|
+
interface PropField {
|
|
250
|
+
name: string;
|
|
251
|
+
/** TypeScript type text. */
|
|
252
|
+
type: string;
|
|
253
|
+
required: boolean;
|
|
254
|
+
/** Doc comment lines (label, help text), without the comment markers. */
|
|
255
|
+
doc: string[];
|
|
256
|
+
}
|
|
257
|
+
/** The union of a select's option values, or null when the options are not plain values or `{ value }` objects. */
|
|
258
|
+
declare function optionUnion(options: unknown): string | null;
|
|
259
|
+
/** The TypeScript type for one field of the field DSL (or a FormBuilder field node, given its field type). */
|
|
260
|
+
declare function tsTypeForField(field: {
|
|
261
|
+
type?: unknown;
|
|
262
|
+
options?: unknown;
|
|
263
|
+
multiple?: unknown;
|
|
264
|
+
fields?: unknown;
|
|
265
|
+
}): string;
|
|
266
|
+
/** Properties for the field DSL, in schema order. Non-object values are skipped. */
|
|
267
|
+
declare function collectDslFields(schema: Record<string, unknown>): PropField[];
|
|
268
|
+
/** Properties for the FormBuilder format: field and repeater nodes, with groups flattened. */
|
|
269
|
+
declare function collectFormBuilderFields(nodes: SectionFormBuilderNode[]): PropField[];
|
|
270
|
+
/** Properties for a definition schema in either format; empty for anything else. */
|
|
271
|
+
declare function collectFields(schema: unknown): PropField[];
|
|
272
|
+
/** The property names a definition schema defines, in either format. */
|
|
273
|
+
declare function schemaFieldNames(schema: unknown): string[];
|
|
274
|
+
/** `hero-banner` or `forum_new_thread` → `HeroBanner` / `ForumNewThread`. */
|
|
275
|
+
declare function pascalCase(slug: string): string;
|
|
276
|
+
/** `<ExportName>Props`, from the manifest's `exportName` or a PascalCase of the slug. */
|
|
277
|
+
declare function propsInterfaceName(manifest: Pick<SectionManifest, "section" | "exportName">): string;
|
|
278
|
+
interface GenerateOptions {
|
|
279
|
+
/** Section slug, named in the header comment. */
|
|
280
|
+
section: string;
|
|
281
|
+
interfaceName: string;
|
|
282
|
+
}
|
|
283
|
+
/** The full text of `<name>.props.ts` for a definition schema. */
|
|
284
|
+
declare function generatePropsSource(schema: unknown, options: GenerateOptions): string;
|
|
285
|
+
declare function propsPath(sectionsDir: string, name: string): string;
|
|
286
|
+
interface PropsTypesUpdate {
|
|
287
|
+
file: string;
|
|
288
|
+
interfaceName: string;
|
|
289
|
+
/** False when the file already held the generated text. */
|
|
290
|
+
changed: boolean;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Write `<name>.props.ts` for a section, leaving the file alone when its
|
|
294
|
+
* text is already what would be generated.
|
|
295
|
+
*/
|
|
296
|
+
declare function writePropsTypes(sectionsDir: string, manifest: SectionManifest, schema: unknown): Promise<PropsTypesUpdate>;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Schema drift: the props a section's code expects (the manifest's optional
|
|
300
|
+
* `schema`, field DSL only) against the props the dashboard defines (the
|
|
301
|
+
* section definition's schema from the server). The CLI only reports the
|
|
302
|
+
* difference; the dashboard owns the definition's schema.
|
|
303
|
+
*/
|
|
304
|
+
|
|
305
|
+
interface SchemaDrift {
|
|
306
|
+
/** Props the code lists that the dashboard does not define. */
|
|
307
|
+
missingInDashboard: string[];
|
|
308
|
+
/** Props the dashboard defines that the code does not list. */
|
|
309
|
+
missingInCode: string[];
|
|
310
|
+
}
|
|
311
|
+
/** The manifest's `schema` when it is a schema object in either format, else null. */
|
|
312
|
+
declare function manifestSchema(manifest: SectionManifest): SectionSchema | null;
|
|
313
|
+
/**
|
|
314
|
+
* Key difference between the code's schema and the definition's schema
|
|
315
|
+
* (either format on either side; FormBuilder schemas contribute their node
|
|
316
|
+
* names). Null when the manifest has no schema object or the keys match.
|
|
317
|
+
*/
|
|
318
|
+
declare function compareSchemas(manifest: SectionManifest, definitionSchema: unknown): SchemaDrift | null;
|
|
319
|
+
/** The warning text for a drift, one line per direction, naming the two commands that resolve it. */
|
|
320
|
+
declare function formatDriftWarning(name: string, drift: SchemaDrift): string;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Field-key diff between two props schemas, for `botlr schema push` to show
|
|
324
|
+
* before it replaces the dashboard's schema with the code's. Field DSL keys
|
|
325
|
+
* are the object's keys; FormBuilder schemas contribute their node names
|
|
326
|
+
* (groups flattened), so the two formats can be compared with each other.
|
|
327
|
+
*/
|
|
328
|
+
|
|
329
|
+
interface SchemaKeyDiff {
|
|
330
|
+
/** Keys the new schema has that the current one lacks. */
|
|
331
|
+
added: string[];
|
|
332
|
+
/** Keys the current schema has that the new one lacks. */
|
|
333
|
+
removed: string[];
|
|
334
|
+
/** Keys both have. */
|
|
335
|
+
kept: string[];
|
|
336
|
+
}
|
|
337
|
+
/** The field keys of a schema in either format, in schema order and without duplicates. */
|
|
338
|
+
declare function schemaKeys(schema: unknown): string[];
|
|
339
|
+
/** Keys added, removed and kept going from `current` to `next`; each list sorted. */
|
|
340
|
+
declare function diffSchemaKeys(current: unknown, next: unknown): SchemaKeyDiff;
|
|
341
|
+
interface SchemaPushPreview {
|
|
342
|
+
name: string;
|
|
343
|
+
/** The dashboard's current schema. */
|
|
344
|
+
current: unknown;
|
|
345
|
+
/** Its format as the server reports it, else as detected. */
|
|
346
|
+
currentFormat: SectionSchemaFormat | null;
|
|
347
|
+
/** The manifest's schema, about to replace it. */
|
|
348
|
+
next: unknown;
|
|
349
|
+
nextFormat: SectionSchemaFormat | null;
|
|
350
|
+
diff: SchemaKeyDiff;
|
|
351
|
+
}
|
|
352
|
+
/** The preview for a push, with formats detected from the schemas unless given. */
|
|
353
|
+
declare function previewSchemaPush(name: string, current: unknown, next: unknown, formats?: {
|
|
354
|
+
currentFormat?: SectionSchemaFormat | null;
|
|
355
|
+
nextFormat?: SectionSchemaFormat | null;
|
|
356
|
+
}): SchemaPushPreview;
|
|
357
|
+
/**
|
|
358
|
+
* The diff as the CLI prints it: one header line with both formats and
|
|
359
|
+
* field counts, then one line per non-empty direction. The `kept` line is
|
|
360
|
+
* always printed, with "none" when nothing survives.
|
|
361
|
+
*/
|
|
362
|
+
declare function formatSchemaDiff(preview: SchemaPushPreview): string;
|
|
141
363
|
|
|
142
364
|
/** A client from the resolved config. `needPersonalToken` makes a missing `BOTLR_PAT` an error up front. */
|
|
143
365
|
declare function clientFor(config: ResolvedConfig, options?: {
|
|
@@ -153,6 +375,10 @@ interface PullOptions {
|
|
|
153
375
|
shared?: boolean;
|
|
154
376
|
/** Overwrite local files that changed since the last pull. */
|
|
155
377
|
force?: boolean;
|
|
378
|
+
/** Leave the registry file alone. */
|
|
379
|
+
noRegistry?: boolean;
|
|
380
|
+
/** Do not write `<name>.props.ts`; also off when the config says `types: false`. */
|
|
381
|
+
noTypes?: boolean;
|
|
156
382
|
}
|
|
157
383
|
interface PullResult {
|
|
158
384
|
name: string;
|
|
@@ -161,6 +387,14 @@ interface PullResult {
|
|
|
161
387
|
files: string[];
|
|
162
388
|
/** Set when the section was skipped instead of written. */
|
|
163
389
|
skipped?: string;
|
|
390
|
+
/** Whether `<name>.botlr.json` changed; false when the local manifest already said the same. */
|
|
391
|
+
manifestChanged?: boolean;
|
|
392
|
+
/** What happened to the registry file; absent for skipped sections and with `noRegistry`. */
|
|
393
|
+
registry?: RegistryUpdate;
|
|
394
|
+
/** What happened to `<name>.props.ts`; absent when types are off or the section has no definition. */
|
|
395
|
+
types?: PropsTypesUpdate;
|
|
396
|
+
/** Why no prop types were written, when they were expected. */
|
|
397
|
+
typesNotice?: string;
|
|
164
398
|
}
|
|
165
399
|
declare function pullSections(config: ResolvedConfig, options: PullOptions): Promise<PullResult[]>;
|
|
166
400
|
|
|
@@ -178,6 +412,8 @@ interface PushResult {
|
|
|
178
412
|
scope: SectionSourceScope;
|
|
179
413
|
version: number;
|
|
180
414
|
contentHash: string;
|
|
415
|
+
/** Set when the manifest's `schema` and the definition's schema list different props. */
|
|
416
|
+
drift?: SchemaDrift;
|
|
181
417
|
}
|
|
182
418
|
declare function pushSection(config: ResolvedConfig, options: PushOptions): Promise<PushResult>;
|
|
183
419
|
|
|
@@ -190,6 +426,8 @@ interface SectionStatusRow {
|
|
|
190
426
|
remote: number | null;
|
|
191
427
|
scope: string;
|
|
192
428
|
detail?: string;
|
|
429
|
+
/** Set when the manifest's `schema` and the dashboard's definition list different props (not offline). */
|
|
430
|
+
drift?: SchemaDrift;
|
|
193
431
|
}
|
|
194
432
|
declare function sectionStatuses(config: ResolvedConfig, options?: {
|
|
195
433
|
names?: string[];
|
|
@@ -215,4 +453,63 @@ interface InitResult {
|
|
|
215
453
|
*/
|
|
216
454
|
declare function initSections(config: ResolvedConfig, options?: InitOptions): Promise<InitResult[]>;
|
|
217
455
|
|
|
218
|
-
|
|
456
|
+
interface SchemaPullOptions {
|
|
457
|
+
/** Section names; empty with `all: true` means every manifest in the sections directory. */
|
|
458
|
+
names: string[];
|
|
459
|
+
all?: boolean;
|
|
460
|
+
/** Do not write `<name>.props.ts`; also off when the config says `types: false`. */
|
|
461
|
+
noTypes?: boolean;
|
|
462
|
+
}
|
|
463
|
+
interface SchemaPullResult {
|
|
464
|
+
name: string;
|
|
465
|
+
/** Whether `<name>.botlr.json` changed; false when its `schema` already equalled the dashboard's. */
|
|
466
|
+
changed: boolean;
|
|
467
|
+
/** The manifest file. */
|
|
468
|
+
file: string;
|
|
469
|
+
format?: string;
|
|
470
|
+
/** What happened to `<name>.props.ts`; absent when types are off or the pull failed. */
|
|
471
|
+
types?: PropsTypesUpdate;
|
|
472
|
+
/** Why nothing was written: no manifest, or no section type of that name in the app. */
|
|
473
|
+
error?: string;
|
|
474
|
+
}
|
|
475
|
+
/** Copy the dashboard's schema into each manifest's `schema`, then regenerate the prop types. */
|
|
476
|
+
declare function pullSchemas(config: ResolvedConfig, options: SchemaPullOptions): Promise<SchemaPullResult[]>;
|
|
477
|
+
interface SchemaPushOptions {
|
|
478
|
+
name: string;
|
|
479
|
+
/** Replace the schema even when the dashboard's is in the other format. */
|
|
480
|
+
force?: boolean;
|
|
481
|
+
/**
|
|
482
|
+
* Asked once with the preview before anything is sent; return false to
|
|
483
|
+
* stop. Omit to push without asking (`--yes`).
|
|
484
|
+
*/
|
|
485
|
+
confirm?: (preview: SchemaPushPreview) => Promise<boolean> | boolean;
|
|
486
|
+
/** Do not write `<name>.props.ts` afterwards; also off when the config says `types: false`. */
|
|
487
|
+
noTypes?: boolean;
|
|
488
|
+
}
|
|
489
|
+
interface SchemaPushResult {
|
|
490
|
+
name: string;
|
|
491
|
+
preview: SchemaPushPreview;
|
|
492
|
+
/** False when `confirm` said no; nothing was sent. */
|
|
493
|
+
pushed: boolean;
|
|
494
|
+
/** From the server: false when the stored schema already equalled the manifest's. */
|
|
495
|
+
changed?: boolean;
|
|
496
|
+
previousFormat?: string;
|
|
497
|
+
format?: string;
|
|
498
|
+
types?: PropsTypesUpdate;
|
|
499
|
+
}
|
|
500
|
+
/** 409: the dashboard's schema is in the other format and `--force` was not given. */
|
|
501
|
+
declare class SchemaFormatConflict extends Error {
|
|
502
|
+
readonly sectionName: string;
|
|
503
|
+
readonly currentFormat: string;
|
|
504
|
+
readonly newFormat: string;
|
|
505
|
+
constructor(sectionName: string, currentFormat: string, newFormat: string, message?: string);
|
|
506
|
+
}
|
|
507
|
+
/** 422: the server refused the schema (not an object of fields, or the definition is not project-scoped). */
|
|
508
|
+
declare class SchemaRejected extends Error {
|
|
509
|
+
readonly sectionName: string;
|
|
510
|
+
constructor(sectionName: string, message: string);
|
|
511
|
+
}
|
|
512
|
+
/** Send the manifest's `schema` to the dashboard, after showing the diff and asking. */
|
|
513
|
+
declare function pushSchema(config: ResolvedConfig, options: SchemaPushOptions): Promise<SchemaPushResult>;
|
|
514
|
+
|
|
515
|
+
export { type BotlrCliConfigFile, CONFIG_FILE, ConfigError, type ConfigOverrides, DEFAULT_FRAMEWORK, DEFAULT_REGISTRY_FILE, DEFAULT_SECTIONS_DIR, type DefinitionMeta, type DeriveOptions, type DerivedManifest, type GenerateOptions, type InitOptions, type InitResult, LOCK_DIR, LOCK_FILE, type LockEntry, MANIFEST_KEY_ORDER, MANIFEST_SUFFIX, ManifestError, PROPS_SUFFIX, type PropField, type PropsTypesUpdate, type PullOptions, type PullResult, type PushOptions, type PushResult, REGISTRY_FILE, type RegistryAddition, type RegistryEditResult, type RegistryEntry, type RegistryUpdate, type ResolvedConfig, type SchemaDrift, SchemaFormatConflict, type SchemaKeyDiff, type SchemaPullOptions, type SchemaPullResult, type SchemaPushOptions, type SchemaPushPreview, type SchemaPushResult, SchemaRejected, type SectionStatus, type SectionStatusRow, type SectionsLock, type StatusInput, addRegistryEntry, clientFor, collectDslFields, collectFields, collectFormBuilderFields, compareSchemas, computeStatus, deriveManifests, diffSchemaKeys, findConfigFile, formatDriftWarning, formatManifest, formatSchemaDiff, generatePropsSource, hasRegistry, importPathFor, initSections, listManifests, listSections, loadConfig, lockPath, manifestPath, manifestSchema, manifestsEqual, nextLockEntry, normalizeManifest, optionUnion, parseDefinition, parseImports, parseRegistry, parseZodSchema, pascalCase, previewSchemaPush, propsInterfaceName, propsPath, pullSchemas, pullSections, pushSchema, pushSection, readConfigFile, readLock, readManifest, readNpmVersions, readSectionFiles, registerSection, remoteForLock, safeJoin, schemaFieldNames, schemaKeys, sectionStatuses, tsTypeForField, updateLock, validateManifest, writeLock, writeManifest, writeManifestIfChanged, writePropsTypes, writeSectionFiles, zodFieldToSchemaField };
|