@glasshome/widget-sdk 1.3.0 → 1.4.0

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.
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Reusable deprecation mechanism: one registry drives all three channels
3
+ * (runtime warn-once, JSDoc `@deprecated`, and the widget-cli source lint) plus the
4
+ * generated docs table. Every future deprecation is one registry entry + one
5
+ * `deprecate()` wrapper call, giving widget developers a timed window to migrate.
6
+ */
7
+ export interface DeprecationEntry {
8
+ /** Stable identifier, e.g. `widgetFields.title`. Used for warn-once and lint matching. */
9
+ id: string;
10
+ /** Version the symbol/pattern was deprecated in. */
11
+ since: string;
12
+ /** Version it is removed in. */
13
+ removeIn: string;
14
+ /** Human-readable replacement, e.g. `field.title()`. */
15
+ replacement: string;
16
+ /** Public docs URL for the migration. */
17
+ docsUrl: string;
18
+ /**
19
+ * Regex source matched against widget files by the CLI lint. Present for patterns
20
+ * with no wrappable runtime symbol (e.g. the raw-zod config pattern).
21
+ */
22
+ sourcePattern?: string;
23
+ }
24
+ export declare const deprecations: readonly DeprecationEntry[];
25
+ /** Format a registry entry into the one-line notice shared by every channel. */
26
+ export declare function formatDeprecation(d: DeprecationEntry): string;
27
+ /** Reset warn-once state. Test-only. */
28
+ export declare function _resetDeprecationWarnings(): void;
29
+ /**
30
+ * Wrap a deprecated export. On its first call in a dev build, emits a `console.warn`
31
+ * once per id (formatted from the registry); production builds are silent and add no
32
+ * overhead beyond a Set lookup. The wrapped function's signature is preserved.
33
+ */
34
+ export declare function deprecate<A extends unknown[], R>(fn: (...args: A) => R, id: string): (...args: A) => R;
@@ -0,0 +1,65 @@
1
+ //#region src/deprecations.ts
2
+ var e = "https://glasshome.app/docs/widget-sdk/config", t = [
3
+ {
4
+ id: "widgetFields.title",
5
+ since: "1.4.0",
6
+ removeIn: "2.0.0",
7
+ replacement: "field.title()",
8
+ docsUrl: e,
9
+ sourcePattern: "widgetFields\\.title\\b"
10
+ },
11
+ {
12
+ id: "widgetFields.entityIds",
13
+ since: "1.4.0",
14
+ removeIn: "2.0.0",
15
+ replacement: "field.entities(domain, options?)",
16
+ docsUrl: e,
17
+ sourcePattern: "widgetFields\\.entityIds\\b"
18
+ },
19
+ {
20
+ id: "widgetFields.singleEntity",
21
+ since: "1.4.0",
22
+ removeIn: "2.0.0",
23
+ replacement: "field.entity(domain, options?)",
24
+ docsUrl: e,
25
+ sourcePattern: "widgetFields\\.singleEntity\\b"
26
+ },
27
+ {
28
+ id: "widgetFields.areaId",
29
+ since: "1.4.0",
30
+ removeIn: "2.0.0",
31
+ replacement: "field.area()",
32
+ docsUrl: e,
33
+ sourcePattern: "widgetFields\\.areaId\\b"
34
+ },
35
+ {
36
+ id: "raw-zod-config",
37
+ since: "1.4.0",
38
+ removeIn: "2.0.0",
39
+ replacement: "defineConfig({ ... })",
40
+ docsUrl: e,
41
+ sourcePattern: "configSchema\\s*=\\s*z\\.object\\("
42
+ }
43
+ ];
44
+ function n(e) {
45
+ return `[@glasshome/widget-sdk] ${e.id} is deprecated since ${e.since}, removed in ${e.removeIn}. Use ${e.replacement}. See ${e.docsUrl}`;
46
+ }
47
+ var r = /* @__PURE__ */ new Set();
48
+ function i() {
49
+ r.clear();
50
+ }
51
+ function a() {
52
+ return typeof process < "u" && process.env.NODE_ENV !== "production";
53
+ }
54
+ function o(e, i) {
55
+ return (...o) => {
56
+ if (a() && !r.has(i)) {
57
+ r.add(i);
58
+ let e = t.find((e) => e.id === i);
59
+ e && console.warn(n(e));
60
+ }
61
+ return e(...o);
62
+ };
63
+ }
64
+ //#endregion
65
+ export { i as _resetDeprecationWarnings, o as deprecate, t as deprecations, n as formatDeprecation };
@@ -0,0 +1,96 @@
1
+ import { z, type ZodType } from "zod";
2
+ /**
3
+ * Widget config API: declare a widget's configSchema without importing zod.
4
+ *
5
+ * `field.*` produce config fields; `defineConfig` composes them into a schema
6
+ * accepted by `defineWidget.configSchema` and rendered by SchemaForm. zod stays a
7
+ * hidden implementation detail (a field IS a zod schema, but widgets never name it).
8
+ * For refinements/unions the API can't express, the raw `z` re-export is the escape
9
+ * hatch (couples the widget to the SDK's zod version).
10
+ *
11
+ * Fields return their concrete zod schema type (`ZodOptional`/`ZodDefault`/…) rather
12
+ * than an erased `Field<T>`, because `z.object` reads that brand to decide whether a
13
+ * key is optional. Erasing it silently diverges `Infer` from raw `z.infer` (a key
14
+ * becomes `x: T | undefined` instead of `x?: T`), so the concrete types are load-bearing.
15
+ *
16
+ * SchemaForm renders a FLAT object only; `field.group` is the sole nested exception.
17
+ */
18
+ /** A single config field. Structurally a zod schema producing `T`. */
19
+ export type Field<T> = ZodType<T>;
20
+ /** A map of field name → field, accepted by `defineConfig` and `field.group`. */
21
+ export type ConfigShape = Record<string, ZodType>;
22
+ /** Infer a widget's config type from its schema, without naming zod. */
23
+ export type Infer<C extends ZodType> = z.infer<C>;
24
+ type TextOpts = {
25
+ title: string;
26
+ description?: string;
27
+ default?: string;
28
+ };
29
+ type NumberOpts = {
30
+ title: string;
31
+ description?: string;
32
+ min?: number;
33
+ max?: number;
34
+ default?: number;
35
+ };
36
+ type ToggleOpts = {
37
+ title: string;
38
+ description?: string;
39
+ default?: boolean;
40
+ };
41
+ type ChoiceOpts<T extends string> = {
42
+ title: string;
43
+ description?: string;
44
+ default?: T;
45
+ };
46
+ type EntitiesOpts = {
47
+ title?: string;
48
+ description?: string;
49
+ deviceClass?: string;
50
+ };
51
+ declare function title(): z.ZodOptional<z.ZodString>;
52
+ declare function text(o: TextOpts & {
53
+ default: string;
54
+ }): z.ZodDefault<z.ZodString>;
55
+ declare function text(o: TextOpts): z.ZodOptional<z.ZodString>;
56
+ declare function number(o: NumberOpts & {
57
+ default: number;
58
+ }): z.ZodDefault<z.ZodNumber>;
59
+ declare function number(o: NumberOpts): z.ZodOptional<z.ZodNumber>;
60
+ declare function toggle(o: ToggleOpts): z.ZodDefault<z.ZodBoolean>;
61
+ declare function choice<const T extends string>(values: readonly T[], o: ChoiceOpts<T> & {
62
+ default: T;
63
+ }): z.ZodDefault<z.ZodEnum<{
64
+ [K in T]: K;
65
+ }>>;
66
+ declare function choice<const T extends string>(values: readonly T[], o: ChoiceOpts<T>): z.ZodOptional<z.ZodEnum<{
67
+ [K in T]: K;
68
+ }>>;
69
+ declare function entities(domain: string, o?: EntitiesOpts): z.ZodDefault<z.ZodArray<z.ZodString>>;
70
+ declare function entity(domain: string, o?: EntitiesOpts): z.ZodDefault<z.ZodArray<z.ZodString>>;
71
+ declare function area(o?: {
72
+ title?: string;
73
+ }): z.ZodOptional<z.ZodString>;
74
+ declare function stringList(o: {
75
+ title: string;
76
+ description?: string;
77
+ }): z.ZodDefault<z.ZodArray<z.ZodString>>;
78
+ declare function group<S extends ConfigShape>(shape: S, o: {
79
+ title: string;
80
+ }): Field<{
81
+ [K in keyof S]: Infer<S[K]>;
82
+ }>;
83
+ export declare const field: {
84
+ title: typeof title;
85
+ text: typeof text;
86
+ number: typeof number;
87
+ toggle: typeof toggle;
88
+ choice: typeof choice;
89
+ entities: typeof entities;
90
+ entity: typeof entity;
91
+ area: typeof area;
92
+ stringList: typeof stringList;
93
+ group: typeof group;
94
+ };
95
+ export declare function defineConfig<S extends ConfigShape>(shape: S): z.ZodObject<{ -readonly [P in keyof S]: S[P]; }, z.core.$strip>;
96
+ export {};
@@ -1,20 +1,34 @@
1
1
  import { z } from "zod";
