mirror of
https://github.com/xtool-org/xtool.git
synced 2026-02-04 11:53:30 +01:00
111 lines
3.2 KiB
JavaScript
111 lines
3.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import fs from 'fs';
|
|
|
|
function update(schema, value) {
|
|
for (const key in value) {
|
|
const val = value[key];
|
|
if (val === null) {
|
|
delete schema[key];
|
|
} else if (Array.isArray(val)) {
|
|
schema[key] = (schema[key] ?? []).concat(val);
|
|
} else if (typeof val === 'object') {
|
|
if (schema[key] === undefined) {
|
|
schema[key] = {};
|
|
}
|
|
update(schema[key], val);
|
|
} else {
|
|
schema[key] = val;
|
|
}
|
|
}
|
|
}
|
|
|
|
// in-place update
|
|
function replace(schema, value) {
|
|
Object.keys(schema).forEach(k => delete schema[k]);
|
|
Object.assign(schema, value);
|
|
}
|
|
|
|
function clone(schema) {
|
|
return JSON.parse(JSON.stringify(schema));
|
|
}
|
|
|
|
function makeOpen(enumSchema) {
|
|
replace(enumSchema, {
|
|
anyOf: [
|
|
clone(enumSchema),
|
|
{ type: 'string' },
|
|
]
|
|
});
|
|
}
|
|
|
|
function openAll(schema, path = []) {
|
|
if (Array.isArray(schema)) {
|
|
schema.forEach((s, i) => openAll(s, [...path, i]))
|
|
} else if (typeof schema === 'object' && schema !== null) {
|
|
const keys = new Set(Object.keys(schema))
|
|
if (keys.size === 2
|
|
&& keys.has('type')
|
|
&& keys.has('enum')
|
|
&& schema.type === 'string'
|
|
&& Array.isArray(schema.enum)) {
|
|
// several polymorphic schemas have a field literally named 'type', that always has a single case.
|
|
// skip that instance, but make all other enums open.
|
|
if (!(path[path.length - 1] === 'type' && schema.enum.length === 1)) {
|
|
makeOpen(schema);
|
|
}
|
|
} else {
|
|
for (const key in schema) {
|
|
openAll(schema[key], [...path, key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function patch(schema) {
|
|
const schemas = schema.components.schemas;
|
|
|
|
// this field is required when using the private Xcode API
|
|
update(schemas.BundleIdCapabilityCreateRequest.properties.data.properties.relationships, {
|
|
properties: {
|
|
capability: {
|
|
type: 'object',
|
|
properties: {
|
|
data: {
|
|
type: 'object',
|
|
properties: {
|
|
type: {
|
|
type: 'string',
|
|
enum: ['capabilities'],
|
|
},
|
|
id: { $ref: '#/components/schemas/CapabilityType' },
|
|
},
|
|
required: ['id', 'type'],
|
|
},
|
|
},
|
|
required: ['data'],
|
|
}
|
|
},
|
|
required: ['capability'],
|
|
})
|
|
|
|
// we don't use this but it triggers a deprecation warning. see:
|
|
// https://github.com/apple/swift-openapi-generator/issues/715
|
|
schemas.App.properties.relationships.properties.inAppPurchases.deprecated = false;
|
|
|
|
// openapi-generator expects response enums to be exhaustive. Apple's ASC OpenAPI spec
|
|
// misses some cases that they do, actually, return. So we make all bona fide enums in
|
|
// schema.components.schemas open. We don't do this on the schema.paths side because
|
|
// most (all?) of the enums in there are on the request side rather than the response.
|
|
// https://swiftpackageindex.com/apple/swift-openapi-generator/1.7.2/documentation/swift-openapi-generator/useful-openapi-patterns#Open-enums-and-oneOfs
|
|
openAll(schemas);
|
|
|
|
return schema;
|
|
}
|
|
|
|
const text = fs.readFileSync(process.stdin.fd, 'utf8');
|
|
const json = JSON.parse(text);
|
|
const patched = patch(json);
|
|
const patchedText = JSON.stringify(patched);
|
|
console.log(patchedText);
|