Repository navigation
Use OpenAPI schema for config editor fields, fixes #871 - #1767
UmmmAGoodName wants to merge 10 commits into
Conversation
|
Thanks for pointing out ASF flaws, I agree with all stated here.
I've added proper support for JustArchiNET/ArchiSteamFarm@a39fb49 Now properties carry proper default value: "OnlineStatus": {
"type": "integer",
"default": 1,
"x-definition": {
"Offline": 0,
"Online": 1,
"Busy": 2,
"Away": 3,
"Snooze": 4,
"LookingToTrade": 5,
"LookingToPlay": 6,
"Invisible": 7
}It works even for complex types like "default": {
"WebProxy": null,
"AcceptGifts": false,
"BotBehaviour": 0,
"CompleteTypesToSend": [ ],
"CustomGamePlayedWhileFarming": null,
"CustomGamePlayedWhileIdle": null,
"Enabled": false,
"FarmingOrders": [ ],
"FarmingPreferences": 0,
"GamesPlayedWhileIdle": [ ],
"GamingDeviceType": 1,
"HoursUntilCardDrops": 3,
"LootableTypes": [
1,
3,
5
],
"MachineName": null,
"MatchableTypes": [
5
],
"OnlineFlags": 0,
"OnlineStatus": 1,
"PasswordFormat": 0,
"RedeemingPreferences": 0,
"RemoteCommunication": 3,
"SendTradePeriod": 0,
"SteamMasterClanID": 0,
"SteamTradeToken": null,
"SteamUserPermissions": { },
"TradeCheckPeriod": 60,
"TradingPreferences": 0,
"TransferableTypes": [
1,
3,
5
],
"UseLoginKeys": true,
"UserInterfaceMode": 0,
"WebProxyUsername": null,
"s_SteamMasterClanID": "0"
}I believe no
I'll see tomorrow what can be done about that. |
|
After implementing JustArchiNET/ArchiSteamFarm@3d5b45b - ASF-ui can now distinguish sets from lists by looking up whether "FarmingOrders": {
"type": "array",
"items": {
"$ref": "#/components/schemas/EFarmingOrder"
},
"default": [ ] "CompleteTypesToSend": {
"uniqueItems": true,
"type": "array",
"items": {
"$ref": "#/components/schemas/EAssetType"
},
"default": [ ]
},This can also be used for determining whether order matters, e.g. for |
|
Finally, after JustArchiNET/ArchiSteamFarm@0eb23c8, it's now possible to determine exact key type in all dictionaries: "SteamUserPermissions": {
"propertyNames": {
"maxLength": 20,
"pattern": "^[0-9]+$",
"type": "string"
},
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/EAccess"
},
"x-key-type": "System.UInt64"
},I went with hybrid approach here, that is:
That should cover all needs in this PR:
Let me know if you stumble upon any other limitations @UmmmAGoodName |
|
Thanks, that covers everything this PR needed. Updated in the latest commit:
Two small things I noticed while testing against 6.3.11.0:
|
Yeah, ASF-ui can't assume exact placement of some schema component - instead, it should traverse the tree in the expected way, that is, look up schema definition for given property in request/response that interests you, and grab definition from there - either directly (if it's inlined), or by navigating to appropriate Inlining was required since the same schemas can have different default values depending on usage. The current code is smart and tries to avoid duplicate inlines - this is why you see combination of Definitely no assumption can be done whether given schema is inlined or not - it can and will change across different ASF versions. Caller must support both - inlined, as well as referenced schema definition for given property. It should not be a problem - just look up if you have In any case, the only proper lookup can be done by analyzing the request/response property that you want to understand - not by taking arbitrary unlinked component that just happened to have correctly matching name.
I'll take a look, chance is we can fix that. |
@UmmmAGoodName Fixed in V6.3.11.1, thanks for info. Let me know if you discover any other inconsistencies. |
… its own default since ASF 6.3.11.1
|
Thanks for the quick fix. Verified against 6.3.11.1 and pushed two more commits:
With this the PR requires ASF 6.3.11.1 or newer. No |
|
@MrBurrBurr care to check the status of this PR and whether it's possible to merge? It seems to do far more good than bad, and also fixes some outstanding ASF-ui issues that we had before. |
|
@UmmmAGoodName New This affects all sensitive fields, including ones which need clear distinction between empty and null ( After discussing with Archi:
|
|
As per what @Aareksio said:
For keeping existing value: {}For setting new value: { "SteamPassword": "new" }For removing value, same concept as above (assumes { "SteamPassword": null }All of that can be done with existing ASF API functionality and swagger definition. Therefore, fix seems to be NOT to render |
|
Thanks @Aareksio, good catch. Fixed in 767c2bf and verified against 6.3.11.3: properties carrying There is one gap this leaves, and I'd rather fix it in ASF than in ASF-ui:
I could hardcode those two names in ASF-ui as a workaround, but that's the kind of assumption we just removed from the schema loader (lists, dictionary keys, component names), and it would silently break the next time a sensitive property is added or renamed. The clean fix on the ASF side would be:
With that in place the rule in ASF-ui stays a single line, |
|
Missing It's proper assumption that every single property behaving this way must carry |
|
LGTM, @JustArchi if possible, I would love for this to land in pre-release ASF and wait a little (2 week-ish) before being promoted to stable. Just in case of hidden user-facing regression synthetic tests omitted. |
|
In this case we can wait a few days to a week more, and I'll release a new monthly pre-release cycle with this bundled. You get like full month till stable then. I can merge the PR myself then when ready, thanks! |
Description
Fixes #871, supersedes #1022.
fetchConfigSchema.jsno longer callsGET /Api/Typeand no longer parses .NET generic type strings with regexes. Field schemas for the config editor are now derived from ASF's OpenAPI document (swagger/ASF/swagger.json), whichutils/swagger/parse.jsalready fetches, caches and$ref-dereferences for the currency codes, so the document is still requested only once per page load.unwindType()keeps its name, signature and output shape, soEditor.vue, theFields/components and all views that call it are untouched.Mapping from the OpenAPI property schema to the editor field
type:typetype: booleanbooleantype: string/["null", "string"]string(nullable: truewhennullis listed)format: uuid(LicenseID)string, as before (Editor.vuewould acceptguid, butisEqual()has noguidcase, so switching would change default detection; left for a follow-up)format: uint8/uint16/uint32/uint64byte/uint16/uint32/uint64(uint64still gets thes_paramName)type: arrayhashSet;listforFarmingOrdersandGamesPlayedWhileIdle, which areImmutableListin ASF. OpenAPI cannot tell sets and lists apart, so these are hardcoded (verified against/Api/Typeon 6.3.9.6).values= resolveditemstype: object+additionalPropertiesdictionary;keyisstring, exceptSteamUserPermissions(Dictionary<ulong, EAccess>) →uint64.value= resolvedadditionalProperties$refto a schema withx-definitionflagwhenformat: flags, elseenum;values= thex-definitionmapunknown(InputUnknown fallback)Properties named
s_*are skipped: the spec listsSteamOwnerIDands_SteamOwnerID(and the clan ID pair) separately, while the UI derives thes_name from theuint64property as before.Defaults: the OpenAPI schema carries no
defaultvalues, soGET /Api/Structure/{type}is still used (one cached call per type) fordefaultValue. ASF can drop/Api/Typeas far as ASF-ui is concerned, but not/Api/Structureyet.Passthrough keys (not consumed yet):
minimum,maximum,maxItems,x-valid-values→validValuesandx-security-critical→securityCriticalare copied onto each field schema for #1445 / #1650. No UI logic uses them in this PR.Screenshots
No visual changes by design. ASF config, bot config, Create Bot and the Mass Editor render the same inputs as before: flag multi-selects and enum selects show names,
FarmingOrdersis an ordered list,SteamUserPermissionsuses the select-based dictionary editor andGamesPlayedWhileIdleuses InputGames. The only observable difference is in the network tab: opening a config page no longer issues the ~20/Api/Type/...requests, onlyswagger.jsonand one/Api/Structure/...call.Additional information
Verified against a live ASF 6.3.9.6 instance. The old and new implementations were run side by side and the resulting
bodyobjects deep-diffed for bothBotConfig(34 fields) andGlobalConfig(35 fields). Everytype,values,key/value,paramNameanddefaultValueis identical. The only differences are in thenullablekey, which nothing in the UI reads:Nullable<T>value types via reflection, sostring?properties never gotnullable; the new code marks every["null", "string"]property as nullable;LicenseID(Guid?) is described by the spec as{ format: uuid }with notype, so it losesnullable: true.Two small things to be aware of:
typearrays withnull,format: uint8/…/uint64,format: flags,x-definition). A spec with a different shape would degrade affected fields to the InputUnknown fallback rather than fail.A follow-up could let ASF mark ordered collections and
ulong-keyed dictionaries in the spec (e.g. anx-extension), which would remove the two hardcoded property sets in this file.Checklist