@uipath/codedapp-convert-sdk 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +3 -0
- package/README.md +54 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +30770 -0
- package/dist/index.js.map +7 -0
- package/dist/roslyn-bridge/Microsoft.CodeAnalysis.VisualBasic.dll +0 -0
- package/dist/roslyn-bridge/Microsoft.CodeAnalysis.dll +0 -0
- package/dist/roslyn-bridge/Newtonsoft.Json.dll +0 -0
- package/dist/roslyn-bridge/cs/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/cs/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/de/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/de/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/es/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/es/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/fr/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/fr/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/it/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/it/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/ja/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/ja/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/ko/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/ko/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/pl/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/pl/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/pt-BR/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/pt-BR/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/roslyn-bridge +0 -0
- package/dist/roslyn-bridge/roslyn-bridge.deps.json +157 -0
- package/dist/roslyn-bridge/roslyn-bridge.dll +0 -0
- package/dist/roslyn-bridge/roslyn-bridge.pdb +0 -0
- package/dist/roslyn-bridge/roslyn-bridge.runtimeconfig.json +14 -0
- package/dist/roslyn-bridge/ru/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/ru/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/tr/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/tr/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/zh-Hans/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/zh-Hans/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/roslyn-bridge/zh-Hant/Microsoft.CodeAnalysis.VisualBasic.resources.dll +0 -0
- package/dist/roslyn-bridge/zh-Hant/Microsoft.CodeAnalysis.resources.dll +0 -0
- package/dist/skills/fix-converted-app/SKILL.md +333 -0
- package/package.json +39 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"runtimeTarget": {
|
|
3
|
+
"name": ".NETCoreApp,Version=v10.0",
|
|
4
|
+
"signature": ""
|
|
5
|
+
},
|
|
6
|
+
"compilationOptions": {},
|
|
7
|
+
"targets": {
|
|
8
|
+
".NETCoreApp,Version=v10.0": {
|
|
9
|
+
"roslyn-bridge/1.0.0": {
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"Microsoft.CodeAnalysis.VisualBasic": "5.6.0",
|
|
12
|
+
"Newtonsoft.Json": "13.0.3"
|
|
13
|
+
},
|
|
14
|
+
"runtime": {
|
|
15
|
+
"roslyn-bridge.dll": {}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"Microsoft.CodeAnalysis.Common/5.6.0": {
|
|
19
|
+
"runtime": {
|
|
20
|
+
"lib/net10.0/Microsoft.CodeAnalysis.dll": {
|
|
21
|
+
"assemblyVersion": "5.6.0.0",
|
|
22
|
+
"fileVersion": "5.600.26.26310"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"resources": {
|
|
26
|
+
"lib/net10.0/cs/Microsoft.CodeAnalysis.resources.dll": {
|
|
27
|
+
"locale": "cs"
|
|
28
|
+
},
|
|
29
|
+
"lib/net10.0/de/Microsoft.CodeAnalysis.resources.dll": {
|
|
30
|
+
"locale": "de"
|
|
31
|
+
},
|
|
32
|
+
"lib/net10.0/es/Microsoft.CodeAnalysis.resources.dll": {
|
|
33
|
+
"locale": "es"
|
|
34
|
+
},
|
|
35
|
+
"lib/net10.0/fr/Microsoft.CodeAnalysis.resources.dll": {
|
|
36
|
+
"locale": "fr"
|
|
37
|
+
},
|
|
38
|
+
"lib/net10.0/it/Microsoft.CodeAnalysis.resources.dll": {
|
|
39
|
+
"locale": "it"
|
|
40
|
+
},
|
|
41
|
+
"lib/net10.0/ja/Microsoft.CodeAnalysis.resources.dll": {
|
|
42
|
+
"locale": "ja"
|
|
43
|
+
},
|
|
44
|
+
"lib/net10.0/ko/Microsoft.CodeAnalysis.resources.dll": {
|
|
45
|
+
"locale": "ko"
|
|
46
|
+
},
|
|
47
|
+
"lib/net10.0/pl/Microsoft.CodeAnalysis.resources.dll": {
|
|
48
|
+
"locale": "pl"
|
|
49
|
+
},
|
|
50
|
+
"lib/net10.0/pt-BR/Microsoft.CodeAnalysis.resources.dll": {
|
|
51
|
+
"locale": "pt-BR"
|
|
52
|
+
},
|
|
53
|
+
"lib/net10.0/ru/Microsoft.CodeAnalysis.resources.dll": {
|
|
54
|
+
"locale": "ru"
|
|
55
|
+
},
|
|
56
|
+
"lib/net10.0/tr/Microsoft.CodeAnalysis.resources.dll": {
|
|
57
|
+
"locale": "tr"
|
|
58
|
+
},
|
|
59
|
+
"lib/net10.0/zh-Hans/Microsoft.CodeAnalysis.resources.dll": {
|
|
60
|
+
"locale": "zh-Hans"
|
|
61
|
+
},
|
|
62
|
+
"lib/net10.0/zh-Hant/Microsoft.CodeAnalysis.resources.dll": {
|
|
63
|
+
"locale": "zh-Hant"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"Microsoft.CodeAnalysis.VisualBasic/5.6.0": {
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"Microsoft.CodeAnalysis.Common": "5.6.0"
|
|
70
|
+
},
|
|
71
|
+
"runtime": {
|
|
72
|
+
"lib/net10.0/Microsoft.CodeAnalysis.VisualBasic.dll": {
|
|
73
|
+
"assemblyVersion": "5.6.0.0",
|
|
74
|
+
"fileVersion": "5.600.26.26310"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"resources": {
|
|
78
|
+
"lib/net10.0/cs/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
79
|
+
"locale": "cs"
|
|
80
|
+
},
|
|
81
|
+
"lib/net10.0/de/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
82
|
+
"locale": "de"
|
|
83
|
+
},
|
|
84
|
+
"lib/net10.0/es/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
85
|
+
"locale": "es"
|
|
86
|
+
},
|
|
87
|
+
"lib/net10.0/fr/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
88
|
+
"locale": "fr"
|
|
89
|
+
},
|
|
90
|
+
"lib/net10.0/it/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
91
|
+
"locale": "it"
|
|
92
|
+
},
|
|
93
|
+
"lib/net10.0/ja/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
94
|
+
"locale": "ja"
|
|
95
|
+
},
|
|
96
|
+
"lib/net10.0/ko/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
97
|
+
"locale": "ko"
|
|
98
|
+
},
|
|
99
|
+
"lib/net10.0/pl/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
100
|
+
"locale": "pl"
|
|
101
|
+
},
|
|
102
|
+
"lib/net10.0/pt-BR/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
103
|
+
"locale": "pt-BR"
|
|
104
|
+
},
|
|
105
|
+
"lib/net10.0/ru/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
106
|
+
"locale": "ru"
|
|
107
|
+
},
|
|
108
|
+
"lib/net10.0/tr/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
109
|
+
"locale": "tr"
|
|
110
|
+
},
|
|
111
|
+
"lib/net10.0/zh-Hans/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
112
|
+
"locale": "zh-Hans"
|
|
113
|
+
},
|
|
114
|
+
"lib/net10.0/zh-Hant/Microsoft.CodeAnalysis.VisualBasic.resources.dll": {
|
|
115
|
+
"locale": "zh-Hant"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"Newtonsoft.Json/13.0.3": {
|
|
120
|
+
"runtime": {
|
|
121
|
+
"lib/net6.0/Newtonsoft.Json.dll": {
|
|
122
|
+
"assemblyVersion": "13.0.0.0",
|
|
123
|
+
"fileVersion": "13.0.3.27908"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"libraries": {
|
|
130
|
+
"roslyn-bridge/1.0.0": {
|
|
131
|
+
"type": "project",
|
|
132
|
+
"serviceable": false,
|
|
133
|
+
"sha512": ""
|
|
134
|
+
},
|
|
135
|
+
"Microsoft.CodeAnalysis.Common/5.6.0": {
|
|
136
|
+
"type": "package",
|
|
137
|
+
"serviceable": true,
|
|
138
|
+
"sha512": "sha512-eWYNB5e92PSdkQ0xcmy2aLtrvBXNydnVi0Hj/VjaAely6XBqA3By+ClGAJaj4d16pzQmrXPLLK9RDVuS1Ec9xQ==",
|
|
139
|
+
"path": "microsoft.codeanalysis.common/5.6.0",
|
|
140
|
+
"hashPath": "microsoft.codeanalysis.common.5.6.0.nupkg.sha512"
|
|
141
|
+
},
|
|
142
|
+
"Microsoft.CodeAnalysis.VisualBasic/5.6.0": {
|
|
143
|
+
"type": "package",
|
|
144
|
+
"serviceable": true,
|
|
145
|
+
"sha512": "sha512-biaSTpVc2aVkqg1fQsVmKGqxLnckzdJEOV0aUVPqpV9GczuwtxONyVrlQ2AzZNE6741FkO75tyj0VS6qlxJ/PA==",
|
|
146
|
+
"path": "microsoft.codeanalysis.visualbasic/5.6.0",
|
|
147
|
+
"hashPath": "microsoft.codeanalysis.visualbasic.5.6.0.nupkg.sha512"
|
|
148
|
+
},
|
|
149
|
+
"Newtonsoft.Json/13.0.3": {
|
|
150
|
+
"type": "package",
|
|
151
|
+
"serviceable": true,
|
|
152
|
+
"sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
|
|
153
|
+
"path": "newtonsoft.json/13.0.3",
|
|
154
|
+
"hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"runtimeOptions": {
|
|
3
|
+
"tfm": "net10.0",
|
|
4
|
+
"framework": {
|
|
5
|
+
"name": "Microsoft.NETCore.App",
|
|
6
|
+
"version": "10.0.0"
|
|
7
|
+
},
|
|
8
|
+
"configProperties": {
|
|
9
|
+
"System.Globalization.Invariant": false,
|
|
10
|
+
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
|
|
11
|
+
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fix-converted-app
|
|
3
|
+
description: Finish a converted Apps project — the generated React code in an output directory. Fixes what `conversion-report.json` reports, anything the developer found by testing the app by hand, and anything a screenshot of the original next to the converted app shows. Fixes it in the generated code whether the fault is this app's or the converter's, and writes the systemic ones up so they can be fixed at the source. Use after `npm run convert`.
|
|
4
|
+
argument-hint: <output directory, e.g. out/MyApp or .> [what is wrong, in your own words, or a screenshot of the original]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Fix a converted app
|
|
8
|
+
|
|
9
|
+
The converter wrote a React + TypeScript project into the output directory and a
|
|
10
|
+
`conversion-report.json` beside it. Your job is to make that app behave and look like the Apps
|
|
11
|
+
app it came from: what the report already knows about, what the developer found by using the
|
|
12
|
+
app, and what a screenshot of the two side by side shows.
|
|
13
|
+
|
|
14
|
+
The output directory is the first part of `$ARGUMENTS` (`.` means the current directory).
|
|
15
|
+
Anything else in `$ARGUMENTS` is the developer telling you what is wrong. Pick the path that
|
|
16
|
+
matches what you were given, and more than one can apply:
|
|
17
|
+
|
|
18
|
+
- nothing but a directory → **Path A**, work the report;
|
|
19
|
+
- a description of something that misbehaves → **Path B**;
|
|
20
|
+
- a screenshot of the original app, or "it does not look right" → **Path C**.
|
|
21
|
+
|
|
22
|
+
## Hard rules
|
|
23
|
+
|
|
24
|
+
1. **Edit only files inside the output directory.** Never edit the converter itself
|
|
25
|
+
(`packages/`, `tools/`), even when the real defect is there — you are almost certainly not
|
|
26
|
+
in that repository anyway. Fix it in the generated code and write it up (rules 5 and 6).
|
|
27
|
+
2. **Never modify `conversion-report.json` or `conversion-log.ndjson`.** They are the record
|
|
28
|
+
handed back to the converter team. The report is read-only on disk; leave its permissions.
|
|
29
|
+
3. **Never edit `node_modules`, `dist`, `uipath.json` or `.env*`.**
|
|
30
|
+
4. **The original app is the specification.** Translate what it does; do not improve it, and
|
|
31
|
+
do not invent behaviour you have not checked. If you cannot establish what Apps does, say
|
|
32
|
+
so in the log rather than guessing.
|
|
33
|
+
5. **Fix everything you can in this project, whoever is at fault.** A defect the converter
|
|
34
|
+
would repeat on every app is still fixed HERE, in the generated code, because that is what
|
|
35
|
+
unblocks the developer today. The difference the blame makes is only what you write down.
|
|
36
|
+
6. **Write `conversion-fixes.md`** in the output directory, with three parts: what you changed
|
|
37
|
+
and why; what you could not fix; and a section headed `## For the converter team` listing
|
|
38
|
+
every defect that is systemic, each with the file and symbol you patched, the VB or the
|
|
39
|
+
Apps behaviour it should match, and a minimal example. That section is what the developer
|
|
40
|
+
sends back to us, and it is also what they will need when a future conversion overwrites
|
|
41
|
+
your patch — so write it even when the fix here was easy.
|
|
42
|
+
|
|
43
|
+
## Path A — the report
|
|
44
|
+
|
|
45
|
+
1. Read `<out>/conversion-report.json` and work through `issues` where `blame` is
|
|
46
|
+
`"converter"`. `blame: "source-app"` is the only kind you do NOT fix — not out of
|
|
47
|
+
deference, but because the app itself is broken (an expression naming a control that does
|
|
48
|
+
not exist) and only its author knows what it was meant to say; report those and move on.
|
|
49
|
+
`by-design` needs nothing. `expressionRows` lists deliberate, measured approximations —
|
|
50
|
+
read them for context, act on them only if asked.
|
|
51
|
+
2. Some reports also carry `runtime`-scoped issues and a `runtime` block: those come from the
|
|
52
|
+
converter team driving both apps through the same steps, and they are the most concrete
|
|
53
|
+
issues in the file because each one states what Apps did and what this app did. Treat them
|
|
54
|
+
like any other converter issue. Neither you nor the developer can re-run that comparison —
|
|
55
|
+
it is internal tooling — so note in the log that the fix is unconfirmed by it.
|
|
56
|
+
3. Fix, then `npm run build` in the output directory (it typechecks and bundles). A freshly
|
|
57
|
+
converted project has no `node_modules` — the converter does not install anything — so run
|
|
58
|
+
`npm install` there first if the directory is absent. If installing is not possible
|
|
59
|
+
(offline), skip the build and say in the log that the fix is unverified. A generated app is
|
|
60
|
+
expected to compile with zero errors; if it does not, that is a defect worth writing up
|
|
61
|
+
even when it is not what you were asked to fix.
|
|
62
|
+
4. Write the log and report back.
|
|
63
|
+
|
|
64
|
+
### Where each issue lives
|
|
65
|
+
|
|
66
|
+
| issue code | what you will find | what to do |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `expression-no-rule`, `expression-unbound` (property) | In `src/pages/<Page>.tsx` the prop reads `notConvertedValue("<VB>")` or `notConvertedFlag("<VB>", <default>)`; `where` and `location` name page, control and prop. | Replace the marker with TypeScript computing the VB's value. Read state through the accessors already imported in that page. |
|
|
69
|
+
| `expression-no-rule` (source binding, column, page, tab) | `src/pages/<Page>.bindings.ts` has a `TODO` block returning empty rows or `undefined`. | Implement the binding with the helpers in `src/lib/data.ts` and `src/lib/compat.ts`. |
|
|
70
|
+
| `rule-unimplemented`, `rule-expression-unconverted` | In `<Page>.bindings.ts`, the handler `<control>_<event>` holds a `// TODO` or a `notConvertedInput("<VB>")`. | Implement the statement the rule describes (`method` names the Apps rule kind, e.g. `vb-set-value`). |
|
|
71
|
+
| `rule-bad-target` | Same handler; the assignment target was not understood. | Write the assignment the VB intends. |
|
|
72
|
+
| `event-undeliverable` | The handler exists but the component never calls it. | Wire the prop the message names, in `src/components/ui/`. |
|
|
73
|
+
| `property-unmapped` | An authored property reached no component prop. | Add the prop to the component and pass it from the page — unless Apps' own control ignores that property too, in which case log it and change nothing. |
|
|
74
|
+
| `style-unmapped` | An authored style produced no CSS. | Add the rule to the control's class in `src/pages/<Page>.module.css`. |
|
|
75
|
+
| `control-unsupported` | An inert placeholder. | Implement it only if the message gives enough to go on; otherwise leave it and say why. |
|
|
76
|
+
| `emit-inconsistent` | Described in the message. | Fix as described. |
|
|
77
|
+
| `runtime-*` | The app was driven beside the low-code app: `step` is what was done, `expected` what Apps showed or sent, `actual` what this app did. | Make the code produce `expected`. For `runtime-request-differs` compare the bodies field by field. For `runtime-text-differs` find the binding behind the control. For `runtime-request-missing`/`-extra` look at the control's source hook and its handler. |
|
|
78
|
+
|
|
79
|
+
### Resolving what an unconverted expression REFERS to
|
|
80
|
+
|
|
81
|
+
Rewriting a refused expression needs more than its VB text: what an identifier in it
|
|
82
|
+
denotes, and what that thing holds. Most of it is already in the output directory.
|
|
83
|
+
|
|
84
|
+
| you need to know | read |
|
|
85
|
+
|---|---|
|
|
86
|
+
| an entity's fields and what each holds | `src/types/entities.ts` — the doc comment on each interface lists every field with its declared type (`Guid`, `Decimal`, `DateTimeOffset`, `file attachment`, `list of number`, or a related entity). The shape is open, so the compiler will not tell you; this table will. |
|
|
87
|
+
| which entity a control's rows came from | the control's `entity` prop in `src/pages/<Page>.tsx`, and `src/lib/entity-ids.ts` |
|
|
88
|
+
| a process's real key, a bucket's real name, the folder any resource was authored in | `src/lib/resource-folders.ts` |
|
|
89
|
+
| what a media name resolves to | `src/lib/app-media.ts` |
|
|
90
|
+
| a control's authored literal defaults | `src/store/defaults.ts`, keyed `<Page>/<Control>` |
|
|
91
|
+
| a control's id in the original app | `src/components/ui/provenance.ts` |
|
|
92
|
+
| an action app's arguments and outcomes | `src/lib/action-schema.ts` |
|
|
93
|
+
| the VB that failed, and where it sat | the issue's `vb`, `where` and `location`; `expressionRows` for expressions that converted with a measured approximation |
|
|
94
|
+
|
|
95
|
+
**The `.uiapp` is NOT in the output directory.** The report's `generatedFrom` names the
|
|
96
|
+
file; ask the developer for it when the tables above are not enough — a rule's nesting, a
|
|
97
|
+
property you cannot find, or an expression whose identifiers resolve to nothing you can
|
|
98
|
+
see. It is JSON, and the parts worth knowing are:
|
|
99
|
+
|
|
100
|
+
- `models[]` — one per page (`type: "form"`) and one container per Data Service
|
|
101
|
+
connection (`type: "entity"`). A page carries `controls`, keyed by control id, each with
|
|
102
|
+
`name`, `component`, `config`, `properties` and `ruleInstances`.
|
|
103
|
+
- `models[].instances[]` on an entity container — the entities themselves, each with typed
|
|
104
|
+
`fields[]`. This is where `src/types/entities.ts` gets its table, so you rarely need it.
|
|
105
|
+
- `models[].expressions` — the VB. Every scope holds
|
|
106
|
+
`expressions: { "<expressionId>": { "expression": "<VB text>" } }`.
|
|
107
|
+
- A bound property is `properties.<name> = { valueType: "vb-expression", value: {
|
|
108
|
+
expressionId } }`. Follow the id into the expression map to read what was authored.
|
|
109
|
+
|
|
110
|
+
**An expression id with no text is a slot the designer never filled in.** Apps writes an
|
|
111
|
+
id for every bindable property whether or not anything was authored there, so the presence
|
|
112
|
+
of an id proves nothing — only text does. That distinction is load-bearing and easy to get
|
|
113
|
+
backwards: an image control with no `url` text renders nothing in Apps, while one whose
|
|
114
|
+
`url` was authored but evaluates to nothing renders its "unable to render" placeholder.
|
|
115
|
+
Where the emitted code omits a prop entirely, the slot was blank; where it passes one that
|
|
116
|
+
happens to be undefined at run time, it was authored.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
## Path B — a bug the developer found by hand
|
|
120
|
+
|
|
121
|
+
This is the common case once the app runs, and the report will not mention it. Work in this
|
|
122
|
+
order; skipping step 2 is how a wrong "fix" gets written.
|
|
123
|
+
|
|
124
|
+
1. **Get the evidence, from the developer's browser.** You can start the app
|
|
125
|
+
(`npm run dev` in the output directory, `npm install` first if there is no
|
|
126
|
+
`node_modules`) but you cannot see it; they can. Ask for the three things that decide
|
|
127
|
+
most of these: the browser console output while the problem happens, the control's name
|
|
128
|
+
from the inspector — every control carries `data-uiapp-name="<authored name>"`, which is
|
|
129
|
+
exactly the name to search for in `src/pages/` — and a screenshot. A control that threw
|
|
130
|
+
while rendering leaves a marked placeholder instead of disappearing, and names itself in
|
|
131
|
+
the console, so that alone often identifies it. If the app says it is not configured, the
|
|
132
|
+
dev server was started BEFORE the project was written or re-written: restart it, because
|
|
133
|
+
the platform settings are injected into the page at startup.
|
|
134
|
+
2. **Establish what the original does** before changing anything. In order of authority: the
|
|
135
|
+
low-code app itself, if the developer can open it or screenshot it; the `.uiapp` export
|
|
136
|
+
(the report's `generatedFrom` names the file) — its `models[].controls` hold each control's
|
|
137
|
+
authored properties and expressions under the same names; the report's `expressionRows`.
|
|
138
|
+
A difference is not automatically a converter bug: Apps has its own quirks, and a converted
|
|
139
|
+
app that is *more* correct than Apps is still a difference worth recording rather than
|
|
140
|
+
"fixing".
|
|
141
|
+
3. **Locate the code.** The map is in the next section.
|
|
142
|
+
4. **Fix it here either way, and say which kind it is.** Wrong for THIS app only — a value, a
|
|
143
|
+
binding, a missing wire — is a local fix and a line in the log. Wrong for EVERY app — a
|
|
144
|
+
helper in `src/lib/`, a component that never accepts a property, a rule that mistranslates
|
|
145
|
+
— is fixed in this project exactly the same way, and additionally written under
|
|
146
|
+
`## For the converter team` so it can be fixed at the source. Never leave the developer
|
|
147
|
+
with a broken app because the real defect is upstream.
|
|
148
|
+
5. **Fix the smallest thing that makes it behave like the original.**
|
|
149
|
+
6. **Verify what you can, and be honest about the rest.** `npm run build` is yours to run and
|
|
150
|
+
proves the code compiles; it proves nothing about behaviour. For that, ask the developer
|
|
151
|
+
to repeat their steps and send the console output or a screenshot. Never report a
|
|
152
|
+
behavioural fix as confirmed on the strength of having written it.
|
|
153
|
+
7. **Log it**, including what you verified, how, and what is still unconfirmed.
|
|
154
|
+
|
|
155
|
+
## Path C — two screenshots, side by side
|
|
156
|
+
|
|
157
|
+
The developer gives you a picture of the low-code app and a picture of the converted one, and
|
|
158
|
+
you find the differences by LOOKING at them. There is no harness and no browser automation
|
|
159
|
+
here: those are internal tools the developer does not have. Everything below works from two
|
|
160
|
+
images and, when a measurement is needed, one line they paste into their browser.
|
|
161
|
+
|
|
162
|
+
Use this whenever the complaint is about how a page looks, and whenever you are about to tell
|
|
163
|
+
someone a page "looks right".
|
|
164
|
+
|
|
165
|
+
1. **Check the two pictures are comparable.** Same page, same data, same window width. If
|
|
166
|
+
they are not, ask for a matching pair rather than reading meaning into the mismatch — a
|
|
167
|
+
narrower window re-wraps a layout and invents differences that are not there. If you were
|
|
168
|
+
given only the low-code picture, ask for the converted one; you cannot take it yourself.
|
|
169
|
+
2. **Read both in the same order, top to bottom and left to right, and write every
|
|
170
|
+
difference down before explaining any of them.** Explaining as you go makes you stop at
|
|
171
|
+
the first one. Work the list: is every control present, and in the same order; is each
|
|
172
|
+
one's text identical, character for character; are heading and label colour, weight and
|
|
173
|
+
size the same; do the fields have the same frame; is spacing and alignment the same; is
|
|
174
|
+
anything cut off, overlapping or missing a scrollbar; do empty states match ("No data" on
|
|
175
|
+
one side against real rows on the other); are images shown or placeholdered.
|
|
176
|
+
3. **Turn each difference into a hypothesis before touching code.** Text present on one side
|
|
177
|
+
and absent on the other is usually invisible rather than missing — an authored colour that
|
|
178
|
+
matches the background. Text at a different size or weight is usually a named heading or
|
|
179
|
+
label style overriding the authored typography. A different STRING is an expression or a
|
|
180
|
+
format helper, not CSS. A missing row is a data call. A control in the wrong place is
|
|
181
|
+
layout; a control that is not there at all is the component.
|
|
182
|
+
4. **Measure rather than squint, without any tooling.** The eye cannot separate 28px from
|
|
183
|
+
32px, and white text on a white page looks exactly like a control that failed to render.
|
|
184
|
+
Ask the developer to open each app, press F12, paste this into the Console and send you
|
|
185
|
+
both answers — it works in the low-code app and the converted one alike:
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
(function (text) {
|
|
189
|
+
const all = [...document.querySelectorAll('*')].filter(
|
|
190
|
+
(e) => e.children.length === 0 && (e.textContent || '').trim() === text);
|
|
191
|
+
const el = all[all.length - 1];
|
|
192
|
+
if (!el) return 'no element with exactly that text';
|
|
193
|
+
const c = getComputedStyle(el);
|
|
194
|
+
const p = el.parentElement ? getComputedStyle(el.parentElement) : c;
|
|
195
|
+
return { text, color: c.color, fontWeight: c.fontWeight, fontSize: c.fontSize,
|
|
196
|
+
fontFamily: c.fontFamily, background: c.backgroundColor, behind: p.backgroundColor,
|
|
197
|
+
textAlign: c.textAlign, box: el.getBoundingClientRect().toJSON() };
|
|
198
|
+
})('the exact text you can see')
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Two answers side by side settle colour, weight, size, font, the background behind the
|
|
202
|
+
text and the box, in seconds. That is how a heading that looked "missing" turned out to be
|
|
203
|
+
the authored white being applied where Apps ignores it and renders 32px.
|
|
204
|
+
5. **Fix in the generated code, then ask for one more screenshot of that page.** A visual fix
|
|
205
|
+
is not finished until the second pair agrees. List in the log the differences that remain
|
|
206
|
+
and why, and put anything systemic under `## For the converter team`.
|
|
207
|
+
|
|
208
|
+
Things this comparison catches that nothing else does: invisible text, a heading at the wrong
|
|
209
|
+
size or weight, a control that rendered off-screen, a grid whose columns do not line up, a
|
|
210
|
+
page that cannot scroll, an image placeholder where the original shows a picture, and text
|
|
211
|
+
that is right but formatted differently. Every one of those has happened on a real app.
|
|
212
|
+
|
|
213
|
+
### Symptom → where to look
|
|
214
|
+
|
|
215
|
+
| What the developer sees | Look at | Usually |
|
|
216
|
+
|---|---|---|
|
|
217
|
+
| A page is blank, or blank until a refresh | the console; `src/routes.tsx` | something threw while rendering OR while unmounting the previous page; each route is wrapped in a boundary, so read which one it names |
|
|
218
|
+
| A control renders but shows nothing / "No data" | the `use…Source` hook in `<Page>.bindings.ts`, then `src/lib/data.ts` | the query's filter or expansion fields, entity-id resolution, the folder id, or a list source handed on where an array was expected |
|
|
219
|
+
| A dropdown or grid editor has no options | the column's `options` in the page, `dropdownValues` in the grid component | a `{ data, totalRecords }` list source where an array was expected |
|
|
220
|
+
| A button does nothing, or only part of what it should | `<control>_<event>` in `<Page>.bindings.ts` | the handler is a TODO, its guard is false (an unset variable), one rule in the chain threw and stopped the rest, or the component never calls it |
|
|
221
|
+
| Typing behaves differently: a mask, decimals, a prefix, separators | the control in `src/components/ui/`, then the authored property in `<Page>.tsx` | an authored input property that reaches no component prop — the page shows what was authored, the component decides whether it is honoured |
|
|
222
|
+
| An image or document does not appear | `src/lib/app-media.ts` and `assetUrl` in `src/lib/runtime.ts`; the Network tab | a media asset resolved by title, an entity attachment that has to be downloaded before it can be shown, or an external URL the host refuses |
|
|
223
|
+
| A value set on one page is not there on another | `src/store/` and the `setAppVar` call in the first page's handler | an app variable written to the wrong name, or a page that re-runs its load rules and overwrites it |
|
|
224
|
+
| The value is right but reads wrong | `src/lib/compat.ts` | a VB-vs-JavaScript formatting difference — see the idioms below |
|
|
225
|
+
| Fonts, colour, weight or size differ | `src/pages/<Page>.module.css` | a control with a NAMED heading or label style takes its typography from Apps' preset, not from the authored properties; only `customized` uses what the designer set |
|
|
226
|
+
| The page does not scroll, or is cut off | `src/styles/tokens.css` | the page host scrolls and the page is as tall as its content |
|
|
227
|
+
| A backend call fails (400/403/404) | the Network tab, then `src/lib/data.ts` and `src/lib/resource-folders.ts` | a process needs its RELEASE key rather than the package id, a bucket its real Orchestrator name rather than the VB identifier, a choice set the tenant-wide flag — or `uipath.json` is missing a scope |
|
|
228
|
+
| Session values are empty (`CurrentUser.*`) | `src/lib/sdk.ts` | the claims the token actually carries |
|
|
229
|
+
| A validation message differs | `useControlValidation` in `src/lib/runtime.ts` | Apps checks by control KIND, only once a value is filled, and a pattern rule outranks a length rule on the same field |
|
|
230
|
+
| A popup, toast or spinner behaves differently | `src/lib/rules.ts`, `src/lib/overlays.tsx` | the rule's own options (modal, position, seconds) |
|
|
231
|
+
|
|
232
|
+
### Differences that are not bugs
|
|
233
|
+
|
|
234
|
+
Measured on real apps. Reporting one of these as fixed, or "fixing" it, makes the converted
|
|
235
|
+
app wrong:
|
|
236
|
+
|
|
237
|
+
- A control with a named heading or label style shows Apps' preset, not the authored font,
|
|
238
|
+
size, weight or colour. Only `customized` uses what the designer set.
|
|
239
|
+
- Apps' own button ignores an authored `url`, and its image an authored `icon`.
|
|
240
|
+
- A label authored white on a white page is invisible in BOTH apps. That is the app's own
|
|
241
|
+
styling, not a conversion fault.
|
|
242
|
+
- Apps' grid shows an unexpanded relationship cell as `[object Object`; the converted grid
|
|
243
|
+
shows the related record's name. Ours is better; leave it.
|
|
244
|
+
- Apps does not always re-render a label after a load rule changes what it reads, so the
|
|
245
|
+
low-code app can show a stale value where the converted app shows the current one.
|
|
246
|
+
- Apps' Preview can fail to render the lower part of a long page, and can fail to fetch
|
|
247
|
+
documents. An empty area on the Apps side is not proof the converted side is wrong.
|
|
248
|
+
- Apps does not draw what is below the fold until the page is scrolled to it, and it shows
|
|
249
|
+
"Loading your app" for several seconds first. A screenshot of the Apps side is only
|
|
250
|
+
evidence once it has been scrolled to the bottom and back and the page has settled —
|
|
251
|
+
otherwise a whole section reads as something the converter invented.
|
|
252
|
+
- Apps wraps every control in a panel named after it (`forms-host-table-panel` around
|
|
253
|
+
`forms-host-table-control`); the converted app has no such wrapper. Extra elements in the
|
|
254
|
+
Apps DOM are not missing elements in ours.
|
|
255
|
+
|
|
256
|
+
### Defects already found and fixed at least once
|
|
257
|
+
|
|
258
|
+
Every row happened on a real app. If what the developer describes matches one, check that
|
|
259
|
+
first — and if this project still has it, fix it here and put it under
|
|
260
|
+
`## For the converter team`, because it means the version that converted this app predates
|
|
261
|
+
the fix.
|
|
262
|
+
|
|
263
|
+
| Area | What it looked like | Where it was | What it needed |
|
|
264
|
+
|---|---|---|---|
|
|
265
|
+
| Data | Starting a process fails, 400 "Undefined process" | `src/lib/data.ts` | the SDK's `processKey` is the RELEASE key, not the package id — list the folder's releases, match the package id, start with the match's `key` |
|
|
266
|
+
| Data | A bucket upload or download says the bucket does not exist | `src/lib/data.ts`, `resource-folders.ts` | send the bucket's real Orchestrator name, not the VB identifier the expressions use |
|
|
267
|
+
| Data | A choice set is "not found" once deployed | `src/lib/data.ts` | list with the tenant-wide flag, not scoped to the app's install folder |
|
|
268
|
+
| Data | An entity query is refused for "not supplying expansion fields" | `src/lib/data.ts` | every fetch has to pass expansion fields |
|
|
269
|
+
| Data | A dropdown or grid shows only the first page of rows | `src/lib/data.ts` | follow the cursor to the end; Apps asks for everything |
|
|
270
|
+
| Data | `FetchOne` pulls the whole table | the page's binding | ask for one record, and express the authored start as a page |
|
|
271
|
+
| Data | A failed read leaves a silent "No data" | `src/store/controls.ts` | Apps shows an error toast; say what failed |
|
|
272
|
+
| Session | `CurrentUser.*` is empty | `src/lib/sdk.ts` | read the signed-in user from the access token's claims |
|
|
273
|
+
| Session | Signing in loses the page the user opened | `src/lib/sdk.ts` | stash the path before initialising, restore it after the callback |
|
|
274
|
+
| Session | Data calls fail right after sign-in, then recover | `src/lib/sdk.ts` | hold the first render until the SDK is authenticated |
|
|
275
|
+
| Expressions | A date renders as `Sun Mar 01 2026 00:00:00 GMT…` | `src/lib/compat.ts` | .NET's default, which is the invariant `MM/dd/yyyy` |
|
|
276
|
+
| Expressions | A date or number looks different on another machine | `src/lib/compat.ts` | Apps is invariant-culture; never `toLocaleString` |
|
|
277
|
+
| Expressions | A page is blank and the console says "unsupported .NET format specifier" | `formatDate` / `formatNumber` | implement the standard specifiers (`C`, `D3`, `E`, `G`, `N2`, `P1`, `X`, `s`, `u`, `o`…) |
|
|
278
|
+
| Expressions | `42 + 19.99` shows `61.989999999999995` | `src/lib/compat.ts` | decimal arithmetic through the `dec*` helpers |
|
|
279
|
+
| Expressions | `"…" & True` shows `true` | the concatenation | VB renders a Boolean as `True`/`False` |
|
|
280
|
+
| Expressions | A grid cell shows `True` where Apps shows `true` | the grid's cell text | a grid cell is not a text field |
|
|
281
|
+
| Expressions | `.join` or a spread throws on an unset list variable | the store default | an unset list variable is an empty list |
|
|
282
|
+
| Components | A mask, prefix, decimals or separators are ignored while typing | `src/components/ui/` | the authored property reached no component prop |
|
|
283
|
+
| Components | A grid's dropdown editor has no options | the grid component | unwrap the `{ data }` list source |
|
|
284
|
+
| Components | A bold button renders regular | `src/styles/tokens.css` | a zero-specificity reset, so the authored weight wins |
|
|
285
|
+
| Components | A heading is invisible, or the wrong font or size | the page's CSS module | a named heading or label style overrides the authored typography |
|
|
286
|
+
| Components | Leaving a page with a document viewer blanks the app | the viewer component, `src/routes.tsx` | guard the unmount cleanup, and keep every route in its own boundary |
|
|
287
|
+
| Components | An entity attachment shows no image | the image component | download the attachment and show it through an object URL |
|
|
288
|
+
| Layout | A long page cannot scroll | `src/styles/tokens.css` | the page host scrolls; the page is as tall as its content |
|
|
289
|
+
| Components | An icon draws at 24px whatever size the author set | `src/styles/tokens.css` | Material Icons pins `font-size` on its own class; the glyph must inherit from the control, and everything under a mis-sized icon sits too high |
|
|
290
|
+
| Components | An open dropdown has no blue ring | `src/styles/tokens.css` | Apps draws 2px `#0067DF` on the trigger while its panel is open, and 1px on the grid's search box |
|
|
291
|
+
| Components | A grid's row icons grey out while another row is being edited | the edit grid component | Apps keeps them lit; only a disabled grid dims them |
|
|
292
|
+
| Components | A grid's rows stop short of the right edge | the edit grid component | a column with no authored width takes `flex: 1` and shares the free space, as Apps' grid does |
|
|
293
|
+
| Components | A dropdown, multi-select or uploader is invisible to an end-to-end selector | the component registry | Apps tags both the dropdown and the multi-select `forms-host-combo-box-control`, and its uploader `upload-file-input` on the file input — there is no `forms-host-file-picker-control` in its vocabulary |
|
|
294
|
+
| Project | The whole app is blank and the console shows an unresolved import | the emitted imports | an import naming a file the project does not contain |
|
|
295
|
+
| Project | The app runs but `npm run build` fails | the pages and components | a prop passed to a component that never declared it, or a name used without importing it |
|
|
296
|
+
|
|
297
|
+
## The generated project
|
|
298
|
+
|
|
299
|
+
| Path | What it is |
|
|
300
|
+
|---|---|
|
|
301
|
+
| `src/pages/<Page>.tsx` | the page's JSX: one element per control, `ctl` is the authored name |
|
|
302
|
+
| `src/pages/<Page>.bindings.ts` | that page's event handlers and source hooks — where rules live |
|
|
303
|
+
| `src/pages/<Page>.module.css` | that page's authored styles, one class per control |
|
|
304
|
+
| `src/components/ui/` | the control components, plus `ui-base.tsx` (shared props, `Guarded`) |
|
|
305
|
+
| `src/lib/runtime.ts` | the accessors expressions call: `getAppVar`/`setAppVar`, control props, validation |
|
|
306
|
+
| `src/lib/rules.ts` | navigation, toasts, spinners, confirmations |
|
|
307
|
+
| `src/lib/data.ts` | every backend call: entities, choice sets, processes, queues, buckets, tasks |
|
|
308
|
+
| `src/lib/compat.ts` | the VB-vs-JavaScript behaviour differences. Read this before writing a formatting fix |
|
|
309
|
+
| `src/lib/resource-folders.ts` | which folder each backend resource lives in, and the keys to reach it |
|
|
310
|
+
| `src/store/` | app variables, control state and data sources (Redux Toolkit) |
|
|
311
|
+
| `src/styles/tokens.css` | every colour and font, plus the app-wide layout rules |
|
|
312
|
+
|
|
313
|
+
## VB → TypeScript, as the generated code does it
|
|
314
|
+
|
|
315
|
+
- `&` concatenates with `Nothing` as `""`; a Boolean in a concatenation is `True`/`False`
|
|
316
|
+
(`boolText`), a date is the invariant `MM/dd/yyyy` (`formatDate`).
|
|
317
|
+
- Apps' VB engine runs under the invariant culture: dates and numbers render the same for
|
|
318
|
+
every viewer. Never reach for `toLocaleString`.
|
|
319
|
+
- A grid CELL prints a boolean as `true`/`false`; a text field prints `True`/`False`.
|
|
320
|
+
- `.ToString(format)` on a date or number goes through `formatDate` / `formatNumber`, which
|
|
321
|
+
implement the .NET format strings; `String.Format` goes through `formatString`.
|
|
322
|
+
- Decimals are exact: `dec`, `decAdd`, `decMul`, `decRound` from `src/lib/compat.ts`.
|
|
323
|
+
- `If(c, a, b)` is `c ? a : b`; `Nothing` is `null`; an unset list variable reads as `[]`.
|
|
324
|
+
- LINQ maps onto array methods: `Where`→`filter`, `Select`→`map`, `First`→`firstOrThrow`,
|
|
325
|
+
`Any`→`some`, `Sum`→`reduce`. `ThisRow` inside a list template is the `row` parameter.
|
|
326
|
+
|
|
327
|
+
## What you must not do
|
|
328
|
+
|
|
329
|
+
- Do not change the report, the log, or the converter.
|
|
330
|
+
- Do not rename generated symbols, reorder files, or reformat code you did not need to touch.
|
|
331
|
+
- Do not remove a `notConverted…` marker without replacing it with a real implementation.
|
|
332
|
+
- Do not fix `source-app` or `by-design` issues.
|
|
333
|
+
- Do not claim a fix works because it should. Say what you ran and what you saw.
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uipath/codedapp-convert-sdk",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "Convert a UiPath Apps export (.uiapp) into a React + TypeScript coded app. The SDK behind `uip codedapp convert`.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
|
+
"author": "UiPath",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/UiPath/apps-dev-tools.git",
|
|
25
|
+
"directory": "lowcode-to-procode-migration/packages/sdk"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"registry": "https://registry.npmjs.org/",
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsx build.mts",
|
|
33
|
+
"smoke": "node -e \"import('./dist/index.js').then((m) => console.log(Object.keys(m).sort().join(', ')))\""
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"decimal.js": "10.6.0",
|
|
37
|
+
"typescript": "^5.4.0"
|
|
38
|
+
}
|
|
39
|
+
}
|