[request] Trimmed version
Hey!
Would you mind to add the trimmed version to this repository as well?
Bests
The trimmed version is an artifact of the full version of the spec. I don't fully like that artifacts would be included next to the source in source control.
All of the artifacts are available here: https://jman012.github.io/FloatplaneAPIDocs/ and the trimmed spec specifically at https://jman012.github.io/FloatplaneAPIDocs/floatplane-openapi-specification-trimmed.json. Or if you prefer Git: https://github.com/Jman012/jman012.github.io/blob/main/FloatplaneAPIDocs/floatplane-openapi-specification-trimmed.json (which I think is public).
Do any of the above work for your process?
My problem is that I want to have the API specs as a git submodule in my Android project. I checked that I couldn't have a single file as a git submodule, and the docs repo You referenced contains many irrelevant other files that aren't needed to my workflow. If this change is firmly against Your will, I don't mind if I have to manage it manually!
Thanks for your fast reply!
In my Wasserflug project, https://github.com/Jman012/Wasserflug-tvOS/, I opted to just copy it in manually from https://jman012.github.io/FloatplaneAPIDocs/.
Being a build artifact, it really should be a versioned document on something akin to npm, but it being just a json file instead of code, and frequently coming with breaking changes as I settle on things, I'm not sure how feasible that would be.
My biggest fear is making changes to the source document, and committing that without remembering to re-generate the trimmed document. That would be embarrassing.
Would it be possible to use git submodules for this repo and then always re-trim the file upon build? All you need to do to trim the document is run src/trim.js or run npm run trim. You don't need any dependencies aside from node.
My biggest fear is making changes to the source document, and committing that without remembering to re-generate the trimmed document. That would be embarrassing.
I'm not familiar with GitHub actions but maybe you can automate this part with it.
Would it be possible to use git submodules for this repo and then always re-trim the file upon build?
Currently, I use this repo as a submodule and copy-pasted the trimmed version into it.
As an Android dev, I'm not that familiar with node, and to be honest, I don't want to mix in another tech stack just for the trimming.
I completely understand Your point so I will close this issue. Maybe in the future, I will adapt Your JS script to Kotlin and open a PR with it. Until then the copy-paste solution would be fine for me!
Thanks for your time!
The trim.js script could easily be adapted to any language. Python and Ruby tend to be installed on most OSes by default, for instance.
I'll re-open this so I don't lose track of this. I'll keep thinking on it. I might end up making the change. I'll be busy soon so it might be a bit.
I made some progress here!
My goal with all of this is to make the project as self-contained as possible.
So I found a gradle plugin to run js scripts (https://github.com/node-gradle/gradle-node-plugin), and added the following line to trim.js:
var specLocation = process.argv[2] !== null ? process.argv[2] : "../floatplane-openapi-specification.json"
to handle the path correctly without modifying your original path. Note here: I have zero experience with JS
So my custom gradle task calls your script with the correct path:
tasks.register("generateTrimmedSpecs", NodeTask){
group = "generator"
script = file("$rootDir/contract/src/trim.js")
args = ["$rootDir/contract/floatplane-openapi-specification.json"]
}
But I'm stuck here:
........
Removed: /api/v3/experiments/vpn/profile/download get
Removed: /api/v3/experiments/vpn/profile/ephemeral get
Removed: /api/v3/experiments/vpn/server/list get
C:\Users\stewe\StudioProjects\FightJet\contract\src\trim.js:32
if (!Object.keys(spec.paths).flatMap(path => Object.keys(spec.paths[path]).map(operation => spec.paths[path] operation])).some(op => op.tags.some(t => t == spec.tags[tag].name))) {
^
TypeError: Object.keys(...).flatMap is not a function
at fs.readFile (C:\Users\stewe\StudioProjects\FightJet\contract\src\trim.js:32:33)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':generateTrimmedSpecs'.
> Process 'command 'node'' finished with non-zero exit value 1
Could you help me out with the above issue?
That's odd. flatMap isn't that new of a function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
My guess is that the node that plugin uses is older/out of date and doesn't include flatMap as a method on arrays. If you could see which version of Node it's using, that could be helpful.
Feel free to re-create the trim.js script in Java/Kotlin, if you wish. They can exist side-by-side.
My fault :"D Actually the plugin primarily uses the locally installed Node instance, I didn't even remember I installed it, but it's v8.12 :D But the plugin can be configured to download any version, so the complete solution: Gradle config:
plugins {
..........
id "com.github.node-gradle.node" version "3.4.0"
}
..........
node {
download = true
version = "16.17.1"
distBaseUrl = "https://nodejs.org/dist"
}
tasks.register("generateTrimmedSpecs", NodeTask) {
group = "generator"
script = file("$rootDir/contract/src/trim.js")
args = [
"$rootDir/contract/floatplane-openapi-specification.json",
"$rootDir/contract/floatplane-openapi-specification-trimmed.json"
]
}
Completed trim.js:
const fs = require("fs");
// Nothing to trim for either Frontend nor Chat AsyncAPI files.
var specLocation = process.argv[2] !== null ? process.argv[2] : "../floatplane-openapi-specification.json"
var outputLocation = process.argv[3] !== null ? process.argv[3] : "../floatplane-openapi-specification-trimmed.json"
fs.readFile(specLocation, "utf8", (err, data) => {
if (err) {
console.log("Could not read ../floatplane-openapi-specification.json");
} else {
const spec = JSON.parse(data);
for (var path in spec.paths) {
for (var method in spec.paths[path]) {
if (spec.paths[path][method].description.indexOf("TODO") == 0) {
console.log("Removed: " + path + " " + method);
delete spec.paths[path][method];
}
}
}
for (var path in spec.paths) {
if (Object.keys(spec.paths[path]).length == 0) {
delete spec.paths[path];
}
}
var tagsToRemove = [];
for (var tag in spec.tags) {
if (!Object.keys(spec.paths).flatMap(path => Object.keys(spec.paths[path]).map(operation => spec.paths[path][operation])).some(op => op.tags.some(t => t == spec.tags[tag].name))) {
console.log("Removing tag " + spec.tags[tag].name);
tagsToRemove.push(spec.tags[tag].name);
}
}
for (var tagToRemove of tagsToRemove) {
spec.tags = spec.tags.filter(tag => tag.name != tagToRemove);
}
fs.writeFile(outputLocation, JSON.stringify(spec, null, 4), "utf8", (err) => {
if (err) {
console.log("Cound not write to ../floatplane-openapi-specification-trimmed.json");
} else {
console.log("Done");
}
});
}
});
And for a newer Android project turn off the dependency resolution strategy in setting.gradle:
dependencyResolutionManagement {
//repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
This way every step is done by gradle and I can build tasks around it.