@yahoo/uds-create-config 2.45.0 → 3.0.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/README.md +129 -0
- package/dist/ai-lanes.d.ts +23 -0
- package/dist/ai-lanes.js +34 -0
- package/dist/authoring/define-component.d.ts +85 -0
- package/dist/configs/CanvasConfig.d.ts +3237 -0
- package/dist/configs/CanvasConfig.js +332 -0
- package/dist/configs/build-options.d.ts +10 -0
- package/dist/configs/build-options.js +68 -0
- package/dist/configs/platform.d.ts +15 -0
- package/dist/configs/platform.js +17 -0
- package/dist/configs/react-native-system.d.ts +3026 -0
- package/dist/configs/react-native-system.js +64 -0
- package/dist/configs/system.d.ts +2771 -0
- package/dist/configs/system.js +74 -0
- package/dist/css/properties.generated.d.ts +14 -0
- package/dist/css/properties.generated.js +6260 -0
- package/dist/css/value-type.d.ts +48 -0
- package/dist/css/value-type.js +131 -0
- package/dist/css/values.d.ts +33 -0
- package/dist/css/values.js +116 -0
- package/dist/entities/native/NativeModifier.d.ts +25 -0
- package/dist/entities/native/NativeModifier.js +41 -0
- package/dist/entities/native/NativeSettings.d.ts +44 -0
- package/dist/entities/native/NativeSettings.js +39 -0
- package/dist/entities/native/NativeStyleProperty.d.ts +355 -0
- package/dist/entities/native/NativeStyleProperty.js +28 -0
- package/dist/entities/native/NativeToken.d.ts +31 -0
- package/dist/entities/native/NativeToken.js +49 -0
- package/dist/entities/system/CanvasRole.d.ts +34 -0
- package/dist/entities/system/CanvasRole.js +45 -0
- package/dist/entities/system/Component.d.ts +1287 -0
- package/dist/entities/system/Component.js +1840 -0
- package/dist/entities/system/Composite.d.ts +12 -0
- package/dist/entities/system/Composite.js +26 -0
- package/dist/entities/system/Device.d.ts +11 -0
- package/dist/entities/system/Device.js +18 -0
- package/dist/entities/system/File.d.ts +72 -0
- package/dist/entities/system/File.js +136 -0
- package/dist/entities/system/Font.d.ts +48 -0
- package/dist/entities/system/Font.js +56 -0
- package/dist/entities/system/GlobalStyle.d.ts +26 -0
- package/dist/entities/system/GlobalStyle.js +54 -0
- package/dist/entities/system/Guidance.d.ts +85 -0
- package/dist/entities/system/Guidance.js +59 -0
- package/dist/entities/system/GuidanceStyle.d.ts +14 -0
- package/dist/entities/system/GuidanceStyle.js +8 -0
- package/dist/entities/system/Icon.d.ts +46 -0
- package/dist/entities/system/Icon.js +46 -0
- package/dist/entities/system/LinkedSystem.d.ts +504 -0
- package/dist/entities/system/LinkedSystem.js +814 -0
- package/dist/entities/system/Modifier.d.ts +92 -0
- package/dist/entities/system/Modifier.js +120 -0
- package/dist/entities/system/Motion.d.ts +28 -0
- package/dist/entities/system/Motion.js +48 -0
- package/dist/entities/system/Operation.d.ts +100 -0
- package/dist/entities/system/Operation.js +236 -0
- package/dist/entities/system/Package.d.ts +42 -0
- package/dist/entities/system/Package.js +75 -0
- package/dist/entities/system/Settings.d.ts +94 -0
- package/dist/entities/system/Settings.js +166 -0
- package/dist/entities/system/StyleProperty.d.ts +135 -0
- package/dist/entities/system/StyleProperty.js +438 -0
- package/dist/entities/system/Token.d.ts +67 -0
- package/dist/entities/system/Token.js +129 -0
- package/dist/entities/system/Tool.d.ts +134 -0
- package/dist/entities/system/Tool.js +124 -0
- package/dist/entities/system/color.d.ts +64 -0
- package/dist/entities/system/color.js +123 -0
- package/dist/entities/system/component-module.d.ts +63 -0
- package/dist/entities/system/component-module.js +258 -0
- package/dist/entities/system/copy-plan.d.ts +98 -0
- package/dist/entities/system/copy-plan.js +451 -0
- package/dist/entities/system/defineComponent.d.ts +428 -0
- package/dist/entities/system/defineComponent.js +337 -0
- package/dist/entities/system/element.d.ts +101 -0
- package/dist/entities/system/element.js +171 -0
- package/dist/entities/system/icon-library.d.ts +64 -0
- package/dist/entities/system/icon-library.js +112 -0
- package/dist/entities/system/icon-metadata.d.ts +72 -0
- package/dist/entities/system/icon-metadata.js +111 -0
- package/dist/entities/system/link-declaration.d.ts +27 -0
- package/dist/entities/system/link-declaration.js +64 -0
- package/dist/entities/system/link-plan.d.ts +160 -0
- package/dist/entities/system/link-plan.js +770 -0
- package/dist/entities/system/runtime-modules.d.ts +25 -0
- package/dist/entities/system/runtime-modules.js +38 -0
- package/dist/entities/system/style-bag.d.ts +20 -0
- package/dist/entities/system/style-bag.js +246 -0
- package/dist/entities/system/token-index.d.ts +89 -0
- package/dist/entities/system/token-index.js +112 -0
- package/dist/framework/Config.d.ts +2472 -0
- package/dist/framework/Config.js +5023 -0
- package/dist/framework/Entity.d.ts +127 -0
- package/dist/framework/Entity.js +125 -0
- package/dist/framework/authoring.d.ts +24 -0
- package/dist/framework/authoring.js +7 -0
- package/dist/framework/change-hooks.d.ts +119 -0
- package/dist/framework/change-hooks.js +131 -0
- package/dist/framework/changes.d.ts +88 -0
- package/dist/framework/changes.js +246 -0
- package/dist/framework/class-names.d.ts +260 -0
- package/dist/framework/class-names.js +630 -0
- package/dist/framework/coalesce.d.ts +25 -0
- package/dist/framework/coalesce.js +60 -0
- package/dist/framework/config-op.d.ts +76 -0
- package/dist/framework/config-op.js +43 -0
- package/dist/framework/config-operation-kind.d.ts +14 -0
- package/dist/framework/config-operation-kind.js +14 -0
- package/dist/framework/config-ops.d.ts +34 -0
- package/dist/framework/config-ops.js +187 -0
- package/dist/framework/defineConfig.d.ts +196 -0
- package/dist/framework/defineConfig.js +100 -0
- package/dist/framework/defineDerivedEntity.d.ts +74 -0
- package/dist/framework/defineDerivedEntity.js +83 -0
- package/dist/framework/defineEntity.d.ts +318 -0
- package/dist/framework/defineEntity.js +183 -0
- package/dist/framework/defineSubEntity.d.ts +148 -0
- package/dist/framework/defineSubEntity.js +121 -0
- package/dist/framework/derived-mutations.d.ts +20 -0
- package/dist/framework/derived-mutations.js +38 -0
- package/dist/framework/entity-search.d.ts +29 -0
- package/dist/framework/entity-search.js +117 -0
- package/dist/framework/inline-sources.d.ts +49 -0
- package/dist/framework/inline-sources.js +388 -0
- package/dist/framework/layer-styles.d.ts +25 -0
- package/dist/framework/layer-styles.js +49 -0
- package/dist/framework/memo.d.ts +48 -0
- package/dist/framework/memo.js +84 -0
- package/dist/framework/overlay.d.ts +49 -0
- package/dist/framework/overlay.js +17 -0
- package/dist/framework/plan.d.ts +49 -0
- package/dist/framework/plan.js +73 -0
- package/dist/framework/projections.d.ts +480 -0
- package/dist/framework/projections.js +974 -0
- package/dist/framework/prop-surface.d.ts +132 -0
- package/dist/framework/prop-surface.js +278 -0
- package/dist/framework/ref-graph.d.ts +71 -0
- package/dist/framework/ref-graph.js +158 -0
- package/dist/framework/ref-integrity.d.ts +55 -0
- package/dist/framework/ref-integrity.js +171 -0
- package/dist/framework/registered.d.ts +95 -0
- package/dist/framework/registry-dir.d.ts +42 -0
- package/dist/framework/registry-dir.js +48 -0
- package/dist/framework/registry.d.ts +300 -0
- package/dist/framework/registry.js +104 -0
- package/dist/framework/rejection.d.ts +58 -0
- package/dist/framework/rejection.js +111 -0
- package/dist/framework/rename-inference.d.ts +26 -0
- package/dist/framework/rename-inference.js +50 -0
- package/dist/framework/render-spec.d.ts +296 -0
- package/dist/framework/render-spec.js +809 -0
- package/dist/framework/schema-version.d.ts +140 -0
- package/dist/framework/schema-version.js +214 -0
- package/dist/framework/schemas.d.ts +109 -0
- package/dist/framework/schemas.js +615 -0
- package/dist/framework/session.d.ts +196 -0
- package/dist/framework/session.js +367 -0
- package/dist/framework/signature.d.ts +15 -0
- package/dist/framework/signature.js +83 -0
- package/dist/framework/snapshot.d.ts +115 -0
- package/dist/framework/snapshot.js +277 -0
- package/dist/framework/source-integrity.d.ts +226 -0
- package/dist/framework/source-integrity.js +478 -0
- package/dist/framework/sources.d.ts +211 -0
- package/dist/framework/sources.js +89 -0
- package/dist/framework/utils/compiled-schema.d.ts +23 -0
- package/dist/framework/utils/compiled-schema.js +46 -0
- package/dist/framework/utils/content-key.d.ts +15 -0
- package/dist/framework/utils/content-key.js +33 -0
- package/dist/framework/utils/enumerated.d.ts +13 -0
- package/dist/framework/utils/enumerated.js +19 -0
- package/dist/framework/utils/field-path.d.ts +95 -0
- package/dist/framework/utils/field-path.js +136 -0
- package/dist/framework/utils/field-schema.d.ts +55 -0
- package/dist/framework/utils/field-schema.js +183 -0
- package/dist/framework/utils/group.d.ts +37 -0
- package/dist/framework/utils/group.js +13 -0
- package/dist/framework/utils/package-path.d.ts +37 -0
- package/dist/framework/utils/package-path.js +61 -0
- package/dist/framework/utils/refs.d.ts +194 -0
- package/dist/framework/utils/refs.js +403 -0
- package/dist/framework/validate-spec.d.ts +27 -0
- package/dist/framework/validate-spec.js +45 -0
- package/dist/framework/value-domain.d.ts +26 -0
- package/dist/framework/value-domain.js +202 -0
- package/dist/framework/views-facade.d.ts +15 -0
- package/dist/framework/views-facade.js +19 -0
- package/dist/index.d.ts +90 -42
- package/dist/index.js +86 -37
- package/dist/migrations/2.0.0/raw-css.d.ts +11 -0
- package/dist/migrations/2.0.0/raw-css.js +72 -0
- package/dist/migrations/2.0.0/v1-artifact.d.ts +1559 -0
- package/dist/migrations/2.0.0/v1-artifact.js +1018 -0
- package/dist/migrations/20260908171448_settings_as_kind.d.ts +22 -0
- package/dist/migrations/20260908171448_settings_as_kind.js +89 -0
- package/dist/migrations/20260908194245_visible_state_pointer.d.ts +19 -0
- package/dist/migrations/20260908194245_visible_state_pointer.js +115 -0
- package/dist/migrations/20260909183001_icon_knockout_variants.d.ts +18 -0
- package/dist/migrations/20260909183001_icon_knockout_variants.js +8 -0
- package/dist/migrations/20260910212453_linked_system_link_ops.d.ts +13 -0
- package/dist/migrations/20260910212453_linked_system_link_ops.js +8 -0
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.js +2 -0
- package/dist/react-native/style-keys.generated.d.ts +10 -0
- package/dist/react-native/style-keys.generated.js +167 -0
- package/dist/renderer/RendererErrorBoundary.d.ts +32 -5
- package/dist/renderer/RendererErrorBoundary.js +59 -10
- package/dist/renderer/UdsRenderer.d.ts +11 -10
- package/dist/renderer/UdsRenderer.js +1 -1
- package/dist/renderer/assetEntries.d.ts +37 -0
- package/dist/renderer/assetEntries.js +39 -0
- package/dist/renderer/assetRenderable.d.ts +14 -6
- package/dist/renderer/assetRenderable.js +8 -2
- package/dist/renderer/componentEntry.d.ts +58 -0
- package/dist/renderer/componentEntry.js +71 -0
- package/dist/renderer/icon-library.d.ts +20 -0
- package/dist/renderer/index.d.ts +7 -7
- package/dist/renderer/index.js +5 -5
- package/dist/renderer/primitives/SlotRenderer.d.ts +1 -1
- package/dist/renderer/primitives/SlotRenderer.js +1 -1
- package/dist/renderer/runtimeComponent.d.ts +33 -0
- package/dist/renderer/runtimeComponent.js +113 -0
- package/dist/renderer/spec-content.d.ts +43 -0
- package/dist/renderer/spec-content.js +95 -0
- package/dist/renderer/wrapRegistry.d.ts +22 -37
- package/dist/renderer/wrapRegistry.js +10 -20
- package/dist/renderer/wrappers/event-bridge.js +6 -5
- package/dist/renderer/wrappers/hex-normalize.js +6 -5
- package/dist/renderer/wrappers/html-aliases.d.ts +7 -2
- package/dist/renderer/wrappers/html-aliases.js +36 -19
- package/dist/renderer/wrappers/inline-styles.js +7 -6
- package/dist/spec/asset-jsx.d.ts +18 -5
- package/dist/spec/asset-jsx.js +27 -16
- package/dist/spec/collapse-text-labels.d.ts +5 -15
- package/dist/spec/collapse-text-labels.js +26 -19
- package/dist/spec/empty-node-slots.d.ts +56 -34
- package/dist/spec/empty-node-slots.js +87 -47
- package/dist/spec/index.d.ts +21 -10
- package/dist/spec/index.js +21 -10
- package/dist/spec/jsxToSpec.d.ts +14 -9
- package/dist/spec/jsxToSpec.js +20 -3
- package/dist/spec/preview-elements.d.ts +63 -0
- package/dist/spec/preview-elements.js +89 -0
- package/dist/spec/rewrite-refs.d.ts +58 -0
- package/dist/spec/rewrite-refs.js +250 -0
- package/dist/spec/specToJsx.js +18 -29
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +39 -52
- package/dist/AssetGroup.d.ts +0 -77
- package/dist/AssetGroup.js +0 -125
- package/dist/Component.d.ts +0 -333
- package/dist/Component.js +0 -1061
- package/dist/ComponentGroup.d.ts +0 -22
- package/dist/ComponentGroup.js +0 -51
- package/dist/CompositeStyle.d.ts +0 -30
- package/dist/CompositeStyle.js +0 -59
- package/dist/Config.d.ts +0 -528
- package/dist/Config.js +0 -1712
- package/dist/Mode.d.ts +0 -41
- package/dist/Mode.js +0 -81
- package/dist/Modifier.d.ts +0 -51
- package/dist/Modifier.js +0 -97
- package/dist/MotionDef.d.ts +0 -81
- package/dist/MotionDef.js +0 -212
- package/dist/Props.d.ts +0 -332
- package/dist/Props.js +0 -35
- package/dist/Provider.d.ts +0 -20
- package/dist/Provider.js +0 -14
- package/dist/StyleProp.d.ts +0 -145
- package/dist/StyleProp.js +0 -239
- package/dist/Token.d.ts +0 -76
- package/dist/Token.js +0 -133
- package/dist/TokenGroup.d.ts +0 -33
- package/dist/TokenGroup.js +0 -69
- package/dist/asset-kind.d.ts +0 -55
- package/dist/asset-kind.js +0 -29
- package/dist/asset-value.d.ts +0 -23
- package/dist/asset-value.js +0 -40
- package/dist/brands.d.ts +0 -30
- package/dist/brands.js +0 -20
- package/dist/captureCallerPath.d.ts +0 -48
- package/dist/captureCallerPath.js +0 -95
- package/dist/colorExpressions.d.ts +0 -131
- package/dist/colorExpressions.js +0 -148
- package/dist/component-referrers.d.ts +0 -30
- package/dist/component-referrers.js +0 -40
- package/dist/config-diagnostics.d.ts +0 -21
- package/dist/config-diagnostics.js +0 -12
- package/dist/defineAssetGroup.d.ts +0 -200
- package/dist/defineAssetGroup.js +0 -323
- package/dist/defineProvider.d.ts +0 -29
- package/dist/defineProvider.js +0 -60
- package/dist/element-marker.d.ts +0 -63
- package/dist/element-marker.js +0 -113
- package/dist/entity-utils.d.ts +0 -56
- package/dist/entity-utils.js +0 -105
- package/dist/extension.d.ts +0 -55
- package/dist/extension.js +0 -214
- package/dist/factories.d.ts +0 -863
- package/dist/factories.js +0 -475
- package/dist/font-face.d.ts +0 -25
- package/dist/font-face.js +0 -72
- package/dist/foreign-component-name.d.ts +0 -21
- package/dist/foreign-component-name.js +0 -42
- package/dist/interpolate.d.ts +0 -20
- package/dist/interpolate.js +0 -10
- package/dist/jsx/__fixtures__/cross-component-preview.d.ts +0 -3
- package/dist/jsx/__fixtures__/cross-component-preview.js +0 -15
- package/dist/jsx/jsx-dev-runtime.d.ts +0 -15
- package/dist/jsx/jsx-dev-runtime.js +0 -11
- package/dist/jsx/jsx-runtime.d.ts +0 -48
- package/dist/jsx/jsx-runtime.js +0 -305
- package/dist/linked-system-pins.d.ts +0 -30
- package/dist/linked-system-pins.js +0 -45
- package/dist/linkedNodePrefixes.d.ts +0 -73
- package/dist/linkedNodePrefixes.js +0 -99
- package/dist/markers.d.ts +0 -235
- package/dist/markers.js +0 -70
- package/dist/motion-constants.d.ts +0 -37
- package/dist/motion-constants.js +0 -61
- package/dist/native/NativeConfig.d.ts +0 -56
- package/dist/native/NativeConfig.js +0 -162
- package/dist/native/assets.d.ts +0 -20
- package/dist/native/assets.js +0 -17
- package/dist/native/components.d.ts +0 -139
- package/dist/native/components.js +0 -67
- package/dist/native/index.d.ts +0 -18
- package/dist/native/index.js +0 -17
- package/dist/native/modes.d.ts +0 -10
- package/dist/native/modes.js +0 -11
- package/dist/native/types.d.ts +0 -95
- package/dist/native/types.js +0 -0
- package/dist/native/validation.d.ts +0 -8
- package/dist/native/validation.js +0 -885
- package/dist/native/values.d.ts +0 -7
- package/dist/native/values.js +0 -15
- package/dist/native.d.ts +0 -12
- package/dist/native.js +0 -10
- package/dist/refs.d.ts +0 -204
- package/dist/refs.js +0 -129
- package/dist/registry-aliases.d.ts +0 -33
- package/dist/registry-aliases.js +0 -35
- package/dist/registry-dir.d.ts +0 -22
- package/dist/registry-dir.js +0 -10
- package/dist/renderer/makeRegistry.d.ts +0 -34
- package/dist/renderer/makeRegistry.js +0 -52
- package/dist/renderer/makeUdsRenderer.d.ts +0 -13
- package/dist/renderer/makeUdsRenderer.js +0 -51
- package/dist/renderer/wrappers/component-slots.d.ts +0 -41
- package/dist/renderer/wrappers/component-slots.js +0 -66
- package/dist/renderer/wrappers/slot-resolution.d.ts +0 -25
- package/dist/renderer/wrappers/slot-resolution.js +0 -68
- package/dist/renderer/wrappers/void-elements.d.ts +0 -37
- package/dist/renderer/wrappers/void-elements.js +0 -40
- package/dist/spec/layer-props.d.ts +0 -52
- package/dist/spec/layer-props.js +0 -149
- package/dist/spec/preview-controls.d.ts +0 -44
- package/dist/spec/preview-controls.js +0 -139
- package/dist/spec/slot-refs.d.ts +0 -39
- package/dist/spec/slot-refs.js +0 -56
- package/dist/token-override-rows.d.ts +0 -68
- package/dist/token-override-rows.js +0 -233
- package/dist/tokenValueType.d.ts +0 -34
- package/dist/tokenValueType.js +0 -138
- package/dist/types/css-properties.d.ts +0 -233
- package/dist/types/css-properties.js +0 -14
- package/dist/types/css-property-keywords.d.ts +0 -156
- package/dist/types/css-property-keywords.js +0 -616
- package/dist/types/css-values.d.ts +0 -63
- package/dist/types/css-values.js +0 -16
- package/dist/types.d.ts +0 -1138
- package/dist/types.js +0 -12
- package/dist/units.d.ts +0 -14
- package/dist/units.js +0 -16
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.js +0 -4
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { SubEntityClass } from "../../framework/defineSubEntity.js";
|
|
2
|
+
import { EntityClass } from "../../framework/defineEntity.js";
|
|
3
|
+
import { Config } from "../../framework/Config.js";
|
|
4
|
+
import { StyleValue } from "./style-bag.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
|
|
7
|
+
//#region src/entities/system/Modifier.d.ts
|
|
8
|
+
/** The category a typed group gives its members. Untyped groups are folders; their members are
|
|
9
|
+
* plain modifiers that compose as fragments and that no surface treats specially. */
|
|
10
|
+
declare const MODIFIER_CATEGORIES: readonly ["mode", "state"];
|
|
11
|
+
type ModifierCategory = (typeof MODIFIER_CATEGORIES)[number];
|
|
12
|
+
/** How a web modifier activates. A `media-query` is an at-rule the emitter wraps the block in;
|
|
13
|
+
* `selector` composes onto the element, or stands as an ancestor for a mode. */
|
|
14
|
+
declare const WEB_ACTIVATIONS: readonly ["selector", "media-query", "composite"];
|
|
15
|
+
type WebActivation = (typeof WEB_ACTIVATIONS)[number];
|
|
16
|
+
/**
|
|
17
|
+
* A modifier group's own fields.
|
|
18
|
+
*
|
|
19
|
+
* `type` says what category of condition the group's members are. A `mode` is an axis of the
|
|
20
|
+
* document or a subtree: one option active at a time, switched by a viewer, activating on an
|
|
21
|
+
* ancestor or the viewport. A `state` is a condition of the element itself, entered by interaction
|
|
22
|
+
* or by a prop; it gets a grid column and a `data-create-force-<leaf>` twin. A group with no `type`
|
|
23
|
+
* is a folder and its members are plain.
|
|
24
|
+
*
|
|
25
|
+
* `default` names the option a viewer starts in. The native theme reads it; on web the resting state
|
|
26
|
+
* is the base values and no option is default.
|
|
27
|
+
*/
|
|
28
|
+
declare const modifierGroupFields: z.ZodObject<{
|
|
29
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
30
|
+
mode: "mode";
|
|
31
|
+
state: "state";
|
|
32
|
+
}>>;
|
|
33
|
+
default: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
__ref: z.ZodString;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
type ModifierGroupMeta = z.infer<typeof modifierGroupFields> & {
|
|
38
|
+
label?: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
};
|
|
41
|
+
declare const Modifier: EntityClass<z.ZodObject<{
|
|
42
|
+
type: z.ZodEnum<{
|
|
43
|
+
composite: "composite";
|
|
44
|
+
selector: "selector";
|
|
45
|
+
"media-query": "media-query";
|
|
46
|
+
}>;
|
|
47
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodLazy<EntityClass<z.ZodObject<{
|
|
48
|
+
styles: SubEntityClass<z.ZodType<StyleValue, unknown, z.core.$ZodTypeInternals<StyleValue, unknown>>>;
|
|
49
|
+
}, z.core.$strip>, z.ZodObject<Record<never, never>, z.core.$strip>, "composite", Record<never, never>, Record<never, never>, false>>]>;
|
|
50
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
51
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
52
|
+
mode: "mode";
|
|
53
|
+
state: "state";
|
|
54
|
+
}>>;
|
|
55
|
+
default: z.ZodOptional<z.ZodObject<{
|
|
56
|
+
__ref: z.ZodString;
|
|
57
|
+
}, z.core.$strip>>;
|
|
58
|
+
}, z.core.$strip>, "modifier", Record<never, never>, Record<never, never>, false>;
|
|
59
|
+
/** A path's last segment. */
|
|
60
|
+
declare function modifierLeaf(path: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* The typed group a modifier belongs to — its category and the group's path — or `undefined` for a
|
|
63
|
+
* plain one. The nearest typed ancestor answers; folders above it are organisation only.
|
|
64
|
+
*/
|
|
65
|
+
declare function modifierAxis(config: Config, pathOrLeaf: string): {
|
|
66
|
+
group: string;
|
|
67
|
+
type: ModifierCategory;
|
|
68
|
+
meta: ModifierGroupMeta;
|
|
69
|
+
} | undefined;
|
|
70
|
+
/** The category of a modifier: `mode`, `state`, or `undefined` for a plain one. */
|
|
71
|
+
declare function modifierCategory(config: Config, pathOrLeaf: string): ModifierCategory | undefined;
|
|
72
|
+
/** The typed groups of one category, each with the options it offers, in group order. */
|
|
73
|
+
declare function modifierAxes(config: Config, type: ModifierCategory): {
|
|
74
|
+
path: string;
|
|
75
|
+
meta: ModifierGroupMeta;
|
|
76
|
+
options: ReturnType<typeof Modifier.list>;
|
|
77
|
+
}[];
|
|
78
|
+
/** The mode axes a config declares — what a switcher offers and a token override conditions on. */
|
|
79
|
+
declare function modeAxes(config: Config): {
|
|
80
|
+
path: string;
|
|
81
|
+
meta: ModifierGroupMeta;
|
|
82
|
+
options: ReturnType<typeof Modifier.list>;
|
|
83
|
+
}[];
|
|
84
|
+
/**
|
|
85
|
+
* The rule one item's schema cannot see, because it spans the kind: a typed group is the axis, so
|
|
86
|
+
* it sits under no other typed group and holds its options as direct children. That is what lets
|
|
87
|
+
* every reader split an option's path at its last slash to find the axis. Leaf uniqueness is the
|
|
88
|
+
* framework's, from `uniqueLeaves`.
|
|
89
|
+
*/
|
|
90
|
+
declare function modifierInvariants(config: Config): string[];
|
|
91
|
+
//#endregion
|
|
92
|
+
export { MODIFIER_CATEGORIES, Modifier, ModifierCategory, ModifierGroupMeta, WEB_ACTIVATIONS, WebActivation, modeAxes, modifierAxes, modifierAxis, modifierCategory, modifierGroupFields, modifierInvariants, modifierLeaf };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { isRef, kindOf } from "../../framework/utils/refs.js";
|
|
2
|
+
import { defineEntity } from "../../framework/defineEntity.js";
|
|
3
|
+
import { Composite } from "./Composite.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region src/entities/system/Modifier.ts
|
|
6
|
+
/** The category a typed group gives its members. Untyped groups are folders; their members are
|
|
7
|
+
* plain modifiers that compose as fragments and that no surface treats specially. */
|
|
8
|
+
const MODIFIER_CATEGORIES = ["mode", "state"];
|
|
9
|
+
/** How a web modifier activates. A `media-query` is an at-rule the emitter wraps the block in;
|
|
10
|
+
* `selector` composes onto the element, or stands as an ancestor for a mode. */
|
|
11
|
+
const WEB_ACTIVATIONS = [
|
|
12
|
+
"selector",
|
|
13
|
+
"media-query",
|
|
14
|
+
"composite"
|
|
15
|
+
];
|
|
16
|
+
/** A ref to a modifier, spelled out because the kind's own class is what this is a field of. */
|
|
17
|
+
const modifierRef = z.object({ __ref: z.string().refine((raw) => kindOf(raw) === "modifier") }).meta({
|
|
18
|
+
ref: true,
|
|
19
|
+
refKind: "modifier"
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* A modifier group's own fields.
|
|
23
|
+
*
|
|
24
|
+
* `type` says what category of condition the group's members are. A `mode` is an axis of the
|
|
25
|
+
* document or a subtree: one option active at a time, switched by a viewer, activating on an
|
|
26
|
+
* ancestor or the viewport. A `state` is a condition of the element itself, entered by interaction
|
|
27
|
+
* or by a prop; it gets a grid column and a `data-create-force-<leaf>` twin. A group with no `type`
|
|
28
|
+
* is a folder and its members are plain.
|
|
29
|
+
*
|
|
30
|
+
* `default` names the option a viewer starts in. The native theme reads it; on web the resting state
|
|
31
|
+
* is the base values and no option is default.
|
|
32
|
+
*/
|
|
33
|
+
const modifierGroupFields = z.object({
|
|
34
|
+
type: z.enum(MODIFIER_CATEGORIES).optional(),
|
|
35
|
+
default: modifierRef.optional()
|
|
36
|
+
});
|
|
37
|
+
const Modifier = defineEntity({
|
|
38
|
+
kind: "modifier",
|
|
39
|
+
fields: z.object({
|
|
40
|
+
type: z.enum(WEB_ACTIVATIONS),
|
|
41
|
+
value: z.union([z.string(), z.lazy(() => Composite)])
|
|
42
|
+
}).check((ctx) => {
|
|
43
|
+
const { type, value } = ctx.value;
|
|
44
|
+
const wantsRef = type === "composite";
|
|
45
|
+
if (wantsRef === isRef(value)) return;
|
|
46
|
+
ctx.issues.push({
|
|
47
|
+
code: "custom",
|
|
48
|
+
input: ctx.value,
|
|
49
|
+
path: ["value"],
|
|
50
|
+
message: wantsRef ? "a `composite` modifier activates inside an element wearing a composite value, so `value` is a `Composite.ref(…)`" : `a \`${type}\` modifier's \`value\` is a string — a selector fragment, or the at-rule's condition`
|
|
51
|
+
});
|
|
52
|
+
}),
|
|
53
|
+
groupFields: modifierGroupFields,
|
|
54
|
+
uniqueLeaves: true,
|
|
55
|
+
invariants: (config) => modifierInvariants(config)
|
|
56
|
+
});
|
|
57
|
+
/** A path's last segment. */
|
|
58
|
+
function modifierLeaf(path) {
|
|
59
|
+
return path.slice(path.lastIndexOf("/") + 1);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The typed group a modifier belongs to — its category and the group's path — or `undefined` for a
|
|
63
|
+
* plain one. The nearest typed ancestor answers; folders above it are organisation only.
|
|
64
|
+
*/
|
|
65
|
+
function modifierAxis(config, pathOrLeaf) {
|
|
66
|
+
const entity = config.resolve("modifier", pathOrLeaf);
|
|
67
|
+
if (!entity) return void 0;
|
|
68
|
+
return typedAncestor(config, entity.path);
|
|
69
|
+
}
|
|
70
|
+
/** The category of a modifier: `mode`, `state`, or `undefined` for a plain one. */
|
|
71
|
+
function modifierCategory(config, pathOrLeaf) {
|
|
72
|
+
return modifierAxis(config, pathOrLeaf)?.type;
|
|
73
|
+
}
|
|
74
|
+
/** The typed groups of one category, each with the options it offers, in group order. */
|
|
75
|
+
function modifierAxes(config, type) {
|
|
76
|
+
return config.groups("modifier").filter((group) => group.meta.type === type).map((group) => ({
|
|
77
|
+
path: group.path,
|
|
78
|
+
meta: group.meta,
|
|
79
|
+
options: Modifier.list(config).filter((item) => item.path.startsWith(`${group.path}/`))
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
/** The mode axes a config declares — what a switcher offers and a token override conditions on. */
|
|
83
|
+
function modeAxes(config) {
|
|
84
|
+
return modifierAxes(config, "mode");
|
|
85
|
+
}
|
|
86
|
+
function typedAncestor(config, path) {
|
|
87
|
+
const groups = new Map(config.groups("modifier").map((group) => [group.path, group.meta]));
|
|
88
|
+
const segments = path.split("/");
|
|
89
|
+
for (let depth = segments.length - 1; depth >= 1; depth--) {
|
|
90
|
+
const group = segments.slice(0, depth).join("/");
|
|
91
|
+
const meta = groups.get(group);
|
|
92
|
+
if (meta?.type) return {
|
|
93
|
+
group,
|
|
94
|
+
type: meta.type,
|
|
95
|
+
meta
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The rule one item's schema cannot see, because it spans the kind: a typed group is the axis, so
|
|
101
|
+
* it sits under no other typed group and holds its options as direct children. That is what lets
|
|
102
|
+
* every reader split an option's path at its last slash to find the axis. Leaf uniqueness is the
|
|
103
|
+
* framework's, from `uniqueLeaves`.
|
|
104
|
+
*/
|
|
105
|
+
function modifierInvariants(config) {
|
|
106
|
+
const problems = [];
|
|
107
|
+
const items = Modifier.list(config);
|
|
108
|
+
const typed = config.groups("modifier").filter((group) => group.meta.type !== void 0);
|
|
109
|
+
for (const group of typed) {
|
|
110
|
+
const above = typedAncestor(config, group.path);
|
|
111
|
+
if (above) problems.push(`Modifier group "${group.path}" is typed but sits under the typed group "${above.group}"; a typed group is the axis and nests under folders only.`);
|
|
112
|
+
}
|
|
113
|
+
for (const item of items) {
|
|
114
|
+
const axis = typedAncestor(config, item.path);
|
|
115
|
+
if (axis && item.path !== `${axis.group}/${item.leaf}`) problems.push(`Modifier "${item.path}" is nested inside the typed group "${axis.group}"; an axis holds its options directly.`);
|
|
116
|
+
}
|
|
117
|
+
return problems;
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
export { MODIFIER_CATEGORIES, Modifier, WEB_ACTIVATIONS, modeAxes, modifierAxes, modifierAxis, modifierCategory, modifierGroupFields, modifierInvariants, modifierLeaf };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { EntityClass } from "../../framework/defineEntity.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/entities/system/Motion.d.ts
|
|
5
|
+
declare const Motion: EntityClass<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
6
|
+
runtime: z.ZodLiteral<"css">;
|
|
7
|
+
keyframes: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
8
|
+
duration: z.ZodOptional<z.ZodString>;
|
|
9
|
+
delay: z.ZodOptional<z.ZodString>;
|
|
10
|
+
timingFunction: z.ZodOptional<z.ZodString>;
|
|
11
|
+
iterationCount: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
12
|
+
direction: z.ZodOptional<z.ZodString>;
|
|
13
|
+
fillMode: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
15
|
+
runtime: z.ZodLiteral<"js">;
|
|
16
|
+
initial: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
17
|
+
animate: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
18
|
+
transition: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
19
|
+
whileHover: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
20
|
+
whileTap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
+
whileFocus: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
22
|
+
whileDrag: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
23
|
+
drag: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
24
|
+
dragConstraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
25
|
+
dragElastic: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
}, z.core.$strict>], "runtime">, z.ZodObject<Record<never, never>, z.core.$strip>, "motion", Record<never, never>, Record<never, never>, false>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { Motion };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { defineEntity } from "../../framework/defineEntity.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/entities/system/Motion.ts
|
|
4
|
+
/**
|
|
5
|
+
* Motion (`fade/in`) — an animation preset, DISCRIMINATED by `runtime` so the payload is
|
|
6
|
+
* coupled to how it animates, not loosely optional:
|
|
7
|
+
* - `css` → `keyframes` REQUIRED (codegen emits `@keyframes` from them); a css preset with
|
|
8
|
+
* no keyframes — which used to validate and silently emit nothing — is now rejected.
|
|
9
|
+
* - `js` → no keyframes; carries the interaction state the client drives.
|
|
10
|
+
* Illegal cross-runtime mixes (a css preset with `animate`, a js preset with `keyframes`)
|
|
11
|
+
* can't be represented — each member is strict.
|
|
12
|
+
*
|
|
13
|
+
* Each member declares its WHOLE surface, because `strictObject` drops what it doesn't name and does
|
|
14
|
+
* it silently: the first version declared three js fields, so every gesture preset in a real system
|
|
15
|
+
* lost `whileHover`/`whileTap`/`drag` on the way in and animated nothing.
|
|
16
|
+
*/
|
|
17
|
+
const gesture = z.record(z.string(), z.unknown()).optional();
|
|
18
|
+
const CssMotion = z.strictObject({
|
|
19
|
+
runtime: z.literal("css"),
|
|
20
|
+
keyframes: z.record(z.string(), z.record(z.string(), z.unknown())),
|
|
21
|
+
duration: z.string().optional(),
|
|
22
|
+
delay: z.string().optional(),
|
|
23
|
+
timingFunction: z.string().optional(),
|
|
24
|
+
iterationCount: z.union([z.string(), z.number()]).optional(),
|
|
25
|
+
direction: z.string().optional(),
|
|
26
|
+
fillMode: z.string().optional()
|
|
27
|
+
});
|
|
28
|
+
const JsMotion = z.strictObject({
|
|
29
|
+
runtime: z.literal("js"),
|
|
30
|
+
initial: gesture,
|
|
31
|
+
animate: gesture,
|
|
32
|
+
transition: gesture,
|
|
33
|
+
whileHover: gesture,
|
|
34
|
+
whileTap: gesture,
|
|
35
|
+
whileFocus: gesture,
|
|
36
|
+
whileDrag: gesture,
|
|
37
|
+
drag: z.union([z.boolean(), z.string()]).optional(),
|
|
38
|
+
dragConstraints: z.record(z.string(), z.number()).optional(),
|
|
39
|
+
dragElastic: z.number().optional()
|
|
40
|
+
});
|
|
41
|
+
const Motion = defineEntity({
|
|
42
|
+
kind: "motion",
|
|
43
|
+
label: "Motion",
|
|
44
|
+
labelPlural: "Motion presets",
|
|
45
|
+
fields: z.discriminatedUnion("runtime", [CssMotion, JsMotion])
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Motion };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { DerivedEntityClass } from "../../framework/defineDerivedEntity.js";
|
|
2
|
+
import { Config } from "../../framework/Config.js";
|
|
3
|
+
import { ComputedInput } from "../../framework/registry.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
//#region src/entities/system/Operation.d.ts
|
|
7
|
+
declare const Operation: DerivedEntityClass<z.ZodObject<{
|
|
8
|
+
kind: z.ZodString;
|
|
9
|
+
verb: z.ZodString;
|
|
10
|
+
readOnly: z.ZodBoolean;
|
|
11
|
+
label: z.ZodString;
|
|
12
|
+
description: z.ZodString;
|
|
13
|
+
scope: z.ZodString;
|
|
14
|
+
creates: z.ZodBoolean;
|
|
15
|
+
approval: z.ZodOptional<z.ZodEnum<{
|
|
16
|
+
destructive: "destructive";
|
|
17
|
+
"reference-change": "reference-change";
|
|
18
|
+
}>>;
|
|
19
|
+
}, z.core.$strip>, {
|
|
20
|
+
inputSchema: ({
|
|
21
|
+
member: op,
|
|
22
|
+
config
|
|
23
|
+
}: Omit<ComputedInput, "member"> & {
|
|
24
|
+
member: {
|
|
25
|
+
kind: string;
|
|
26
|
+
verb: string;
|
|
27
|
+
readOnly: boolean;
|
|
28
|
+
label: string;
|
|
29
|
+
description: string;
|
|
30
|
+
scope: string;
|
|
31
|
+
creates: boolean;
|
|
32
|
+
approval?: "destructive" | "reference-change" | undefined;
|
|
33
|
+
};
|
|
34
|
+
}) => z.ZodTypeAny<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>> | undefined;
|
|
35
|
+
execute: ({
|
|
36
|
+
member: op,
|
|
37
|
+
config: declaring
|
|
38
|
+
}: Omit<ComputedInput, "member"> & {
|
|
39
|
+
member: {
|
|
40
|
+
kind: string;
|
|
41
|
+
verb: string;
|
|
42
|
+
readOnly: boolean;
|
|
43
|
+
label: string;
|
|
44
|
+
description: string;
|
|
45
|
+
scope: string;
|
|
46
|
+
creates: boolean;
|
|
47
|
+
approval?: "destructive" | "reference-change" | undefined;
|
|
48
|
+
};
|
|
49
|
+
}) => ((input: Record<string, unknown>, config: Config) => unknown) | undefined; /** The sub-entity collection this op targets (`layers`) — absent on a kind-level op. */
|
|
50
|
+
field: ({
|
|
51
|
+
member: op
|
|
52
|
+
}: Omit<ComputedInput, "member"> & {
|
|
53
|
+
member: {
|
|
54
|
+
kind: string;
|
|
55
|
+
verb: string;
|
|
56
|
+
readOnly: boolean;
|
|
57
|
+
label: string;
|
|
58
|
+
description: string;
|
|
59
|
+
scope: string;
|
|
60
|
+
creates: boolean;
|
|
61
|
+
approval?: "destructive" | "reference-change" | undefined;
|
|
62
|
+
};
|
|
63
|
+
}) => string | undefined;
|
|
64
|
+
/** An op-declared title composer, for a verb that doesn't read as `<Verb> <Noun>`. A function,
|
|
65
|
+
* so it can't be stored — the entity label it takes is the caller's to supply. */
|
|
66
|
+
title: ({
|
|
67
|
+
member: op,
|
|
68
|
+
config
|
|
69
|
+
}: Omit<ComputedInput, "member"> & {
|
|
70
|
+
member: {
|
|
71
|
+
kind: string;
|
|
72
|
+
verb: string;
|
|
73
|
+
readOnly: boolean;
|
|
74
|
+
label: string;
|
|
75
|
+
description: string;
|
|
76
|
+
scope: string;
|
|
77
|
+
creates: boolean;
|
|
78
|
+
approval?: "destructive" | "reference-change" | undefined;
|
|
79
|
+
};
|
|
80
|
+
}) => ((entity: string) => string) | undefined;
|
|
81
|
+
/** A runnable example bound to this config — the op's own `example` when it declares one (its
|
|
82
|
+
* input isn't an address shape), else filled from the input schema. */
|
|
83
|
+
example: ({
|
|
84
|
+
member: op,
|
|
85
|
+
config
|
|
86
|
+
}: Omit<ComputedInput, "member"> & {
|
|
87
|
+
member: {
|
|
88
|
+
kind: string;
|
|
89
|
+
verb: string;
|
|
90
|
+
readOnly: boolean;
|
|
91
|
+
label: string;
|
|
92
|
+
description: string;
|
|
93
|
+
scope: string;
|
|
94
|
+
creates: boolean;
|
|
95
|
+
approval?: "destructive" | "reference-change" | undefined;
|
|
96
|
+
};
|
|
97
|
+
}) => Record<string, unknown> | undefined;
|
|
98
|
+
}>;
|
|
99
|
+
//#endregion
|
|
100
|
+
export { Operation };
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { CONFIG_OPERATION_KIND } from "../../framework/config-operation-kind.js";
|
|
2
|
+
import { isPlainObject } from "../../framework/utils/field-path.js";
|
|
3
|
+
import { resolveInputSchema } from "../../framework/schemas.js";
|
|
4
|
+
import { opsForKind } from "../../framework/registry.js";
|
|
5
|
+
import { opOf } from "../../framework/config-op.js";
|
|
6
|
+
import { configSchemas } from "../../framework/config-ops.js";
|
|
7
|
+
import { defineDerivedEntity } from "../../framework/defineDerivedEntity.js";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
//#region src/entities/system/Operation.ts
|
|
10
|
+
/**
|
|
11
|
+
* `Operation` — the capability catalog, a derived entity. One ref-able member per (kind, verb) the
|
|
12
|
+
* Config's owned kinds expose — mutations and reads (`list`/`get`/`dependents`) alike, each tagged
|
|
13
|
+
* `readOnly` — computed from each kind's `schemas` map (`opsForKind`). Read-only: you can't author a
|
|
14
|
+
* capability that doesn't exist.
|
|
15
|
+
*
|
|
16
|
+
* `inputSchema` (a zod schema) and `execute` (a function) are non-serializable, so they live as
|
|
17
|
+
* `computed` fields — recomputed on read from the kind's `schemas[verb]`, never stored.
|
|
18
|
+
*
|
|
19
|
+
* An op also carries what it means: its verb `label`, its `description`, what it addresses (`scope`),
|
|
20
|
+
* whether it `creates`, and a runnable discovery `example`. All declared next to the op's `input` in
|
|
21
|
+
* `schemas.ts` — or, for a custom op, on the entity that declares it — because that's where the verb
|
|
22
|
+
* is defined. A consumer therefore never infers meaning from a verb string, and adding an op touches
|
|
23
|
+
* no consumer: the `Tool` surface picks it up with correct display, prose, and example.
|
|
24
|
+
*/
|
|
25
|
+
/** The op entry behind a member — a kind's own, or the config-scoped table when the "kind" is the
|
|
26
|
+
* Config. One lookup so `inputSchema`, `execute`, `title` and `example` don't each branch. */
|
|
27
|
+
function opEntry(source, kind, verb) {
|
|
28
|
+
if (kind === "config") return configSchemas(source.name)[verb];
|
|
29
|
+
return source.entityOf(kind)?.schemas[verb];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The sub-entity collection a sub-op targets (`sub-create/layers` → `layers`); absent on a
|
|
33
|
+
* kind-level op. The only thing a verb string is ever split for.
|
|
34
|
+
*
|
|
35
|
+
* A nested collection keeps its whole path (`sub-create/props/value` → `props/value`), because that
|
|
36
|
+
* path is what identifies it: truncating at the first segment would name the outer collection, and
|
|
37
|
+
* two ops that address different things would answer to one name.
|
|
38
|
+
*/
|
|
39
|
+
function opField(verb) {
|
|
40
|
+
const slash = verb.indexOf("/");
|
|
41
|
+
return slash === -1 ? void 0 : verb.slice(slash + 1);
|
|
42
|
+
}
|
|
43
|
+
/** Keep only the first field of a body — a minimal patch, for an op that merges rather than sets. */
|
|
44
|
+
function onePartial(data) {
|
|
45
|
+
const key = Object.keys(data)[0];
|
|
46
|
+
return key ? { [key]: data[key] } : {};
|
|
47
|
+
}
|
|
48
|
+
const asRecord = (value) => value && typeof value === "object" ? value : {};
|
|
49
|
+
/** The entity this op's example addresses, plus the body and member it reads from — a real one where
|
|
50
|
+
* the config has one, so a generated example is runnable. A sub-op needs an owner that actually has
|
|
51
|
+
* the collection; a group op addresses a group NODE, never an item. */
|
|
52
|
+
function target(config, kind, scope, field) {
|
|
53
|
+
if (scope === "group") {
|
|
54
|
+
const group = config.groups(kind)[0];
|
|
55
|
+
return {
|
|
56
|
+
path: group?.path ?? kind,
|
|
57
|
+
body: asRecord(group?.meta),
|
|
58
|
+
members: {}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const items = config.list(kind, { retired: false });
|
|
62
|
+
const slash = field?.indexOf("/") ?? -1;
|
|
63
|
+
if (config.entityOf(kind)?.singleton) {
|
|
64
|
+
const body = asRecord(items[0]?.toJSON());
|
|
65
|
+
return {
|
|
66
|
+
path: kind,
|
|
67
|
+
body,
|
|
68
|
+
members: field ? asRecord(body[field]) : {},
|
|
69
|
+
...field ? { section: true } : {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (field && slash !== -1) {
|
|
73
|
+
const [outer, inner] = [field.slice(0, slash), field.slice(slash + 1)];
|
|
74
|
+
for (const item of items) {
|
|
75
|
+
const body = asRecord(item.toJSON());
|
|
76
|
+
for (const [key, member] of Object.entries(asRecord(body[outer]))) {
|
|
77
|
+
const members = asRecord(asRecord(member)[inner]);
|
|
78
|
+
if (Object.keys(members).length === 0) continue;
|
|
79
|
+
return {
|
|
80
|
+
path: item.path,
|
|
81
|
+
body,
|
|
82
|
+
members,
|
|
83
|
+
owner: key
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
path: `${kind}/example`,
|
|
89
|
+
body: {},
|
|
90
|
+
members: {}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const item = field ? items.find((entry) => asRecord(entry.toJSON())[field]) : items[0];
|
|
94
|
+
const body = asRecord(item?.toJSON());
|
|
95
|
+
return {
|
|
96
|
+
path: item?.path ?? `${kind}/example`,
|
|
97
|
+
body,
|
|
98
|
+
members: field ? asRecord(body[field]) : {}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** The sequence a kind-level reorder rearranges — the kind's group nodes when the op is scoped to
|
|
102
|
+
* groups, its items otherwise. Paths, because that is what a reorder's `order` is a list of. */
|
|
103
|
+
function sequenceOf(config, kind, scope) {
|
|
104
|
+
return scope === "group" ? config.groups(kind).map((group) => group.path) : config.list(kind).map((item) => item.path);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* A runnable example invocation, built by filling the op'S own input — one producer per address field
|
|
108
|
+
* (`path`, `key`, `data`, `to`, `order`), so nothing here knows a verb. The op supplies the two bits
|
|
109
|
+
* a schema can't express (`scope`, `creates`); an op whose input isn't an address shape declares its
|
|
110
|
+
* own `example` instead (a component's `validate` does).
|
|
111
|
+
*
|
|
112
|
+
* Bound to a real entity where the config has one, falling back to a `<kind>/example` path when it
|
|
113
|
+
* doesn't — an empty config yields a placeholder example rather than an error.
|
|
114
|
+
*
|
|
115
|
+
* A placeholder covers an address (`{ path: 'token/example' }` parses; it merely resolves to nothing),
|
|
116
|
+
* but it cannot cover a body: a kind with no entity to read has no fields to show, so `data` comes out
|
|
117
|
+
* empty and the schema that requires one refuses it. So the filled example is checked against the op's
|
|
118
|
+
* own input before it is offered, and an input the op would reject is handed back as nothing.
|
|
119
|
+
*
|
|
120
|
+
* Undefined rather than best-effort because of who reads this. Operation discovery prints it and a
|
|
121
|
+
* model copies it verbatim, so an example that cannot be sent is worse than no example at all: it
|
|
122
|
+
* teaches the caller to write a refusal, and the caller has no way to tell that from a real one.
|
|
123
|
+
*/
|
|
124
|
+
function exampleFor(config, op) {
|
|
125
|
+
const field = opField(op.verb);
|
|
126
|
+
const { path, body, members, owner, section } = target(config, op.kind, op.scope, field);
|
|
127
|
+
const targetPath = op.creates === true && field === void 0 ? `${path}-2` : path;
|
|
128
|
+
const [firstKey, firstMember] = Object.entries(members)[0] ?? [];
|
|
129
|
+
const memberKey = op.creates ? "newMember" : firstKey ?? "member";
|
|
130
|
+
let source = body;
|
|
131
|
+
if (section) source = members;
|
|
132
|
+
else if (field) source = firstMember;
|
|
133
|
+
const shape = op.inputSchema instanceof z.ZodObject ? op.inputSchema.shape : {};
|
|
134
|
+
const out = {};
|
|
135
|
+
for (const name of Object.keys(shape)) if (name === "path") out.path = targetPath;
|
|
136
|
+
else if (name === "owner") out.owner = owner ?? "member";
|
|
137
|
+
else if (name === "key") out.key = memberKey;
|
|
138
|
+
else if (name === "order") out.order = field ? Object.keys(members) : sequenceOf(config, op.kind, op.scope);
|
|
139
|
+
else if (name === "data") if (!isPlainObject(source)) out.data = source;
|
|
140
|
+
else out.data = op.creates ? source : onePartial(source);
|
|
141
|
+
else if (name === "to") out.to = "key" in shape ? `${memberKey}-2` : `${targetPath}-2`;
|
|
142
|
+
if (op.inputSchema && !z.validate(op.inputSchema, out)) return void 0;
|
|
143
|
+
return out;
|
|
144
|
+
}
|
|
145
|
+
const Operation = defineDerivedEntity({
|
|
146
|
+
kind: "operation",
|
|
147
|
+
label: "Operation",
|
|
148
|
+
fields: z.object({
|
|
149
|
+
kind: z.string(),
|
|
150
|
+
verb: z.string(),
|
|
151
|
+
readOnly: z.boolean(),
|
|
152
|
+
/** The verb's human name (`Create`, `Add`) — declared by the op, not inferred from the verb. */
|
|
153
|
+
label: z.string(),
|
|
154
|
+
/** What the op does, for a model to choose it by — the derived default a `Tool` may override. */
|
|
155
|
+
description: z.string(),
|
|
156
|
+
/** `item` | `collection` | `group` — what the op addresses. Decides plural-vs-singular display
|
|
157
|
+
* and which entity an example binds to; the reason no consumer parses a verb. */
|
|
158
|
+
scope: z.string(),
|
|
159
|
+
/** The innermost address is new (a create), so an example must not reuse an existing one. */
|
|
160
|
+
creates: z.boolean(),
|
|
161
|
+
approval: z.enum(["destructive", "reference-change"]).optional()
|
|
162
|
+
}),
|
|
163
|
+
deriveMembers: (source) => Object.fromEntries([...Object.entries(configSchemas(source.name)).map(([verb, entry]) => [`${CONFIG_OPERATION_KIND}/${verb}`, {
|
|
164
|
+
kind: CONFIG_OPERATION_KIND,
|
|
165
|
+
verb,
|
|
166
|
+
readOnly: entry.readOnly,
|
|
167
|
+
label: entry.label,
|
|
168
|
+
description: entry.description,
|
|
169
|
+
scope: entry.scope,
|
|
170
|
+
creates: false,
|
|
171
|
+
approval: entry.approval
|
|
172
|
+
}]), ...source.ownedKinds().flatMap((kind) => opsForKind(source.entityOf(kind), source).map((op) => [`${kind}/${op.verb}`, {
|
|
173
|
+
kind: op.kind,
|
|
174
|
+
verb: op.verb,
|
|
175
|
+
readOnly: op.readOnly,
|
|
176
|
+
label: op.label,
|
|
177
|
+
description: op.description,
|
|
178
|
+
scope: op.scope,
|
|
179
|
+
creates: op.creates ?? false,
|
|
180
|
+
approval: op.approval
|
|
181
|
+
}]))]),
|
|
182
|
+
computed: {
|
|
183
|
+
inputSchema: ({ member: op, config }) => {
|
|
184
|
+
const declared = opEntry(config, String(op.kind), String(op.verb))?.input;
|
|
185
|
+
return declared === void 0 ? void 0 : resolveInputSchema(declared, { config });
|
|
186
|
+
},
|
|
187
|
+
execute: ({ member: op, config: declaring }) => {
|
|
188
|
+
if (!opEntry(declaring, String(op.kind), String(op.verb))?.handler) return void 0;
|
|
189
|
+
return (input, config) => {
|
|
190
|
+
const invocation = opOf({
|
|
191
|
+
kind: String(op.kind),
|
|
192
|
+
verb: String(op.verb),
|
|
193
|
+
input
|
|
194
|
+
});
|
|
195
|
+
return config.run(invocation);
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
/** The sub-entity collection this op targets (`layers`) — absent on a kind-level op. */
|
|
199
|
+
field: ({ member: op }) => opField(String(op.verb)),
|
|
200
|
+
/** An op-declared title composer, for a verb that doesn't read as `<Verb> <Noun>`. A function,
|
|
201
|
+
* so it can't be stored — the entity label it takes is the caller's to supply. */
|
|
202
|
+
title: ({ member: op, config }) => opEntry(config, String(op.kind), String(op.verb))?.title,
|
|
203
|
+
/** A runnable example bound to this config — the op's own `example` when it declares one (its
|
|
204
|
+
* input isn't an address shape), else filled from the input schema. */
|
|
205
|
+
example: ({ member: op, config }) => {
|
|
206
|
+
const declared = opEntry(config, String(op.kind), String(op.verb))?.example;
|
|
207
|
+
const inputSchema = (() => {
|
|
208
|
+
const raw = opEntry(config, String(op.kind), String(op.verb))?.input;
|
|
209
|
+
return raw === void 0 ? void 0 : resolveInputSchema(raw, { config });
|
|
210
|
+
})();
|
|
211
|
+
try {
|
|
212
|
+
if (declared) {
|
|
213
|
+
const { path } = target(config, String(op.kind), String(op.scope), opField(String(op.verb)));
|
|
214
|
+
return declared({
|
|
215
|
+
config,
|
|
216
|
+
kind: String(op.kind),
|
|
217
|
+
path
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return exampleFor(config, {
|
|
221
|
+
kind: String(op.kind),
|
|
222
|
+
verb: String(op.verb),
|
|
223
|
+
scope: String(op.scope),
|
|
224
|
+
creates: Boolean(op.creates),
|
|
225
|
+
inputSchema
|
|
226
|
+
});
|
|
227
|
+
} catch (err) {
|
|
228
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
229
|
+
console.warn(`[uds] the example for ${String(op.kind)}/${String(op.verb)} failed and was left out: ${reason}`);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
//#endregion
|
|
236
|
+
export { Operation, opField };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SubEntityClass } from "../../framework/defineSubEntity.js";
|
|
2
|
+
import { EntityClass } from "../../framework/defineEntity.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/entities/system/Package.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Package (`react-native`, `@ariakit/react`, `motion/react`) — one MODULE a system renders through.
|
|
8
|
+
*
|
|
9
|
+
* **The path IS the specifier**, verbatim, subpath and all — the same choice `File` makes for its src.
|
|
10
|
+
* So there is no `module` field: a second copy of the path could disagree with it, which is the
|
|
11
|
+
* reason a `File` computes its `binary` rather than storing one.
|
|
12
|
+
*
|
|
13
|
+
* Verbatim matters because the stored form has to regenerate the import an author wrote. `motion` and
|
|
14
|
+
* `motion/react` are ONE npm package and TWO modules; emitting `from 'motion'` for a source that
|
|
15
|
+
* wrote `from 'motion/react'` names a different entry point that resolves to a different file. That
|
|
16
|
+
* the two are one thing to INSTALL is a separate question, and the seal is the only place it is asked
|
|
17
|
+
* — `packageName` collapses them there.
|
|
18
|
+
*
|
|
19
|
+
* A key derived from the module — a slug like `ariakit` — is what this replaced. The slug was
|
|
20
|
+
* resolved over the whole import SET so two specifiers sharing a scope could both qualify away from
|
|
21
|
+
* it, which made a key depend on what else happened to be imported: `@phosphor-icons/core` arriving
|
|
22
|
+
* beside `@phosphor-icons/react` renamed the latter and stranded every ref that named it. npm has
|
|
23
|
+
* already made a module name unique; nothing here has to.
|
|
24
|
+
*
|
|
25
|
+
* The same shape `Icon` uses for a glyph library, with one difference in where membership comes from.
|
|
26
|
+
* An icon group lists every glyph the package exports, because a person picks one from a picker and
|
|
27
|
+
* all of them are candidates. A package's exports are only what a render actually placed in JSX,
|
|
28
|
+
* because nobody browses a component library's exports; the build registers them from JSX usage. The
|
|
29
|
+
* MODULE set is broader: it records every external module the render closure needs, which is what
|
|
30
|
+
* makes the portable config the source of truth for consumer install requirements.
|
|
31
|
+
*
|
|
32
|
+
* Ordinary component authoring does not maintain this graph: the build derives modules and exports
|
|
33
|
+
* from the source it walked. A human may still author one — to carry a label, or to pin a `version` —
|
|
34
|
+
* and build collection updates rather than replaces it, so that metadata survives. What authoring
|
|
35
|
+
* cannot do is choose the path.
|
|
36
|
+
*/
|
|
37
|
+
declare const Package: EntityClass<z.ZodObject<{
|
|
38
|
+
version: z.ZodOptional<z.ZodString>;
|
|
39
|
+
exports: z.ZodOptional<SubEntityClass<z.ZodObject<{}, z.core.$strict>>>;
|
|
40
|
+
}, z.core.$strict>, z.ZodObject<Record<never, never>, z.core.$strip>, "package", Record<never, never>, Record<never, never>, false>;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { Package };
|