2
2
  /**
3
3
  * Pre-built Zod field helpers for common widget config patterns.
4
- * Each helper returns a Zod schema with `.meta()` annotations that
5
- * SchemaForm uses to render the appropriate UI (entity picker, area picker, etc.).
4
+ *
5
+ * @deprecated since 1.4.0, removed in 2.0.0. Use the config API instead:
6
+ * `defineConfig` + `field.*` (`field.title()`, `field.entities()`, `field.entity()`,
7
+ * `field.area()`). See https://glasshome.app/docs/widget-sdk/config
6
8
  */
7
9
  export declare const widgetFields: {
8
- /** Optional display name override (renders as text input) */
10
+ /**
11
+ * Optional display name override (renders as text input).
12
+ * @deprecated since 1.4.0, removed in 2.0.0. Use `field.title()`.
13
+ */
9
14
  title: () => z.ZodOptional<z.ZodString>;
10
- /** Multi-select entity picker for a HA domain */
15
+ /**
16
+ * Multi-select entity picker for a HA domain.
17
+ * @deprecated since 1.4.0, removed in 2.0.0. Use `field.entities(domain, options?)`.
18
+ */
11
19
  entityIds: (domain: string, options?: {
12
20
  deviceClass?: string;
13
- }) => z.ZodDefault<z.ZodArray<z.ZodString>>;
14
- /** Single-select entity picker for a HA domain */
21
+ } | undefined) => z.ZodDefault<z.ZodArray<z.ZodString>>;
22
+ /**
23
+ * Single-select entity picker for a HA domain.
24
+ * @deprecated since 1.4.0, removed in 2.0.0. Use `field.entity(domain, options?)`.
25
+ */
15
26
  singleEntity: (domain: string, options?: {
16
27
  deviceClass?: string;
17
- }) => z.ZodDefault<z.ZodArray<z.ZodString>>;
18
- /** Area picker dropdown */
28
+ } | undefined) => z.ZodDefault<z.ZodArray<z.ZodString>>;
29
+ /**
30
+ * Area picker dropdown.
31
+ * @deprecated since 1.4.0, removed in 2.0.0. Use `field.area()`.
32
+ */
19
33
  areaId: () => z.ZodOptional<z.ZodString>;
