@svadmin/surface 0.7.0 → 0.7.2

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.
@@ -1,20 +1,4 @@
1
- import { type Static, type TSchema } from "@sinclair/typebox";
2
- export declare function createParsedSchema<T extends TSchema>(schema: T): T & {
3
- parse: (value: unknown) => Static<T>;
4
- safeParse: (value: unknown) => {
5
- success: true;
6
- data: Static<T>;
7
- } | {
8
- success: false;
9
- error: {
10
- issues: Array<{
11
- path: string[];
12
- message: string;
13
- }>;
14
- };
15
- };
16
- Check: (value: unknown) => boolean;
17
- };
1
+ import { type Static } from "@sinclair/typebox";
18
2
  export declare const metricPropsSchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
19
3
  label: import("@sinclair/typebox").TString;
20
4
  format: import("@sinclair/typebox").TLiteral<"currency">;
@@ -25,42 +9,7 @@ export declare const metricPropsSchema: import("@sinclair/typebox").TUnion<[impo
25
9
  format: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"number">, import("@sinclair/typebox").TLiteral<"percent">]>;
26
10
  currency: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNever>;
27
11
  description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
28
- }>]> & {
29
- parse: (value: unknown) => {
30
- description?: string | undefined;
31
- currency: string;
32
- label: string;
33
- format: "currency";
34
- } | {
35
- description?: string | undefined;
36
- currency?: undefined;
37
- label: string;
38
- format: "number" | "percent";
39
- };
40
- safeParse: (value: unknown) => {
41
- success: false;
42
- error: {
43
- issues: Array<{
44
- path: string[];
45
- message: string;
46
- }>;
47
- };
48
- } | {
49
- success: true;
50
- data: {
51
- description?: string | undefined;
52
- currency: string;
53
- label: string;
54
- format: "currency";
55
- } | {
56
- description?: string | undefined;
57
- currency?: undefined;
58
- label: string;
59
- format: "number" | "percent";
60
- };
61
- };
62
- Check: (value: unknown) => boolean;
63
- };
12
+ }>]>;
64
13
  export declare const resourceTablePropsSchema: import("@sinclair/typebox").TObject<{
65
14
  title: import("@sinclair/typebox").TString;
66
15
  emptyLabel: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
@@ -69,103 +18,20 @@ export declare const resourceTablePropsSchema: import("@sinclair/typebox").TObje
69
18
  label: import("@sinclair/typebox").TString;
70
19
  format: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"text">, import("@sinclair/typebox").TLiteral<"number">, import("@sinclair/typebox").TLiteral<"date">, import("@sinclair/typebox").TLiteral<"boolean">]>>;
71
20
  }>>;
