Skip to content

Commit c96aed2

Browse files
feat(repo): add @uipath/flow-node-schema package for lightweight schema-only consumption
Extract Zod schemas from @uipath/apollo-react/canvas into a standalone @uipath/flow-node-schema package with only zod as a dependency. This allows CLI tools and non-React consumers to validate flow/canvas definitions without pulling in React and all UI dependencies. - New packages/flow-node-schema/ with all node-definition, node-instance, and toolbar Zod schemas - apollo-react schema files now re-export from @uipath/flow-node-schema - Replaced FormSchema (apollo-wind) dependency with generic FormSchemaLike type in the standalone package - Added dedicated GitHub Actions release workflow Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b313d16 commit c96aed2

File tree

29 files changed

+1134
-758
lines changed

29 files changed

+1134
-758
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Flow Schema Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'packages/flow-node-schema/**'
9+
- '.github/workflows/flow-schema-release.yml'
10+
11+
env:
12+
GH_NPM_REGISTRY_TOKEN: ${{ secrets.GH_NPM_REGISTRY_TOKEN }}
13+
NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
14+
TURBO_TELEMETRY_DISABLED: 1
15+
DO_NOT_TRACK: 1
16+
17+
concurrency:
18+
group: ${{ github.workflow }}
19+
cancel-in-progress: false
20+
21+
jobs:
22+
release:
23+
name: Release @uipath/flow-node-schema
24+
runs-on: ubuntu-latest
25+
permissions:
26+
contents: write
27+
packages: write
28+
29+
steps:
30+
- name: Checkout code
31+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
32+
with:
33+
fetch-depth: 0
34+
token: ${{ secrets.RELEASE_TOKEN }}
35+
36+
- name: Setup pnpm
37+
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4
38+
39+
- name: Setup Node.js
40+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
41+
with:
42+
node-version: 22
43+
cache: 'pnpm'
44+
45+
- name: Install dependencies
46+
run: pnpm install --frozen-lockfile
47+
48+
- name: Build flow-node-schema
49+
run: pnpm --filter @uipath/flow-node-schema build
50+
51+
- name: Test flow-node-schema
52+
run: pnpm --filter @uipath/flow-node-schema test
53+
54+
- name: Setup git user
55+
run: |
56+
git config --global user.name "semantic-release-bot"
57+
git config --global user.email "semantic-release-bot@users.noreply.github.com"
58+
59+
- name: Release
60+
env:
61+
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
62+
NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
63+
NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
64+
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
65+
GH_NPM_REGISTRY_TOKEN: ${{ secrets.GH_NPM_REGISTRY_TOKEN }}
66+
HUSKY: 0
67+
working-directory: packages/flow-node-schema
68+
run: semantic-release
69+
70+
- name: Commit version bump
71+
env:
72+
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
73+
run: |
74+
if [ -n "$(git status --porcelain packages/flow-node-schema)" ]; then
75+
git add packages/flow-node-schema/
76+
git commit -m "chore(release): @uipath/flow-node-schema version bump [skip ci]"
77+
78+
if ! git push; then
79+
echo "::error::Failed to push version bump commit"
80+
exit 1
81+
fi
82+
echo "✓ Pushed version bump commit"
83+
else
84+
echo "No changes to commit"
85+
fi

