Skip to main content
Glama
small.rs26.6 kB
use dal::{ BuiltinsResult, ComponentType, DalContext, PropKind, SchemaId, action::prototype::ActionKind, pkg::{ ImportOptions, import_pkg_from_pkg, }, }; use si_pkg::{ ActionFuncSpec, ManagementFuncSpec, PkgSpec, PropSpec, SchemaSpec, SchemaSpecData, SchemaVariantSpec, SchemaVariantSpecData, SiPkg, SocketSpec, SocketSpecArity, SocketSpecData, SocketSpecKind, }; use crate::test_exclusive_schemas::{ PKG_CREATED_BY, PKG_VERSION, build_action_func, build_asset_func, build_management_func, create_identity_func, legos::bricks::LegoBricks, }; /// The "small odd lego" has a special importance for our tests. It is a /// repository of example management functions used for management function /// integration tests pub(crate) async fn migrate_test_exclusive_schema_small_odd_lego( ctx: &DalContext, schema_id: SchemaId, ) -> BuiltinsResult<()> { let mut small_lego_builder = PkgSpec::builder(); let schema_name = "small odd lego"; small_lego_builder .name(schema_name) .version(PKG_VERSION) .created_by(PKG_CREATED_BY); let identity_func_spec = create_identity_func()?; // Build Create Action Func let create_action_code = "async function main() { return { payload: { \"poop\": true }, status: \"ok\" }; }"; let fn_name = "test:createActionSmallLego"; let create_action_func = build_action_func(create_action_code, fn_name)?; // Build Refresh Action Func let refresh_action_code = "async function main(component: Input): Promise<Output> { return { payload: JSON.parse(component.properties.resource?.payload) || { \"poop\": true } , status: \"ok\" }; }"; let fn_name = "test:refreshActionSmallLego"; let refresh_action_func = build_action_func(refresh_action_code, fn_name)?; // Build Update Action Func let update_action_code = "async function main(component: Input): Promise<Output> { return { payload: { \"poonami\": true }, status: \"ok\" }; }"; let fn_name = "test:updateActionSmallLego"; let update_action_func = build_action_func(update_action_code, fn_name)?; // Build Delete Action Func let delete_action_code = "async function main() { return { payload: null, status: \"ok\" }; }"; let import_management_func_code = "async function main({ thisComponent }: Input): Promise<Output> { const thisProperties = thisComponent.properties; return { status: 'ok', ops: { update: { self: { properties: { domain: { ...thisProperties.domain, two: 'step', }, ...thisProperties } } } }, message: 'hello' } }"; let import_management_func_name = "test:importManagementSmallLego"; let import_management_func = build_management_func(import_management_func_code, import_management_func_name)?; let simple_create_mgmt_func_code = r#" async function main({ thisComponent, components }: Input): Promise<Output> { const thisName = thisComponent.properties?.si?.name ?? "unknown"; let create = { [`${thisName}_clone`]: { properties: { ...thisComponent.properties, }, geometry: { x: 10, y: 20, } } }; for (let [id, component] of Object.entries(components)) { const name = component.properties?.si?.name ?? "unknown"; let clone_name = `${name}_clone`; if (clone_name in create) { clone_name = `${clone_name}-${id}`; } create[clone_name] = { ...component, }; } return { status: "ok", ops: { create } } } "#; let clone_me_mgmt_func_name = "test:cloneMeSmallLego"; let clone_me_mgmt_func = build_management_func(simple_create_mgmt_func_code, clone_me_mgmt_func_name)?; let update_managed_func_code = r#" async function main({ thisComponent, components }: Input): Promise<Output> { const thisName = thisComponent.properties?.si?.name ?? "unknown"; const update: { [key: string]: unknown } = {}; for (let [id, component] of Object.entries(components)) { let name = component.properties?.si?.name ?? "unknown"; update[id] = { properties: { ...component.properties, si: { ...component.properties?.si, name: `${name} managed by ${thisName}`, } }, }; } return { status: "ok", ops: { update } } } "#; let update_mgmt_func_name = "test:updateManagedComponent"; let update_mgmt_func = build_management_func(update_managed_func_code, update_mgmt_func_name)?; let update_managed_func_in_view_code = r#" async function main({ thisComponent, components, currentView }: Input): Promise<Output> { const thisName = thisComponent.properties?.si?.name ?? "unknown"; const update: { [key: string]: unknown } = {}; for (let [id, component] of Object.entries(components)) { let name = component.properties?.si?.name ?? "unknown"; update[id] = { properties: { ...component.properties, si: { ...component.properties?.si, name: `${name} managed by ${thisName}`, } }, geometry: { [currentView]: { x: 1000, y: 750, } } }; } return { status: "ok", message: currentView, ops: { update }, } } "#; let update_in_view_mgmt_func_name = "test:updateManagedComponentInView"; let update_in_view_mgmt_func = build_management_func( update_managed_func_in_view_code, update_in_view_mgmt_func_name, )?; // This will grab the manager component's input socket values and put them in test_result. let get_input_values_func = build_management_func( r#" async function main({ thisComponent, components }: Input): Promise<Output> { return { status: "ok", ops: { update: { self: { properties: { domain: { test_result: { arity_one: thisComponent.incomingConnections.arity_one?.value, one: thisComponent.incomingConnections.one.map((c) => c.value).sort(), } } } } } } }; } "#, "test:getInputValues", )?; let deeply_nested_children_code = r#" async function main({ thisComponent, components }: Input): Promise<Output> { const thisName = thisComponent.properties?.si?.name ?? "unknown"; const count = 10; let create: { [key: string]: unknown } = {}; let prevName = "self"; for (let i = 0; i < count; i++) { let name = `clone_${i}`; create[name] = { kind: "small odd lego", properties: { si: { name, type: "configurationFrameDown" }, }, parent: prevName, }; prevName = name; } return { status: "ok", ops: { update: { self: { properties: { si: { type: "configurationFrameDown" } } } }, create, } } } "#; let deeply_nested_children = build_management_func(deeply_nested_children_code, "test:deeplyNestedChildren")?; let create_component_in_other_views_code = r#" async function main({ thisComponent, currentView }: Input): Promise<Output> { const thisView = thisComponent.properties?.si?.resourceId ?? currentView; const name = `component in ${thisView}`; return { status: "ok", ops: { create: { [name]: { geometry: { [currentView]: { x: 100, y: 100 }, [thisView]: { x: 15, y: 15 } } } } } } } "#; let create_component_in_other_views = build_management_func( create_component_in_other_views_code, "test:createComponentsInOtherViews", )?; let create_view_and_component_in_view_code = r#" async function main({ thisComponent, currentView }: Input): Promise<Output> { const thisView = thisComponent.properties?.si?.resourceId ?? currentView; const componentName = `component in ${thisView}`; return { status: "ok", ops: { views: { create: [thisView], }, create: { [componentName]: { geometry: { [thisView]: { x: 315, y: 315 } } } } } } } "#; let create_view_and_component_in_view = build_management_func( create_view_and_component_in_view_code, "test:createViewAndComponentInView", )?; let delete_and_erase_components_code = r#" async function main({ thisComponent, currentView }: Input): Promise<Output> { const components = thisComponent.properties?.si?.resourceId?.split(","); console.log(components); const deleteComponent = components[0]; const deleteComponentWithResource = components[1]; const deleteComponentStillOnHead = components[2]; const eraseComponent = components[3]; return { status: "ok", ops: { delete: [ deleteComponent, deleteComponentWithResource, deleteComponentStillOnHead ], erase: [eraseComponent], } }; } "#; let delete_and_erase_components = build_management_func( delete_and_erase_components_code, "test:deleteAndEraseComponents", )?; let remove_all_components_from_a_view_and_the_view_code = r#" async function main({ thisComponent, components, currentView }: Input): Promise<Output> { const viewName = thisComponent.properties?.si?.resourceId ?? currentView; return { status: "ok", ops: { views: { remove: [viewName] }, remove: { [viewName]: Object.values(components).map((component) => component.properties.si.name), } } }; } "#; let remove_all_components_from_a_view_and_the_view = build_management_func( remove_all_components_from_a_view_and_the_view_code, "test:removeAllCompsFromViewAndRemoveView", )?; let override_values_set_by_sockets_code = r#" async function main({ thisComponent, components }: Input): Promise<Output> { const thisName = thisComponent.properties?.si?.name ?? "unknown"; const componentName = `bluey`; return { status: "ok", ops: { update: { self: { properties: { si: { type: "configurationFrameDown" } } } }, create: { [componentName]: { kind: "small odd lego", properties: { si: { name }, domain: { one: `bingo` } }, parent: "self" } } } } } "#; let override_values_set_by_sockets = build_management_func( override_values_set_by_sockets_code, "test:overrideValuesSetBySocket", )?; let fn_name = "test:deleteActionSmallLego"; let delete_action_func = build_action_func(delete_action_code, fn_name)?; // Create Scaffold Func let fn_name = "test:scaffoldSmallLegoAsset"; let small_lego_authoring_schema_func = build_asset_func(fn_name)?; let bricks = LegoBricks::new_for_odd()?; let small_lego_schema = SchemaSpec::builder() .name(schema_name) .data( SchemaSpecData::builder() .name(schema_name) .category("test exclusive") .category_name(schema_name) .build()?, ) .variant( SchemaVariantSpec::builder() .version("v0") .unique_id("small_lego_sv") .data( SchemaVariantSpecData::builder() .version("v0") .color("#ffffff") .func_unique_id(&small_lego_authoring_schema_func.unique_id) .component_type(ComponentType::ConfigurationFrameUp) .build()?, ) .domain_prop(bricks.domain_name_prop) .domain_prop(bricks.domain_one_prop) .domain_prop(bricks.domain_two_prop) .domain_prop( PropSpec::builder() .name("test_result") .kind(PropKind::Json) .build()?, ) // Input socket "one" .socket(bricks.socket_one) // Output socket "two" .socket(bricks.socket_two) .socket( SocketSpec::builder() .name("arity_one") .data( SocketSpecData::builder() .name("arity_one") .connection_annotations(serde_json::to_string(&vec!["arity_one"])?) .arity(SocketSpecArity::One) .kind(SocketSpecKind::Input) .build()?, ) .build()?, ) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Create) .func_unique_id(&create_action_func.unique_id) .build()?, ) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Refresh) .func_unique_id(&refresh_action_func.unique_id) .build()?, ) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Manual) .func_unique_id(&update_action_func.unique_id) .build()?, ) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Destroy) .func_unique_id(&delete_action_func.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Import small odd lego") .func_unique_id(&import_management_func.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Clone") .func_unique_id(&clone_me_mgmt_func.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Update") .func_unique_id(&update_mgmt_func.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Update in View") .func_unique_id(&update_in_view_mgmt_func.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Get Input Values") .func_unique_id(&get_input_values_func.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Deeply Nested Children") .func_unique_id(&deeply_nested_children.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Create in Other Views") .func_unique_id(&create_component_in_other_views.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Create View and Component in View") .func_unique_id(&create_view_and_component_in_view.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Delete and Erase") .func_unique_id(&delete_and_erase_components.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Remove View and Components") .func_unique_id(&remove_all_components_from_a_view_and_the_view.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Override Props") .func_unique_id(&override_values_set_by_sockets.unique_id) .build()?, ) .build()?, ) .build()?; let small_odd_lego_spec = small_lego_builder .func(identity_func_spec) .func(refresh_action_func) .func(create_action_func) .func(update_action_func) .func(delete_action_func) .func(small_lego_authoring_schema_func) .func(import_management_func) .func(clone_me_mgmt_func) .func(update_mgmt_func) .func(update_in_view_mgmt_func) .func(get_input_values_func) .func(deeply_nested_children) .func(create_component_in_other_views) .func(create_view_and_component_in_view) .func(delete_and_erase_components) .func(remove_all_components_from_a_view_and_the_view) .func(override_values_set_by_sockets) .schema(small_lego_schema) .build()?; let pkg = SiPkg::load_from_spec(small_odd_lego_spec)?; import_pkg_from_pkg( ctx, &pkg, Some(ImportOptions { schema_id: Some(schema_id.into()), ..Default::default() }), ) .await?; Ok(()) } pub(crate) async fn migrate_test_exclusive_schema_small_even_lego( ctx: &DalContext, schema_id: SchemaId, ) -> BuiltinsResult<()> { let mut small_lego_builder = PkgSpec::builder(); let schema_name = "small even lego"; small_lego_builder .name(schema_name) .version(PKG_VERSION) .created_by(PKG_CREATED_BY); let identity_func_spec = create_identity_func()?; // Build Create Action Func let create_action_code = "async function main() { return { payload: { \"poop\": \"created\", \"refresh_count\": 0 }, status: \"ok\" }; }"; let fn_name = "test:createActionSmallLego"; let create_action_func = build_action_func(create_action_code, fn_name)?; // Build Refresh Action Func let refresh_action_code = r#"async function main(component: Input) { const currentCount = typeof component.properties.resource?.payload?.refresh_count === 'number' ? component.properties.resource.payload.refresh_count : 0; const newCount = currentCount + 1; if (component.properties.resource?.payload?.poop) { return { payload: { "poop": "refreshed again", "refresh_count": newCount }, status: "ok" }; } else { return { payload: { "poop": "refreshed", "refresh_count": newCount }, status: "ok" }; } }"#; let fn_name = "test:refreshActionSmallLego"; let refresh_action_func = build_action_func(refresh_action_code, fn_name)?; let update_action_code = "async function main(component: Input): Promise<Output> { return { payload: { \"poop\": updated }, status: \"ok\" }; }"; let fn_name = "test:updateActionSmallLego"; let update_action_func = build_action_func(update_action_code, fn_name)?; // Build Delete Action Func let delete_action_code = "async function main() { return { payload: null, status: \"ok\" }; }"; let fn_name = "test:deleteActionSmallLego"; let delete_action_func = build_action_func(delete_action_code, fn_name)?; // Create Scaffold Func let fn_name = "test:scaffoldSmallLegoAsset"; let small_lego_authoring_schema_func = build_asset_func(fn_name)?; // This import func mimics our Clover funcs in name so we can test logic related to that let import_management_func_code = r#"async function main({ thisComponent }: Input): Promise<Output> { const thisProperties = thisComponent.properties; return { status: 'ok', ops: { update: { self: { properties: { ...thisProperties, domain: { ...thisProperties.domain, one: 'twostep', }, } } }, actions: { self: { remove: ["create"], add: ["refresh"], }, }, }, message: 'hello' } }"#; let import_management_func_name = "Import from AWS"; let import_management_func = build_management_func(import_management_func_code, import_management_func_name)?; let bricks = LegoBricks::new_for_even()?; let small_lego_schema = SchemaSpec::builder() .name(schema_name) .data( SchemaSpecData::builder() .name(schema_name) .category("test exclusive") .category_name(schema_name) .build()?, ) .variant( SchemaVariantSpec::builder() .version("v0") .unique_id("small_even_lego_sv") .data( SchemaVariantSpecData::builder() .version("v0") .color("#ffffff") .func_unique_id(&small_lego_authoring_schema_func.unique_id) .component_type(ComponentType::ConfigurationFrameUp) .build()?, ) .domain_prop(bricks.domain_name_prop) .domain_prop(bricks.domain_one_prop) .domain_prop(bricks.domain_two_prop) .socket(bricks.socket_one) .socket(bricks.socket_two) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Create) .func_unique_id(&create_action_func.unique_id) .build()?, ) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Refresh) .func_unique_id(&refresh_action_func.unique_id) .build()?, ) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Manual) .func_unique_id(&update_action_func.unique_id) .build()?, ) .action_func( ActionFuncSpec::builder() .kind(ActionKind::Destroy) .func_unique_id(&delete_action_func.unique_id) .build()?, ) .management_func( ManagementFuncSpec::builder() .name("Import from AWS") .func_unique_id(&import_management_func.unique_id) .build()?, ) .build()?, ) .build()?; let small_lego_spec = small_lego_builder .func(identity_func_spec) .func(refresh_action_func) .func(create_action_func) .func(update_action_func) .func(delete_action_func) .func(import_management_func) .func(small_lego_authoring_schema_func) .schema(small_lego_schema) .build()?; let pkg = SiPkg::load_from_spec(small_lego_spec)?; import_pkg_from_pkg( ctx, &pkg, Some(ImportOptions { schema_id: Some(schema_id.into()), ..Default::default() }), ) .await?; Ok(()) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server