72
- }> & {
73
- parse: (value: unknown) => {
74
- emptyLabel?: string | undefined;
75
- title: string;
76
- columns: {
77
- format?: "number" | "boolean" | "text" | "date" | undefined;
78
- field: string;
79
- label: string;
80
- }[];
81
- };
82
- safeParse: (value: unknown) => {
83
- success: false;
84
- error: {
85
- issues: Array<{
86
- path: string[];
87
- message: string;
88
- }>;
89
- };
90
- } | {
91
- success: true;
92
- data: {
93
- emptyLabel?: string | undefined;
94
- title: string;
95
- columns: {
96
- format?: "number" | "boolean" | "text" | "date" | undefined;
97
- field: string;
98
- label: string;
99
- }[];
100
- };
101
- };
102
- Check: (value: unknown) => boolean;
103
- };
21
+ }>;
104
22
  export declare const barChartPropsSchema: import("@sinclair/typebox").TObject<{
105
23
  title: import("@sinclair/typebox").TString;
106
24
  labelField: import("@sinclair/typebox").TString;
107
25
  valueField: import("@sinclair/typebox").TString;
108
26
  showValues: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
109
- }> & {
110
- parse: (value: unknown) => {
111
- showValues?: boolean | undefined;
112
- title: string;
113
- labelField: string;
114
- valueField: string;
115
- };
116
- safeParse: (value: unknown) => {
117
- success: false;
118
- error: {
119
- issues: Array<{
120
- path: string[];
121
- message: string;
122
- }>;
123
- };
124
- } | {
125
- success: true;
126
- data: {
127
- showValues?: boolean | undefined;
128
- title: string;
129
- labelField: string;
130
- valueField: string;
131
- };
132
- };
133
- Check: (value: unknown) => boolean;
134
- };
27
+ }>;
135
28
  export declare const lineChartPropsSchema: import("@sinclair/typebox").TObject<{
136
29
  title: import("@sinclair/typebox").TString;
137
30
  labelField: import("@sinclair/typebox").TString;
138
31
  valueField: import("@sinclair/typebox").TString;
139
32
  showDots: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
140
33
  fill: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
141
- }> & {
142
- parse: (value: unknown) => {
143
- fill?: boolean | undefined;
144
- showDots?: boolean | undefined;
145
- title: string;
146
- labelField: string;
147
- valueField: string;
148
- };
149
- safeParse: (value: unknown) => {
150
- success: false;
151
- error: {
152
- issues: Array<{
153
- path: string[];
154
- message: string;
155
- }>;
156
- };
157
- } | {
158
- success: true;
159
- data: {
160
- fill?: boolean | undefined;
161
- showDots?: boolean | undefined;
162
- title: string;
163
- labelField: string;
164
- valueField: string;
165
- };
166
- };
167
- Check: (value: unknown) => boolean;
168
- };
34
+ }>;
169
35
  export type MetricProps = Static<typeof metricPropsSchema>;
170
36
  export type ResourceTableProps = Static<typeof resourceTablePropsSchema>;
171
37
  export type BarChartProps = Static<typeof barChartPropsSchema>;
@@ -1,40 +1,4 @@
1
1
  import { Type } from "@sinclair/typebox";
