@morit/cli 1.4.2 → 1.5.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.
- package/assets/plugin_contract.json +3 -2
- package/package.json +1 -1
- package/src/workspace.js +23 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sdk_version": "1.7.
|
|
2
|
+
"sdk_version": "1.7.13",
|
|
3
3
|
"manifest_schema_versions": [1, 2],
|
|
4
4
|
"recommended_schema_version": 2,
|
|
5
5
|
"package_content_type": "application/vnd.morit.plugin+zip",
|
|
@@ -293,7 +293,8 @@
|
|
|
293
293
|
,"suggestions_source"
|
|
294
294
|
,"searchable"
|
|
295
295
|
,"options_source"
|
|
296
|
-
,"submit_label"
|
|
296
|
+
,"submit_label",
|
|
297
|
+
"gradient_colors", "item_key", "font_size", "font_weight", "line_height", "selected_background_color", "selected_foreground_color", "disabled_background_color", "pressed_color"
|
|
297
298
|
],
|
|
298
299
|
"app_bar_fields": ["title", "subtitle", "center_title", "pinned", "leading", "actions"],
|
|
299
300
|
"navigation_fields": ["type", "items", "selected_state_key", "persist", "label_behavior", "rail_breakpoint"],
|
package/package.json
CHANGED
package/src/workspace.js
CHANGED
|
@@ -152,7 +152,7 @@ export class LocalWorkspace {
|
|
|
152
152
|
version: "1.0.0",
|
|
153
153
|
cloud_project_id: null,
|
|
154
154
|
required_secrets: [],
|
|
155
|
-
min_morit_version: "1.7.
|
|
155
|
+
min_morit_version: "1.7.13",
|
|
156
156
|
max_morit_version: "1.999.999",
|
|
157
157
|
permissions: [],
|
|
158
158
|
capabilities: [],
|
|
@@ -738,6 +738,14 @@ function validateMetadata(pluginId, name, publisher, description) {
|
|
|
738
738
|
if (typeof description !== "string" || description.length > 4000) throw new Error("description must not exceed 4000 characters");
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
+
function usesUi1713(node) {
|
|
742
|
+
if (!node || typeof node !== "object") return false;
|
|
743
|
+
const props = node.props || {};
|
|
744
|
+
return ["gradient_colors", "item_key", "font_size", "font_weight", "line_height", "selected_background_color", "selected_foreground_color", "disabled_background_color", "pressed_color"].some(key => Object.hasOwn(props, key))
|
|
745
|
+
|| (node.type === "list" && props.scroll_direction === "horizontal")
|
|
746
|
+
|| (Array.isArray(node.children) && node.children.some(usesUi1713));
|
|
747
|
+
}
|
|
748
|
+
|
|
741
749
|
function validateManifest(manifest, files) {
|
|
742
750
|
assertObject(manifest, "manifest");
|
|
743
751
|
rejectUnknownFields(manifest, MANIFEST_FIELDS, "manifest");
|
|
@@ -782,6 +790,8 @@ function validateManifest(manifest, files) {
|
|
|
782
790
|
if (!["purge", "retain"].includes(manifest.data_policy)) throw new Error("manifest.data_policy must be purge or retain");
|
|
783
791
|
const capabilities = objectCollection(manifest.capabilities, "manifest.capabilities", 64);
|
|
784
792
|
const uiExtensions = objectCollection(manifest.ui_extensions, "manifest.ui_extensions", 64);
|
|
793
|
+
const minimum = manifest.min_morit_version.split(".").map(Number);
|
|
794
|
+
if ((minimum[0] < 1 || (minimum[0] === 1 && (minimum[1] < 7 || (minimum[1] === 7 && minimum[2] < 13)))) && uiExtensions.some(extension => usesUi1713(extension.config?.view))) throw new Error("new UI properties require min_morit_version 1.7.13 or newer");
|
|
785
795
|
const credentials = objectCollection(manifest.credentials === undefined ? [] : manifest.credentials, "manifest.credentials", 16);
|
|
786
796
|
const slashCommands = objectCollection(manifest.slash_commands === undefined ? [] : manifest.slash_commands, "manifest.slash_commands", 32);
|
|
787
797
|
const connectors = objectCollection(manifest.connectors === undefined ? [] : manifest.connectors, "manifest.connectors", 32);
|
|
@@ -1691,8 +1701,9 @@ function validateUiProps(nodeType, props, sources, stateKeys) {
|
|
|
1691
1701
|
const allowed = new Set(contract.ui_runtime.prop_fields);
|
|
1692
1702
|
rejectUnknownFields(props, allowed, "UI component props");
|
|
1693
1703
|
const surfaceProps = new Set([
|
|
1704
|
+
"selected",
|
|
1694
1705
|
"spacing", "padding", "margin", "width", "height", "min_width", "max_width", "min_height", "max_height",
|
|
1695
|
-
"alignment", "color", "background_color", "foreground_color", "border_color", "border_width",
|
|
1706
|
+
"alignment", "color", "gradient_colors", "selected_background_color", "selected_foreground_color", "disabled_background_color", "pressed_color", "background_color", "foreground_color", "border_color", "border_width",
|
|
1696
1707
|
"border_radius", "elevation", "opacity", "clip", "enabled", "tooltip", "semantic_label", "exclude_semantics",
|
|
1697
1708
|
]);
|
|
1698
1709
|
if (nodeType === "surface") rejectUnknownFields(props, surfaceProps, "surface UI component props");
|
|
@@ -1726,7 +1737,15 @@ function validateUiProps(nodeType, props, sources, stateKeys) {
|
|
|
1726
1737
|
if (props.main_axis_alignment !== undefined && !["start", "end", "center", "space_between", "space_around", "space_evenly"].includes(props.main_axis_alignment)) throw new Error("UI main-axis alignment is invalid");
|
|
1727
1738
|
if (props.cross_axis_alignment !== undefined && !["start", "end", "center", "stretch", "baseline"].includes(props.cross_axis_alignment)) throw new Error("UI cross-axis alignment is invalid");
|
|
1728
1739
|
if (props.main_axis_size !== undefined && !["min", "max"].includes(props.main_axis_size)) throw new Error("UI main-axis size is invalid");
|
|
1729
|
-
|
|
1740
|
+
if (props.font_size !== undefined) validateUiNumber(props.font_size, "UI font_size", 10, 64);
|
|
1741
|
+
if (props.line_height !== undefined) validateUiNumber(props.line_height, "UI line_height", 1, 2.5);
|
|
1742
|
+
if (props.font_weight !== undefined && (!Number.isInteger(props.font_weight) || props.font_weight < 100 || props.font_weight > 900 || props.font_weight % 100)) throw new Error("invalid UI font_weight");
|
|
1743
|
+
if (props.gradient_colors !== undefined) {
|
|
1744
|
+
if (!Array.isArray(props.gradient_colors) || props.gradient_colors.length < 2 || props.gradient_colors.length > 8) throw new Error("invalid UI gradient_colors: expected 2–8 colors");
|
|
1745
|
+
for (const color of props.gradient_colors) validateUiColor(color, "UI gradient_colors");
|
|
1746
|
+
}
|
|
1747
|
+
if (props.item_key !== undefined && (typeof props.item_key !== "string" || !/^[A-Za-z0-9_-]{1,80}$/.test(props.item_key))) throw new Error("invalid UI item_key");
|
|
1748
|
+
for (const key of ["color", "background_color", "foreground_color", "border_color", "selected_background_color", "selected_foreground_color", "disabled_background_color", "pressed_color"]) if (props[key] !== undefined) validateUiColor(props[key], `UI ${key}`);
|
|
1730
1749
|
if (props.border_width !== undefined) validateUiNumber(props.border_width, "UI border width", 0, 8);
|
|
1731
1750
|
if (props.border_radius !== undefined) validateUiNumber(props.border_radius, "UI border radius", 0, 64);
|
|
1732
1751
|
if (props.elevation !== undefined) validateUiNumber(props.elevation, "UI elevation", 0, 24);
|
|
@@ -1748,7 +1767,7 @@ function validateUiProps(nodeType, props, sources, stateKeys) {
|
|
|
1748
1767
|
)) throw new Error("positioned UI component over-constrains an axis");
|
|
1749
1768
|
if (nodeType !== "positioned" && ["left", "top", "right", "bottom"].some((key) => props[key] !== undefined)) throw new Error("position offsets require a positioned UI component");
|
|
1750
1769
|
if (nodeType !== "expanded" && props.flex !== undefined) throw new Error("flex requires an expanded UI component");
|
|
1751
|
-
if (nodeType !== "scroll" && ["
|
|
1770
|
+
if ((nodeType !== "scroll" && props.shrink_wrap !== undefined) || (!["scroll", "list"].includes(nodeType) && props.scroll_direction !== undefined)) throw new Error("scroll properties require a scroll UI component");
|
|
1752
1771
|
if (["list", "timeline", "calendar", "chart", "table"].includes(nodeType)) {
|
|
1753
1772
|
if (typeof props.source !== "string" || !UI_BINDING.test(props.source) || !props.source.startsWith("data.") || !sources.has(props.source.split(".")[1])) throw new Error("UI list source is invalid");
|
|
1754
1773
|
}
|