packages/apollo-react/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@
218218
"sanitize-html": "^2.17.0",
219219
"unist-util-visit": "^5.0.0",
220220
"use-sync-external-store": "^1.2.0",
221+
"@uipath/flow-node-schema": "workspace:*",
221222
"zod": "^4.3.5",
222223
"zustand": "^5.0.9"
223224
},
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
export * from './node-definition';
2-
export * from './node-instance';
3-
export * from './toolbar';
1+
export * from '@uipath/flow-node-schema';
Lines changed: 2 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,2 @@
1-
/**
2-
* Category Manifest Schemas
3-
*
4-
* Zod schemas for category definitions.
5-
* Supports arbitrary nesting using parent references.
6-
* Nodes define their own category membership.
7-
*/
8-
9-
import { z } from 'zod';
10-
11-
/**
12-
* Category manifest from server
13-
*
14-
* Categories form a hierarchy using parentId references:
15-
* - { id: 'control-flow', parentId: null } (root)
16-
* - { id: 'decision', parentId: 'control-flow' } (child)
17-
* - { id: 'advanced', parentId: 'decision' } (grandchild)
18-
*
19-
* Nodes define which categories they belong to via category property.
20-
* This allows:
21-
* - Stable category IDs (reorganization just changes parentId)
22-
* - Nodes control their own categorization
23-
*/
24-
export const categoryManifestSchema = z.object({
25-
/**
26-
* Unique category identifier
27-
*
28-
* Should be stable by version.
29-
* Examples: 'control-flow', 'decision', 'loops', 'advanced'
30-
*/
31-
id: z.string().min(1),
32-
33-
/** Human-readable category name */
34-
name: z.string().min(1),
35-
36-
/**
37-
* Parent category ID for nesting
38-
*
39-
* - null or undefined: root category
40-
* - string: ID of parent category
41-
*
42-
* Categories can be reorganized by changing this field without
43-
* affecting node references or constraint definitions.
44-
*/
45-
parentId: z.string().optional(),
46-
47-
/**
48-
* Sort order for display within the same parent level
49-
* Categories at the same level are sorted by this value
50-
*/
51-
sortOrder: z.number().int().nonnegative(),
52-
53-
/** Light mode color/gradient */
54-
color: z.string().min(1),
55-
56-
/** Dark mode color/gradient */
57-
colorDark: z.string().min(1),
58-
59-
/** Icon identifier */
60-
icon: z.string().min(1),
61-
62-
/** Tags for search and filtering */
63-
tags: z.array(z.string()),
64-
});
65-
66-
// Export inferred type
67-
export type CategoryManifest = z.infer<typeof categoryManifestSchema>;
1+
export type { CategoryManifest } from '@uipath/flow-node-schema';
2+
export { categoryManifestSchema } from '@uipath/flow-node-schema';
Lines changed: 2 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,2 @@
1-
/**
2-
* Connection Constraints
3-
*
4-
* Defines semantic rules for valid connections between nodes and handles.
5-
* Focus on workflow composition semantics, not just data types.
6-
*/
7-
8-
import { z } from 'zod';
9-
10-
/**
11-
* Specific node and handle targeting
12-
* Used for precise semantic constraints like "Agent Model can only connect to Agent node's 'model' handle"
13-
*/
14-
export const handleTargetSchema = z.object({
15-
/**
16-
* Specific node type this can connect to
17-
* Example: "uipath.agent" (exact match, no wildcards)
18-
*/
19-
nodeType: z.string(),
20-
21-
/**
22-
* Specific handle ID on the target node
23-
* Example: "model", "input", "configuration"
24-
*/
25-
handleId: z.string().optional(),
26-
});
27-
28-
/**
29-
* Connection constraint configuration for a handle
30-
*/
31-
export const connectionConstraintSchema = z.object({
32-
/**
33-
* Maximum number of connections allowed
34-
* - 1: Single connection only
35-
* - undefined: Unlimited connections
36-
*/
37-
maxConnections: z.number().int().positive().optional(),
38-
39-
/**
40-
* Minimum number of connections required (for validation)
41-
* Example: Trigger output must connect to at least 1 node
42-
*/
43-
minConnections: z.number().int().nonnegative().optional(),
44-
45-
/**
46-
* WHITELIST: Allowed target nodes/handles (for source handles)
47-
* If specified, this handle can ONLY connect to these specific targets
48-
*
49-
* Example: Agent Model output can only connect to Agent node's "model" handle
50-
* ```
51-
* allowedTargets: [
52-
* { nodeType: "uipath.agent", handleId: "model" }
53-
* ]
54-
* ```
55-
*/
56-
allowedTargets: z.array(handleTargetSchema).optional(),
57-
58-
/**
59-
* BLACKLIST: Forbidden target nodes/handles (for source handles)
60-
* If specified, this handle CANNOT connect to these targets
61-
*
62-
* Example: Control flow cannot connect to triggers
63-
* ```
64-
* forbiddenTargets: [
65-
* { nodeType: "uipath.trigger.*" }
66-
* ]
67-
* ```
68-
*/
69-
forbiddenTargets: z.array(handleTargetSchema).optional(),
70-
71-
/**
72-
* WHITELIST: Allowed source nodes/handles (for target handles)
73-
* If specified, this handle can ONLY accept connections from these sources
74-
*
75-
* Example: Agent's "model" handle can only accept Agent Model nodes
76-
* ```
77-
* allowedSources: [
78-
* { nodeType: "uipath.ai.agent-model" }
79-
* ]
80-
* ```
81-
*/
82-
allowedSources: z.array(handleTargetSchema).optional(),
83-
84-
/**
85-
* BLACKLIST: Forbidden source nodes/handles (for target handles)
86-
* If specified, this handle CANNOT accept connections from these sources
87-
*/
88-
forbiddenSources: z.array(handleTargetSchema).optional(),
89-
90-
/**
91-
* Required target categories
92-
* If specified, can only connect to nodes in these categories
93-
* Example: ["agent", "data-and-tools"]
94-
*/
95-
allowedTargetCategories: z.array(z.string()).optional(),
96-
97-
/**
98-
* Forbidden target categories
99-
* If specified, cannot connect to nodes in these categories
100-
* Example: ["control-flow", "trigger"]
101-
*/
102-
forbiddenTargetCategories: z.array(z.string()).optional(),
103-
104-
/**
105-
* Required source categories (for target handles)
106-
*/
107-
allowedSourceCategories: z.array(z.string()).optional(),
108-
109-
/**
110-
* Forbidden source categories (for target handles)
111-
*/
112-
forbiddenSourceCategories: z.array(z.string()).optional(),
113-
114-
/**
115-
* Custom validation expression
116-
* Template expression that must evaluate to true for connection to be valid
117-
* Context: sourceNode, targetNode, sourceHandle, targetHandle
118-
* Example: "{sourceNode.model.agentType === targetNode.model.agentType}"
119-
*/
120-
customValidation: z.string().optional(),
121-
122-
/**
123-
* Error message to show when connection is invalid
124-
* Supports template expressions
125-
* Example: "Agent Model can only connect to Agent node's model handle"
126-
*/
127-
validationMessage: z.string().optional(),
128-
129-
/**
130-
* Severity level for constraint violations
131-
* Controls whether violations appear as errors or warnings
132-
* - 'error' (default): Blocks execution/publish
133-
* - 'warning': Shows advisory badge but doesn't block
134-
*/
135-
severity: z.enum(['warning', 'error', 'critical', 'info']).optional(),
136-
});
137-
138-
// Export inferred types
139-
export type HandleTarget = z.infer<typeof handleTargetSchema>;
140-
export type ConnectionConstraint = z.infer<typeof connectionConstraintSchema>;
1+
export type { HandleTarget, ConnectionConstraint } from '@uipath/flow-node-schema';
2+
export { handleTargetSchema, connectionConstraintSchema } from '@uipath/flow-node-schema';

0 commit comments

Comments
 (0)