@nice2dev/ui-forms 1.3.10 → 1.3.11
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 +38 -8
- package/dist/index.cjs +5 -3
- package/dist/index.d.ts +760 -161
- package/dist/index.mjs +3653 -1769
- package/dist/studio.cjs +10 -0
- package/dist/studio.d.ts +796 -0
- package/dist/studio.mjs +1233 -0
- package/dist/ui-forms.css +1 -1
- package/package.json +10 -5
package/dist/studio.d.ts
ADDED
|
@@ -0,0 +1,796 @@
|
|
|
1
|
+
import { default as default_2 } from 'react';
|
|
2
|
+
import { NiceDataSourceDef } from '@nice2dev/ui';
|
|
3
|
+
import { NiceDataSourceSchemaTable } from '@nice2dev/ui';
|
|
4
|
+
import { NiceFormItem } from '@nice2dev/ui';
|
|
5
|
+
import { NiceHookBinding } from '@nice2dev/ui';
|
|
6
|
+
import { NiceRbacModel } from '@nice2dev/ui';
|
|
7
|
+
import { NiceViewDefinition } from '@nice2dev/ui';
|
|
8
|
+
import { NiceWorkflowDefinition } from '@nice2dev/ui';
|
|
9
|
+
|
|
10
|
+
/** A file holding one array, either bare or under `property`; the rest of the file is kept. */
|
|
11
|
+
export declare function arrayFileKind<T>(o: NiceArrayFileKindOptions): NiceStudioFileKind<T[]>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The documents of a module: files grouped by kind and group, each decoded. A document whose
|
|
15
|
+
* files a kind cannot decode — or would not store unchanged — opens raw, one JSON / text
|
|
16
|
+
* document per file, with the error.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildDocuments(kinds: readonly NiceStudioFileKind[], files: readonly NiceStudioFile[], ctx: NiceStudioCodecContext): NiceStudioDocument[];
|
|
19
|
+
|
|
20
|
+
/** A provider over modules held in memory, with versions, conflicts and revisions. */
|
|
21
|
+
export declare function createMemoryStudioProvider(options: NiceMemoryStudioOptions): NiceMemoryStudioProvider;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Identity helper that infers the precise `schema` type from a section literal,
|
|
25
|
+
* so consumers can write a plain JSON-Schema object without `as JsonSchema`
|
|
26
|
+
* assertions. `const general = defineManifestSection({ id, title, schema: {…} });`
|
|
27
|
+
*/
|
|
28
|
+
export declare function defineManifestSection<TSchema extends JsonSchema>(section: NiceManifestSection<TSchema>): NiceManifestSection<TSchema>;
|
|
29
|
+
|
|
30
|
+
/** A starter access model: admin / user × view / create / edit / delete over the module's views and entities. */
|
|
31
|
+
export declare function deriveDefaultRbac(module: {
|
|
32
|
+
manifest?: Row;
|
|
33
|
+
views?: ReadonlyArray<{
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
}>;
|
|
37
|
+
entities?: readonly Row[];
|
|
38
|
+
}): NiceRbacModel;
|
|
39
|
+
|
|
40
|
+
/** Reads how `text` is written: BOM, line breaks, indentation, final newline, colon spacing. */
|
|
41
|
+
export declare function detectJsonTextFormat(text: string): NiceJsonTextFormat;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The file changes that store a document's new model: only files whose text differs from what
|
|
45
|
+
* was read, plus files the encoder adds or removes.
|
|
46
|
+
*/
|
|
47
|
+
export declare function encodeDocument(doc: NiceStudioDocument, model: unknown, files: readonly NiceStudioFile[], ctx: NiceStudioCodecContext): NiceStudioFileChange[];
|
|
48
|
+
|
|
49
|
+
/** Ends with one of the suffixes (case-insensitive). */
|
|
50
|
+
export declare const endsWithAny: (...suffixes: string[]) => (path: string) => boolean;
|
|
51
|
+
|
|
52
|
+
/** The module's entities as the tables NiceDataSourceBuilder queries. */
|
|
53
|
+
export declare function entitiesToSchemas(entities: readonly Row[]): NiceDataSourceSchemaTable[];
|
|
54
|
+
|
|
55
|
+
/** The file name of a path. */
|
|
56
|
+
export declare const fileName: (path: string) => string;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A section narrowed to the properties a form can edit in this manifest: a value that does not fit
|
|
60
|
+
* its property's schema ({@link jsonValueFitsSchema}) leaves the section and is edited as JSON
|
|
61
|
+
* among the "Other properties".
|
|
62
|
+
*/
|
|
63
|
+
export declare function fitManifestSection(section: NiceManifestSection, manifest: Record<string, unknown>): {
|
|
64
|
+
section: NiceManifestSection;
|
|
65
|
+
keys: string[];
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/** Conditional visibility rule. */
|
|
69
|
+
declare interface FormFieldCondition {
|
|
70
|
+
field: string;
|
|
71
|
+
operator: 'equals' | 'notEquals' | 'contains' | 'greaterThan' | 'lessThan' | 'isEmpty' | 'isNotEmpty';
|
|
72
|
+
value?: any;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Form field definition. */
|
|
76
|
+
declare interface FormFieldDefinition {
|
|
77
|
+
/** Unique field ID */
|
|
78
|
+
id: string;
|
|
79
|
+
/** Field type */
|
|
80
|
+
type: FormFieldType;
|
|
81
|
+
/** Field name (for form data) */
|
|
82
|
+
name: string;
|
|
83
|
+
/** Display label */
|
|
84
|
+
label?: string;
|
|
85
|
+
/** Placeholder text */
|
|
86
|
+
placeholder?: string;
|
|
87
|
+
/** Help text */
|
|
88
|
+
helpText?: string;
|
|
89
|
+
/** Default value */
|
|
90
|
+
defaultValue?: any;
|
|
91
|
+
/** Options for select/radio fields. Plain strings are treated as `{ value: s, label: s }`. */
|
|
92
|
+
options?: Array<FormFieldOption | string>;
|
|
93
|
+
/** Validation rules */
|
|
94
|
+
validations?: FormFieldValidation[];
|
|
95
|
+
/** Convenience flag — expanded into a `required` validation rule when serialised. */
|
|
96
|
+
required?: boolean;
|
|
97
|
+
/** Conditional visibility */
|
|
98
|
+
conditions?: FormFieldCondition[];
|
|
99
|
+
/** Is field disabled */
|
|
100
|
+
disabled?: boolean;
|
|
101
|
+
/** Is field readonly */
|
|
102
|
+
readonly?: boolean;
|
|
103
|
+
/** Column span (1-12) */
|
|
104
|
+
colSpan?: number;
|
|
105
|
+
/** Custom CSS class */
|
|
106
|
+
className?: string;
|
|
107
|
+
/** Custom styles */
|
|
108
|
+
style?: default_2.CSSProperties;
|
|
109
|
+
/** Additional field-specific props */
|
|
110
|
+
props?: Record<string, any>;
|
|
111
|
+
/** Nested fields (for section type) */
|
|
112
|
+
children?: FormFieldDefinition[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Option for select/radio fields. */
|
|
116
|
+
declare interface FormFieldOption {
|
|
117
|
+
value: string | number;
|
|
118
|
+
label: string;
|
|
119
|
+
disabled?: boolean;
|
|
120
|
+
/** Optional stable identifier for keyed rendering. */
|
|
121
|
+
id?: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Available field types. */
|
|
125
|
+
declare type FormFieldType = 'text' | 'textarea' | 'number' | 'email' | 'password' | 'phone' | 'url' | 'date' | 'datetime' | 'time' | 'select' | 'multiselect' | 'checkbox' | 'toggle' | 'radio' | 'slider' | 'rating' | 'color' | 'file' | 'signature' | 'richtext' | 'markdown' | 'code' | 'heading' | 'paragraph' | 'divider' | 'spacer' | 'image' | 'section';
|
|
126
|
+
|
|
127
|
+
/** Validation rule. */
|
|
128
|
+
declare interface FormFieldValidation {
|
|
129
|
+
type: 'required' | 'minLength' | 'maxLength' | 'min' | 'max' | 'pattern' | 'email' | 'url' | 'custom';
|
|
130
|
+
value?: string | number | boolean;
|
|
131
|
+
message?: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Translations split into one file per language, edited as one document. A new language gets a
|
|
136
|
+
* file shaped and formatted like its siblings; a language removed in the editor loses its file.
|
|
137
|
+
*/
|
|
138
|
+
export declare function i18nFileKind(o?: NiceI18nFileKindOptions): NiceStudioFileKind<NiceStudioTranslations>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* A file holding a list of entries edited one at a time (views, workflows). Entries the editor
|
|
142
|
+
* does not understand stay raw and round-trip as they are.
|
|
143
|
+
*/
|
|
144
|
+
export declare function itemsFileKind<D>(o: NiceItemsFileKindOptions<D>): NiceStudioFileKind<Array<NiceStudioItem<D>>>;
|
|
145
|
+
|
|
146
|
+
/** Any JSON file, edited as JSON. */
|
|
147
|
+
export declare const jsonFallbackKind: NiceStudioFileKind<unknown>;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* A kind for one JSON file per document: `select` picks the model out of the file, `assign` puts
|
|
151
|
+
* it back, and the file's text is patched so only the changed values move.
|
|
152
|
+
*/
|
|
153
|
+
export declare function jsonFileKind<M>(o: NiceJsonFileKindOptions<M>): NiceStudioFileKind<M>;
|
|
154
|
+
|
|
155
|
+
export declare interface JsonSchema {
|
|
156
|
+
$schema?: string;
|
|
157
|
+
$id?: string;
|
|
158
|
+
type?: 'object' | 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'null';
|
|
159
|
+
title?: string;
|
|
160
|
+
description?: string;
|
|
161
|
+
properties?: Record<string, JsonSchema>;
|
|
162
|
+
required?: string[];
|
|
163
|
+
items?: JsonSchema;
|
|
164
|
+
enum?: Array<string | number | boolean | null>;
|
|
165
|
+
minLength?: number;
|
|
166
|
+
maxLength?: number;
|
|
167
|
+
minimum?: number;
|
|
168
|
+
maximum?: number;
|
|
169
|
+
pattern?: string;
|
|
170
|
+
format?: string;
|
|
171
|
+
default?: unknown;
|
|
172
|
+
additionalProperties?: boolean;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Whether a value has exactly the shape its schema describes — every object key known to the
|
|
177
|
+
* schema, every array item of the item schema, an `enum` value among its options — so a form can
|
|
178
|
+
* edit it without losing or reshaping anything. Seeds written by hand often do not (a per-language
|
|
179
|
+
* `description` object, a list of strings where the schema has objects); such a value is edited
|
|
180
|
+
* as JSON instead.
|
|
181
|
+
*/
|
|
182
|
+
export declare function jsonValueFitsSchema(value: unknown, schema: JsonSchema | undefined): boolean;
|
|
183
|
+
|
|
184
|
+
/** Whether two JSON values are equal (objects compared by their keys, not their order). */
|
|
185
|
+
export declare function jsonValuesEqual(a: unknown, b: unknown): boolean;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Text from an editor given the line breaks and BOM of the file it replaces. A browser text box
|
|
189
|
+
* hands back LF only (and some drop a BOM), which would rewrite every line of a CRLF file.
|
|
190
|
+
*/
|
|
191
|
+
export declare function keepTextFormat(text: string, original: string | undefined): string;
|
|
192
|
+
|
|
193
|
+
/** The manifest keys the sections' schemas cover — the rest shows on an "Other properties" tab. */
|
|
194
|
+
export declare function manifestSectionKeys(sections: readonly NiceManifestSection[]): Set<string>;
|
|
195
|
+
|
|
196
|
+
/** The prefix a module's files share (`orders` of `orders.manifest.json`). */
|
|
197
|
+
export declare function modulePrefix(files: readonly NiceStudioFile[]): string;
|
|
198
|
+
|
|
199
|
+
export declare const nativeDataSourcesKind: NiceStudioFileKind<NiceDataSourceDef[]>;
|
|
200
|
+
|
|
201
|
+
export declare const nativeEntitiesKind: NiceStudioFileKind<Row_2[]>;
|
|
202
|
+
|
|
203
|
+
/** The file kinds of the native format, in matching order. */
|
|
204
|
+
export declare const nativeFileKinds: NiceStudioFileKind[];
|
|
205
|
+
|
|
206
|
+
export declare const nativeHooksKind: NiceStudioFileKind<NiceHookBinding[]>;
|
|
207
|
+
|
|
208
|
+
export declare const nativeI18nKind: NiceStudioFileKind<NiceStudioTranslations>;
|
|
209
|
+
|
|
210
|
+
export declare const nativeManifestKind: NiceStudioFileKind<Row_2>;
|
|
211
|
+
|
|
212
|
+
export declare const nativeRbacKind: NiceStudioFileKind<NiceRbacModel>;
|
|
213
|
+
|
|
214
|
+
/** The studio's own format: manifest, entities, translations, views, workflows, data sources, access, hooks. */
|
|
215
|
+
export declare const nativeStudioPreset: NiceStudioPreset;
|
|
216
|
+
|
|
217
|
+
export declare const nativeViewsKind: NiceStudioFileKind<NiceStudioItem<NiceViewDefinition>[]>;
|
|
218
|
+
|
|
219
|
+
export declare const nativeWorkflowsKind: NiceStudioFileKind<NiceStudioItem<NiceWorkflowDefinition>[]>;
|
|
220
|
+
|
|
221
|
+
/** Options of {@link arrayFileKind}. */
|
|
222
|
+
export declare interface NiceArrayFileKindOptions {
|
|
223
|
+
id: string;
|
|
224
|
+
label: string;
|
|
225
|
+
labelKey?: string;
|
|
226
|
+
icon?: string;
|
|
227
|
+
editor: NiceStudioEditorId;
|
|
228
|
+
match(path: string): boolean;
|
|
229
|
+
/** The property holding the array (`views`); the file may also be the bare array. */
|
|
230
|
+
property: string;
|
|
231
|
+
/** The property that identifies an item, for minimal diffs. */
|
|
232
|
+
itemKey?: string;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Options of {@link i18nFileKind}. */
|
|
236
|
+
export declare interface NiceI18nFileKindOptions {
|
|
237
|
+
id?: string;
|
|
238
|
+
label?: string;
|
|
239
|
+
labelKey?: string;
|
|
240
|
+
/**
|
|
241
|
+
* The locale of a path and the path without it, or `null` when the path is not a translation.
|
|
242
|
+
* Default: `{prefix}.{locale}.i18n.json` (`en`, `pl`, `pt-BR`, `zh-CN`).
|
|
243
|
+
*/
|
|
244
|
+
parse?(path: string): {
|
|
245
|
+
group: string;
|
|
246
|
+
locale: string;
|
|
247
|
+
} | null;
|
|
248
|
+
/** The path of a new language's file in a group. Default: `{group}.{locale}.i18n.json`. */
|
|
249
|
+
pathFor?(group: string, locale: string): string;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Options of {@link itemsFileKind}. */
|
|
253
|
+
export declare interface NiceItemsFileKindOptions<D> extends NiceArrayFileKindOptions {
|
|
254
|
+
/** A stored entry as a list item: with `definition` when the editor understands it. */
|
|
255
|
+
toItem(raw: unknown, index: number): NiceStudioItem<D>;
|
|
256
|
+
/** A list item back as the stored entry (merge onto `item.source` to keep unknown fields). */
|
|
257
|
+
fromItem(item: NiceStudioItem<D>): unknown;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/** Options of {@link jsonFileKind}. */
|
|
261
|
+
export declare interface NiceJsonFileKindOptions<M> {
|
|
262
|
+
id: string;
|
|
263
|
+
label: string;
|
|
264
|
+
labelKey?: string;
|
|
265
|
+
icon?: string;
|
|
266
|
+
match(path: string): boolean;
|
|
267
|
+
editor: NiceStudioEditorId;
|
|
268
|
+
/** The editor's model out of the file's parsed JSON. */
|
|
269
|
+
select(root: unknown, ctx: NiceStudioCodecContext): M;
|
|
270
|
+
/** The file's JSON with the model put back (return a new root; the text is patched in place). */
|
|
271
|
+
assign(root: unknown, model: M, ctx: NiceStudioCodecContext): unknown;
|
|
272
|
+
/** Identifies array items for the patch (see {@link NiceJsonPatchOptions.arrayKey}). */
|
|
273
|
+
arrayKey?: NiceJsonPatchOptions['arrayKey'];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** Options of {@link patchJsonText}. */
|
|
277
|
+
export declare interface NiceJsonPatchOptions {
|
|
278
|
+
/**
|
|
279
|
+
* The property that identifies the items of an array (by JSON pointer of the array), so a
|
|
280
|
+
* removed or inserted item does not shift every item after it. Without it the items are
|
|
281
|
+
* matched by `name`, `id`, `code`, `key`, `slug`, `state` or `Id` when every item has a unique
|
|
282
|
+
* one, otherwise by position.
|
|
283
|
+
*/
|
|
284
|
+
arrayKey?: (pointer: string) => string | undefined;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** What {@link patchJsonTextDetailed} did. */
|
|
288
|
+
export declare interface NiceJsonPatchResult {
|
|
289
|
+
text: string;
|
|
290
|
+
/** `false`: the text could not be patched in place and was written anew in its format. */
|
|
291
|
+
exact: boolean;
|
|
292
|
+
/** Why it was written anew. */
|
|
293
|
+
reason?: string;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* JSON text that keeps its look (NiceDevelopmentStudio).
|
|
298
|
+
*
|
|
299
|
+
* Seed files are written by hand and by many tools: a UTF-8 BOM, CRLF, two or four spaces or tabs,
|
|
300
|
+
* rows aligned in columns, `25.0` instead of `25`. Writing them back with `JSON.stringify` turns a
|
|
301
|
+
* one-field edit into a diff of the whole file. `patchJsonText` changes only the bytes of what
|
|
302
|
+
* changed: untouched values keep their exact text, a changed value replaces only its own token,
|
|
303
|
+
* added and removed members follow the indentation around them.
|
|
304
|
+
*
|
|
305
|
+
* No React and no dependencies — usable in Node (validators, CI) as well as in the studio.
|
|
306
|
+
*/
|
|
307
|
+
/** How a JSON file is written. */
|
|
308
|
+
export declare interface NiceJsonTextFormat {
|
|
309
|
+
/** Starts with a UTF-8 byte order mark (kept as a leading U+FEFF). */
|
|
310
|
+
bom: boolean;
|
|
311
|
+
eol: '\n' | '\r\n';
|
|
312
|
+
/** One level of indentation (`' '`, `' '`, `'\t'`). */
|
|
313
|
+
indent: string;
|
|
314
|
+
/** Ends with a line break. */
|
|
315
|
+
finalNewline: boolean;
|
|
316
|
+
/** A space after the colon of a property. */
|
|
317
|
+
colonSpace: boolean;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* One editable manifest section, described by a JSON Schema or field model.
|
|
322
|
+
*
|
|
323
|
+
* Generic over `TSchema` so a literal JSON-Schema object keeps its precise type
|
|
324
|
+
* (use {@link defineManifestSection} for inference) — no `as JsonSchema` casts on
|
|
325
|
+
* nested `properties`. Defaults to `JsonSchema`, so `NiceManifestSection` and
|
|
326
|
+
* `NiceManifestSection[]` keep working unchanged.
|
|
327
|
+
*/
|
|
328
|
+
export declare interface NiceManifestSection<TSchema extends JsonSchema = JsonSchema> {
|
|
329
|
+
id: string;
|
|
330
|
+
title: string;
|
|
331
|
+
icon?: default_2.ReactNode;
|
|
332
|
+
/** JSON Schema describing this section's fields (subset of the manifest). */
|
|
333
|
+
schema?: TSchema;
|
|
334
|
+
/** Or the repo's field-descriptor model. */
|
|
335
|
+
fields?: FormFieldDefinition[];
|
|
336
|
+
/** Per-field UI overrides forwarded to NiceSchemaForm. */
|
|
337
|
+
uiSchema?: Record<string, Partial<NiceFormItem>>;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/** A module given to {@link createMemoryStudioProvider}. */
|
|
341
|
+
export declare interface NiceMemoryStudioModule {
|
|
342
|
+
id: string;
|
|
343
|
+
packageId?: string;
|
|
344
|
+
label?: string;
|
|
345
|
+
description?: string;
|
|
346
|
+
icon?: string;
|
|
347
|
+
version?: string;
|
|
348
|
+
readOnly?: boolean;
|
|
349
|
+
/** Its files: path → exact text. */
|
|
350
|
+
files: Record<string, string>;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Options of {@link createMemoryStudioProvider}. */
|
|
354
|
+
export declare interface NiceMemoryStudioOptions {
|
|
355
|
+
workspaces: NiceMemoryStudioWorkspace[];
|
|
356
|
+
templates?: NiceStudioTemplate[];
|
|
357
|
+
/** Keep earlier versions of written files (default true). */
|
|
358
|
+
revisions?: boolean;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/** {@link NiceStudioProvider} plus a way to read everything back. */
|
|
362
|
+
export declare interface NiceMemoryStudioProvider extends NiceStudioProvider {
|
|
363
|
+
/** The current state, in the shape the provider was created from. */
|
|
364
|
+
snapshot(): NiceMemoryStudioOptions;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** A workspace given to {@link createMemoryStudioProvider}. */
|
|
368
|
+
export declare interface NiceMemoryStudioWorkspace extends NiceStudioWorkspace {
|
|
369
|
+
/** Stored packages; without them packages are the modules' `packageId`s. */
|
|
370
|
+
packages?: Array<Omit<NiceStudioPackage, 'workspaceId'>>;
|
|
371
|
+
modules: NiceMemoryStudioModule[];
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** Options of {@link objectFileKind}. */
|
|
375
|
+
export declare interface NiceObjectFileKindOptions {
|
|
376
|
+
id: string;
|
|
377
|
+
label: string;
|
|
378
|
+
labelKey?: string;
|
|
379
|
+
icon?: string;
|
|
380
|
+
editor: NiceStudioEditorId;
|
|
381
|
+
match(path: string): boolean;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** What a file kind's decode and encode know about the module. */
|
|
385
|
+
export declare interface NiceStudioCodecContext {
|
|
386
|
+
moduleId: string;
|
|
387
|
+
/** All files of the module (e.g. to read the manifest while decoding views). */
|
|
388
|
+
files: readonly NiceStudioFile[];
|
|
389
|
+
locales: readonly string[];
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/** A document of an open module: the files one editor works on. */
|
|
393
|
+
export declare interface NiceStudioDocument<M = unknown> {
|
|
394
|
+
/** Stable within the module: `${kind.id}:${group}`. */
|
|
395
|
+
key: string;
|
|
396
|
+
kind: NiceStudioFileKind<M>;
|
|
397
|
+
paths: string[];
|
|
398
|
+
/** For the explorer and the tab (the file name, or the group). */
|
|
399
|
+
label: string;
|
|
400
|
+
/** The decoded model; absent when decoding failed (`error`) — the document then opens raw. */
|
|
401
|
+
model?: M;
|
|
402
|
+
error?: string;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** The built-in editors a file kind can open in. */
|
|
406
|
+
export declare type NiceStudioEditorId = 'manifest' | 'entities' | 'i18n' | 'views' | 'workflows' | 'permissions' | 'rbac' | 'dataSources' | 'seeds' | 'hooks' | 'script' | 'json' | 'text';
|
|
407
|
+
|
|
408
|
+
/** New and removed files of an encoded document. */
|
|
409
|
+
export declare interface NiceStudioEncoded {
|
|
410
|
+
files: Array<{
|
|
411
|
+
path: string;
|
|
412
|
+
text: string;
|
|
413
|
+
}>;
|
|
414
|
+
deleted?: string[];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/** Entity editor settings of a preset. */
|
|
418
|
+
export declare interface NiceStudioEntityOptions {
|
|
419
|
+
/** JSON Schema of an entity's own properties (name, table, flags). */
|
|
420
|
+
entityMetaSchema?: JsonSchema;
|
|
421
|
+
/** JSON Schema of one field. */
|
|
422
|
+
fieldSchema?: JsonSchema;
|
|
423
|
+
/** Property holding the fields. Default `fields`. */
|
|
424
|
+
fieldsKey?: string;
|
|
425
|
+
/** Property holding the name. Default `name`. */
|
|
426
|
+
nameKey?: string;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/** One file of a module: its path inside the module and its exact text (a BOM as a leading U+FEFF). */
|
|
430
|
+
export declare interface NiceStudioFile {
|
|
431
|
+
/** Relative to the module folder, `/`-separated (e.g. `inv.invoices.entities.json`, `services/x.js`). */
|
|
432
|
+
path: string;
|
|
433
|
+
text: string;
|
|
434
|
+
/** Opaque version for conflict checks (hash, `lastModified:size`, ETag). */
|
|
435
|
+
version?: string;
|
|
436
|
+
/** This file cannot be written (e.g. shipped and read-only in production). */
|
|
437
|
+
readOnly?: boolean;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/** A change the studio asks the provider to write. */
|
|
441
|
+
export declare type NiceStudioFileChange = {
|
|
442
|
+
type: 'write';
|
|
443
|
+
path: string;
|
|
444
|
+
text: string;
|
|
445
|
+
baseVersion?: string;
|
|
446
|
+
} | {
|
|
447
|
+
type: 'delete';
|
|
448
|
+
path: string;
|
|
449
|
+
baseVersion?: string;
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* A kind of file and how the studio edits it. A document is one file, or several when `group`
|
|
454
|
+
* puts them together (the translations of one prefix in every locale).
|
|
455
|
+
*/
|
|
456
|
+
export declare interface NiceStudioFileKind<M = unknown> {
|
|
457
|
+
id: string;
|
|
458
|
+
label: string;
|
|
459
|
+
labelKey?: string;
|
|
460
|
+
/** NiceIcon name. */
|
|
461
|
+
icon?: string;
|
|
462
|
+
match(path: string): boolean;
|
|
463
|
+
/** The document a file belongs to (files with the same group open together). Default: the path. */
|
|
464
|
+
group?(path: string): string;
|
|
465
|
+
editor: NiceStudioEditorId;
|
|
466
|
+
/** The files of one document → the editor's model. Throwing opens the files as raw JSON / text. */
|
|
467
|
+
decode(files: readonly NiceStudioFile[], ctx: NiceStudioCodecContext): M;
|
|
468
|
+
/** The model → the document's files (only their text; unchanged files may be returned as they were). */
|
|
469
|
+
encode(model: M, files: readonly NiceStudioFile[], ctx: NiceStudioCodecContext): NiceStudioEncoded;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/** A generated module, before it is created. */
|
|
473
|
+
export declare interface NiceStudioGeneratedModule {
|
|
474
|
+
id: string;
|
|
475
|
+
packageId?: string;
|
|
476
|
+
files: Array<{
|
|
477
|
+
path: string;
|
|
478
|
+
text: string;
|
|
479
|
+
}>;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/** A problem found in a module. */
|
|
483
|
+
export declare interface NiceStudioIssue {
|
|
484
|
+
severity: 'error' | 'warning' | 'info';
|
|
485
|
+
/** Stable code of the rule (e.g. `manifest.required`). */
|
|
486
|
+
code?: string;
|
|
487
|
+
/** English text. */
|
|
488
|
+
message: string;
|
|
489
|
+
/** Translation key of `message`, with `{name}` placeholders filled from `params`. */
|
|
490
|
+
messageKey?: string;
|
|
491
|
+
params?: Record<string, string | number>;
|
|
492
|
+
moduleId?: string;
|
|
493
|
+
/** The file it is about. */
|
|
494
|
+
path?: string;
|
|
495
|
+
/** Where in that file: a JSON pointer (`/entities/0/fields/2`). */
|
|
496
|
+
pointer?: string;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* An entry of a list document — a view, a workflow — that its editor may or may not understand.
|
|
501
|
+
* An entry in a shape the editor does not know keeps only `source` and is edited as raw JSON.
|
|
502
|
+
*/
|
|
503
|
+
export declare interface NiceStudioItem<D> {
|
|
504
|
+
/** Stable within the document (an id, a name, a position). */
|
|
505
|
+
key: string;
|
|
506
|
+
label: string;
|
|
507
|
+
/** The editor's model of the entry; absent for an entry edited raw. */
|
|
508
|
+
definition?: D;
|
|
509
|
+
/** The entry as it is stored. */
|
|
510
|
+
source: unknown;
|
|
511
|
+
/** Why the entry is edited raw (shown to the user). */
|
|
512
|
+
rawReason?: string;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** What validators and generators get. */
|
|
516
|
+
export declare interface NiceStudioModuleContext {
|
|
517
|
+
key: NiceStudioModuleKey;
|
|
518
|
+
files: readonly NiceStudioFile[];
|
|
519
|
+
documents: readonly NiceStudioDocument[];
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/** Which module, in which workspace. */
|
|
523
|
+
export declare interface NiceStudioModuleKey {
|
|
524
|
+
workspaceId: string;
|
|
525
|
+
id: string;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/** A module as listed in the explorer. */
|
|
529
|
+
export declare interface NiceStudioModuleRef extends NiceStudioModuleKey {
|
|
530
|
+
packageId?: string;
|
|
531
|
+
label: string;
|
|
532
|
+
description?: string;
|
|
533
|
+
icon?: string;
|
|
534
|
+
version?: string;
|
|
535
|
+
/** Where it lives, for display (a folder, a URL). */
|
|
536
|
+
location?: string;
|
|
537
|
+
readOnly?: boolean;
|
|
538
|
+
/** Another workspace's module with the same id wins over this one (e.g. shipped over overlay). */
|
|
539
|
+
shadowedBy?: string;
|
|
540
|
+
/** Its file paths, when the listing knows them (lets the explorer show files without reading). */
|
|
541
|
+
files?: string[];
|
|
542
|
+
/** Extra text the explorer's search looks in. */
|
|
543
|
+
search?: string;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/** The answers of the new-module wizard. */
|
|
547
|
+
export declare interface NiceStudioModuleSpec {
|
|
548
|
+
workspaceId: string;
|
|
549
|
+
packageId?: string;
|
|
550
|
+
/** Display name, e.g. "Bike rental". */
|
|
551
|
+
name: string;
|
|
552
|
+
description?: string;
|
|
553
|
+
icon?: string;
|
|
554
|
+
/** Entities to create, in the preset's entity shape. */
|
|
555
|
+
entities: Array<Record<string, unknown>>;
|
|
556
|
+
locales: string[];
|
|
557
|
+
/** Scaffold a list and a form view per entity. */
|
|
558
|
+
views?: boolean;
|
|
559
|
+
/** Scaffold viewer / editor / admin permissions. */
|
|
560
|
+
permissions?: boolean;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/** A group of modules in a workspace (a category, a product line). */
|
|
564
|
+
export declare interface NiceStudioPackage {
|
|
565
|
+
id: string;
|
|
566
|
+
workspaceId: string;
|
|
567
|
+
label: string;
|
|
568
|
+
description?: string;
|
|
569
|
+
icon?: string;
|
|
570
|
+
/** Computed from the modules (e.g. their `category`) rather than stored: it cannot be edited. */
|
|
571
|
+
derived?: boolean;
|
|
572
|
+
readOnly?: boolean;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/** The model of the `permissions` editor: permission codes and the groups (roles) granting them. */
|
|
576
|
+
export declare interface NiceStudioPermissions {
|
|
577
|
+
permissions: Array<{
|
|
578
|
+
code: string;
|
|
579
|
+
name?: string;
|
|
580
|
+
description?: string;
|
|
581
|
+
}>;
|
|
582
|
+
groups: Array<{
|
|
583
|
+
id: string;
|
|
584
|
+
label: string;
|
|
585
|
+
description?: string;
|
|
586
|
+
permissions: string[];
|
|
587
|
+
}>;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* How one host's modules look: which files there are (kinds), what the manifest holds (sections),
|
|
592
|
+
* which languages are required, how a module is checked and generated.
|
|
593
|
+
*/
|
|
594
|
+
export declare interface NiceStudioPreset {
|
|
595
|
+
id: string;
|
|
596
|
+
/** Tried in order; a path no kind matches opens as raw JSON (`*.json`) or text. */
|
|
597
|
+
kinds: NiceStudioFileKind[];
|
|
598
|
+
/** The manifest's sections, each a form over part of the manifest. */
|
|
599
|
+
manifestSections?: NiceManifestSection[];
|
|
600
|
+
entities?: NiceStudioEntityOptions;
|
|
601
|
+
/** Languages offered for translations. */
|
|
602
|
+
locales?: string[];
|
|
603
|
+
/** Languages every module must have. */
|
|
604
|
+
requiredLocales?: string[];
|
|
605
|
+
/** The module's id from its files (e.g. the manifest's `packageName`). */
|
|
606
|
+
moduleId?(files: readonly NiceStudioFile[]): string | undefined;
|
|
607
|
+
validateModule?(ctx: NiceStudioModuleContext): NiceStudioIssue[];
|
|
608
|
+
generateModule?(spec: NiceStudioModuleSpec, ctx: {
|
|
609
|
+
existingIds: ReadonlySet<string>;
|
|
610
|
+
}): Promise<NiceStudioGeneratedModule>;
|
|
611
|
+
duplicateModule?(files: readonly NiceStudioFile[], target: {
|
|
612
|
+
id: string;
|
|
613
|
+
packageId?: string;
|
|
614
|
+
name?: string;
|
|
615
|
+
}): Promise<NiceStudioGeneratedModule>;
|
|
616
|
+
/** A new, empty file of a kind (the explorer's "New file"). */
|
|
617
|
+
newFile?(kindId: string, ctx: NiceStudioModuleContext): {
|
|
618
|
+
path: string;
|
|
619
|
+
text: string;
|
|
620
|
+
} | undefined;
|
|
621
|
+
/** Lifecycle triggers offered by a `hooks` document. */
|
|
622
|
+
hooks?: {
|
|
623
|
+
triggers: Array<{
|
|
624
|
+
id: string;
|
|
625
|
+
label: string;
|
|
626
|
+
description?: string;
|
|
627
|
+
group?: string;
|
|
628
|
+
}>;
|
|
629
|
+
handlers?: Array<{
|
|
630
|
+
id: string;
|
|
631
|
+
label: string;
|
|
632
|
+
description?: string;
|
|
633
|
+
}>;
|
|
634
|
+
};
|
|
635
|
+
/** Extra template properties (shown in the template editor). */
|
|
636
|
+
templateSchema?: JsonSchema;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* How the studio reaches the host's modules. Only the four list/read/write methods are needed;
|
|
641
|
+
* each optional one turns on the matching feature (create, delete, packages, templates,
|
|
642
|
+
* validation, history) and its absence hides it.
|
|
643
|
+
*/
|
|
644
|
+
export declare interface NiceStudioProvider {
|
|
645
|
+
listWorkspaces(): Promise<NiceStudioWorkspace[]>;
|
|
646
|
+
listModules(workspaceId: string): Promise<NiceStudioModuleRef[]>;
|
|
647
|
+
readModule(key: NiceStudioModuleKey): Promise<NiceStudioFile[]>;
|
|
648
|
+
/** Writes only the files given (the studio drops changes that leave a file's text as it was). */
|
|
649
|
+
writeModule(key: NiceStudioModuleKey, changes: NiceStudioFileChange[]): Promise<NiceStudioWriteResult>;
|
|
650
|
+
/** Stored packages. Absent: the explorer groups modules by their `packageId`. */
|
|
651
|
+
listPackages?(workspaceId: string): Promise<NiceStudioPackage[]>;
|
|
652
|
+
createModule?(input: {
|
|
653
|
+
workspaceId: string;
|
|
654
|
+
packageId?: string;
|
|
655
|
+
id: string;
|
|
656
|
+
files: Array<{
|
|
657
|
+
path: string;
|
|
658
|
+
text: string;
|
|
659
|
+
}>;
|
|
660
|
+
}): Promise<NiceStudioModuleRef>;
|
|
661
|
+
deleteModule?(key: NiceStudioModuleKey): Promise<void>;
|
|
662
|
+
savePackage?(pkg: NiceStudioPackage): Promise<NiceStudioPackage>;
|
|
663
|
+
deletePackage?(ref: {
|
|
664
|
+
workspaceId: string;
|
|
665
|
+
id: string;
|
|
666
|
+
}): Promise<void>;
|
|
667
|
+
listTemplates?(): Promise<NiceStudioTemplate[]>;
|
|
668
|
+
/** `previousId`: the template's id before a rename. */
|
|
669
|
+
saveTemplate?(template: NiceStudioTemplate, options?: {
|
|
670
|
+
previousId?: string;
|
|
671
|
+
}): Promise<NiceStudioTemplate>;
|
|
672
|
+
deleteTemplate?(id: string): Promise<void>;
|
|
673
|
+
/** Server-side checks, on top of the preset's own. */
|
|
674
|
+
validate?(key: NiceStudioModuleKey, files: NiceStudioFile[]): Promise<NiceStudioIssue[]>;
|
|
675
|
+
listRevisions?(key: NiceStudioModuleKey, path?: string): Promise<NiceStudioRevision[]>;
|
|
676
|
+
readRevision?(key: NiceStudioModuleKey, revisionId: string, path?: string): Promise<string>;
|
|
677
|
+
rollback?(key: NiceStudioModuleKey, revisionId: string, path?: string): Promise<void>;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/** A saved earlier version of a module or one of its files. */
|
|
681
|
+
export declare interface NiceStudioRevision {
|
|
682
|
+
id: string;
|
|
683
|
+
/** When it was saved: epoch ms. */
|
|
684
|
+
timestamp: number;
|
|
685
|
+
label?: string;
|
|
686
|
+
author?: string;
|
|
687
|
+
summary?: string;
|
|
688
|
+
/** The file it belongs to (absent: the whole module). */
|
|
689
|
+
path?: string;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/** The model of the `seeds` editor: rows per entity, plus demo rows. */
|
|
693
|
+
export declare interface NiceStudioSeeds {
|
|
694
|
+
seeds: Record<string, Array<Record<string, unknown>>>;
|
|
695
|
+
demoSeeds?: Record<string, Array<Record<string, unknown>>>;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/** A template: a set of modules installed together (an industry bundle). */
|
|
699
|
+
export declare interface NiceStudioTemplate {
|
|
700
|
+
id: string;
|
|
701
|
+
category?: string;
|
|
702
|
+
subCategory?: string;
|
|
703
|
+
parentId?: string;
|
|
704
|
+
icon?: string;
|
|
705
|
+
sortOrder?: number;
|
|
706
|
+
tags?: string[];
|
|
707
|
+
/** Name and description per language: `{ en: { name, description } }`. */
|
|
708
|
+
translations: Record<string, {
|
|
709
|
+
name: string;
|
|
710
|
+
description?: string;
|
|
711
|
+
}>;
|
|
712
|
+
modules: NiceStudioTemplateModule[];
|
|
713
|
+
/** Anything else the host's template carries, kept as it is. */
|
|
714
|
+
extra?: Record<string, unknown>;
|
|
715
|
+
readOnly?: boolean;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/** A module of a template. */
|
|
719
|
+
export declare interface NiceStudioTemplateModule {
|
|
720
|
+
moduleId: string;
|
|
721
|
+
required?: boolean;
|
|
722
|
+
condition?: string;
|
|
723
|
+
description?: string;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/** Translations of one document: `{ en: { key: text }, pl: { … } }` (the shape of NiceI18nEditor). */
|
|
727
|
+
export declare type NiceStudioTranslations = Record<string, Record<string, string>>;
|
|
728
|
+
|
|
729
|
+
/** A place modules live in — a project: shipped seeds, a custom overlay, a tenant's modules. */
|
|
730
|
+
export declare interface NiceStudioWorkspace {
|
|
731
|
+
id: string;
|
|
732
|
+
label: string;
|
|
733
|
+
description?: string;
|
|
734
|
+
icon?: string;
|
|
735
|
+
/** Modules here can be opened but not changed. */
|
|
736
|
+
readOnly?: boolean;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/** The outcome of writing a module. */
|
|
740
|
+
export declare type NiceStudioWriteResult = {
|
|
741
|
+
ok: true;
|
|
742
|
+
versions?: Record<string, string>;
|
|
743
|
+
revision?: string;
|
|
744
|
+
} | {
|
|
745
|
+
ok: false;
|
|
746
|
+
conflicts: Array<{
|
|
747
|
+
path: string;
|
|
748
|
+
currentVersion?: string;
|
|
749
|
+
}>;
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
/** A file whose whole content is the model (a manifest, an access model). */
|
|
753
|
+
export declare function objectFileKind<T extends object>(o: NiceObjectFileKindOptions): NiceStudioFileKind<T>;
|
|
754
|
+
|
|
755
|
+
/** Parses JSON text that may start with a BOM, and tells how it is written. */
|
|
756
|
+
export declare function parseJsonText(text: string): {
|
|
757
|
+
value: unknown;
|
|
758
|
+
format: NiceJsonTextFormat;
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* `previous` with its content replaced by `next`, changing as few bytes as possible. Falls back
|
|
763
|
+
* to {@link stringifyJsonText} in the file's own format when the text cannot be patched (invalid
|
|
764
|
+
* JSON, duplicate keys) or the patch would not read back as `next`.
|
|
765
|
+
*/
|
|
766
|
+
export declare function patchJsonText(previous: string, next: unknown, options?: NiceJsonPatchOptions): string;
|
|
767
|
+
|
|
768
|
+
/** {@link patchJsonText}, also telling whether the patch was exact. */
|
|
769
|
+
export declare function patchJsonTextDetailed(previous: string, next: unknown, options?: NiceJsonPatchOptions): NiceJsonPatchResult;
|
|
770
|
+
|
|
771
|
+
/** The translations inside a file: `translations`, `keys`, or the whole file when it is a flat map. */
|
|
772
|
+
export declare function readTranslations(root: unknown): Record<string, string>;
|
|
773
|
+
|
|
774
|
+
/** The kind a path opens with: the first that matches, else JSON or text. */
|
|
775
|
+
export declare function resolveFileKind(kinds: readonly NiceStudioFileKind[], path: string): NiceStudioFileKind;
|
|
776
|
+
|
|
777
|
+
declare type Row = Record<string, unknown>;
|
|
778
|
+
|
|
779
|
+
declare type Row_2 = Record<string, unknown>;
|
|
780
|
+
|
|
781
|
+
/** Parses JSON without a BOM and returns `fallback` when the text is not JSON. */
|
|
782
|
+
export declare function safeJson<T = unknown>(text: string, fallback: T): T;
|
|
783
|
+
|
|
784
|
+
/** A file-name-safe id out of a display name: "Bike rental" → `bike-rental`. */
|
|
785
|
+
export declare function slugifyModuleId(name: string): string;
|
|
786
|
+
|
|
787
|
+
/** Writes `value` in a given format (defaults: two spaces, LF, final newline, no BOM). */
|
|
788
|
+
export declare function stringifyJsonText(value: unknown, format?: Partial<NiceJsonTextFormat>): string;
|
|
789
|
+
|
|
790
|
+
/** Any other file, edited as text. */
|
|
791
|
+
export declare const textFallbackKind: NiceStudioFileKind<string>;
|
|
792
|
+
|
|
793
|
+
/** The file with its translations replaced, in the same place they were. */
|
|
794
|
+
export declare function writeTranslations(root: unknown, entries: Record<string, string>): unknown;
|
|
795
|
+
|
|
796
|
+
export { }
|