20
34
  };
@@ -41,5 +41,6 @@ export { type AggregationPreset, type ReactiveWidgetContext, type ServiceCallFn,
41
41
  export { type GestureHandlers, useWidgetGestures } from "./gestures/use-widget-gestures";
42
42
  export { injectTokens, type SvgColorKey, svgColors, type Tone, ToneSchema, } from "./theming";
43
43
  export { widgetFields } from "./fields";
44
+ export { type ConfigShape, defineConfig, field, type Field, type Infer, } from "./config";
44
45
  export { calculateLightGroup, calculateSensorGroup, countActiveEntities, getEntityAttribute, isEntityActive, type LightGroupResult, type SensorGroupResult, type SensorGroupType, } from "./utils";
45
46
  export type { EntityView, WidgetStyles, WidgetVariantConfig, } from "./types";
package/dist/index.d.ts CHANGED
@@ -6,3 +6,5 @@ export { formatSchemaError, WidgetManifestSchema } from "./schemas";
6
6
  export { isDark } from "./theme";
7
7
  export type { GridSize, WidgetContext, WidgetDefinition, WidgetManifest, } from "./types";
8
8
  export { SDK_VERSION } from "./version";
9
+ export { type DeprecationEntry, deprecations, formatDeprecation } from "./deprecations";
10
+ export { z } from "zod";