2
- import { TypeCompiler } from "@sinclair/typebox/compiler";
3
- export function createParsedSchema(schema) {
4
- const compiled = TypeCompiler.Compile(schema);
5
- const parse = (value) => {
6
- if (compiled.Check(value))
7
- return value;
8
- const errors = [...compiled.Errors(value)];
9
- const message = errors.map((e) => (e.path ? e.path + ": " : "") + e.message).join(", ") || "Validation error";
10
- const err = new Error(message);
11
- err.issues = errors.map((e) => ({
12
- path: e.path ? (e.path.startsWith("/") ? e.path.slice(1) : e.path).split("/") : [],
13
- message: e.message,
14
- }));
15
- throw err;
16
- };
17
- const safeParse = (value) => {
18
- if (compiled.Check(value)) {
19
- return { success: true, data: value };
20
- }
21
- const errors = [...compiled.Errors(value)];
22
- return {
23
- success: false,
24
- error: {
25
- issues: errors.map((e) => ({
26
- path: e.path ? (e.path.startsWith("/") ? e.path.slice(1) : e.path).split("/") : [],
27
- message: e.message,
28
- })),
29
- },
30
- };
31
- };
32
- return Object.assign(schema, {
33
- parse,
34
- safeParse,
35
- Check: (val) => compiled.Check(val),
36
- });
37
- }
38
2
  const catalogFieldSchema = Type.String({
39
3
  minLength: 1,
40
4
  maxLength: 64,
@@ -52,8 +16,8 @@ const otherMetric = Type.Object({
52
16
  currency: Type.Optional(Type.Never()),
53
17
  description: Type.Optional(Type.String({ minLength: 1, maxLength: 160 })),
54
18
  }, { additionalProperties: false });
55
- export const metricPropsSchema = createParsedSchema(Type.Union([currencyMetric, otherMetric]));
56
- export const resourceTablePropsSchema = createParsedSchema(Type.Object({
19
+ export const metricPropsSchema = Type.Union([currencyMetric, otherMetric]);
20
+ export const resourceTablePropsSchema = Type.Object({
57
21
  title: Type.String({ minLength: 1, maxLength: 80 }),
58
22
  emptyLabel: Type.Optional(Type.String({ minLength: 1, maxLength: 80 })),
59
23
  columns: Type.Array(Type.Object({
@@ -66,17 +30,17 @@ export const resourceTablePropsSchema = createParsedSchema(Type.Object({
66
30
  Type.Literal("boolean"),
67
31
  ])),
68
32
  }, { additionalProperties: false }), { minItems: 1, maxItems: 8 }),
69
- }, { additionalProperties: false }));
70
- export const barChartPropsSchema = createParsedSchema(Type.Object({
33
+ }, { additionalProperties: false });
34
+ export const barChartPropsSchema = Type.Object({
71
35
  title: Type.String({ minLength: 1, maxLength: 80 }),
72
36
  labelField: catalogFieldSchema,
73
37
  valueField: catalogFieldSchema,
74
38
  showValues: Type.Optional(Type.Boolean()),
75
- }, { additionalProperties: false }));
76
- export const lineChartPropsSchema = createParsedSchema(Type.Object({
39
+ }, { additionalProperties: false });
40
+ export const lineChartPropsSchema = Type.Object({
77
41
  title: Type.String({ minLength: 1, maxLength: 80 }),
78
42
  labelField: catalogFieldSchema,
79
43
  valueField: catalogFieldSchema,
80
44
  showDots: Type.Optional(Type.Boolean()),
81
45
  fill: Type.Optional(Type.Boolean()),
82
- }, { additionalProperties: false }));
46
+ }, { additionalProperties: false });
package/dist/catalog.d.ts CHANGED
@@ -31,42 +31,7 @@ export declare const defaultSurfaceCatalog: {
31
31
  format: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"number">, import("@sinclair/typebox").TLiteral<"percent">]>;
32
32
  currency: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNever>;
33
33
  description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
34
- }>]> & {
35
- parse: (value: unknown) => {
36
- description?: string | undefined;
37
- currency: string;
38
- label: string;
39
- format: "currency";
40
- } | {
41
- description?: string | undefined;
42
- currency?: undefined;
43
- label: string;
44
- format: "number" | "percent";
45
- };
46
- safeParse: (value: unknown) => {
47
- success: false;
48
- error: {
49
- issues: Array<{
50
- path: string[];
51
- message: string;
52
- }>;
53
- };
54
- } | {
55
- success: true;
56
- data: {
57
- description?: string | undefined;
58
- currency: string;
59
- label: string;
60
- format: "currency";
61
- } | {
62
- description?: string | undefined;
63
- currency?: undefined;
64
- label: string;
65
- format: "number" | "percent";
66
- };
67
- };
68
- Check: (value: unknown) => boolean;
69
- };
34
+ }>]>;
70
35
  readonly component: Component<SurfaceWidgetRendererProps, {}, "">;
71
36
  }, {
72
37
  readonly type: "resource-table";
@@ -79,38 +44,7 @@ export declare const defaultSurfaceCatalog: {
79
44
  label: import("@sinclair/typebox").TString;
80
45
  format: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"text">, import("@sinclair/typebox").TLiteral<"number">, import("@sinclair/typebox").TLiteral<"date">, import("@sinclair/typebox").TLiteral<"boolean">]>>;
81
46
  }>>;
82
- }> & {
83
- parse: (value: unknown) => {
84
- emptyLabel?: string | undefined;
85
- title: string;
86
- columns: {
87
- format?: "number" | "boolean" | "text" | "date" | undefined;
88
- field: string;
89
- label: string;
90
- }[];
91
- };
92
- safeParse: (value: unknown) => {
93
- success: false;
94
- error: {
95
- issues: Array<{
96
- path: string[];
97
- message: string;
98
- }>;
99
- };
100
- } | {
101
- success: true;
102
- data: {
103
- emptyLabel?: string | undefined;
104
- title: string;
105
- columns: {
106
- format?: "number" | "boolean" | "text" | "date" | undefined;
107
- field: string;
108
- label: string;
109
- }[];
110
- };
111
- };
112
- Check: (value: unknown) => boolean;
113
- };
47
+ }>;
114
48
  readonly getReferencedFields: typeof tableFields;
115
49
  readonly component: Component<SurfaceWidgetRendererProps, {}, "">;
