Skip to content

Commit

Permalink
Merge pull request #5419 from systeminit/clover/generate-sockets-for-…
Browse files Browse the repository at this point in the history
…string-props

feat(clover): Generate sockets for string props
  • Loading branch information
jkeiser authored Feb 3, 2025
2 parents bb4a74f + e267845 commit b4d2aad
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 50 deletions.
6 changes: 3 additions & 3 deletions bin/clover/src/cfDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,10 @@ export async function loadCfDatabase(
const typeName: string = data.typeName;

if (
// false &&
false &&
![
"AWS::EC2::Subnet",
"AWS::EC2::SecurityGroup",
"AWS::ElasticLoadBalancingV2::LoadBalancer",
"AWS::ECS::Service",
"AWS::EC2::SecurityGroupIngress",
"AWS::EC2::SecurityGroupEgress",
"AWS::EC2::SecurityGroupVpcAssociation",
Expand All @@ -294,11 +292,13 @@ export async function loadCfDatabase(
"AWS::EC2::EIP",
"AWS::EC2::EIPAssociation",
"AWS::EC2::VPCGatewayAttachment",
"AWS::ElasticLoadBalancingV2::LoadBalancer",
"AWS::ElasticLoadBalancingV2::Listener",
"AWS::ElasticLoadBalancingV2::ListenerRule",
"AWS::ElasticLoadBalancingV2::TargetGroup",
"AWS::ECS::CapacityProvider",
"AWS::ECS::Cluster",
"AWS::ECS::Service",
"AWS::ECS::ClusterCapacityProviderAssociations",
"AWS::ECS::TaskDefinition",
"AWS::IAM::Policy",
Expand Down
6 changes: 4 additions & 2 deletions bin/clover/src/commands/generateSiSpecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { generateDefaultActionFuncs } from "../pipeline-steps/generateActionFunc
import { generateDefaultLeafFuncs } from "../pipeline-steps/generateLeafFuncs.ts";
import { generateDefaultManagementFuncs } from "../pipeline-steps/generateManagementFuncs.ts";
import { addDefaultPropsAndSockets } from "../pipeline-steps/addDefaultPropsAndSockets.ts";
import { generateOutputSocketsFromResourceProps } from "../pipeline-steps/generateSocketsFromResourceProps.ts";
import { generateSubAssets } from "../pipeline-steps/generateSubAssets.ts";
import { generateIntrinsicFuncs } from "../pipeline-steps/generateIntrinsicFuncs.ts";
import { createInputSocketsBasedOnOutputSockets } from "../pipeline-steps/createInputSocketsAcrossAssets.ts";
Expand All @@ -19,6 +18,9 @@ import { assetSpecificOverrides } from "../pipeline-steps/assetSpecificOverrides
import {
addSignatureToCategoryName,
} from "../pipeline-steps/addSignatureToCategoryName.ts";
import {
generateOutputSocketsFromProps,
} from "../pipeline-steps/generateOutputSocketsFromProps.ts";

const logger = _logger.ns("siSpecs").seal();
const SI_SPEC_DIR = "si-specs";
Expand Down Expand Up @@ -49,7 +51,7 @@ export async function generateSiSpecs() {
}

// EXECUTE PIPELINE STEPS
specs = generateOutputSocketsFromResourceProps(specs);
specs = generateOutputSocketsFromProps(specs);
specs = addDefaultPropsAndSockets(specs);
specs = generateDefaultActionFuncs(specs);
specs = generateDefaultLeafFuncs(specs);
Expand Down
26 changes: 21 additions & 5 deletions bin/clover/src/pipeline-steps/createInputSocketsAcrossAssets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
import pluralize from "npm:pluralize";
import { SchemaVariantSpec } from "../bindings/SchemaVariantSpec.ts";
import { SocketSpec } from "../bindings/SocketSpec.ts";
import { PropSpec } from "../bindings/PropSpec.ts";
import { SocketSpecKind } from "../bindings/SocketSpecKind.ts";

export function createInputSocketsBasedOnOutputSockets(
specs: PkgSpec[],
Expand Down Expand Up @@ -46,7 +48,7 @@ export function createInputSocketsBasedOnOutputSockets(
if (socket.data?.kind === "output") {
foundOutputSockets.add(socket.name);

// add annotations as we may generate relavant output socket annotations
// add annotations as we may generate relevant output socket annotations
// that match props
const existingAnnotations = JSON.parse(
socket.data?.connectionAnnotations,
Expand Down Expand Up @@ -134,13 +136,15 @@ export function createInputSocketsBasedOnOutputSockets(
bfsPropTree(domain, (prop) => {
if (
isExpandedPropSpec(prop) && !propHasSocket(prop) &&
prop.kind === "array" && prop.typeProp.kind === "string"
(prop.kind === "array" && prop.typeProp.kind === "string") ||
prop.kind === "string"
) {
const possiblePeers = specsByName[prop.name];
const possiblePeers = specsByName[prop.name] ??
specsByName[pluralize(prop.name)];
if (!possiblePeers) return;

for (const peer of possiblePeers) {
bfsPropTree(peer.resourceValue, (peerProp) => {
const addSocketIfPeerExists = (peerProp: PropSpec) => {
if (!isExpandedPropSpec(peerProp)) return;

if (peerProp.metadata.primaryIdentifier) {
Expand All @@ -157,6 +161,7 @@ export function createInputSocketsBasedOnOutputSockets(
!socketExistsInSockets(
schemaVariant.sockets,
prop.name,
"input",
)
) {
schemaVariant.sockets.push(
Expand All @@ -168,7 +173,14 @@ export function createInputSocketsBasedOnOutputSockets(
}
}
}
}, { skipTypeProps: true });
};

bfsPropTree(peer.resourceValue, addSocketIfPeerExists, {
skipTypeProps: true,
});
bfsPropTree(peer.domain, addSocketIfPeerExists, {
skipTypeProps: true,
});
}
}
}, { skipTypeProps: true });
Expand All @@ -182,8 +194,12 @@ export function createInputSocketsBasedOnOutputSockets(
function socketExistsInSockets(
sockets: SocketSpec[],
name: string,
direction?: SocketSpecKind,
): boolean {
for (const socket of sockets) {
if (direction) {
if (direction !== socket.data.kind) continue;
}
if (socket.name === name) return true;
}
return false;
Expand Down
111 changes: 73 additions & 38 deletions bin/clover/src/pipeline-steps/generateAssetFuncs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ function generateAssetCodeFromVariantSpec(variant: SchemaVariantSpec): string {

for (const prop of variant.domain.entries) {
const varName = `${prop.name}Prop`.replace(" ", "");
propDeclarations += `${indent(1)}const ${varName} = ${generatePropBuilderString(prop, 2)
};\n\n`;
propDeclarations += `${indent(1)}const ${varName} = ${
generatePropBuilderString(prop, 2)
};\n\n`;
propAdds += `${indent(2)}.addProp(${varName})\n`;
}

Expand All @@ -82,7 +83,6 @@ function generateAssetCodeFromVariantSpec(variant: SchemaVariantSpec): string {

// Code for Secret Props


{
if (variant.secrets.kind !== "object") {
console.log(
Expand All @@ -95,8 +95,9 @@ function generateAssetCodeFromVariantSpec(variant: SchemaVariantSpec): string {

for (const prop of variant.secrets.entries) {
const varName = `${prop.name}SecretProp`.replace(" ", "");
propDeclarations += `${indent(1)}const ${varName} = ${generateSecretPropBuilderString(prop, 2)
};\n\n`;
propDeclarations += `${indent(1)}const ${varName} = ${
generateSecretPropBuilderString(prop, 2)
};\n\n`;
propAdds += `${indent(2)}.addSecretProp(${varName})\n`;
}
declarations += propDeclarations;
Expand All @@ -112,8 +113,9 @@ function generateAssetCodeFromVariantSpec(variant: SchemaVariantSpec): string {

for (const prop of variant.resourceValue.entries) {
const varName = `${prop.name}Resource`.replace(" ", "");
propDeclarations += `${indent(1)}const ${varName} = ${generatePropBuilderString(prop, 2)
};\n\n`;
propDeclarations += `${indent(1)}const ${varName} = ${
generatePropBuilderString(prop, 2)
};\n\n`;
propAdds += `${indent(2)}.addResourceProp(${varName})\n`;
}

Expand All @@ -138,9 +140,11 @@ function generateAssetCodeFromVariantSpec(variant: SchemaVariantSpec): string {
if (!data) continue;
// if this socket in the spec is for a secret, don't add the input socket, we'll get
// it for free by using the SecretPropBuilder above.
if (variant.secrets.entries.map(entry => entry.name).includes(socket.name)) continue;
if (
variant.secrets.entries.map((entry) => entry.name).includes(socket.name)
) continue;

const varName = `${socket.name}Socket`.replace(" ", "");
const varName = `${socket.name}${data.kind}Socket`.replace(" ", "");

type AnnotationItem = {
tokens: string[];
Expand All @@ -154,7 +158,8 @@ function generateAssetCodeFromVariantSpec(variant: SchemaVariantSpec): string {
`${indent(2)}.setName("${socket.name}")\n` +
`${indent(2)}.setArity("${data.arity}")\n` +
annotations.map((item: AnnotationItem) =>
`${indent(2)}.setConnectionAnnotation("${item.tokens.join("<")}${">".repeat(item.tokens.length - 1)
`${indent(2)}.setConnectionAnnotation("${item.tokens.join("<")}${
">".repeat(item.tokens.length - 1)
}")`
).join("\n") + "\n" +
`${indent(2)}.build();\n\n`;
Expand Down Expand Up @@ -201,21 +206,29 @@ function generatePropBuilderString(
case "array":
case "map": {
const entryBlock = `${indent(indent_level)}.setEntry(\n` +
`${indent(indent_level + 1)}${generatePropBuilderString(prop.typeProp, indent_level + 1)
`${indent(indent_level + 1)}${
generatePropBuilderString(prop.typeProp, indent_level + 1)
}\n` +
`${indent(indent_level)})\n`;

return `new PropBuilder()\n` +
`${indent(indent_level)}.setKind("${prop.kind}")\n` +
`${indent(indent_level)}.setName("${prop.name}")\n` +
`${indent(indent_level)}.setHidden(${prop.data?.hidden ?? false})\n` +
`${generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
)
`${
generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
)
}` +
`${
prop.data?.defaultValue
? `${indent(indent_level)}.setDefaultValue(${
JSON.stringify(prop.data.defaultValue)
})\n`
: ""
}` +
`${prop.data?.defaultValue ? `${indent(indent_level)}.setDefaultValue(${JSON.stringify(prop.data.defaultValue)})\n` : ''}` +
`${entryBlock}` +
`${indent(indent_level)}.build()`;
}
Expand All @@ -236,13 +249,20 @@ function generatePropBuilderString(
`${indent(indent_level)}.setKind("object")\n` +
`${indent(indent_level)}.setName("${prop.name}")\n` +
`${indent(indent_level)}.setHidden(${prop.data?.hidden ?? false})\n` +
`${generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
)
`${
generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
)
}` +
`${
prop.data?.defaultValue
? `${indent(indent_level)}.setDefaultValue(${
JSON.stringify(prop.data.defaultValue)
})\n`
: ""
}` +
`${prop.data?.defaultValue ? `${indent(indent_level)}.setDefaultValue(${JSON.stringify(prop.data.defaultValue)})\n` : ''}` +
`${addChildBlock}` +
`${indent(indent_level)}.build()`;
}
Expand All @@ -251,13 +271,20 @@ function generatePropBuilderString(
`${indent(indent_level)}.setName("${prop.name}")\n` +
`${indent(indent_level)}.setKind("integer")\n` +
`${indent(indent_level)}.setHidden(${prop.data?.hidden ?? false})\n` +
`${generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
)
`${
generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
)
}` +
`${
prop.data?.defaultValue
? `${indent(indent_level)}.setDefaultValue(${
JSON.stringify(prop.data.defaultValue)
})\n`
: ""
}` +
`${prop.data?.defaultValue ? `${indent(indent_level)}.setDefaultValue(${JSON.stringify(prop.data.defaultValue)})\n` : ''}` +
`${indent(indent_level)}.build()`;
case "boolean":
case "json":
Expand All @@ -266,14 +293,21 @@ function generatePropBuilderString(
`${indent(indent_level)}.setName("${prop.name}")\n` +
`${indent(indent_level)}.setKind("${prop.kind}")\n` +
`${indent(indent_level)}.setHidden(${prop.data?.hidden ?? false})\n` +
`${generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
prop.data?.widgetOptions,
)
`${
generateWidgetString(
prop.data?.widgetKind,
is_create_only,
indent_level,
prop.data?.widgetOptions,
)
}` +
`${
prop.data?.defaultValue
? `${indent(indent_level)}.setDefaultValue(${
JSON.stringify(prop.data.defaultValue)
})\n`
: ""
}` +
`${prop.data?.defaultValue ? `${indent(indent_level)}.setDefaultValue(${JSON.stringify(prop.data.defaultValue)})\n` : ''}` +
`${indent(indent_level)}.build()`;
}
}
Expand Down Expand Up @@ -304,8 +338,9 @@ function generateWidgetString(
if (options) {
for (const option of options) {
if (option.label === CREATE_ONLY_PROP_LABEL) continue;
widgetStr += `\n${indent(indentLevel + 1)
}.addOption("${option.label}", "${option.value}")`;
widgetStr += `\n${
indent(indentLevel + 1)
}.addOption("${option.label}", "${option.value}")`;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { PkgSpec } from "../bindings/PkgSpec.ts";
import { SchemaVariantSpec } from "../bindings/SchemaVariantSpec.ts";
import _ from "lodash";
import { SocketSpec } from "../bindings/SocketSpec.ts";
import { isExpandedPropSpec } from "../spec/props.ts";
import { bfsPropTree, isExpandedPropSpec } from "../spec/props.ts";
import {
createOutputSocketFromProp,
setAnnotationOnSocket,
} from "../spec/sockets.ts";

export function generateOutputSocketsFromResourceProps(
export function generateOutputSocketsFromProps(
specs: PkgSpec[],
): PkgSpec[] {
const newSpecs = [] as PkgSpec[];
Expand All @@ -26,6 +26,7 @@ export function generateOutputSocketsFromResourceProps(
schemaVariant.sockets = [
...schemaVariant.sockets,
...createSocketsFromResource(schemaVariant),
...createSocketsFromPrimaryIdentifier(schemaVariant),
];

newSpecs.push(spec);
Expand Down Expand Up @@ -58,3 +59,27 @@ function createSocketsFromResource(variant: SchemaVariantSpec): SocketSpec[] {
}
return sockets;
}

function createSocketsFromPrimaryIdentifier(
variant: SchemaVariantSpec,
): SocketSpec[] {
const domain = variant.domain;

if (domain.kind !== "object") throw "Domain prop is not object";

const sockets: SocketSpec[] = [];

bfsPropTree(domain, (prop) => {
if (!isExpandedPropSpec(prop)) return;

// We don't check if the socket already exists before adding, since on the other func
// we only look at resourceValue props
if (prop.metadata.primaryIdentifier) {
sockets.push(createOutputSocketFromProp(prop));
}
}, {
skipTypeProps: true,
});

return sockets;
}

0 comments on commit b4d2aad

Please sign in to comment.