@glasshome/widget-cli 0.3.0 → 0.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glasshome/widget-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "CLI for creating and managing GlassHome widgets",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,8 +44,8 @@ export async function runInfo(cwd: string, widgetName?: string): Promise<void> {
44
44
  const manifest = readManifest(cwd, name);
45
45
  log.info(` Tag: ${manifest.tag}`);
46
46
  log.info(` Name: ${manifest.name}`);
47
- log.info(` Type: ${manifest.type}`);
48
- log.info(` Size: ${manifest.size}`);
47
+ log.info(` Min Size: ${manifest.minSize.w}×${manifest.minSize.h}`);
48
+ log.info(` Max Size: ${manifest.maxSize.w}×${manifest.maxSize.h}`);
49
49
  log.info(` SDK Version: ${manifest.sdkVersion}`);
50
50
  if (manifest.version) {
51
51
  log.info(` Version: ${manifest.version}`);
@@ -161,6 +161,7 @@ export async function runPublish(cwd: string, hubUrlOverride?: string): Promise<
161
161
  name: widgetName,
162
162
  displayName: manifest.name,
163
163
  description: manifest.description,
164
+ icon: manifest.icon,
164
165
  minSize: manifest.minSize,
165
166
  maxSize: manifest.maxSize,
166
167
  sdkVersion: manifest.sdkVersion,
@@ -1,6 +1,7 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
3
  import { log, spinner } from "@clack/prompts";
4
+ import { WidgetManifestSchema } from "@glasshome/widget-sdk/schemas";
4
5
  import {
5
6
  discoverWidgets,
6
7
  formatBytes,
@@ -22,54 +23,43 @@ function validateManifest(manifest: WidgetManifest): ValidationResult {
22
23
  const errors: string[] = [];
23
24
  const warnings: string[] = [];
24
25
 
25
- // Required fields
26
- if (!manifest.tag) errors.push("Missing required field: tag");
27
- if (!manifest.name) errors.push("Missing required field: name");
28
- if (!manifest.sdkVersion) errors.push("Missing required field: sdkVersion");
26
+ // Validate core manifest shape using the shared schema
27
+ const result = WidgetManifestSchema.safeParse(manifest);
28
+ if (!result.success) {
29
+ for (const issue of result.error.issues) {
30
+ const path = issue.path.length > 0 ? issue.path.join(".") : "manifest";
31
+ errors.push(`${path}: ${issue.message}`);
32
+ }
33
+ }
29
34
 
30
- // Tag format
35
+ // Tag format (stricter than schema — enforces kebab-case with at least one hyphen)
31
36
  if (manifest.tag && !TAG_REGEX.test(manifest.tag)) {
32
37
  errors.push(
33
38
  `Invalid tag format "${manifest.tag}" — must match ${TAG_REGEX} (e.g. glasshome-my-widget)`,
34
39
  );
35
40
  }
36
41
 
37
- // minSize validation
38
- if (
39
- !manifest.minSize ||
40
- typeof manifest.minSize !== "object" ||
41
- typeof manifest.minSize.w !== "number" ||
42
- typeof manifest.minSize.h !== "number"
43
- ) {
44
- errors.push("minSize must be an object with numeric w and h properties");
45
- }
46
-
47
- // maxSize validation
48
- if (
49
- !manifest.maxSize ||
50
- typeof manifest.maxSize !== "object" ||
51
- typeof manifest.maxSize.w !== "number" ||
52
- typeof manifest.maxSize.h !== "number"
53
- ) {
54
- errors.push("maxSize must be an object with numeric w and h properties");
55
- }
56
-
57
42
  // Schema validation
58
43
  if (manifest.schema) {
59
44
  if (typeof manifest.schema !== "object") {
60
45
  errors.push("Schema must be an object");
61
46
  } else {
62
- if (manifest.schema.type !== "object") {
47
+ if ((manifest.schema as Record<string, unknown>).type !== "object") {
63
48
  warnings.push('Schema type should be "object"');
64
49
  }
65
- if (!manifest.schema.properties || typeof manifest.schema.properties !== "object") {
50
+ if (
51
+ !(manifest.schema as Record<string, unknown>).properties ||
52
+ typeof (manifest.schema as Record<string, unknown>).properties !== "object"
53
+ ) {
66
54
  warnings.push("Schema should have a properties object");
67
55
  }
68
56
  }
69
57
 
70
58
  // Check defaultConfig matches schema properties
71
- if (manifest.defaultConfig && manifest.schema.properties) {
72
- const schemaKeys = Object.keys(manifest.schema.properties as Record<string, unknown>);
59
+ if (manifest.defaultConfig && (manifest.schema as Record<string, unknown>).properties) {
60
+ const schemaKeys = Object.keys(
61
+ (manifest.schema as Record<string, unknown>).properties as Record<string, unknown>,
62
+ );
73
63
  const configKeys = Object.keys(manifest.defaultConfig);
74
64
  for (const key of configKeys) {
75
65
  if (!schemaKeys.includes(key)) {
@@ -134,7 +124,8 @@ export async function runValidate(
134
124
  try {
135
125
  manifest = readManifest(cwd, name);
136
126
  } catch (err) {
137
- if (!quiet) log.error(` Failed to read manifest: ${err instanceof Error ? err.message : String(err)}`);
127
+ if (!quiet)
128
+ log.error(` Failed to read manifest: ${err instanceof Error ? err.message : String(err)}`);
138
129
  failed.push(name);
139
130
  allPassed = false;
140
131
  continue;
@@ -15,14 +15,16 @@ export async function fetchScopes(hubUrl: string, token: string): Promise<Publis
15
15
  return data.scopes;
16
16
  }
17
17
 
18
+ import type { GridSize } from "@glasshome/widget-sdk";
19
+
18
20
  interface PublishRequestParams {
19
21
  scope: string;
20
22
  name: string;
21
23
  displayName: string;
22
24
  description?: string;
23
25
  icon?: string;
24
- minSize: { w: number; h: number };
25
- maxSize: { w: number; h: number };
26
+ minSize: GridSize;
27
+ maxSize: GridSize;
26
28
  sdkVersion: string;
27
29
  version: string;
28
30
  bundleSize: number;
@@ -1,18 +1,9 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
3
  import { gzipSync } from "node:zlib";
4
+ import type { WidgetManifest as SdkWidgetManifest } from "@glasshome/widget-sdk";
4
5
 
5
- export interface WidgetManifest {
6
- tag: string;
7
- name: string;
8
- minSize: { w: number; h: number };
9
- maxSize: { w: number; h: number };
10
- sdkVersion: string;
11
- version?: string;
12
- description?: string;
13
- schema?: Record<string, unknown>;
14
- defaultConfig?: Record<string, unknown>;
15
- }
6
+ export type WidgetManifest = SdkWidgetManifest & { version?: string };
16
7
 
17
8
  export interface Registry {
18
9
  version: number;