@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 +1 -1
- package/src/commands/info.ts +2 -2
- package/src/commands/publish.ts +1 -0
- package/src/commands/validate.ts +21 -30
- package/src/utils/hub-api.ts +4 -2
- package/src/utils/manifest.ts +2 -11
package/package.json
CHANGED
package/src/commands/info.ts
CHANGED
|
@@ -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(`
|
|
48
|
-
log.info(` 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}`);
|
package/src/commands/publish.ts
CHANGED
|
@@ -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,
|
package/src/commands/validate.ts
CHANGED
|
@@ -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
|
-
//
|
|
26
|
-
|
|
27
|
-
if (!
|
|
28
|
-
|
|
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 (
|
|
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(
|
|
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)
|
|
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;
|
package/src/utils/hub-api.ts
CHANGED
|
@@ -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:
|
|
25
|
-
maxSize:
|
|
26
|
+
minSize: GridSize;
|
|
27
|
+
maxSize: GridSize;
|
|
26
28
|
sdkVersion: string;
|
|
27
29
|
version: string;
|
|
28
30
|
bundleSize: number;
|
package/src/utils/manifest.ts
CHANGED
|
@@ -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
|
|
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;
|