openuispec 0.1.10 → 0.1.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 +36 -0
- package/cli/init.ts +47 -44
- package/package.json +1 -1
- package/schema/validate.ts +36 -2
package/README.md
CHANGED
|
@@ -119,6 +119,42 @@ openuispec/
|
|
|
119
119
|
└── README.md
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
+
## File formats and schemas
|
|
123
|
+
|
|
124
|
+
Every file type has a corresponding JSON Schema in `schema/`. **Read the schema before creating or editing a file** — do not guess the structure.
|
|
125
|
+
|
|
126
|
+
| File | Schema | Root key | Example |
|
|
127
|
+
|------|--------|----------|---------|
|
|
128
|
+
| `openuispec.yaml` | `openuispec.schema.json` | `spec_version` | [openuispec.yaml](./examples/taskflow/openuispec.yaml) |
|
|
129
|
+
| `screens/*.yaml` | `screen.schema.json` | `<screen_id>` | [home.yaml](./examples/taskflow/screens/home.yaml) |
|
|
130
|
+
| `flows/*.yaml` | `flow.schema.json` | `<flow_id>` | [create_task.yaml](./examples/taskflow/flows/create_task.yaml) |
|
|
131
|
+
| `platform/*.yaml` | `platform.schema.json` | `platform` | [ios.yaml](./examples/taskflow/platform/ios.yaml) |
|
|
132
|
+
| `locales/*.json` | `locale.schema.json` | (object) | [en.json](./examples/taskflow/locales/en.json) |
|
|
133
|
+
| `contracts/x_*.yaml` | `custom-contract.schema.json` | `contract` | [x_media_player.yaml](./examples/taskflow/contracts/x_media_player.yaml) |
|
|
134
|
+
| `tokens/color.yaml` | `tokens/color.schema.json` | `color` | [color.yaml](./examples/taskflow/tokens/color.yaml) |
|
|
135
|
+
| `tokens/typography.yaml` | `tokens/typography.schema.json` | `typography` | [typography.yaml](./examples/taskflow/tokens/typography.yaml) |
|
|
136
|
+
| `tokens/spacing.yaml` | `tokens/spacing.schema.json` | `spacing` | [spacing.yaml](./examples/taskflow/tokens/spacing.yaml) |
|
|
137
|
+
| `tokens/elevation.yaml` | `tokens/elevation.schema.json` | `elevation` | [elevation.yaml](./examples/taskflow/tokens/elevation.yaml) |
|
|
138
|
+
| `tokens/motion.yaml` | `tokens/motion.schema.json` | `motion` | [motion.yaml](./examples/taskflow/tokens/motion.yaml) |
|
|
139
|
+
| `tokens/layout.yaml` | `tokens/layout.schema.json` | `layout` | [layout.yaml](./examples/taskflow/tokens/layout.yaml) |
|
|
140
|
+
| `tokens/themes.yaml` | `tokens/themes.schema.json` | `themes` | [themes.yaml](./examples/taskflow/tokens/themes.yaml) |
|
|
141
|
+
| `tokens/icons.yaml` | `tokens/icons.schema.json` | `icons` | [icons.yaml](./examples/taskflow/tokens/icons.yaml) |
|
|
142
|
+
|
|
143
|
+
Every token file **must** have a single root wrapper key matching its type:
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
# Correct — tokens/color.yaml
|
|
147
|
+
color:
|
|
148
|
+
brand:
|
|
149
|
+
primary: ...
|
|
150
|
+
|
|
151
|
+
# Wrong — missing root key
|
|
152
|
+
brand:
|
|
153
|
+
primary: ...
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Validate with: `openuispec validate`
|
|
157
|
+
|
|
122
158
|
## Spec at a glance
|
|
123
159
|
|
|
124
160
|
| Section | What it defines |
|
package/cli/init.ts
CHANGED
|
@@ -198,38 +198,30 @@ scale: ...
|
|
|
198
198
|
|
|
199
199
|
Root keys: \`color\`, \`typography\`, \`spacing\`, \`elevation\`, \`motion\`, \`layout\`, \`themes\`, \`icons\`.
|
|
200
200
|
|
|
201
|
-
##
|
|
202
|
-
|
|
203
|
-
**IMPORTANT:** Before creating or editing any spec file, read the corresponding JSON Schema to understand the valid structure.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
├── data-binding.schema.json ← data sources, state, params
|
|
226
|
-
├── adaptive.schema.json ← adaptive override pattern
|
|
227
|
-
└── validation.schema.json ← validation rule definitions
|
|
228
|
-
\`\`\`
|
|
229
|
-
|
|
230
|
-
**Workflow:** read the schema → create the YAML file → run \`openuispec validate\` to verify.
|
|
231
|
-
|
|
232
|
-
**Example spec files:** \`node_modules/openuispec/examples/taskflow/\` — a complete app demonstrating all file types. Read these for real-world examples of screens, flows, tokens, and platform overrides.
|
|
201
|
+
## File formats and schemas
|
|
202
|
+
|
|
203
|
+
**IMPORTANT:** Before creating or editing any spec file, read the corresponding JSON Schema to understand the valid structure. Do not guess the file format.
|
|
204
|
+
|
|
205
|
+
| File | Schema | Root key |
|
|
206
|
+
|------|--------|----------|
|
|
207
|
+
| \`openuispec.yaml\` | \`openuispec.schema.json\` | \`spec_version\` |
|
|
208
|
+
| \`screens/*.yaml\` | \`screen.schema.json\` | \`<screen_id>\` |
|
|
209
|
+
| \`flows/*.yaml\` | \`flow.schema.json\` | \`<flow_id>\` |
|
|
210
|
+
| \`platform/*.yaml\` | \`platform.schema.json\` | \`platform\` |
|
|
211
|
+
| \`locales/*.json\` | \`locale.schema.json\` | (object) |
|
|
212
|
+
| \`contracts/x_*.yaml\` | \`custom-contract.schema.json\` | \`contract\` |
|
|
213
|
+
| \`tokens/color.yaml\` | \`tokens/color.schema.json\` | \`color\` |
|
|
214
|
+
| \`tokens/typography.yaml\` | \`tokens/typography.schema.json\` | \`typography\` |
|
|
215
|
+
| \`tokens/spacing.yaml\` | \`tokens/spacing.schema.json\` | \`spacing\` |
|
|
216
|
+
| \`tokens/elevation.yaml\` | \`tokens/elevation.schema.json\` | \`elevation\` |
|
|
217
|
+
| \`tokens/motion.yaml\` | \`tokens/motion.schema.json\` | \`motion\` |
|
|
218
|
+
| \`tokens/layout.yaml\` | \`tokens/layout.schema.json\` | \`layout\` |
|
|
219
|
+
| \`tokens/themes.yaml\` | \`tokens/themes.schema.json\` | \`themes\` |
|
|
220
|
+
| \`tokens/icons.yaml\` | \`tokens/icons.schema.json\` | \`icons\` |
|
|
221
|
+
|
|
222
|
+
All schemas are in \`node_modules/openuispec/schema/\`. Shared type definitions (actions, data-binding, adaptive, validation, common) are in \`schema/defs/\`.
|
|
223
|
+
|
|
224
|
+
**Workflow:** read the schema → read an example from \`node_modules/openuispec/examples/taskflow/\` → create the YAML → run \`openuispec validate\`.
|
|
233
225
|
|
|
234
226
|
## Spec format quick reference
|
|
235
227
|
|
|
@@ -337,18 +329,29 @@ Every token file must have a single root key matching the token type. Do NOT put
|
|
|
337
329
|
- \`tokens/themes.yaml\` → root key: \`themes\`
|
|
338
330
|
- \`tokens/icons.yaml\` → root key: \`icons\`
|
|
339
331
|
|
|
340
|
-
##
|
|
341
|
-
Before creating or editing any spec file, read the corresponding JSON Schema
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
332
|
+
## File formats and schemas — read before creating spec files
|
|
333
|
+
Before creating or editing any spec file, read the corresponding JSON Schema. Do not guess the file format.
|
|
334
|
+
|
|
335
|
+
| File | Schema (in \`node_modules/openuispec/schema/\`) | Root key |
|
|
336
|
+
|------|--------|----------|
|
|
337
|
+
| \`openuispec.yaml\` | \`openuispec.schema.json\` | \`spec_version\` |
|
|
338
|
+
| \`screens/*.yaml\` | \`screen.schema.json\` | \`<screen_id>\` |
|
|
339
|
+
| \`flows/*.yaml\` | \`flow.schema.json\` | \`<flow_id>\` |
|
|
340
|
+
| \`platform/*.yaml\` | \`platform.schema.json\` | \`platform\` |
|
|
341
|
+
| \`locales/*.json\` | \`locale.schema.json\` | (object) |
|
|
342
|
+
| \`contracts/x_*.yaml\` | \`custom-contract.schema.json\` | \`contract\` |
|
|
343
|
+
| \`tokens/color.yaml\` | \`tokens/color.schema.json\` | \`color\` |
|
|
344
|
+
| \`tokens/typography.yaml\` | \`tokens/typography.schema.json\` | \`typography\` |
|
|
345
|
+
| \`tokens/spacing.yaml\` | \`tokens/spacing.schema.json\` | \`spacing\` |
|
|
346
|
+
| \`tokens/elevation.yaml\` | \`tokens/elevation.schema.json\` | \`elevation\` |
|
|
347
|
+
| \`tokens/motion.yaml\` | \`tokens/motion.schema.json\` | \`motion\` |
|
|
348
|
+
| \`tokens/layout.yaml\` | \`tokens/layout.schema.json\` | \`layout\` |
|
|
349
|
+
| \`tokens/themes.yaml\` | \`tokens/themes.schema.json\` | \`themes\` |
|
|
350
|
+
| \`tokens/icons.yaml\` | \`tokens/icons.schema.json\` | \`icons\` |
|
|
351
|
+
|
|
352
|
+
Shared type definitions (actions, data-binding, adaptive, validation, common) are in \`schema/defs/\`.
|
|
353
|
+
|
|
354
|
+
Workflow: read the schema → read an example from \`node_modules/openuispec/examples/taskflow/\` → create the YAML → run \`openuispec validate\`.
|
|
352
355
|
|
|
353
356
|
## Spec format reference
|
|
354
357
|
- 7 contract families: nav_container, surface, action_trigger, input_field, data_display, collection, feedback
|
package/package.json
CHANGED
package/schema/validate.ts
CHANGED
|
@@ -71,6 +71,8 @@ function buildAjv(): AjvInstance {
|
|
|
71
71
|
return ajv;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
const BASE = "https://openuispec.org/schema/";
|
|
75
|
+
|
|
74
76
|
// ── validate one file ────────────────────────────────────────────────
|
|
75
77
|
|
|
76
78
|
function validateFile(
|
|
@@ -94,6 +96,12 @@ function validateFile(
|
|
|
94
96
|
return 0;
|
|
95
97
|
}
|
|
96
98
|
|
|
99
|
+
// Convert schema URL to a local path for display
|
|
100
|
+
const schemaLocalPath = schemaId.replace(
|
|
101
|
+
BASE,
|
|
102
|
+
"node_modules/openuispec/schema/",
|
|
103
|
+
);
|
|
104
|
+
|
|
97
105
|
const errors: ErrorObject[] = validate.errors ?? [];
|
|
98
106
|
console.log(` FAIL ${name} (${errors.length} error(s))`);
|
|
99
107
|
for (const e of errors.slice(0, 5)) {
|
|
@@ -109,13 +117,39 @@ function validateFile(
|
|
|
109
117
|
if (errors.length > 5) {
|
|
110
118
|
console.log(` ... and ${errors.length - 5} more`);
|
|
111
119
|
}
|
|
120
|
+
|
|
121
|
+
// Show hint when root-level structure is wrong (missing wrapper key)
|
|
122
|
+
const hasRootRequired = errors.some(
|
|
123
|
+
(e) => !e.instancePath && e.keyword === "required",
|
|
124
|
+
);
|
|
125
|
+
const hasRootAdditional = errors.some(
|
|
126
|
+
(e) => !e.instancePath && e.keyword === "additionalProperties",
|
|
127
|
+
);
|
|
128
|
+
if (hasRootRequired || hasRootAdditional) {
|
|
129
|
+
const expectedKey = errors.find(
|
|
130
|
+
(e) => !e.instancePath && e.keyword === "required",
|
|
131
|
+
)?.params?.missingProperty as string | undefined;
|
|
132
|
+
if (expectedKey) {
|
|
133
|
+
console.log(
|
|
134
|
+
`\n Hint: "${name}" needs a root "${expectedKey}:" wrapper key.`,
|
|
135
|
+
);
|
|
136
|
+
console.log(` Example:`);
|
|
137
|
+
console.log(` ${expectedKey}:`);
|
|
138
|
+
console.log(` ...your content here...`);
|
|
139
|
+
} else {
|
|
140
|
+
console.log(
|
|
141
|
+
`\n Hint: This file has unexpected top-level properties.`,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log(` Schema: ${schemaLocalPath}`);
|
|
147
|
+
|
|
112
148
|
return errors.length;
|
|
113
149
|
}
|
|
114
150
|
|
|
115
151
|
// ── validation groups ────────────────────────────────────────────────
|
|
116
152
|
|
|
117
|
-
const BASE = "https://openuispec.org/schema/";
|
|
118
|
-
|
|
119
153
|
interface ValidationGroup {
|
|
120
154
|
label: string;
|
|
121
155
|
run(ajv: AjvInstance, projectDir: string): number;
|