@powerduck/schema-designer 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +134 -142
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -5,213 +5,205 @@
5
5
  <a href="https://www.powerduck.com/"><img src="https://img.shields.io/badge/website-powerduck.com-f28c28" alt="website"></a>
6
6
  </p>
7
7
 
8
- Composable JSON Schema and OpenAPI parameter editors extracted from Powerduck React. The tree, field settings, and parameter table share immutable schema operations while remaining independently importable.
8
+ Build JSON Schema and OpenAPI parameter editing UIs in minutes. Drop-in React components for designing request bodies, response schemas, query/path parameters, and variable-aware text fields all sharing a single immutable schema engine.
9
9
 
10
10
  **Website**: [https://www.powerduck.com/](https://www.powerduck.com/)
11
11
 
12
- ## Installation
12
+ ---
13
13
 
14
- The package currently lives in this workspace and has not been published. Build it before installing the local directory:
14
+ ## Quick Start
15
+
16
+ Install:
15
17
 
16
18
  ```sh
17
- cd schema-designer
18
- npm ci
19
- npm run build
20
- cd ../powerduck-react
21
- npm install ../schema-designer --install-links
19
+ npm install @powerduck/schema-designer
20
+ ```
21
+
22
+ Import the CSS once:
23
+
24
+ ```tsx
25
+ import "@powerduck/schema-designer/styles.css";
22
26
  ```
23
27
 
24
- The React components require React 18.2 or 19, Chakra UI 3, and Emotion. Wrap them in your application's `ChakraProvider`. Do not create a second React runtime. Development and generation adapters require Node 22.12 or later.
28
+ Wrap your app in a `ChakraProvider` (Chakra UI v3 required).
29
+
30
+ ### Edit a JSON Schema tree
25
31
 
26
32
  ```tsx
27
33
  import { useState } from "react";
28
- import {
29
- SchemaTreeEditor,
30
- InlineSchemaEditor,
31
- ParametersTable,
32
- } from "@powerduck/schema-designer";
34
+ import { SchemaTreeEditor } from "@powerduck/schema-designer";
33
35
  import type { SchemaValue } from "@powerduck/schema-designer";
34
- import "@powerduck/schema-designer/styles.css";
35
36
 
36
- function Designer() {
37
+ function DesignSchema() {
37
38
  const [schema, setSchema] = useState<SchemaValue>({
38
39
  type: "object",
39
- properties: { email: { type: "string", format: "email" } },
40
+ properties: {
41
+ email: { type: "string", format: "email" },
42
+ age: { type: "integer", minimum: 0 },
43
+ },
44
+ required: ["email"],
40
45
  });
46
+
41
47
  return <SchemaTreeEditor value={schema} onChange={setSchema} />;
42
48
  }
43
49
  ```
44
50
 
45
- ## Entry points
51
+ ### Edit OpenAPI parameters
52
+
53
+ ```tsx
54
+ import { ParametersTable } from "@powerduck/schema-designer/react/parameters";
46
55
 
47
- | Import | Purpose |
48
- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
49
- | `@powerduck/schema-designer/core` | Schema patches, pointers, traversal, reference resolution, parameter identities, and values; no React or DOM runtime dependency |
50
- | `@powerduck/schema-designer/react/tree` | Visual schema tree, with Inline settings as the default field popover |
51
- | `@powerduck/schema-designer/react/inline` | Standalone field constraints, arrays, objects, composition, examples, defaults, and preview |
52
- | `@powerduck/schema-designer/react/parameters` | Parameter definitions and request value tables |
53
- | `@powerduck/schema-designer/react/variable-editor` | The retained CodeMirror variable-aware input |
54
- | `@powerduck/schema-designer/adapters/generator` | Optional Faker, JSON Schema Faker, and Ajv generation adapter |
55
- | `@powerduck/schema-designer/styles.css` | Combined, scoped component styles; import once |
56
- | `@powerduck/schema-designer/compat/*` | Migration exports for existing Powerduck code |
56
+ const [parameters, setParameters] = useState([
57
+ { name: "page", in: "query", schema: { type: "integer", default: 1 } },
58
+ { name: "limit", in: "query", schema: { type: "integer", default: 20, maximum: 100 } },
59
+ ]);
57
60
 
58
- Both ESM and CommonJS builds include TypeScript declarations. The generation adapter is dynamically loaded only when default generation is requested. Tree imports do not load parameter editing, CodeMirror, or Faker code.
61
+ <ParametersTable parameters={parameters} onChange={setParameters} />
62
+ ```
59
63
 
60
- ## Schema editing
64
+ ### Variable-aware text input
61
65
 
62
- Use `value` and `onChange` for new integrations. Tree also accepts the original `schema` property. Inline additionally retains `schema` and `update(patch)`; an `undefined` patch value removes that keyword. Prefer one change interface per component. If both callbacks are provided, both are notified.
66
+ ```tsx
67
+ import { VariableTextEditor } from "@powerduck/schema-designer/react/variable-editor";
63
68
 
64
- Treat input schemas as immutable. Replace the changed branch when applying external updates; in-place mutation is unsupported. Unknown keywords, extensions, union types, boolean schema children, and unchanged branches are retained. Explicit type conversion removes incompatible type-specific constraints.
69
+ <VariableTextEditor
70
+ value={url}
71
+ onChange={setUrl}
72
+ variables={[{ name: "baseUrl", value: "https://api.example.com" }]}
73
+ />
74
+ ```
65
75
 
66
- Boolean schema roots and children remain `true` or `false`, rather than being coerced into empty objects. Their configuration UI supports toggling acceptance or explicitly converting to object constraints. Tree rendering includes array roots, items, tuple items, and composition branches. Existing object property lists retain their original layout.
76
+ ---
67
77
 
68
- Local references can be resolved against `document` on Tree and ParametersTable, or `fullSchema` on Inline. Without a document, Tree uses the edited schema. Referenced child rows are read-only; editing a reference occurrence does not rewrite its shared target. Unknown, external, and recursive references are retained, never automatically fetched. The default generator reports unresolved or recursive references instead of making a network request.
78
+ ## What You Get
69
79
 
70
- Tree preserves adding children and siblings, rename, required flags, description editing, delete confirmation, drag reorder, keyboard reorder, expansion, overflow reporting, error recovery, and custom `renderAdvanced(context)`. `context.update(next)` replaces that node. Inline patches and full replacements must not be confused.
80
+ | Component | Use case |
81
+ |-----------|----------|
82
+ | **SchemaTreeEditor** | Visual tree for designing JSON Schema — add properties, set types, edit constraints, drag to reorder |
83
+ | **InlineSchemaEditor** | Single-field editor for editing one schema node inline (type, format, enum, examples, composition) |
84
+ | **ParametersTable** | OpenAPI parameter table — design query/path/header/cookie params, or switch to "request" mode to fill values |
85
+ | **VariableTextEditor** | CodeMirror input with `{{variable}}` token support for URLs, headers, and scripts |
71
86
 
72
- Inline preserves type-specific constraints, property duplication, nested editing, references, enum values, composition, examples/defaults, copy, and diff preview. `showAdvanced`, `showComposition`, and `showLiveJson` control their respective UI. Copy uses the normal clipboard shortcut; field duplication uses Ctrl/Cmd+Shift+D.
87
+ ---
73
88
 
74
- ## Parameter definitions versus request values
89
+ ## Common Scenarios
75
90
 
76
- `mode="design"` is the default. It permits editing definitions, opening field configuration, selecting rows for batch operations, resizing columns, reordering, and deletion. `mode="request"` locks definition edits and adds request enablement independently of batch selection. Required path parameters stay enabled.
91
+ ### Design mode vs Request mode
77
92
 
78
93
  ```tsx
79
- import { ParametersTable } from "@powerduck/schema-designer/react/parameters";
80
- import { initializeParameterValues } from "@powerduck/schema-designer/core";
81
- import type { ParameterValues } from "@powerduck/schema-designer";
82
-
83
- const [values, setValues] = useState<ParameterValues>(() =>
84
- initializeParameterValues(parameters),
85
- );
94
+ // Design: edit parameter definitions
95
+ <ParametersTable parameters={params} onChange={setParams} />
86
96
 
97
+ // Request: fill in values to send (definitions locked)
87
98
  <ParametersTable
88
- parameters={parameters}
99
+ parameters={params}
89
100
  mode="request"
90
- values={values}
91
- onValuesChange={setValues}
92
- onError={reportError}
93
- />;
101
+ values={requestValues}
102
+ onValuesChange={setRequestValues}
103
+ />
94
104
  ```
95
105
 
96
- Values are keyed by `parameterKey(parameter)`, which includes location and name. Parameter definitions should have unique `(in, name)` pairs. Text edits remain raw strings so variables, incomplete JSON, and intentionally empty input are not lost. Examples and defaults supply initial display values; explicit request values take precedence, including `false`, `0`, `null`, and `""`. No HTTP serialization is performed by this package. Serialize against the current parameter definitions in your request layer.
97
-
98
- `onChange` emits parameter definitions, while `onValuesChange` emits request values and enablement. Both controlled and local request values are supported. `onSelectionChange` retains the original internal row IDs and remains independent of enablement. Use `readOnly` to prevent edits and generation.
99
-
100
- Generation skips supplied examples and values. A generation that makes no changes does not emit `onValuesChange`. A custom `generateValue(context)` may be asynchronous and receives an abort signal and optional document. Pending results merge only into unchanged rows and unchanged controlled values. Unmounting, entering read-only mode, changing mode or the reference document, or starting another generation cancels the previous operation. Errors are delivered through `onError`. Strict default generation rejects invalid candidates rather than returning an invalid fallback. Unsupported constraints may therefore require an explicit example or custom generator.
101
-
102
- OpenAPI parameter content and extension fields are preserved. The table is not a complete OpenAPI document validator: hosts remain responsible for cross-parameter constraints such as duplicate names, path-template membership, and the incompatibility of `query` with `querystring` parameters.
103
-
104
- ## Theme and accessibility
105
-
106
- All editors consume the existing Powerduck CSS tokens, including surface, text, border, radius, focus, and accent variables. Component CSS supplies light-theme fallbacks without overriding the host's tokens. Define the tokens on the page root for both themes so portaled menus and popovers inherit the same theme. Keep the Chakra color mode aligned with the page theme. `examples/tokens.css` is a reference copy of the application's tokens, not an automatically injected global stylesheet.
107
-
108
- Controls retain accessible names, keyboard focus indicators, Escape handling, disabled states, and keyboard reordering. Popovers are mounted lazily and constrained to the viewport. Invalid value drafts remain visible for correction.
109
-
110
- ### Compact presentation
111
-
112
- Both lists prioritize frequent edits. Tree shows field names and types by default; ParametersTable shows names and values. Optional columns are controlled independently with `showType`, `showRequired`, and `showDescription`. Hidden attributes remain available from the settings icon. Request mode opens settings read-only.
106
+ ### Show optional columns
113
107
 
114
108
  ```tsx
115
109
  <SchemaTreeEditor value={schema} onChange={setSchema} showRequired showDescription />
116
- <ParametersTable parameters={parameters} onChange={setParameters} showType showRequired showDescription />
110
+ <ParametersTable parameters={params} onChange={setParams} showType showRequired showDescription />
117
111
  ```
118
112
 
119
- Tree and parameter settings share the same compact, themed popover surface. Parameter settings separate Schema constraints from Parameter metadata; reference and serialization controls are expandable. Tree offers both Expand all and Collapse all, with expansion bounded by `maxRows` and cycle detection. Row settings stay visible; add/delete actions appear on hover or keyboard focus and remain visible on touch devices. Deletion still requires confirmation.
120
-
121
- ## Performance and boundaries
113
+ ### Resolve $ref references
122
114
 
123
- Updates share unchanged branches. Tree traversal visits expanded branches, uses occurrence-specific pointer IDs, stops at `maxRows`, and limits nesting depth. `maxRows` defaults to 5,000 and shows an overflow notice; the tree is bounded but not virtualized. Avoid expanding thousands of rows simultaneously when a smaller view is sufficient. Diff previews use a bounded algorithm instead of an unbounded quadratic allocation. Unchanged property branches and reconciled parameter rows retain their identities. Column sizing runs before paint, ignores height-only resize notifications, and remembers each visible-column layout separately. The table retains its CodeMirror inputs across placeholder, dimension, and column-visibility changes. Both tables scroll horizontally within their own containers when optional columns exceed available space.
124
-
125
- Run `npm run benchmark` for the pure traversal-plus-update benchmark at 100, 1,000, and 10,000 fields. This does not measure React rendering or interaction latency. Browser validation is also required for release acceptance.
115
+ ```tsx
116
+ <SchemaTreeEditor
117
+ value={schema}
118
+ onChange={setSchema}
119
+ document={openApiDocument} // resolves local $ref pointers
120
+ />
121
+ ```
126
122
 
127
- ## Development and verification
123
+ ### Generate sample values
128
124
 
129
- ```sh
130
- npm run typecheck
131
- npm test -- --pool=forks --maxWorkers=1 --minWorkers=1
132
- npm run build
133
- npm run verify:package
134
- npm run benchmark
135
- npm run dev
136
- npm pack
125
+ ```tsx
126
+ <ParametersTable
127
+ parameters={params}
128
+ mode="request"
129
+ values={values}
130
+ onValuesChange={setValues}
131
+ onError={reportError}
132
+ />
137
133
  ```
138
134
 
139
- The example uses the built distribution, so rebuild after changing library sources. Tests cover data preservation, pointer escaping, repeated references, boolean schemas, prototype-named fields, immutable updates, bounded diffing, incomplete input, disabled controls, default Tree-to-Inline integration, request enablement, generation, and stale async responses.
135
+ The built-in generator creates realistic sample values from your schema using Faker + JSON Schema Faker, with Ajv validation.
140
136
 
141
- Existing Powerduck component paths are compatibility entries backed by this package. The application's compact parameter table defaults remain unchanged. The tree compatibility adapter retains its original object-root contract; new integrations should use the package entry directly for boolean roots.
137
+ ---
142
138
 
143
- This workspace package is marked `UNLICENSED`. Publishing and license selection remain with the package owner.
139
+ ## Entry Points
144
140
 
145
- ### Variable text editor
141
+ | Import | Contents |
142
+ |--------|----------|
143
+ | `@powerduck/schema-designer` | All React components (tree, inline, parameters, variable editor) |
144
+ | `@powerduck/schema-designer/core` | Pure schema operations — patch, pointers, traversal, reference resolution (no React) |
145
+ | `@powerduck/schema-designer/react/tree` | SchemaTreeEditor only |
146
+ | `@powerduck/schema-designer/react/inline` | InlineSchemaEditor only |
147
+ | `@powerduck/schema-designer/react/parameters` | ParametersTable only |
148
+ | `@powerduck/schema-designer/react/variable-editor` | VariableTextEditor only |
149
+ | `@powerduck/schema-designer/styles.css` | Combined component styles |
146
150
 
147
- `VariableTextEditor` is exported from the package root and from `@powerduck/schema-designer/react/variable-editor`. The subpath is preferred when only variable input is needed. Import `@powerduck/schema-designer/styles.css` once in the application. Existing Powerduck import paths forward to the library, including legacy utility imports.
151
+ ESM + CommonJS builds with full TypeScript declarations. Tree-shaking friendly importing `react/tree` doesn't load CodeMirror or Faker.
148
152
 
149
- ```tsx
150
- import { VariableTextEditor } from "@powerduck/schema-designer/react/variable-editor";
153
+ ---
151
154
 
152
- <VariableTextEditor value={url} onChange={setUrl} variables={variables} />;
153
- ```
155
+ ## Requirements
154
156
 
155
- Composition editing remains available under Validation > Composition rules. The section is collapsed initially and respects `showComposition={false}`. These operators model schema alternatives and intersections; they are not request values.
157
+ - React 18.2+ or 19
158
+ - Chakra UI v3 (wrap app in `ChakraProvider`)
159
+ - Node 22.12+ (for the optional generator adapter)
156
160
 
157
- ## Integration reference
161
+ ---
158
162
 
159
- ### Tree
163
+ ## API Reference
160
164
 
161
- | Property | Default | Behavior |
162
- | --------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------- |
163
- | `value`, `onChange` | Required controlled pair | Accepts object or boolean schemas; emits immutable replacements. |
164
- | `document` | Edited schema | Root document for local `$ref` pointers. |
165
- | `showType` | `true` | Shows the inline type selector. |
166
- | `showRequired`, `showDescription` | `false` | Reveals optional columns without dropping their data. |
167
- | `defaultExpanded` | `[]` | Initial occurrence paths, such as `properties/customer`; escape `~` and `/` as `~0` and `~1`. |
168
- | `maxRows` | `5000` | Stops expanded traversal and displays an overflow notice. |
169
- | `readOnly` | `false` | Prevents commits, including custom advanced-editor updates. |
170
- | `renderAdvanced` | Shared Inline editor | Custom content receives a full-node replacement callback. |
171
- | `onError` | Unset | Receives recovered errors with scope and path. Throwing observers cannot break recovery. |
165
+ ### SchemaTreeEditor
172
166
 
173
- Enter commits buffered tree input; Escape cancels it. Ctrl/Cmd+Up/Down reorders properties. Array items have no required toggle, and composition entries can be removed. Local URI-fragment pointers, escaped property names, boolean references, and composition beside root properties are supported. Reference targets remain read-only in expanded rows.
167
+ | Prop | Default | Description |
168
+ |------|---------|-------------|
169
+ | `value` | required | The JSON Schema to edit (object or boolean) |
170
+ | `onChange` | required | Callback receiving the new schema |
171
+ | `document` | edited schema | Root document for resolving local `$ref` |
172
+ | `showType` | `true` | Show inline type selector |
173
+ | `showRequired` | `false` | Show required column |
174
+ | `showDescription` | `false` | Show description column |
175
+ | `defaultExpanded` | `[]` | Initially expanded paths |
176
+ | `maxRows` | `5000` | Max expanded rows before overflow notice |
177
+ | `readOnly` | `false` | Disable all edits |
178
+ | `onError` | — | Recovered errors with scope and path |
174
179
 
175
180
  ### ParametersTable
176
181
 
177
- | Property | Default | Behavior |
178
- | --------------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------- |
179
- | `parameters` | Required | Array of OpenAPI parameter definitions. |
180
- | `mode` | `design` | `request` locks definition changes while permitting request values and enablement. |
181
- | `showType`, `showRequired`, `showDescription` | `false` | Name and value stay visible. |
182
- | `values`, `onValuesChange` | Local state | Optional controlled request values indexed by `parameterKey`. |
183
- | `document` | Unset | Resolves local schema and example references. |
184
- | `height` | `100%` | Use a bounded height for internal scrolling or `auto` for document flow. |
185
- | `stickyHeader` | `true` | Sticky within the table viewport; `false` uses normal flow. |
186
- | `readOnly` | `false` | Prevents definition edits, value edits, enablement changes, and generation. |
187
- | `generateValue` | Optional built-in adapter | Receives parameter, row index, document, and abort signal. |
188
-
189
- Focused column separators accept Left/Right for 8px adjustments, or Shift+Left/Right for 32px. The adjacent pair retains its total width. The final column has no inactive resize handle. Content-based parameter schemas are preserved and are not accidentally combined with a new top-level `schema` by the type column. Boolean parameter schemas remain booleans in settings and reference resolution.
182
+ | Prop | Default | Description |
183
+ |------|---------|-------------|
184
+ | `parameters` | required | OpenAPI parameter array |
185
+ | `onChange` | | Callback receiving updated parameter definitions |
186
+ | `mode` | `"design"` | `"design"` edits definitions; `"request"` fills values |
187
+ | `values` | local state | Controlled request values keyed by `parameterKey` |
188
+ | `onValuesChange` | | Callback for request value changes |
189
+ | `document` | | Root document for `$ref` resolution |
190
+ | `showType` / `showRequired` / `showDescription` | `false` | Toggle optional columns |
191
+ | `readOnly` | `false` | Disable all edits |
190
192
 
191
193
  ### VariableTextEditor
192
194
 
193
- | Property | Default | Behavior |
194
- | ------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
195
- | `value`, `onChange` | Required value / optional callback | Raw text, including an empty string when cleared. |
196
- | `variables` | `[]` | Immutable definitions; names, values, descriptions, types, and custom colors update without rebuilding the editor. |
197
- | `ariaLabel` | `Variable text editor` | Use a field-specific accessible name. |
198
- | `allowLineBreaks` | `false` | Paste normalizes line breaks to spaces when disabled. |
199
- | `submitOnEnter` | `false` | Submits single-line input after completion handling; IME confirmation is preserved. |
200
- | `minHeight`, `maxFocusedHeight` | `32`, `320` | Pixel heights; focused overflow is scrollable. |
201
- | `safePadding` | `8` | Nonnegative vertical padding while focused; tables use `4`. |
202
- | `maxLength` | `16384` | UTF-16 code-unit limit, configurable up to 1,000,000. |
203
- | `disabled`, `readOnly` | `false` | Prevents edits, including paste/drop paths. |
204
-
205
- Treat variable arrays and their entries as immutable. Inline token decorations update with the same document transaction, so deletion cannot leave stale token ranges. Updating presentation props preserves focus, selection, and history. Hosts should echo changes; delayed acknowledgments are tolerated, but this is not a collaborative-edit conflict-resolution protocol.
206
-
207
- ## Generator safety and release boundaries
208
-
209
- The optional default generator validates candidates against the original schema in strict mode. `false` schemas reject generation. `maxArrayItems` defaults to 3 and is an allocation budget (1–1,000); increase it explicitly when an array's minimum requires more items. `maxDepth` accepts 1–32, and `validationRetryCount` accepts 0–20. Generated strings are bounded to 16,384 code units; larger required minimums produce an error. Local dereferencing is bounded to 20,000 visited nodes and a maximum depth of 128. Reference resolution never fetches remote documents.
210
-
211
- These limits do not sandbox user-supplied regexes or third-party synchronous generation. For untrusted schemas or hard time limits, provide a worker-backed `generateValue` adapter and enforce a timeout there. An abort signal prevents stale results from being committed; it cannot interrupt synchronous JavaScript already executing.
195
+ | Prop | Default | Description |
196
+ |------|---------|-------------|
197
+ | `value` | required | Raw text string |
198
+ | `onChange` | | Callback receiving new text |
199
+ | `variables` | `[]` | Array of `{ name, value, description, type? }` |
200
+ | `allowLineBreaks` | `false` | Enable multi-line input |
201
+ | `submitOnEnter` | `false` | Call submit on Enter |
202
+ | `minHeight` / `maxFocusedHeight` | `32` / `320` | Pixel height bounds |
203
+ | `readOnly` / `disabled` | `false` | Lock input |
212
204
 
213
- This is a schema editor, not a complete JSON Schema or OpenAPI validator. Unknown keywords are preserved, but not every keyword has a dedicated control. The host must validate a document before saving or sending requests. Large trees are bounded, not virtualized; large parameter tables instantiate an editor per visible text cell, so paginate or filter large parameter collections in the host.
205
+ ---
214
206
 
215
- The current audit verifies the installed dependency set and the local Chromium preview. React 18 and 19 are declared peer ranges; a full React-version, Safari, and Firefox matrix has not been run in this workspace. Run your supported-browser matrix before release. See [VERIFICATION.md](./VERIFICATION.md) for measured results and the source audit record. No numeric quality score substitutes for these checks.
207
+ ## License
216
208
 
217
- Multiline parameter values use `expansionMode="overlay"` to expand above neighboring content while preserving row height, and collapse on blur. Standalone editors default to `"inline"` expansion. Expanded editors use a thin theme border, visible blank-line markers, and internal scrolling at `maxFocusedHeight`. Markers are visual only and are never included in copied or emitted values.
209
+ UNLICENSED owned by Powerduck.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powerduck/schema-designer",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Composable JSON Schema and OpenAPI parameter editors for React.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",