116
50
  }, {
@@ -121,32 +55,7 @@ export declare const defaultSurfaceCatalog: {
121
55
  labelField: import("@sinclair/typebox").TString;
122
56
  valueField: import("@sinclair/typebox").TString;
123
57
  showValues: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
124
- }> & {
125
- parse: (value: unknown) => {
126
- showValues?: boolean | undefined;
127
- title: string;
128
- labelField: string;
129
- valueField: string;
130
- };
131
- safeParse: (value: unknown) => {
132
- success: false;
133
- error: {
134
- issues: Array<{
135
- path: string[];
136
- message: string;
137
- }>;
138
- };
139
- } | {
140
- success: true;
141
- data: {
142
- showValues?: boolean | undefined;
143
- title: string;
144
- labelField: string;
145
- valueField: string;
146
- };
147
- };
148
- Check: (value: unknown) => boolean;
149
- };
58
+ }>;
150
59
  readonly getReferencedFields: typeof barChartFields;
151
60
  readonly component: Component<SurfaceWidgetRendererProps, {}, "">;
152
61
  }, {
@@ -158,34 +67,7 @@ export declare const defaultSurfaceCatalog: {
158
67
  valueField: import("@sinclair/typebox").TString;
159
68
  showDots: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
160
69
  fill: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
161
- }> & {
162
- parse: (value: unknown) => {
163
- fill?: boolean | undefined;
164
- showDots?: boolean | undefined;
165
- title: string;
166
- labelField: string;
167
- valueField: string;
168
- };
169
- safeParse: (value: unknown) => {
170
- success: false;
171
- error: {
172
- issues: Array<{
173
- path: string[];
174
- message: string;
175
- }>;
176
- };
177
- } | {
178
- success: true;
179
- data: {
180
- fill?: boolean | undefined;
181
- showDots?: boolean | undefined;
182
- title: string;
183
- labelField: string;
184
- valueField: string;
185
- };
186
- };
187
- Check: (value: unknown) => boolean;
188
- };
70
+ }>;
189
71
  readonly getReferencedFields: typeof lineChartFields;
190
72
  readonly component: Component<SurfaceWidgetRendererProps, {}, "">;
191
73
  }];
package/dist/catalog.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { Value } from '@sinclair/typebox/value';
1
2
  import BarChartWidget from './components/BarChartWidget.svelte';
2
3
  import LineChartWidget from './components/LineChartWidget.svelte';
3
4
  import MetricWidget from './components/MetricWidget.svelte';
@@ -16,14 +17,14 @@ export function defineSurfaceCatalog(catalog) {
16
17
  return catalog;
17
18
  }
18
19
  function tableFields(props) {
19
- return resourceTablePropsSchema.parse(props).columns.map((column) => column.field);
20
+ return Value.Decode(resourceTablePropsSchema, props).columns.map((column) => column.field);
20
21
  }
21
22
  function barChartFields(props) {
22
- const chartProps = barChartPropsSchema.parse(props);
23
+ const chartProps = Value.Decode(barChartPropsSchema, props);
23
24
  return [chartProps.labelField, chartProps.valueField];
24
25
  }
25
26
  function lineChartFields(props) {
26
- const chartProps = lineChartPropsSchema.parse(props);
27
+ const chartProps = Value.Decode(lineChartPropsSchema, props);
27
28
  return [chartProps.labelField, chartProps.valueField];
28
29
  }
