@things-factory/figure-service 10.1.70 → 10.1.71
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/dist-server/index.js +6 -11
- package/dist-server/index.js.map +1 -1
- package/dist-server/routers/figure-thumbnail-router.js +22 -0
- package/dist-server/routers/figure-thumbnail-router.js.map +1 -1
- package/dist-server/service/figure-recipe/figure-recipe-resolver.d.ts +4 -6
- package/dist-server/service/figure-recipe/figure-recipe-resolver.js +36 -51
- package/dist-server/service/figure-recipe/figure-recipe-resolver.js.map +1 -1
- package/dist-server/service/figure-recipe/figure-recipe-templates.d.ts +28 -0
- package/dist-server/service/figure-recipe/figure-recipe-templates.js +57 -0
- package/dist-server/service/figure-recipe/figure-recipe-templates.js.map +1 -0
- package/dist-server/service/figure-recipe/figure-recipe-type.d.ts +11 -0
- package/dist-server/service/figure-recipe/figure-recipe-type.js +48 -0
- package/dist-server/service/figure-recipe/figure-recipe-type.js.map +1 -0
- package/dist-server/service/figure-recipe/index.d.ts +2 -4
- package/dist-server/service/figure-recipe/index.js +2 -4
- package/dist-server/service/figure-recipe/index.js.map +1 -1
- package/dist-server/service/index.d.ts +4 -4
- package/dist-server/service/index.js +7 -8
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/recipes/_lib/model.mts +71 -0
- package/recipes/air-cylinder/build.mts +14 -0
- package/recipes/air-cylinder/facts.md +3 -0
- package/recipes/air-cylinder/guide.en.md +18 -0
- package/recipes/air-cylinder/guide.ko.md +18 -0
- package/recipes/air-cylinder/models/default.json +1 -0
- package/recipes/air-cylinder/recipe.json +129 -0
- package/recipes/air-cylinder/spec.json +45 -0
- package/recipes/air-cylinder/thumbnail.png +0 -0
- package/recipes/air-shower/build.mts +14 -0
- package/recipes/air-shower/facts.md +3 -0
- package/recipes/air-shower/guide.en.md +17 -0
- package/recipes/air-shower/guide.ko.md +17 -0
- package/recipes/air-shower/models/default.json +1 -0
- package/recipes/air-shower/recipe.json +111 -0
- package/recipes/air-shower/spec.json +18 -0
- package/recipes/air-shower/thumbnail.png +0 -0
- package/recipes/barrier-gate/build.mts +11 -0
- package/recipes/barrier-gate/facts.md +3 -0
- package/recipes/barrier-gate/guide.en.md +18 -0
- package/recipes/barrier-gate/guide.ko.md +18 -0
- package/recipes/barrier-gate/models/default.json +1 -0
- package/recipes/barrier-gate/recipe.json +87 -0
- package/recipes/barrier-gate/spec.json +45 -0
- package/recipes/barrier-gate/thumbnail.png +0 -0
- package/recipes/base-frame/build.mts +11 -0
- package/recipes/base-frame/facts.md +3 -0
- package/recipes/base-frame/guide.en.md +18 -0
- package/recipes/base-frame/guide.ko.md +18 -0
- package/recipes/base-frame/models/default.json +1 -0
- package/recipes/base-frame/recipe.json +259 -0
- package/recipes/base-frame/spec.json +72 -0
- package/recipes/base-frame/thumbnail.png +0 -0
- package/recipes/belt-surface/build.mts +12 -0
- package/recipes/belt-surface/facts.md +3 -0
- package/recipes/belt-surface/guide.en.md +18 -0
- package/recipes/belt-surface/guide.ko.md +18 -0
- package/recipes/belt-surface/models/default.json +1 -0
- package/recipes/belt-surface/recipe.json +116 -0
- package/recipes/belt-surface/spec.json +69 -0
- package/recipes/belt-surface/thumbnail.png +0 -0
- package/recipes/bin-row/build.mts +11 -0
- package/recipes/bin-row/facts.md +3 -0
- package/recipes/bin-row/guide.en.md +18 -0
- package/recipes/bin-row/guide.ko.md +18 -0
- package/recipes/bin-row/models/default.json +1 -0
- package/recipes/bin-row/recipe.json +87 -0
- package/recipes/bin-row/spec.json +45 -0
- package/recipes/bin-row/thumbnail.png +0 -0
- package/recipes/bollard-row/build.mts +11 -0
- package/recipes/bollard-row/facts.md +3 -0
- package/recipes/bollard-row/guide.en.md +18 -0
- package/recipes/bollard-row/guide.ko.md +18 -0
- package/recipes/bollard-row/models/default.json +1 -0
- package/recipes/bollard-row/recipe.json +107 -0
- package/recipes/bollard-row/spec.json +71 -0
- package/recipes/bollard-row/thumbnail.png +0 -0
- package/recipes/buzzer/build.mts +10 -0
- package/recipes/buzzer/facts.md +3 -0
- package/recipes/buzzer/guide.en.md +17 -0
- package/recipes/buzzer/guide.ko.md +17 -0
- package/recipes/buzzer/models/default.json +1 -0
- package/recipes/buzzer/recipe.json +68 -0
- package/recipes/buzzer/spec.json +18 -0
- package/recipes/buzzer/thumbnail.png +0 -0
- package/recipes/cabinet-doors/build.mts +21 -0
- package/recipes/cabinet-doors/facts.md +3 -0
- package/recipes/cabinet-doors/guide.en.md +19 -0
- package/recipes/cabinet-doors/guide.ko.md +19 -0
- package/recipes/cabinet-doors/models/default.json +1 -0
- package/recipes/cabinet-doors/models/doors=1.json +1 -0
- package/recipes/cabinet-doors/models/doors=2.json +1 -0
- package/recipes/cabinet-doors/recipe.json +240 -0
- package/recipes/cabinet-doors/spec.json +36 -0
- package/recipes/cabinet-doors/thumbnail.png +0 -0
- package/recipes/cable-tray/build.mts +16 -0
- package/recipes/cable-tray/facts.md +3 -0
- package/recipes/cable-tray/guide.en.md +18 -0
- package/recipes/cable-tray/guide.ko.md +18 -0
- package/recipes/cable-tray/models/default.json +1 -0
- package/recipes/cable-tray/recipe.json +198 -0
- package/recipes/cable-tray/spec.json +45 -0
- package/recipes/cable-tray/thumbnail.png +0 -0
- package/recipes/camera-mount/build.mts +10 -0
- package/recipes/camera-mount/facts.md +3 -0
- package/recipes/camera-mount/guide.en.md +16 -0
- package/recipes/camera-mount/guide.ko.md +16 -0
- package/recipes/camera-mount/models/default.json +1 -0
- package/recipes/camera-mount/recipe.json +108 -0
- package/recipes/camera-mount/spec.json +18 -0
- package/recipes/camera-mount/thumbnail.png +0 -0
- package/recipes/canopy/build.mts +17 -0
- package/recipes/canopy/facts.md +3 -0
- package/recipes/canopy/guide.en.md +18 -0
- package/recipes/canopy/guide.ko.md +18 -0
- package/recipes/canopy/models/default.json +1 -0
- package/recipes/canopy/recipe.json +281 -0
- package/recipes/canopy/spec.json +81 -0
- package/recipes/canopy/thumbnail.png +0 -0
- package/recipes/cart/build.mts +24 -0
- package/recipes/cart/facts.md +3 -0
- package/recipes/cart/guide.en.md +16 -0
- package/recipes/cart/guide.ko.md +16 -0
- package/recipes/cart/models/default.json +1 -0
- package/recipes/cart/recipe.json +555 -0
- package/recipes/cart/spec.json +11 -0
- package/recipes/cart/thumbnail.png +0 -0
- package/recipes/cart-handle/build.mts +13 -0
- package/recipes/cart-handle/facts.md +3 -0
- package/recipes/cart-handle/guide.en.md +16 -0
- package/recipes/cart-handle/guide.ko.md +16 -0
- package/recipes/cart-handle/models/default.json +1 -0
- package/recipes/cart-handle/recipe.json +161 -0
- package/recipes/cart-handle/spec.json +18 -0
- package/recipes/cart-handle/thumbnail.png +0 -0
- package/recipes/casters-four/build.mts +16 -0
- package/recipes/casters-four/facts.md +3 -0
- package/recipes/casters-four/guide.en.md +19 -0
- package/recipes/casters-four/guide.ko.md +19 -0
- package/recipes/casters-four/models/default.json +1 -0
- package/recipes/casters-four/recipe.json +409 -0
- package/recipes/casters-four/spec.json +72 -0
- package/recipes/casters-four/thumbnail.png +0 -0
- package/recipes/ceiling-rail-carriage/build.mts +15 -0
- package/recipes/ceiling-rail-carriage/facts.md +3 -0
- package/recipes/ceiling-rail-carriage/guide.en.md +17 -0
- package/recipes/ceiling-rail-carriage/guide.ko.md +17 -0
- package/recipes/ceiling-rail-carriage/models/default.json +1 -0
- package/recipes/ceiling-rail-carriage/recipe.json +127 -0
- package/recipes/ceiling-rail-carriage/spec.json +19 -0
- package/recipes/ceiling-rail-carriage/thumbnail.png +0 -0
- package/recipes/chain-rails/build.mts +15 -0
- package/recipes/chain-rails/facts.md +3 -0
- package/recipes/chain-rails/guide.en.md +18 -0
- package/recipes/chain-rails/guide.ko.md +18 -0
- package/recipes/chain-rails/models/default.json +1 -0
- package/recipes/chain-rails/recipe.json +166 -0
- package/recipes/chain-rails/spec.json +54 -0
- package/recipes/chain-rails/thumbnail.png +0 -0
- package/recipes/charging-station/build.mts +9 -0
- package/recipes/charging-station/facts.md +3 -0
- package/recipes/charging-station/guide.en.md +16 -0
- package/recipes/charging-station/guide.ko.md +16 -0
- package/recipes/charging-station/models/default.json +1 -0
- package/recipes/charging-station/recipe.json +105 -0
- package/recipes/charging-station/spec.json +18 -0
- package/recipes/charging-station/thumbnail.png +0 -0
- package/recipes/column-row/build.mts +11 -0
- package/recipes/column-row/facts.md +3 -0
- package/recipes/column-row/guide.en.md +18 -0
- package/recipes/column-row/guide.ko.md +18 -0
- package/recipes/column-row/models/default.json +1 -0
- package/recipes/column-row/recipe.json +103 -0
- package/recipes/column-row/spec.json +71 -0
- package/recipes/column-row/thumbnail.png +0 -0
- package/recipes/control-cabinet/build.mts +14 -0
- package/recipes/control-cabinet/facts.md +3 -0
- package/recipes/control-cabinet/guide.en.md +17 -0
- package/recipes/control-cabinet/guide.ko.md +17 -0
- package/recipes/control-cabinet/models/default.json +1 -0
- package/recipes/control-cabinet/recipe.json +111 -0
- package/recipes/control-cabinet/spec.json +18 -0
- package/recipes/control-cabinet/thumbnail.png +0 -0
- package/recipes/conveyor-skirts/build.mts +9 -0
- package/recipes/conveyor-skirts/facts.md +3 -0
- package/recipes/conveyor-skirts/guide.en.md +16 -0
- package/recipes/conveyor-skirts/guide.ko.md +16 -0
- package/recipes/conveyor-skirts/models/default.json +1 -0
- package/recipes/conveyor-skirts/recipe.json +141 -0
- package/recipes/conveyor-skirts/spec.json +18 -0
- package/recipes/conveyor-skirts/thumbnail.png +0 -0
- package/recipes/counter-display/build.mts +13 -0
- package/recipes/counter-display/facts.md +3 -0
- package/recipes/counter-display/guide.en.md +17 -0
- package/recipes/counter-display/guide.ko.md +17 -0
- package/recipes/counter-display/models/default.json +1 -0
- package/recipes/counter-display/recipe.json +106 -0
- package/recipes/counter-display/spec.json +18 -0
- package/recipes/counter-display/thumbnail.png +0 -0
- package/recipes/dock-bumpers/build.mts +9 -0
- package/recipes/dock-bumpers/facts.md +3 -0
- package/recipes/dock-bumpers/guide.en.md +16 -0
- package/recipes/dock-bumpers/guide.ko.md +16 -0
- package/recipes/dock-bumpers/models/default.json +1 -0
- package/recipes/dock-bumpers/recipe.json +107 -0
- package/recipes/dock-bumpers/spec.json +18 -0
- package/recipes/dock-bumpers/thumbnail.png +0 -0
- package/recipes/dock-leveler/build.mts +11 -0
- package/recipes/dock-leveler/facts.md +3 -0
- package/recipes/dock-leveler/guide.en.md +16 -0
- package/recipes/dock-leveler/guide.ko.md +16 -0
- package/recipes/dock-leveler/models/default.json +1 -0
- package/recipes/dock-leveler/recipe.json +69 -0
- package/recipes/dock-leveler/spec.json +18 -0
- package/recipes/dock-leveler/thumbnail.png +0 -0
- package/recipes/double-hinged-door/build.mts +19 -0
- package/recipes/double-hinged-door/facts.md +3 -0
- package/recipes/double-hinged-door/guide.en.md +19 -0
- package/recipes/double-hinged-door/guide.ko.md +19 -0
- package/recipes/double-hinged-door/models/default.json +1 -0
- package/recipes/double-hinged-door/recipe.json +273 -0
- package/recipes/double-hinged-door/spec.json +69 -0
- package/recipes/double-hinged-door/thumbnail.png +0 -0
- package/recipes/drawer-stack/build.mts +17 -0
- package/recipes/drawer-stack/facts.md +3 -0
- package/recipes/drawer-stack/guide.en.md +18 -0
- package/recipes/drawer-stack/guide.ko.md +18 -0
- package/recipes/drawer-stack/models/default.json +1 -0
- package/recipes/drawer-stack/models/drawers=2.json +1 -0
- package/recipes/drawer-stack/models/drawers=3.json +1 -0
- package/recipes/drawer-stack/models/drawers=4.json +1 -0
- package/recipes/drawer-stack/recipe.json +789 -0
- package/recipes/drawer-stack/spec.json +37 -0
- package/recipes/drawer-stack/thumbnail.png +0 -0
- package/recipes/drip-tray/build.mts +12 -0
- package/recipes/drip-tray/facts.md +3 -0
- package/recipes/drip-tray/guide.en.md +16 -0
- package/recipes/drip-tray/guide.ko.md +16 -0
- package/recipes/drip-tray/models/default.json +1 -0
- package/recipes/drip-tray/recipe.json +86 -0
- package/recipes/drip-tray/spec.json +18 -0
- package/recipes/drip-tray/thumbnail.png +0 -0
- package/recipes/duct-fan/build.mts +14 -0
- package/recipes/duct-fan/facts.md +3 -0
- package/recipes/duct-fan/guide.en.md +16 -0
- package/recipes/duct-fan/guide.ko.md +16 -0
- package/recipes/duct-fan/models/default.json +1 -0
- package/recipes/duct-fan/recipe.json +122 -0
- package/recipes/duct-fan/spec.json +18 -0
- package/recipes/duct-fan/thumbnail.png +0 -0
- package/recipes/emergency-stop/build.mts +14 -0
- package/recipes/emergency-stop/facts.md +3 -0
- package/recipes/emergency-stop/guide.en.md +17 -0
- package/recipes/emergency-stop/guide.ko.md +17 -0
- package/recipes/emergency-stop/models/default.json +1 -0
- package/recipes/emergency-stop/recipe.json +109 -0
- package/recipes/emergency-stop/spec.json +18 -0
- package/recipes/emergency-stop/thumbnail.png +0 -0
- package/recipes/end-covers/build.mts +13 -0
- package/recipes/end-covers/facts.md +3 -0
- package/recipes/end-covers/guide.en.md +17 -0
- package/recipes/end-covers/guide.ko.md +17 -0
- package/recipes/end-covers/models/default.json +1 -0
- package/recipes/end-covers/recipe.json +141 -0
- package/recipes/end-covers/spec.json +18 -0
- package/recipes/end-covers/thumbnail.png +0 -0
- package/recipes/ffu-row/build.mts +11 -0
- package/recipes/ffu-row/facts.md +3 -0
- package/recipes/ffu-row/guide.en.md +18 -0
- package/recipes/ffu-row/guide.ko.md +18 -0
- package/recipes/ffu-row/models/default.json +1 -0
- package/recipes/ffu-row/recipe.json +82 -0
- package/recipes/ffu-row/spec.json +45 -0
- package/recipes/ffu-row/thumbnail.png +0 -0
- package/recipes/fire-extinguisher/build.mts +13 -0
- package/recipes/fire-extinguisher/facts.md +3 -0
- package/recipes/fire-extinguisher/guide.en.md +16 -0
- package/recipes/fire-extinguisher/guide.ko.md +16 -0
- package/recipes/fire-extinguisher/models/default.json +1 -0
- package/recipes/fire-extinguisher/recipe.json +114 -0
- package/recipes/fire-extinguisher/spec.json +18 -0
- package/recipes/fire-extinguisher/thumbnail.png +0 -0
- package/recipes/first-aid-box/build.mts +9 -0
- package/recipes/first-aid-box/facts.md +3 -0
- package/recipes/first-aid-box/guide.en.md +16 -0
- package/recipes/first-aid-box/guide.ko.md +16 -0
- package/recipes/first-aid-box/models/default.json +1 -0
- package/recipes/first-aid-box/recipe.json +97 -0
- package/recipes/first-aid-box/spec.json +18 -0
- package/recipes/first-aid-box/thumbnail.png +0 -0
- package/recipes/floor-zone/build.mts +17 -0
- package/recipes/floor-zone/facts.md +3 -0
- package/recipes/floor-zone/guide.en.md +18 -0
- package/recipes/floor-zone/guide.ko.md +18 -0
- package/recipes/floor-zone/models/default.json +1 -0
- package/recipes/floor-zone/recipe.json +257 -0
- package/recipes/floor-zone/spec.json +72 -0
- package/recipes/floor-zone/thumbnail.png +0 -0
- package/recipes/folding-door/build.mts +20 -0
- package/recipes/folding-door/facts.md +3 -0
- package/recipes/folding-door/guide.en.md +18 -0
- package/recipes/folding-door/guide.ko.md +18 -0
- package/recipes/folding-door/models/default.json +1 -0
- package/recipes/folding-door/recipe.json +217 -0
- package/recipes/folding-door/spec.json +44 -0
- package/recipes/folding-door/thumbnail.png +0 -0
- package/recipes/fork/build.mts +13 -0
- package/recipes/fork/facts.md +3 -0
- package/recipes/fork/guide.en.md +18 -0
- package/recipes/fork/guide.ko.md +18 -0
- package/recipes/fork/models/default.json +1 -0
- package/recipes/fork/recipe.json +136 -0
- package/recipes/fork/spec.json +45 -0
- package/recipes/fork/thumbnail.png +0 -0
- package/recipes/gantry-frame/build.mts +13 -0
- package/recipes/gantry-frame/facts.md +3 -0
- package/recipes/gantry-frame/guide.en.md +18 -0
- package/recipes/gantry-frame/guide.ko.md +18 -0
- package/recipes/gantry-frame/models/default.json +1 -0
- package/recipes/gantry-frame/recipe.json +178 -0
- package/recipes/gantry-frame/spec.json +63 -0
- package/recipes/gantry-frame/thumbnail.png +0 -0
- package/recipes/gripper-2f/build.mts +16 -0
- package/recipes/gripper-2f/facts.md +3 -0
- package/recipes/gripper-2f/guide.en.md +18 -0
- package/recipes/gripper-2f/guide.ko.md +18 -0
- package/recipes/gripper-2f/models/default.json +1 -0
- package/recipes/gripper-2f/recipe.json +172 -0
- package/recipes/gripper-2f/spec.json +45 -0
- package/recipes/gripper-2f/thumbnail.png +0 -0
- package/recipes/guard-cover/build.mts +13 -0
- package/recipes/guard-cover/facts.md +3 -0
- package/recipes/guard-cover/guide.en.md +18 -0
- package/recipes/guard-cover/guide.ko.md +18 -0
- package/recipes/guard-cover/models/default.json +1 -0
- package/recipes/guard-cover/recipe.json +92 -0
- package/recipes/guard-cover/spec.json +18 -0
- package/recipes/guard-cover/thumbnail.png +0 -0
- package/recipes/handrail/build.mts +15 -0
- package/recipes/handrail/facts.md +3 -0
- package/recipes/handrail/guide.en.md +18 -0
- package/recipes/handrail/guide.ko.md +18 -0
- package/recipes/handrail/models/default.json +1 -0
- package/recipes/handrail/recipe.json +140 -0
- package/recipes/handrail/spec.json +45 -0
- package/recipes/handrail/thumbnail.png +0 -0
- package/recipes/hatch/build.mts +17 -0
- package/recipes/hatch/facts.md +3 -0
- package/recipes/hatch/guide.en.md +18 -0
- package/recipes/hatch/guide.ko.md +18 -0
- package/recipes/hatch/models/default.json +1 -0
- package/recipes/hatch/recipe.json +194 -0
- package/recipes/hatch/spec.json +69 -0
- package/recipes/hatch/thumbnail.png +0 -0
- package/recipes/hinged-door/build.mts +26 -0
- package/recipes/hinged-door/facts.md +21 -0
- package/recipes/hinged-door/guide.en.md +19 -0
- package/recipes/hinged-door/guide.ko.md +19 -0
- package/recipes/hinged-door/models/default.json +1 -0
- package/recipes/hinged-door/models/hinge=left.json +1 -0
- package/recipes/hinged-door/models/hinge=right.json +1 -0
- package/recipes/hinged-door/recipe.json +252 -0
- package/recipes/hinged-door/spec.json +23 -0
- package/recipes/hinged-door/thumbnail.png +0 -0
- package/recipes/hmi-monitor/build.mts +14 -0
- package/recipes/hmi-monitor/facts.md +3 -0
- package/recipes/hmi-monitor/guide.en.md +17 -0
- package/recipes/hmi-monitor/guide.ko.md +17 -0
- package/recipes/hmi-monitor/models/default.json +1 -0
- package/recipes/hmi-monitor/recipe.json +108 -0
- package/recipes/hmi-monitor/spec.json +18 -0
- package/recipes/hmi-monitor/thumbnail.png +0 -0
- package/recipes/hopper/build.mts +14 -0
- package/recipes/hopper/facts.md +3 -0
- package/recipes/hopper/guide.en.md +18 -0
- package/recipes/hopper/guide.ko.md +18 -0
- package/recipes/hopper/models/default.json +1 -0
- package/recipes/hopper/recipe.json +137 -0
- package/recipes/hopper/spec.json +22 -0
- package/recipes/hopper/thumbnail.png +0 -0
- package/recipes/interlock-switch/build.mts +8 -0
- package/recipes/interlock-switch/facts.md +3 -0
- package/recipes/interlock-switch/guide.en.md +17 -0
- package/recipes/interlock-switch/guide.ko.md +17 -0
- package/recipes/interlock-switch/models/default.json +1 -0
- package/recipes/interlock-switch/recipe.json +63 -0
- package/recipes/interlock-switch/spec.json +18 -0
- package/recipes/interlock-switch/thumbnail.png +0 -0
- package/recipes/junction-box/build.mts +8 -0
- package/recipes/junction-box/facts.md +3 -0
- package/recipes/junction-box/guide.en.md +16 -0
- package/recipes/junction-box/guide.ko.md +16 -0
- package/recipes/junction-box/models/default.json +1 -0
- package/recipes/junction-box/recipe.json +64 -0
- package/recipes/junction-box/spec.json +18 -0
- package/recipes/junction-box/thumbnail.png +0 -0
- package/recipes/ladder/build.mts +13 -0
- package/recipes/ladder/facts.md +3 -0
- package/recipes/ladder/guide.en.md +18 -0
- package/recipes/ladder/guide.ko.md +18 -0
- package/recipes/ladder/models/default.json +1 -0
- package/recipes/ladder/recipe.json +191 -0
- package/recipes/ladder/spec.json +44 -0
- package/recipes/ladder/thumbnail.png +0 -0
- package/recipes/legs-four/build.mts +12 -0
- package/recipes/legs-four/facts.md +3 -0
- package/recipes/legs-four/guide.en.md +18 -0
- package/recipes/legs-four/guide.ko.md +18 -0
- package/recipes/legs-four/models/default.json +1 -0
- package/recipes/legs-four/recipe.json +217 -0
- package/recipes/legs-four/spec.json +72 -0
- package/recipes/legs-four/thumbnail.png +0 -0
- package/recipes/leveling-feet/build.mts +11 -0
- package/recipes/leveling-feet/facts.md +3 -0
- package/recipes/leveling-feet/guide.en.md +18 -0
- package/recipes/leveling-feet/guide.ko.md +18 -0
- package/recipes/leveling-feet/models/default.json +1 -0
- package/recipes/leveling-feet/recipe.json +233 -0
- package/recipes/leveling-feet/spec.json +72 -0
- package/recipes/leveling-feet/thumbnail.png +0 -0
- package/recipes/lift-updown/build.mts +13 -0
- package/recipes/lift-updown/facts.md +3 -0
- package/recipes/lift-updown/guide.en.md +18 -0
- package/recipes/lift-updown/guide.ko.md +18 -0
- package/recipes/lift-updown/models/default.json +1 -0
- package/recipes/lift-updown/recipe.json +107 -0
- package/recipes/lift-updown/spec.json +45 -0
- package/recipes/lift-updown/thumbnail.png +0 -0
- package/recipes/light-curtain/build.mts +11 -0
- package/recipes/light-curtain/facts.md +3 -0
- package/recipes/light-curtain/guide.en.md +18 -0
- package/recipes/light-curtain/guide.ko.md +18 -0
- package/recipes/light-curtain/models/default.json +1 -0
- package/recipes/light-curtain/recipe.json +127 -0
- package/recipes/light-curtain/spec.json +54 -0
- package/recipes/light-curtain/thumbnail.png +0 -0
- package/recipes/limit-switch/build.mts +14 -0
- package/recipes/limit-switch/facts.md +3 -0
- package/recipes/limit-switch/guide.en.md +17 -0
- package/recipes/limit-switch/guide.ko.md +17 -0
- package/recipes/limit-switch/models/default.json +1 -0
- package/recipes/limit-switch/recipe.json +107 -0
- package/recipes/limit-switch/spec.json +17 -0
- package/recipes/limit-switch/thumbnail.png +0 -0
- package/recipes/linear-guide/build.mts +15 -0
- package/recipes/linear-guide/facts.md +3 -0
- package/recipes/linear-guide/guide.en.md +18 -0
- package/recipes/linear-guide/guide.ko.md +18 -0
- package/recipes/linear-guide/models/default.json +1 -0
- package/recipes/linear-guide/recipe.json +145 -0
- package/recipes/linear-guide/spec.json +44 -0
- package/recipes/linear-guide/thumbnail.png +0 -0
- package/recipes/locker-row/build.mts +11 -0
- package/recipes/locker-row/facts.md +3 -0
- package/recipes/locker-row/guide.en.md +18 -0
- package/recipes/locker-row/guide.ko.md +18 -0
- package/recipes/locker-row/models/default.json +1 -0
- package/recipes/locker-row/recipe.json +82 -0
- package/recipes/locker-row/spec.json +45 -0
- package/recipes/locker-row/thumbnail.png +0 -0
- package/recipes/motor-box/build.mts +10 -0
- package/recipes/motor-box/facts.md +3 -0
- package/recipes/motor-box/guide.en.md +17 -0
- package/recipes/motor-box/guide.ko.md +17 -0
- package/recipes/motor-box/models/default.json +1 -0
- package/recipes/motor-box/recipe.json +64 -0
- package/recipes/motor-box/spec.json +18 -0
- package/recipes/motor-box/thumbnail.png +0 -0
- package/recipes/observation-window/build.mts +16 -0
- package/recipes/observation-window/facts.md +3 -0
- package/recipes/observation-window/guide.en.md +19 -0
- package/recipes/observation-window/guide.ko.md +19 -0
- package/recipes/observation-window/models/default.json +1 -0
- package/recipes/observation-window/recipe.json +185 -0
- package/recipes/observation-window/spec.json +68 -0
- package/recipes/observation-window/thumbnail.png +0 -0
- package/recipes/operator-panel/build.mts +14 -0
- package/recipes/operator-panel/facts.md +3 -0
- package/recipes/operator-panel/guide.en.md +18 -0
- package/recipes/operator-panel/guide.ko.md +18 -0
- package/recipes/operator-panel/models/buttons=2.json +1 -0
- package/recipes/operator-panel/models/buttons=3.json +1 -0
- package/recipes/operator-panel/models/buttons=4.json +1 -0
- package/recipes/operator-panel/models/buttons=5.json +1 -0
- package/recipes/operator-panel/models/default.json +1 -0
- package/recipes/operator-panel/recipe.json +210 -0
- package/recipes/operator-panel/spec.json +38 -0
- package/recipes/operator-panel/thumbnail.png +0 -0
- package/recipes/pallet/build.mts +12 -0
- package/recipes/pallet/facts.md +3 -0
- package/recipes/pallet/guide.en.md +17 -0
- package/recipes/pallet/guide.ko.md +17 -0
- package/recipes/pallet/models/default.json +1 -0
- package/recipes/pallet/recipe.json +181 -0
- package/recipes/pallet/spec.json +18 -0
- package/recipes/pallet/thumbnail.png +0 -0
- package/recipes/partition-wall/build.mts +16 -0
- package/recipes/partition-wall/facts.md +3 -0
- package/recipes/partition-wall/guide.en.md +18 -0
- package/recipes/partition-wall/guide.ko.md +18 -0
- package/recipes/partition-wall/models/default.json +1 -0
- package/recipes/partition-wall/recipe.json +203 -0
- package/recipes/partition-wall/spec.json +54 -0
- package/recipes/partition-wall/thumbnail.png +0 -0
- package/recipes/pass-box/build.mts +14 -0
- package/recipes/pass-box/facts.md +3 -0
- package/recipes/pass-box/guide.en.md +17 -0
- package/recipes/pass-box/guide.ko.md +17 -0
- package/recipes/pass-box/models/default.json +1 -0
- package/recipes/pass-box/recipe.json +107 -0
- package/recipes/pass-box/spec.json +18 -0
- package/recipes/pass-box/thumbnail.png +0 -0
- package/recipes/peg-board/build.mts +14 -0
- package/recipes/peg-board/facts.md +3 -0
- package/recipes/peg-board/guide.en.md +17 -0
- package/recipes/peg-board/guide.ko.md +17 -0
- package/recipes/peg-board/models/default.json +1 -0
- package/recipes/peg-board/recipe.json +120 -0
- package/recipes/peg-board/spec.json +45 -0
- package/recipes/peg-board/thumbnail.png +0 -0
- package/recipes/photo-sensor-pair/build.mts +11 -0
- package/recipes/photo-sensor-pair/facts.md +3 -0
- package/recipes/photo-sensor-pair/guide.en.md +18 -0
- package/recipes/photo-sensor-pair/guide.ko.md +18 -0
- package/recipes/photo-sensor-pair/models/default.json +1 -0
- package/recipes/photo-sensor-pair/recipe.json +145 -0
- package/recipes/photo-sensor-pair/spec.json +54 -0
- package/recipes/photo-sensor-pair/thumbnail.png +0 -0
- package/recipes/pipe-run/build.mts +11 -0
- package/recipes/pipe-run/facts.md +3 -0
- package/recipes/pipe-run/guide.en.md +18 -0
- package/recipes/pipe-run/guide.ko.md +18 -0
- package/recipes/pipe-run/models/default.json +1 -0
- package/recipes/pipe-run/recipe.json +100 -0
- package/recipes/pipe-run/spec.json +44 -0
- package/recipes/pipe-run/thumbnail.png +0 -0
- package/recipes/platform/build.mts +14 -0
- package/recipes/platform/facts.md +3 -0
- package/recipes/platform/guide.en.md +18 -0
- package/recipes/platform/guide.ko.md +18 -0
- package/recipes/platform/models/default.json +1 -0
- package/recipes/platform/recipe.json +281 -0
- package/recipes/platform/spec.json +81 -0
- package/recipes/platform/thumbnail.png +0 -0
- package/recipes/power-box/build.mts +10 -0
- package/recipes/power-box/facts.md +3 -0
- package/recipes/power-box/guide.en.md +17 -0
- package/recipes/power-box/guide.ko.md +17 -0
- package/recipes/power-box/models/default.json +1 -0
- package/recipes/power-box/recipe.json +64 -0
- package/recipes/power-box/spec.json +18 -0
- package/recipes/power-box/thumbnail.png +0 -0
- package/recipes/pressure-gauge/build.mts +10 -0
- package/recipes/pressure-gauge/facts.md +3 -0
- package/recipes/pressure-gauge/guide.en.md +17 -0
- package/recipes/pressure-gauge/guide.ko.md +17 -0
- package/recipes/pressure-gauge/models/default.json +1 -0
- package/recipes/pressure-gauge/recipe.json +65 -0
- package/recipes/pressure-gauge/spec.json +18 -0
- package/recipes/pressure-gauge/thumbnail.png +0 -0
- package/recipes/pull-cord/build.mts +11 -0
- package/recipes/pull-cord/facts.md +3 -0
- package/recipes/pull-cord/guide.en.md +17 -0
- package/recipes/pull-cord/guide.ko.md +17 -0
- package/recipes/pull-cord/models/default.json +1 -0
- package/recipes/pull-cord/recipe.json +75 -0
- package/recipes/pull-cord/spec.json +18 -0
- package/recipes/pull-cord/thumbnail.png +0 -0
- package/recipes/pump/build.mts +13 -0
- package/recipes/pump/facts.md +3 -0
- package/recipes/pump/guide.en.md +17 -0
- package/recipes/pump/guide.ko.md +17 -0
- package/recipes/pump/models/default.json +1 -0
- package/recipes/pump/recipe.json +109 -0
- package/recipes/pump/spec.json +18 -0
- package/recipes/pump/thumbnail.png +0 -0
- package/recipes/pusher/build.mts +11 -0
- package/recipes/pusher/facts.md +3 -0
- package/recipes/pusher/guide.en.md +18 -0
- package/recipes/pusher/guide.ko.md +18 -0
- package/recipes/pusher/models/default.json +1 -0
- package/recipes/pusher/recipe.json +105 -0
- package/recipes/pusher/spec.json +45 -0
- package/recipes/pusher/thumbnail.png +0 -0
- package/recipes/robot-plinth/build.mts +9 -0
- package/recipes/robot-plinth/facts.md +3 -0
- package/recipes/robot-plinth/guide.en.md +17 -0
- package/recipes/robot-plinth/guide.ko.md +17 -0
- package/recipes/robot-plinth/models/default.json +1 -0
- package/recipes/robot-plinth/recipe.json +115 -0
- package/recipes/robot-plinth/spec.json +45 -0
- package/recipes/robot-plinth/thumbnail.png +0 -0
- package/recipes/roll-up-shutter/build.mts +17 -0
- package/recipes/roll-up-shutter/facts.md +3 -0
- package/recipes/roll-up-shutter/guide.en.md +18 -0
- package/recipes/roll-up-shutter/guide.ko.md +18 -0
- package/recipes/roll-up-shutter/models/default.json +1 -0
- package/recipes/roll-up-shutter/recipe.json +200 -0
- package/recipes/roll-up-shutter/spec.json +69 -0
- package/recipes/roll-up-shutter/thumbnail.png +0 -0
- package/recipes/roller-row/build.mts +18 -0
- package/recipes/roller-row/facts.md +20 -0
- package/recipes/roller-row/guide.en.md +21 -0
- package/recipes/roller-row/guide.ko.md +21 -0
- package/recipes/roller-row/models/default.json +1 -0
- package/recipes/roller-row/recipe.json +179 -0
- package/recipes/roller-row/spec.json +80 -0
- package/recipes/roller-row/thumbnail.png +0 -0
- package/recipes/room-shell/build.mts +16 -0
- package/recipes/room-shell/facts.md +3 -0
- package/recipes/room-shell/guide.en.md +18 -0
- package/recipes/room-shell/guide.ko.md +18 -0
- package/recipes/room-shell/models/default.json +1 -0
- package/recipes/room-shell/recipe.json +324 -0
- package/recipes/room-shell/spec.json +81 -0
- package/recipes/room-shell/thumbnail.png +0 -0
- package/recipes/rotating-beacon/build.mts +17 -0
- package/recipes/rotating-beacon/facts.md +3 -0
- package/recipes/rotating-beacon/guide.en.md +17 -0
- package/recipes/rotating-beacon/guide.ko.md +17 -0
- package/recipes/rotating-beacon/models/default.json +1 -0
- package/recipes/rotating-beacon/recipe.json +160 -0
- package/recipes/rotating-beacon/spec.json +18 -0
- package/recipes/rotating-beacon/thumbnail.png +0 -0
- package/recipes/safety-fence/build.mts +15 -0
- package/recipes/safety-fence/facts.md +3 -0
- package/recipes/safety-fence/guide.en.md +19 -0
- package/recipes/safety-fence/guide.ko.md +19 -0
- package/recipes/safety-fence/models/default.json +1 -0
- package/recipes/safety-fence/recipe.json +161 -0
- package/recipes/safety-fence/spec.json +80 -0
- package/recipes/safety-fence/thumbnail.png +0 -0
- package/recipes/safety-mat/build.mts +11 -0
- package/recipes/safety-mat/facts.md +3 -0
- package/recipes/safety-mat/guide.en.md +18 -0
- package/recipes/safety-mat/guide.ko.md +18 -0
- package/recipes/safety-mat/models/default.json +1 -0
- package/recipes/safety-mat/recipe.json +93 -0
- package/recipes/safety-mat/spec.json +44 -0
- package/recipes/safety-mat/thumbnail.png +0 -0
- package/recipes/safety-sign-stand/build.mts +16 -0
- package/recipes/safety-sign-stand/facts.md +3 -0
- package/recipes/safety-sign-stand/guide.en.md +16 -0
- package/recipes/safety-sign-stand/guide.ko.md +16 -0
- package/recipes/safety-sign-stand/models/default.json +1 -0
- package/recipes/safety-sign-stand/recipe.json +144 -0
- package/recipes/safety-sign-stand/spec.json +11 -0
- package/recipes/safety-sign-stand/thumbnail.png +0 -0
- package/recipes/scanner-mount/build.mts +10 -0
- package/recipes/scanner-mount/facts.md +3 -0
- package/recipes/scanner-mount/guide.en.md +16 -0
- package/recipes/scanner-mount/guide.ko.md +16 -0
- package/recipes/scanner-mount/models/default.json +1 -0
- package/recipes/scanner-mount/recipe.json +147 -0
- package/recipes/scanner-mount/spec.json +18 -0
- package/recipes/scanner-mount/thumbnail.png +0 -0
- package/recipes/selector-switch/build.mts +14 -0
- package/recipes/selector-switch/facts.md +3 -0
- package/recipes/selector-switch/guide.en.md +17 -0
- package/recipes/selector-switch/guide.ko.md +17 -0
- package/recipes/selector-switch/models/default.json +1 -0
- package/recipes/selector-switch/recipe.json +104 -0
- package/recipes/selector-switch/spec.json +11 -0
- package/recipes/selector-switch/thumbnail.png +0 -0
- package/recipes/shelf-tiers/build.mts +12 -0
- package/recipes/shelf-tiers/facts.md +3 -0
- package/recipes/shelf-tiers/guide.en.md +18 -0
- package/recipes/shelf-tiers/guide.ko.md +18 -0
- package/recipes/shelf-tiers/models/default.json +1 -0
- package/recipes/shelf-tiers/models/tiers=2.json +1 -0
- package/recipes/shelf-tiers/models/tiers=3.json +1 -0
- package/recipes/shelf-tiers/models/tiers=4.json +1 -0
- package/recipes/shelf-tiers/models/tiers=5.json +1 -0
- package/recipes/shelf-tiers/recipe.json +196 -0
- package/recipes/shelf-tiers/spec.json +64 -0
- package/recipes/shelf-tiers/thumbnail.png +0 -0
- package/recipes/side-guides/build.mts +12 -0
- package/recipes/side-guides/facts.md +3 -0
- package/recipes/side-guides/guide.en.md +18 -0
- package/recipes/side-guides/guide.ko.md +18 -0
- package/recipes/side-guides/models/default.json +1 -0
- package/recipes/side-guides/recipe.json +147 -0
- package/recipes/side-guides/spec.json +54 -0
- package/recipes/side-guides/thumbnail.png +0 -0
- package/recipes/sign-board/build.mts +11 -0
- package/recipes/sign-board/facts.md +3 -0
- package/recipes/sign-board/guide.en.md +18 -0
- package/recipes/sign-board/guide.ko.md +18 -0
- package/recipes/sign-board/models/default.json +1 -0
- package/recipes/sign-board/recipe.json +93 -0
- package/recipes/sign-board/spec.json +44 -0
- package/recipes/sign-board/thumbnail.png +0 -0
- package/recipes/signal-tower-3/build.mts +19 -0
- package/recipes/signal-tower-3/facts.md +3 -0
- package/recipes/signal-tower-3/guide.en.md +17 -0
- package/recipes/signal-tower-3/guide.ko.md +17 -0
- package/recipes/signal-tower-3/models/default.json +1 -0
- package/recipes/signal-tower-3/recipe.json +216 -0
- package/recipes/signal-tower-3/spec.json +19 -0
- package/recipes/signal-tower-3/thumbnail.png +0 -0
- package/recipes/sliding-door/build.mts +47 -0
- package/recipes/sliding-door/facts.md +26 -0
- package/recipes/sliding-door/guide.en.md +22 -0
- package/recipes/sliding-door/guide.ko.md +22 -0
- package/recipes/sliding-door/models/default.json +1 -0
- package/recipes/sliding-door/models/leaves=1,lamp=false.json +1 -0
- package/recipes/sliding-door/models/leaves=1,lamp=true.json +1 -0
- package/recipes/sliding-door/models/leaves=2,lamp=false.json +1 -0
- package/recipes/sliding-door/models/leaves=2,lamp=true.json +1 -0
- package/recipes/sliding-door/recipe.json +506 -0
- package/recipes/sliding-door/spec.json +26 -0
- package/recipes/sliding-door/thumbnail.png +0 -0
- package/recipes/stairs/build.mts +11 -0
- package/recipes/stairs/facts.md +3 -0
- package/recipes/stairs/guide.en.md +19 -0
- package/recipes/stairs/guide.ko.md +19 -0
- package/recipes/stairs/models/default.json +1 -0
- package/recipes/stairs/recipe.json +110 -0
- package/recipes/stairs/spec.json +94 -0
- package/recipes/stairs/thumbnail.png +0 -0
- package/recipes/status-lamp/build.mts +17 -0
- package/recipes/status-lamp/facts.md +3 -0
- package/recipes/status-lamp/guide.en.md +17 -0
- package/recipes/status-lamp/guide.ko.md +17 -0
- package/recipes/status-lamp/models/default.json +1 -0
- package/recipes/status-lamp/recipe.json +172 -0
- package/recipes/status-lamp/spec.json +18 -0
- package/recipes/status-lamp/thumbnail.png +0 -0
- package/recipes/stopper/build.mts +12 -0
- package/recipes/stopper/facts.md +3 -0
- package/recipes/stopper/guide.en.md +18 -0
- package/recipes/stopper/guide.ko.md +18 -0
- package/recipes/stopper/models/default.json +1 -0
- package/recipes/stopper/recipe.json +108 -0
- package/recipes/stopper/spec.json +45 -0
- package/recipes/stopper/thumbnail.png +0 -0
- package/recipes/suction-pads/build.mts +11 -0
- package/recipes/suction-pads/facts.md +3 -0
- package/recipes/suction-pads/guide.en.md +18 -0
- package/recipes/suction-pads/guide.ko.md +18 -0
- package/recipes/suction-pads/models/default.json +1 -0
- package/recipes/suction-pads/recipe.json +86 -0
- package/recipes/suction-pads/spec.json +45 -0
- package/recipes/suction-pads/thumbnail.png +0 -0
- package/recipes/tank/build.mts +12 -0
- package/recipes/tank/facts.md +3 -0
- package/recipes/tank/guide.en.md +18 -0
- package/recipes/tank/guide.ko.md +18 -0
- package/recipes/tank/models/default.json +1 -0
- package/recipes/tank/recipe.json +105 -0
- package/recipes/tank/spec.json +44 -0
- package/recipes/tank/thumbnail.png +0 -0
- package/recipes/telescopic-arm/build.mts +15 -0
- package/recipes/telescopic-arm/facts.md +3 -0
- package/recipes/telescopic-arm/guide.en.md +17 -0
- package/recipes/telescopic-arm/guide.ko.md +17 -0
- package/recipes/telescopic-arm/models/default.json +1 -0
- package/recipes/telescopic-arm/recipe.json +108 -0
- package/recipes/telescopic-arm/spec.json +18 -0
- package/recipes/telescopic-arm/thumbnail.png +0 -0
- package/recipes/toe-board/build.mts +11 -0
- package/recipes/toe-board/facts.md +3 -0
- package/recipes/toe-board/guide.en.md +18 -0
- package/recipes/toe-board/guide.ko.md +18 -0
- package/recipes/toe-board/models/default.json +1 -0
- package/recipes/toe-board/recipe.json +92 -0
- package/recipes/toe-board/spec.json +45 -0
- package/recipes/toe-board/thumbnail.png +0 -0
- package/recipes/tote/build.mts +10 -0
- package/recipes/tote/facts.md +3 -0
- package/recipes/tote/guide.en.md +18 -0
- package/recipes/tote/guide.ko.md +18 -0
- package/recipes/tote/models/default.json +1 -0
- package/recipes/tote/recipe.json +82 -0
- package/recipes/tote/spec.json +45 -0
- package/recipes/tote/thumbnail.png +0 -0
- package/recipes/traffic-cones/build.mts +15 -0
- package/recipes/traffic-cones/facts.md +3 -0
- package/recipes/traffic-cones/guide.en.md +18 -0
- package/recipes/traffic-cones/guide.ko.md +18 -0
- package/recipes/traffic-cones/models/default.json +1 -0
- package/recipes/traffic-cones/recipe.json +130 -0
- package/recipes/traffic-cones/spec.json +22 -0
- package/recipes/traffic-cones/thumbnail.png +0 -0
- package/recipes/transfer-belts/build.mts +14 -0
- package/recipes/transfer-belts/facts.md +3 -0
- package/recipes/transfer-belts/guide.en.md +18 -0
- package/recipes/transfer-belts/guide.ko.md +18 -0
- package/recipes/transfer-belts/models/default.json +1 -0
- package/recipes/transfer-belts/recipe.json +174 -0
- package/recipes/transfer-belts/spec.json +45 -0
- package/recipes/transfer-belts/thumbnail.png +0 -0
- package/recipes/tray-stack/build.mts +13 -0
- package/recipes/tray-stack/facts.md +3 -0
- package/recipes/tray-stack/guide.en.md +18 -0
- package/recipes/tray-stack/guide.ko.md +18 -0
- package/recipes/tray-stack/models/default.json +1 -0
- package/recipes/tray-stack/models/trays=3.json +1 -0
- package/recipes/tray-stack/models/trays=4.json +1 -0
- package/recipes/tray-stack/models/trays=5.json +1 -0
- package/recipes/tray-stack/recipe.json +289 -0
- package/recipes/tray-stack/spec.json +20 -0
- package/recipes/tray-stack/thumbnail.png +0 -0
- package/recipes/trough/build.mts +11 -0
- package/recipes/trough/facts.md +3 -0
- package/recipes/trough/guide.en.md +17 -0
- package/recipes/trough/guide.ko.md +17 -0
- package/recipes/trough/models/default.json +1 -0
- package/recipes/trough/recipe.json +75 -0
- package/recipes/trough/spec.json +18 -0
- package/recipes/trough/thumbnail.png +0 -0
- package/recipes/turntable/build.mts +15 -0
- package/recipes/turntable/facts.md +3 -0
- package/recipes/turntable/guide.en.md +18 -0
- package/recipes/turntable/guide.ko.md +18 -0
- package/recipes/turntable/models/default.json +1 -0
- package/recipes/turntable/recipe.json +140 -0
- package/recipes/turntable/spec.json +43 -0
- package/recipes/turntable/thumbnail.png +0 -0
- package/recipes/valve-handle/build.mts +17 -0
- package/recipes/valve-handle/facts.md +3 -0
- package/recipes/valve-handle/guide.en.md +17 -0
- package/recipes/valve-handle/guide.ko.md +17 -0
- package/recipes/valve-handle/models/default.json +1 -0
- package/recipes/valve-handle/recipe.json +149 -0
- package/recipes/valve-handle/spec.json +18 -0
- package/recipes/valve-handle/thumbnail.png +0 -0
- package/recipes/waste-bin/build.mts +10 -0
- package/recipes/waste-bin/facts.md +3 -0
- package/recipes/waste-bin/guide.en.md +17 -0
- package/recipes/waste-bin/guide.ko.md +17 -0
- package/recipes/waste-bin/models/default.json +1 -0
- package/recipes/waste-bin/recipe.json +82 -0
- package/recipes/waste-bin/spec.json +45 -0
- package/recipes/waste-bin/thumbnail.png +0 -0
- package/recipes/work-light/build.mts +18 -0
- package/recipes/work-light/facts.md +3 -0
- package/recipes/work-light/guide.en.md +17 -0
- package/recipes/work-light/guide.ko.md +17 -0
- package/recipes/work-light/models/default.json +1 -0
- package/recipes/work-light/recipe.json +162 -0
- package/recipes/work-light/spec.json +18 -0
- package/recipes/work-light/thumbnail.png +0 -0
- package/recipes/workbench-top/build.mts +12 -0
- package/recipes/workbench-top/facts.md +3 -0
- package/recipes/workbench-top/guide.en.md +18 -0
- package/recipes/workbench-top/guide.ko.md +18 -0
- package/recipes/workbench-top/models/default.json +1 -0
- package/recipes/workbench-top/recipe.json +99 -0
- package/recipes/workbench-top/spec.json +45 -0
- package/recipes/workbench-top/thumbnail.png +0 -0
- package/scripts/build-templates.mts +64 -0
- package/scripts/templates.test.mts +89 -0
- package/server/index.ts +6 -10
- package/server/routers/figure-thumbnail-router.ts +24 -0
- package/server/service/figure-recipe/figure-recipe-resolver.ts +28 -32
- package/server/service/figure-recipe/figure-recipe-templates.test.ts +47 -0
- package/server/service/figure-recipe/figure-recipe-templates.ts +70 -0
- package/server/service/figure-recipe/figure-recipe-type.ts +31 -0
- package/server/service/figure-recipe/index.ts +2 -4
- package/server/service/index.ts +4 -4
- package/dist-server/service/figure-recipe/figure-recipe-store.d.ts +0 -41
- package/dist-server/service/figure-recipe/figure-recipe-store.js +0 -105
- package/dist-server/service/figure-recipe/figure-recipe-store.js.map +0 -1
- package/dist-server/service/figure-recipe/figure-recipe.d.ts +0 -19
- package/dist-server/service/figure-recipe/figure-recipe.js +0 -67
- package/dist-server/service/figure-recipe/figure-recipe.js.map +0 -1
- package/server/service/figure-recipe/figure-recipe-db.test.ts +0 -123
- package/server/service/figure-recipe/figure-recipe-store.ts +0 -101
- package/server/service/figure-recipe/figure-recipe.ts +0 -51
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FigureRecipe = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const typeorm_1 = require("typeorm");
|
|
6
|
-
const type_graphql_1 = require("type-graphql");
|
|
7
|
-
const shell_1 = require("@things-factory/shell");
|
|
8
|
-
/**
|
|
9
|
-
* FigureRecipe — 조각 하나(ADR-0095).
|
|
10
|
-
*
|
|
11
|
-
* 조각은 매개변수가 붙은 제안 명령 목록이다. 형식은 `@hatiolab/figure-model` 의 `V3Recipe` 가 정하고, 여기에는
|
|
12
|
-
* 그 원본을 통째로 담는다 — Figure 가 자산을 `source` 로 담는 것과 같다. 매개변수 · 명령을 컬럼으로 두지 않는다.
|
|
13
|
-
* 넣은 뒤의 부품은 조각과 이어지지 않으므로, 이 행을 고치거나 지워도 도형은 바뀌지 않는다.
|
|
14
|
-
*/
|
|
15
|
-
let FigureRecipe = class FigureRecipe {
|
|
16
|
-
};
|
|
17
|
-
exports.FigureRecipe = FigureRecipe;
|
|
18
|
-
tslib_1.__decorate([
|
|
19
|
-
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
20
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.ID, { nullable: true, description: 'Unique identifier for the recipe.' }),
|
|
21
|
-
tslib_1.__metadata("design:type", String)
|
|
22
|
-
], FigureRecipe.prototype, "id", void 0);
|
|
23
|
-
tslib_1.__decorate([
|
|
24
|
-
(0, typeorm_1.ManyToOne)(type => shell_1.Domain),
|
|
25
|
-
(0, type_graphql_1.Field)(type => shell_1.Domain, { nullable: true, description: 'The domain this recipe belongs to.' }),
|
|
26
|
-
tslib_1.__metadata("design:type", shell_1.Domain)
|
|
27
|
-
], FigureRecipe.prototype, "domain", void 0);
|
|
28
|
-
tslib_1.__decorate([
|
|
29
|
-
(0, typeorm_1.RelationId)((recipe) => recipe.domain),
|
|
30
|
-
tslib_1.__metadata("design:type", String)
|
|
31
|
-
], FigureRecipe.prototype, "domainId", void 0);
|
|
32
|
-
tslib_1.__decorate([
|
|
33
|
-
(0, typeorm_1.Column)(),
|
|
34
|
-
(0, type_graphql_1.Field)({ description: 'The recipe name, unique per domain: lower case, digits and hyphens.' }),
|
|
35
|
-
tslib_1.__metadata("design:type", String)
|
|
36
|
-
], FigureRecipe.prototype, "name", void 0);
|
|
37
|
-
tslib_1.__decorate([
|
|
38
|
-
(0, typeorm_1.Column)({ nullable: true, ...(0, shell_1.longTextColumn)() }),
|
|
39
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'The recipe JSON (figure-model V3Recipe).' }),
|
|
40
|
-
tslib_1.__metadata("design:type", String)
|
|
41
|
-
], FigureRecipe.prototype, "source", void 0);
|
|
42
|
-
tslib_1.__decorate([
|
|
43
|
-
(0, typeorm_1.Column)({ nullable: true, default: 'released' }),
|
|
44
|
-
(0, type_graphql_1.Field)({ nullable: true, description: "'draft' or 'released'. Only released recipes are offered in the modeller." }),
|
|
45
|
-
tslib_1.__metadata("design:type", String)
|
|
46
|
-
], FigureRecipe.prototype, "state", void 0);
|
|
47
|
-
tslib_1.__decorate([
|
|
48
|
-
(0, typeorm_1.CreateDateColumn)(),
|
|
49
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'When the recipe was created.' }),
|
|
50
|
-
tslib_1.__metadata("design:type", Date)
|
|
51
|
-
], FigureRecipe.prototype, "createdAt", void 0);
|
|
52
|
-
tslib_1.__decorate([
|
|
53
|
-
(0, typeorm_1.UpdateDateColumn)(),
|
|
54
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'When the recipe was last changed.' }),
|
|
55
|
-
tslib_1.__metadata("design:type", Date)
|
|
56
|
-
], FigureRecipe.prototype, "updatedAt", void 0);
|
|
57
|
-
tslib_1.__decorate([
|
|
58
|
-
(0, typeorm_1.DeleteDateColumn)(),
|
|
59
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'When the recipe was deleted.' }),
|
|
60
|
-
tslib_1.__metadata("design:type", Date)
|
|
61
|
-
], FigureRecipe.prototype, "deletedAt", void 0);
|
|
62
|
-
exports.FigureRecipe = FigureRecipe = tslib_1.__decorate([
|
|
63
|
-
(0, typeorm_1.Entity)(),
|
|
64
|
-
(0, typeorm_1.Index)('ix_figure_recipe_1', (recipe) => [recipe.domain, recipe.name], { unique: true, where: '"deleted_at" IS NULL' }),
|
|
65
|
-
(0, type_graphql_1.ObjectType)({ description: 'A recipe: a list of figure authoring commands with parameters (ADR-0095).' })
|
|
66
|
-
], FigureRecipe);
|
|
67
|
-
//# sourceMappingURL=figure-recipe.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"figure-recipe.js","sourceRoot":"","sources":["../../../server/service/figure-recipe/figure-recipe.ts"],"names":[],"mappings":";;;;AAAA,qCAAoJ;AACpJ,+CAAoD;AAEpD,iDAA8D;AAE9D;;;;;;GAMG;AAII,IAAM,YAAY,GAAlB,MAAM,YAAY;CAmCxB,CAAA;AAnCY,oCAAY;AAGd;IAFR,IAAA,gCAAsB,EAAC,MAAM,CAAC;IAC9B,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,iBAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;;wCACpE;AAIpB;IAFC,IAAA,mBAAS,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,CAAC;IACzB,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,cAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,oCAAoC,EAAE,CAAC;sCACpF,cAAM;4CAAA;AAGf;IADC,IAAA,oBAAU,EAAC,CAAC,MAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;;8CACnC;AAIjB;IAFC,IAAA,gBAAM,GAAE;IACR,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,qEAAqE,EAAE,CAAC;;0CACjF;AAIb;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAA,sBAAc,GAAE,EAAE,CAAC;IAC/C,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,0CAA0C,EAAE,CAAC;;4CACpE;AAIf;IAFC,IAAA,gBAAM,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAC/C,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2EAA2E,EAAE,CAAC;;2CACxF;AAI5B;IAFC,IAAA,0BAAgB,GAAE;IAClB,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8BAA8B,EAAE,CAAC;sCAC3D,IAAI;+CAAA;AAIhB;IAFC,IAAA,0BAAgB,GAAE;IAClB,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;sCAChE,IAAI;+CAAA;AAIhB;IAFC,IAAA,0BAAgB,GAAE;IAClB,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8BAA8B,EAAE,CAAC;sCAC3D,IAAI;+CAAA;uBAlCL,YAAY;IAHxB,IAAA,gBAAM,GAAE;IACR,IAAA,eAAK,EAAC,oBAAoB,EAAE,CAAC,MAAoB,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IACpI,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,2EAA2E,EAAE,CAAC;GAC5F,YAAY,CAmCxB","sourcesContent":["import { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\nimport { Field, ID, ObjectType } from 'type-graphql'\n\nimport { Domain, longTextColumn } from '@things-factory/shell'\n\n/**\n * FigureRecipe — 조각 하나(ADR-0095).\n *\n * 조각은 매개변수가 붙은 제안 명령 목록이다. 형식은 `@hatiolab/figure-model` 의 `V3Recipe` 가 정하고, 여기에는\n * 그 원본을 통째로 담는다 — Figure 가 자산을 `source` 로 담는 것과 같다. 매개변수 · 명령을 컬럼으로 두지 않는다.\n * 넣은 뒤의 부품은 조각과 이어지지 않으므로, 이 행을 고치거나 지워도 도형은 바뀌지 않는다.\n */\n@Entity()\n@Index('ix_figure_recipe_1', (recipe: FigureRecipe) => [recipe.domain, recipe.name], { unique: true, where: '\"deleted_at\" IS NULL' })\n@ObjectType({ description: 'A recipe: a list of figure authoring commands with parameters (ADR-0095).' })\nexport class FigureRecipe {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { nullable: true, description: 'Unique identifier for the recipe.' })\n readonly id?: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain this recipe belongs to.' })\n domain?: Domain\n\n @RelationId((recipe: FigureRecipe) => recipe.domain)\n domainId?: string\n\n @Column()\n @Field({ description: 'The recipe name, unique per domain: lower case, digits and hyphens.' })\n name?: string\n\n @Column({ nullable: true, ...longTextColumn() })\n @Field({ nullable: true, description: 'The recipe JSON (figure-model V3Recipe).' })\n source?: string\n\n @Column({ nullable: true, default: 'released' })\n @Field({ nullable: true, description: \"'draft' or 'released'. Only released recipes are offered in the modeller.\" })\n state?: 'draft' | 'released'\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'When the recipe was created.' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'When the recipe was last changed.' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'When the recipe was deleted.' })\n deletedAt?: Date\n}\n"]}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 조각 — 시드 · 도메인 규칙 · 저장 검사를 **sqlite 를 실제로 들고** 확인한다(ADR-0095 조건 2 · 3).
|
|
3
|
-
*
|
|
4
|
-
* 규칙이 질의에 있으므로 DB 없이 시험하면 초록이어도 뜻이 없다. figure-rename-db 와 같이 tsc 산출물을 든다.
|
|
5
|
-
*/
|
|
6
|
-
import type { DataSource } from 'typeorm'
|
|
7
|
-
|
|
8
|
-
const { DataSource: TypeOrmDataSource } = require('typeorm')
|
|
9
|
-
const shell = require('@things-factory/shell')
|
|
10
|
-
const authBase = require('@things-factory/auth-base')
|
|
11
|
-
|
|
12
|
-
let dataSource: DataSource | null = null
|
|
13
|
-
let FigureRecipe: any
|
|
14
|
-
let store: any
|
|
15
|
-
|
|
16
|
-
function loadCompiled(modulePath: string): any {
|
|
17
|
-
const { existsSync } = require('fs')
|
|
18
|
-
const { join } = require('path')
|
|
19
|
-
const resolved = join(__dirname, '..', '..', '..', 'dist-server', `${modulePath}.js`)
|
|
20
|
-
if (!existsSync(resolved)) throw new Error(`figure-service 산출물이 없다: ${resolved} — 먼저 빌드할 것: yarn workspace @things-factory/figure-service build:server`)
|
|
21
|
-
return require(resolved)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
beforeAll(async () => {
|
|
25
|
-
FigureRecipe = loadCompiled('service/figure-recipe/figure-recipe').FigureRecipe
|
|
26
|
-
store = loadCompiled('service/figure-recipe/figure-recipe-store')
|
|
27
|
-
dataSource = new TypeOrmDataSource({
|
|
28
|
-
type: 'sqlite',
|
|
29
|
-
database: ':memory:',
|
|
30
|
-
synchronize: true,
|
|
31
|
-
dropSchema: true,
|
|
32
|
-
namingStrategy: new shell.NamingStrategy(),
|
|
33
|
-
entities: [...shell.entities, ...authBase.entities, FigureRecipe],
|
|
34
|
-
logging: false
|
|
35
|
-
})
|
|
36
|
-
await dataSource.initialize()
|
|
37
|
-
shell.addDataSource('default', dataSource)
|
|
38
|
-
shell.addDataSource('tx', dataSource)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
afterAll(async () => {
|
|
42
|
-
if (!dataSource) return
|
|
43
|
-
shell.removeDataSource('default')
|
|
44
|
-
shell.removeDataSource('tx')
|
|
45
|
-
await dataSource.destroy()
|
|
46
|
-
dataSource = null
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
let SYSTEM: any
|
|
50
|
-
let CHILD: any
|
|
51
|
-
|
|
52
|
-
beforeEach(async () => {
|
|
53
|
-
await dataSource!.synchronize(true)
|
|
54
|
-
const domains = dataSource!.getRepository(shell.Domain)
|
|
55
|
-
SYSTEM = await domains.save({ name: 'SYSTEM', subdomain: 'system', systemFlag: true })
|
|
56
|
-
CHILD = await domains.save({ name: 'plant', subdomain: 'plant', parentId: SYSTEM.id })
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
const rows = async () => (await dataSource!.getRepository(FigureRecipe).find({ relations: ['domain'], order: { name: 'ASC' } })).map((r: any) => [r.domain.subdomain, r.name])
|
|
60
|
-
|
|
61
|
-
describe('조각 — 시드', () => {
|
|
62
|
-
it('★ figure-model 이 싣는 조각 셋이 system 에 들어가고, 다시 실어도 같다 — 있으면 건너뛰고 덮지 않는다', async () => {
|
|
63
|
-
const first = await store.seedBuiltInRecipes()
|
|
64
|
-
expect(first.added).toEqual(['hinged-door', 'roller-row', 'sliding-door'])
|
|
65
|
-
expect(first.refused).toEqual([])
|
|
66
|
-
const repo = dataSource!.getRepository(FigureRecipe)
|
|
67
|
-
const door = await repo.findOne({ where: { name: 'sliding-door' } })
|
|
68
|
-
await repo.save({ ...door, state: 'draft' })
|
|
69
|
-
|
|
70
|
-
const again = await store.seedBuiltInRecipes()
|
|
71
|
-
expect(again.added).toEqual([])
|
|
72
|
-
expect(again.skipped).toEqual(['hinged-door', 'roller-row', 'sliding-door'])
|
|
73
|
-
expect(await rows()).toEqual([['system', 'hinged-door'], ['system', 'roller-row'], ['system', 'sliding-door']])
|
|
74
|
-
expect((await repo.findOne({ where: { name: 'sliding-door' } })).state).toBe('draft')
|
|
75
|
-
})
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
describe('조각 — 읽기는 도형과 같은 도메인 규칙', () => {
|
|
79
|
-
it('★ 자식 도메인은 부모의 조각을 보고, 같은 이름의 제 조각이 그것을 대신한다; 초안은 모두를 물을 때만', async () => {
|
|
80
|
-
await store.seedBuiltInRecipes()
|
|
81
|
-
const door = JSON.parse(store.builtInRecipes().find((r: any) => r.name === 'sliding-door').source)
|
|
82
|
-
door.title = { ko: '우리 공장 미닫이 문' }
|
|
83
|
-
await store.saveRecipe(CHILD, JSON.stringify(door))
|
|
84
|
-
const seen = await store.recipesFor({ id: CHILD.id, parentId: SYSTEM.id }, 'released')
|
|
85
|
-
expect(seen.map((r: any) => r.name)).toEqual(['hinged-door', 'roller-row', 'sliding-door'])
|
|
86
|
-
expect(JSON.parse(seen.find((r: any) => r.name === 'sliding-door').source).title.ko).toBe('우리 공장 미닫이 문')
|
|
87
|
-
|
|
88
|
-
const hinged = JSON.parse(store.builtInRecipes().find((r: any) => r.name === 'hinged-door').source)
|
|
89
|
-
await store.saveRecipe(CHILD, JSON.stringify({ ...hinged, name: 'shop-door' }), 'draft')
|
|
90
|
-
expect((await store.recipesFor({ id: CHILD.id, parentId: SYSTEM.id }, 'released')).map((r: any) => r.name)).not.toContain('shop-door')
|
|
91
|
-
expect((await store.recipesFor({ id: CHILD.id, parentId: SYSTEM.id })).map((r: any) => r.name)).toContain('shop-door')
|
|
92
|
-
expect((await store.recipesFor({ id: SYSTEM.id })).map((r: any) => r.name)).not.toContain('shop-door')
|
|
93
|
-
})
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
describe('조각 — 저장은 빈 방에 넣어 본 뒤에', () => {
|
|
97
|
-
it('★ 기본값으로 넣을 수 없는 조각은 커널의 말 그대로 거절되고 저장되지 않는다', async () => {
|
|
98
|
-
const door = JSON.parse(store.builtInRecipes().find((r: any) => r.name === 'sliding-door').source)
|
|
99
|
-
door.steps[2].source.part = 'nowhere'
|
|
100
|
-
await expect(store.saveRecipe(CHILD, JSON.stringify(door))).rejects.toThrow(/steps\[2\]/)
|
|
101
|
-
expect(await rows()).toEqual([])
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
describe('조각 — 제 도메인 것만 바꾼다', () => {
|
|
106
|
-
it('★ 자식은 부모의 조각을 발행 · 삭제하지 못한다; 제 것은 초안으로 돌리면 모델러 목록에서 빠지고, 지우면 부모 것이 다시 보인다', async () => {
|
|
107
|
-
await store.seedBuiltInRecipes()
|
|
108
|
-
const child = { id: CHILD.id, parentId: SYSTEM.id }
|
|
109
|
-
await expect(store.deleteRecipe(child, 'sliding-door')).rejects.toThrow(/copied here to be changed/)
|
|
110
|
-
await expect(store.setRecipeState(child, 'sliding-door', 'draft')).rejects.toThrow(/copied here/)
|
|
111
|
-
|
|
112
|
-
const door = JSON.parse(store.builtInRecipes().find((r: any) => r.name === 'sliding-door').source)
|
|
113
|
-
door.title = { ko: '우리 문' }
|
|
114
|
-
await store.saveRecipe(CHILD, JSON.stringify(door))
|
|
115
|
-
await store.setRecipeState(child, 'sliding-door', 'draft')
|
|
116
|
-
const released = await store.recipesFor(child, 'released')
|
|
117
|
-
expect(JSON.parse(released.find((r: any) => r.name === 'sliding-door').source).title.ko).not.toBe('우리 문')
|
|
118
|
-
|
|
119
|
-
await store.deleteRecipe(child, 'sliding-door')
|
|
120
|
-
const all = await store.recipesFor(child)
|
|
121
|
-
expect(all.find((r: any) => r.name === 'sliding-door').domainId).toBe(SYSTEM.id)
|
|
122
|
-
})
|
|
123
|
-
})
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { readdirSync, readFileSync } from 'fs'
|
|
2
|
-
import { dirname, join } from 'path'
|
|
3
|
-
import { In } from 'typeorm'
|
|
4
|
-
|
|
5
|
-
import { checkV3Recipe } from '@hatiolab/figure-model'
|
|
6
|
-
import { Domain, getRepository } from '@things-factory/shell'
|
|
7
|
-
|
|
8
|
-
import { FigureRecipe } from './figure-recipe.js'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* The recipes a domain sees (ADR-0095 condition 2): its own and its parent's, as figures are read. A recipe of the
|
|
12
|
-
* domain's own stands in for the parent's of the same name.
|
|
13
|
-
*/
|
|
14
|
-
export async function recipesFor(domain: { id: string; parentId?: string | null }, state?: 'released'): Promise<FigureRecipe[]> {
|
|
15
|
-
const ids = [domain.id, domain.parentId].filter(Boolean) as string[]
|
|
16
|
-
const rows = await getRepository(FigureRecipe).find({
|
|
17
|
-
where: { domain: { id: In(ids) }, ...(state ? { state } : {}) },
|
|
18
|
-
relations: ['domain'],
|
|
19
|
-
order: { name: 'ASC' }
|
|
20
|
-
})
|
|
21
|
-
const byName = new Map<string, FigureRecipe>()
|
|
22
|
-
for (const row of rows) {
|
|
23
|
-
const mine = row.domainId === domain.id || (row.domain as Domain | undefined)?.id === domain.id
|
|
24
|
-
if (mine || !byName.has(row.name!)) byName.set(row.name!, row)
|
|
25
|
-
}
|
|
26
|
-
return [...byName.values()]
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* A recipe saved into a domain, by its name: checked first by putting it into the test room with its defaults
|
|
31
|
-
* (figure-model `checkV3Recipe`). Refused, it is not saved and the kernel's sentence goes back as it is.
|
|
32
|
-
*/
|
|
33
|
-
export async function saveRecipe(domain: Domain, source: unknown, state: 'draft' | 'released' = 'released'): Promise<FigureRecipe> {
|
|
34
|
-
const recipe = checkV3Recipe(typeof source === 'string' ? JSON.parse(source) : source)
|
|
35
|
-
const repository = getRepository(FigureRecipe)
|
|
36
|
-
const existing = await repository.findOne({ where: { domain: { id: domain.id }, name: recipe.name } })
|
|
37
|
-
return await repository.save({ ...(existing ?? {}), domain, name: recipe.name, source: JSON.stringify(recipe), state })
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* A recipe of the domain's own, by name. A parent's recipe is not the domain's to change: it is copied in under the same
|
|
42
|
-
* name (`saveRecipe`), and the copy stands in for it.
|
|
43
|
-
*/
|
|
44
|
-
async function ownRecipe(domain: { id: string }, name: string): Promise<FigureRecipe> {
|
|
45
|
-
const row = await getRepository(FigureRecipe).findOne({ where: { domain: { id: domain.id }, name } })
|
|
46
|
-
if (!row) throw new Error(`${name} is not a recipe of this domain; a parent's recipe is copied here to be changed`)
|
|
47
|
-
return row
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** Released or back to draft: only released recipes are offered in the modeller. */
|
|
51
|
-
export async function setRecipeState(domain: { id: string }, name: string, state: 'draft' | 'released'): Promise<FigureRecipe> {
|
|
52
|
-
const row = await ownRecipe(domain, name)
|
|
53
|
-
return await getRepository(FigureRecipe).save({ ...row, state })
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* A recipe of the domain's own taken away. Figures it was put into keep their parts -- nothing ties them to it
|
|
58
|
-
* (ADR-0095). Where the parent has one by that name, the parent's is seen again.
|
|
59
|
-
*/
|
|
60
|
-
export async function deleteRecipe(domain: { id: string }, name: string): Promise<boolean> {
|
|
61
|
-
const row = await ownRecipe(domain, name)
|
|
62
|
-
await getRepository(FigureRecipe).softRemove(row)
|
|
63
|
-
return true
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/** The recipes figure-model ships (`recipes/*.json`), as they are. */
|
|
67
|
-
export function builtInRecipes(): Array<{ name: string; source: string }> {
|
|
68
|
-
const dir = join(dirname(require.resolve('@hatiolab/figure-model/package.json')), 'recipes')
|
|
69
|
-
return readdirSync(dir)
|
|
70
|
-
.filter(file => file.endsWith('.json'))
|
|
71
|
-
.sort()
|
|
72
|
-
.map(file => {
|
|
73
|
-
const source = readFileSync(join(dir, file), 'utf-8')
|
|
74
|
-
return { name: JSON.parse(source).name, source }
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* The built-in recipes put into the system domain (ADR-0095 condition 2): once, and again gives the same result -- a
|
|
80
|
-
* recipe already there by name is skipped, not overwritten, so a system recipe someone changed stays as they left it.
|
|
81
|
-
* Each is checked as a saved one is; one that fails is left out and said, not half put in.
|
|
82
|
-
*/
|
|
83
|
-
export async function seedBuiltInRecipes(): Promise<{ added: string[]; skipped: string[]; refused: string[] }> {
|
|
84
|
-
const system = await getRepository(Domain).findOne({ where: { systemFlag: true } })
|
|
85
|
-
const result = { added: [] as string[], skipped: [] as string[], refused: [] as string[] }
|
|
86
|
-
if (!system) return result
|
|
87
|
-
const repository = getRepository(FigureRecipe)
|
|
88
|
-
for (const { name, source } of builtInRecipes()) {
|
|
89
|
-
if (await repository.count({ where: { domain: { id: system.id }, name } })) {
|
|
90
|
-
result.skipped.push(name)
|
|
91
|
-
continue
|
|
92
|
-
}
|
|
93
|
-
try {
|
|
94
|
-
await saveRecipe(system, source)
|
|
95
|
-
result.added.push(name)
|
|
96
|
-
} catch (error) {
|
|
97
|
-
result.refused.push(`${name}: ${error instanceof Error ? error.message : String(error)}`)
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return result
|
|
101
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'
|
|
2
|
-
import { Field, ID, ObjectType } from 'type-graphql'
|
|
3
|
-
|
|
4
|
-
import { Domain, longTextColumn } from '@things-factory/shell'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* FigureRecipe — 조각 하나(ADR-0095).
|
|
8
|
-
*
|
|
9
|
-
* 조각은 매개변수가 붙은 제안 명령 목록이다. 형식은 `@hatiolab/figure-model` 의 `V3Recipe` 가 정하고, 여기에는
|
|
10
|
-
* 그 원본을 통째로 담는다 — Figure 가 자산을 `source` 로 담는 것과 같다. 매개변수 · 명령을 컬럼으로 두지 않는다.
|
|
11
|
-
* 넣은 뒤의 부품은 조각과 이어지지 않으므로, 이 행을 고치거나 지워도 도형은 바뀌지 않는다.
|
|
12
|
-
*/
|
|
13
|
-
@Entity()
|
|
14
|
-
@Index('ix_figure_recipe_1', (recipe: FigureRecipe) => [recipe.domain, recipe.name], { unique: true, where: '"deleted_at" IS NULL' })
|
|
15
|
-
@ObjectType({ description: 'A recipe: a list of figure authoring commands with parameters (ADR-0095).' })
|
|
16
|
-
export class FigureRecipe {
|
|
17
|
-
@PrimaryGeneratedColumn('uuid')
|
|
18
|
-
@Field(type => ID, { nullable: true, description: 'Unique identifier for the recipe.' })
|
|
19
|
-
readonly id?: string
|
|
20
|
-
|
|
21
|
-
@ManyToOne(type => Domain)
|
|
22
|
-
@Field(type => Domain, { nullable: true, description: 'The domain this recipe belongs to.' })
|
|
23
|
-
domain?: Domain
|
|
24
|
-
|
|
25
|
-
@RelationId((recipe: FigureRecipe) => recipe.domain)
|
|
26
|
-
domainId?: string
|
|
27
|
-
|
|
28
|
-
@Column()
|
|
29
|
-
@Field({ description: 'The recipe name, unique per domain: lower case, digits and hyphens.' })
|
|
30
|
-
name?: string
|
|
31
|
-
|
|
32
|
-
@Column({ nullable: true, ...longTextColumn() })
|
|
33
|
-
@Field({ nullable: true, description: 'The recipe JSON (figure-model V3Recipe).' })
|
|
34
|
-
source?: string
|
|
35
|
-
|
|
36
|
-
@Column({ nullable: true, default: 'released' })
|
|
37
|
-
@Field({ nullable: true, description: "'draft' or 'released'. Only released recipes are offered in the modeller." })
|
|
38
|
-
state?: 'draft' | 'released'
|
|
39
|
-
|
|
40
|
-
@CreateDateColumn()
|
|
41
|
-
@Field({ nullable: true, description: 'When the recipe was created.' })
|
|
42
|
-
createdAt?: Date
|
|
43
|
-
|
|
44
|
-
@UpdateDateColumn()
|
|
45
|
-
@Field({ nullable: true, description: 'When the recipe was last changed.' })
|
|
46
|
-
updatedAt?: Date
|
|
47
|
-
|
|
48
|
-
@DeleteDateColumn()
|
|
49
|
-
@Field({ nullable: true, description: 'When the recipe was deleted.' })
|
|
50
|
-
deletedAt?: Date
|
|
51
|
-
}
|