@stonecrop/schema 0.13.8 → 0.13.10
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 -15
- package/dist/cli.js +6 -6
- package/dist/{index-C08kwqyS.js → index-C5ANE_rn.js} +230 -231
- package/dist/index-C5ANE_rn.js.map +1 -0
- package/dist/{index-COp1U6eU.js → index-D66L9JNw.js} +220 -219
- package/dist/index-D66L9JNw.js.map +1 -0
- package/dist/index.js +30 -25
- package/dist/schema.d.ts +256 -91
- package/dist/src/converter/heuristics.d.ts.map +1 -1
- package/dist/src/converter/heuristics.js +1 -0
- package/dist/src/converter/index.d.ts.map +1 -1
- package/dist/src/converter/index.js +6 -4
- package/dist/src/converter/types.d.ts +6 -6
- package/dist/src/converter/types.d.ts.map +1 -1
- package/dist/src/doctype.d.ts +4 -35
- package/dist/src/doctype.d.ts.map +1 -1
- package/dist/src/doctype.js +2 -2
- package/dist/src/field.d.ts +163 -18
- package/dist/src/field.d.ts.map +1 -1
- package/dist/src/field.js +108 -72
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -0
- package/dist/src/validation.d.ts +4 -5
- package/dist/src/validation.d.ts.map +1 -1
- package/dist/src/validation.js +5 -5
- package/package.json +1 -1
- package/dist/index-C08kwqyS.js.map +0 -1
- package/dist/index-COp1U6eU.js.map +0 -1
- package/dist/index-leHOZ3ll.js +0 -502
- package/dist/index-leHOZ3ll.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Schema definitions and validation for Stonecrop doctypes, fields, and workflows.
|
|
|
6
6
|
|
|
7
7
|
`@stonecrop/schema` provides the foundational type system for Stonecrop applications. It defines strongly-typed schemas using [Zod](https://zod.dev/) for:
|
|
8
8
|
|
|
9
|
-
- **Field definitions** (`
|
|
9
|
+
- **Field definitions** (`DoctypeField`) - Discriminated union of field variants (`ValueField | FieldsetField | TableField`)
|
|
10
10
|
- **Doctype definitions** (`DoctypeMeta`) - Complete document type schemas
|
|
11
11
|
- **Workflows** (`WorkflowMeta`) - State machines and action definitions
|
|
12
12
|
- **Validation** - Runtime schema validation with detailed error reporting
|
|
@@ -31,7 +31,7 @@ pnpm add @stonecrop/schema
|
|
|
31
31
|
Stonecrop uses semantic field types that remain consistent whether rendered in a form or table:
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
import { StonecropFieldType
|
|
34
|
+
import { StonecropFieldType } from '@stonecrop/schema'
|
|
35
35
|
|
|
36
36
|
// Field types include:
|
|
37
37
|
// Text: Data, Text
|
|
@@ -44,14 +44,29 @@ import { StonecropFieldType, FieldMeta } from '@stonecrop/schema'
|
|
|
44
44
|
// Selection: Select
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
### Field
|
|
47
|
+
### Field Definitions
|
|
48
48
|
|
|
49
|
-
`
|
|
49
|
+
`DoctypeField` is a discriminated union of three structural variants:
|
|
50
|
+
|
|
51
|
+
- **`ValueField`** — a scalar or link field; has `fieldtype`
|
|
52
|
+
- **`FieldsetField`** — a layout container grouping other fields; has `schema: DoctypeField[]`
|
|
53
|
+
- **`TableField`** — an inline table with column definitions; has `columns: ColumnSchema[]`
|
|
54
|
+
|
|
55
|
+
**In authored JSON** (doctype files), `kind` is inferred from structure automatically — you only write the properties that define what the field is:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{ "fieldname": "customer_name", "fieldtype": "Data", "label": "Customer Name", "required": true }
|
|
59
|
+
{ "fieldname": "details", "label": "Details", "schema": [...] }
|
|
60
|
+
{ "fieldname": "line_items", "label": "Line Items", "columns": [...] }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**In TypeScript code** that constructs `DoctypeField` objects directly, `kind` is required:
|
|
50
64
|
|
|
51
65
|
```typescript
|
|
52
|
-
import {
|
|
66
|
+
import type { ValueField, FieldsetField, DoctypeField } from '@stonecrop/schema'
|
|
53
67
|
|
|
54
|
-
const field:
|
|
68
|
+
const field: ValueField = {
|
|
69
|
+
kind: 'field',
|
|
55
70
|
fieldname: 'customer_name',
|
|
56
71
|
fieldtype: 'Data',
|
|
57
72
|
label: 'Customer Name',
|
|
@@ -62,21 +77,24 @@ const field: FieldMeta = {
|
|
|
62
77
|
}
|
|
63
78
|
|
|
64
79
|
// Type-specific options
|
|
65
|
-
const linkField:
|
|
80
|
+
const linkField: ValueField = {
|
|
81
|
+
kind: 'field',
|
|
66
82
|
fieldname: 'customer',
|
|
67
83
|
fieldtype: 'Link',
|
|
68
84
|
label: 'Customer',
|
|
69
85
|
options: 'customer', // Target doctype slug
|
|
70
86
|
}
|
|
71
87
|
|
|
72
|
-
const selectField:
|
|
88
|
+
const selectField: ValueField = {
|
|
89
|
+
kind: 'field',
|
|
73
90
|
fieldname: 'status',
|
|
74
91
|
fieldtype: 'Select',
|
|
75
92
|
label: 'Status',
|
|
76
93
|
options: ['Draft', 'Submitted', 'Cancelled'], // Choices array
|
|
77
94
|
}
|
|
78
95
|
|
|
79
|
-
const decimalField:
|
|
96
|
+
const decimalField: ValueField = {
|
|
97
|
+
kind: 'field',
|
|
80
98
|
fieldname: 'price',
|
|
81
99
|
fieldtype: 'Decimal',
|
|
82
100
|
label: 'Price',
|
|
@@ -96,6 +114,7 @@ const doctype: DoctypeMeta = {
|
|
|
96
114
|
slug: 'sales-order',
|
|
97
115
|
fields: [
|
|
98
116
|
{
|
|
117
|
+
kind: 'field',
|
|
99
118
|
fieldname: 'customer',
|
|
100
119
|
fieldtype: 'Link',
|
|
101
120
|
label: 'Customer',
|
|
@@ -103,6 +122,7 @@ const doctype: DoctypeMeta = {
|
|
|
103
122
|
required: true,
|
|
104
123
|
},
|
|
105
124
|
{
|
|
125
|
+
kind: 'field',
|
|
106
126
|
fieldname: 'items',
|
|
107
127
|
fieldtype: 'Link',
|
|
108
128
|
label: 'Items',
|
|
@@ -253,7 +273,7 @@ import { parseField, parseDoctype } from '@stonecrop/schema'
|
|
|
253
273
|
|
|
254
274
|
try {
|
|
255
275
|
const field = parseField(untrustedData)
|
|
256
|
-
// TypeScript knows field is
|
|
276
|
+
// TypeScript knows field is DoctypeField (ValueField | FieldsetField | TableField)
|
|
257
277
|
} catch (error) {
|
|
258
278
|
console.error('Invalid field:', error)
|
|
259
279
|
}
|
|
@@ -427,7 +447,7 @@ This package provides the type system used throughout Stonecrop:
|
|
|
427
447
|
|
|
428
448
|
- **`@stonecrop/stonecrop`** - Registry uses `DoctypeMeta` for schema storage; `getDescendantLinks()` / `getAncestorLinks()` for relationship traversal
|
|
429
449
|
- **`@stonecrop/graphql-client`** - `StonecropClient` implements `DataClient`; uses `GetRecordOptions` / `GetRecordsOptions` for fetch parameters
|
|
430
|
-
- **`@stonecrop/aform`** - Renders fields based on `
|
|
450
|
+
- **`@stonecrop/aform`** - Renders fields based on `DoctypeField` definitions
|
|
431
451
|
- **`@stonecrop/atable`** - Uses `ColumnSchema` for schema-driven column derivation; `TableColumn` (ATable's runtime column type) extends `ColumnSchema`, widening `format`/`modalComponent` to accept live functions and adding `mask`/`originalIndex`
|
|
432
452
|
- **Backend APIs** - Validates and stores doctypes using these schemas
|
|
433
453
|
|
|
@@ -455,10 +475,11 @@ rushx docs
|
|
|
455
475
|
This package is written in TypeScript with strict mode enabled and provides full type definitions:
|
|
456
476
|
|
|
457
477
|
```typescript
|
|
458
|
-
import type {
|
|
478
|
+
import type { ValueField, DoctypeField, DoctypeMeta } from '@stonecrop/schema'
|
|
459
479
|
|
|
460
480
|
// Types are inferred from Zod schemas
|
|
461
|
-
const field:
|
|
481
|
+
const field: ValueField = {
|
|
482
|
+
kind: 'field',
|
|
462
483
|
fieldname: 'title',
|
|
463
484
|
fieldtype: 'Data',
|
|
464
485
|
// TypeScript will catch typos and missing required fields
|
|
@@ -466,7 +487,7 @@ const field: FieldMeta = {
|
|
|
466
487
|
|
|
467
488
|
// Use Zod's infer utility for derived types
|
|
468
489
|
import { z } from 'zod'
|
|
469
|
-
import {
|
|
490
|
+
import { DoctypeFieldSchema } from '@stonecrop/schema'
|
|
470
491
|
|
|
471
|
-
type
|
|
492
|
+
type DoctypeFieldType = z.infer<typeof DoctypeFieldSchema>
|
|
472
493
|
```
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { readFileSync as u, existsSync as S, mkdirSync as w, writeFileSync as x
|
|
|
3
3
|
import { resolve as c, join as O } from "node:path";
|
|
4
4
|
import { parseArgs as $ } from "node:util";
|
|
5
5
|
import { getIntrospectionQuery as N } from "graphql";
|
|
6
|
-
import {
|
|
6
|
+
import { g as P, v as j } from "./index-D66L9JNw.js";
|
|
7
7
|
async function C(e, m) {
|
|
8
8
|
const t = await fetch(e, {
|
|
9
9
|
method: "POST",
|
|
@@ -69,15 +69,15 @@ async function E() {
|
|
|
69
69
|
const s = `${o.slug}.json`, d = O(r, s), v = JSON.stringify(o, null, " ");
|
|
70
70
|
x(d, v + `
|
|
71
71
|
`, "utf-8");
|
|
72
|
-
const
|
|
73
|
-
if (
|
|
74
|
-
const n = o.fields.filter((
|
|
72
|
+
const y = j(o);
|
|
73
|
+
if (y.success) {
|
|
74
|
+
const n = o.fields.filter((g) => g._unmapped);
|
|
75
75
|
n.length > 0 && (h++, console.warn(
|
|
76
|
-
` WARN: ${s} has ${n.length} unmapped field(s): ${n.map((
|
|
76
|
+
` WARN: ${s} has ${n.length} unmapped field(s): ${n.map((g) => g.fieldname).join(", ")}`
|
|
77
77
|
));
|
|
78
78
|
} else {
|
|
79
79
|
p++, console.error(` ERROR: ${s} failed validation:`);
|
|
80
|
-
for (const n of
|
|
80
|
+
for (const n of y.errors)
|
|
81
81
|
console.error(` ${n.path.join(".")}: ${n.message}`);
|
|
82
82
|
}
|
|
83
83
|
}
|