29
30
  export const defaultSurfaceCatalog = defineSurfaceCatalog({
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { Value } from '@sinclair/typebox/value';
2
3
  import BarChart from '@svadmin/ui/components/charts/BarChart.svelte';
3
4
  import CardContent from '@svadmin/ui/components/ui/card/card-content.svelte';
4
5
  import CardHeader from '@svadmin/ui/components/ui/card/card-header.svelte';
@@ -10,7 +11,7 @@
10
11
 
11
12
  let { props, data }: SurfaceWidgetRendererProps = $props();
12
13
 
13
- const chartProps = $derived(barChartPropsSchema.parse(props));
14
+ const chartProps = $derived(Value.Decode(barChartPropsSchema, props));
14
15
  const points = $derived(data.status === 'ready'
15
16
  ? asChartPoints(data.value, chartProps.labelField, chartProps.valueField)
16
17
  : null);
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { Value } from '@sinclair/typebox/value';
2
3
  import LineChart from '@svadmin/ui/components/charts/LineChart.svelte';
3
4
  import CardContent from '@svadmin/ui/components/ui/card/card-content.svelte';
4
5
  import CardHeader from '@svadmin/ui/components/ui/card/card-header.svelte';
@@ -10,7 +11,7 @@
10
11
 
11
12
  let { props, data }: SurfaceWidgetRendererProps = $props();
12
13
 
13
- const chartProps = $derived(lineChartPropsSchema.parse(props));
14
+ const chartProps = $derived(Value.Decode(lineChartPropsSchema, props));
14
15
  const points = $derived(data.status === 'ready'
15
16
  ? asChartPoints(data.value, chartProps.labelField, chartProps.valueField)
16
17
  : null);
@@ -1,11 +1,12 @@
1
1
  <script lang="ts">
2
+ import { Value } from '@sinclair/typebox/value';
2
3
  import StatsCard from '@svadmin/ui/components/StatsCard.svelte';
3
4
  import { metricPropsSchema } from '../builtin-schemas.js';
4
5
  import type { SurfaceWidgetRendererProps } from '../catalog.js';
5
6
 
6
7
  let { widgetId, props, data }: SurfaceWidgetRendererProps = $props();
7
8
 
8
- const metricProps = $derived(metricPropsSchema.parse(props));
9
+ const metricProps = $derived(Value.Decode(metricPropsSchema, props));
9
10
  const formattedValue = $derived.by(() => {
10
11
  if (data.status !== 'ready') return '—';
11
12
  const value = data.value;
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { Value } from '@sinclair/typebox/value';
2
3
  import CardContent from '@svadmin/ui/components/ui/card/card-content.svelte';
3
4
  import CardHeader from '@svadmin/ui/components/ui/card/card-header.svelte';
4
5
  import CardTitle from '@svadmin/ui/components/ui/card/card-title.svelte';
@@ -15,7 +16,7 @@
15
16
 
16
17
  let { props, data }: SurfaceWidgetRendererProps = $props();
17
18
 
18
- const tableProps = $derived(resourceTablePropsSchema.parse(props));
19
+ const tableProps = $derived(Value.Decode(resourceTablePropsSchema, props));
19
20
  const records = $derived(data.status === 'ready' ? asRecordArray(data.value) : null);
20
21
  </script>
21
22
 
package/dist/types.d.ts CHANGED
@@ -92,12 +92,7 @@ export type SurfaceCatalogDataKind = 'none' | 'scalar' | 'items';
92
92
  export interface SurfaceWidgetDefinition {
93
93
  readonly type: string;
94
94
  readonly dataKind: SurfaceCatalogDataKind;
95
- readonly propsSchema: TSchema | {
96
- Check?: (data: unknown) => boolean;
97
- safeParse?: (data: unknown) => {
98
- success: boolean;
99
- };
100
- };
95
+ readonly propsSchema: TSchema;
101
96
  /** 组件从绑定记录中读取的字段,由可信 Catalog 提供。 */
102
97
  readonly getReferencedFields?: (props: JsonObject) => readonly string[];
103
98
  }
@@ -234,9 +234,6 @@ function checkPropsSchema(schema, data) {
234
234
  if ("Check" in schema && typeof schema.Check === "function") {
235
235
  return schema.Check(data);
236
236
  }
237
- if ("safeParse" in schema && typeof schema.safeParse === "function") {
238
- return schema.safeParse(data).success;
239
- }
240
237
  return Value.Check(schema, data);
241
238
  }
242
239
  function widgetIssue(widget, widgetIndex, definition, sources, policy) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/surface",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Validated declarative surfaces for svadmin dashboards",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@svadmin/core": ">=0.34.2 <0.48.0",
29
- "@svadmin/ui": ">=0.40.6 <0.66.0",
29
+ "@svadmin/ui": ">=0.40.6 <0.67.0",
30
30
  "svelte": "^5.56.8"
31
31
  },
32
32
  "dependencies": {