Skip to content

Commit f76e1ed

Browse files
authored
patch.js: improve ergonomics (#85)
1 parent 8f31686 commit f76e1ed

1 file changed

Lines changed: 72 additions & 43 deletions

File tree

Sources/DeveloperAPI/patch.js

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,87 @@
22

33
import fs from 'fs';
44

5-
function makeOpen(enumSchema) {
6-
const copy = structuredClone(enumSchema);
7-
Object.keys(enumSchema).forEach(k => delete enumSchema[k]);
8-
Object.assign(enumSchema, {
9-
anyOf: [
10-
copy,
11-
{ type: 'string' },
12-
]
13-
})
5+
function update(schema, value) {
6+
for (const key in value) {
7+
const val = value[key];
8+
if (val === null) {
9+
delete schema[key];
10+
} else if (Array.isArray(val)) {
11+
schema[key] = (schema[key] ?? []).concat(val);
12+
} else if (typeof val === 'object') {
13+
if (schema[key] === undefined) {
14+
schema[key] = {};
15+
}
16+
update(schema[key], val);
17+
} else {
18+
schema[key] = val;
19+
}
20+
}
21+
}
22+
23+
// in-place update
24+
function replace(schema, value) {
25+
Object.keys(schema).forEach(k => delete schema[k]);
26+
Object.assign(schema, value);
27+
}
28+
29+
function clone(schema) {
30+
return JSON.parse(JSON.stringify(schema));
1431
}
1532

16-
function format(schema) {
17-
const schemas = schema.components.schemas;
33+
function makeOpen(enumSchema) {
34+
replace(enumSchema, {
35+
anyOf: [
36+
clone(enumSchema),
37+
{ type: 'string' },
38+
]
39+
});
40+
}
1841

19-
// this field is required when using the private Xcode API
20-
const capabilityCreateRelationships = schemas.BundleIdCapabilityCreateRequest.properties.data.properties.relationships;
21-
capabilityCreateRelationships.properties.capability = {
42+
function patch(schema) {
43+
const schemas = schema.components.schemas;
44+
45+
// this field is required when using the private Xcode API
46+
update(schemas.BundleIdCapabilityCreateRequest.properties.data.properties.relationships, {
47+
properties: {
48+
capability: {
2249
type: 'object',
2350
properties: {
24-
data: {
25-
type: 'object',
26-
properties: {
27-
type: {
28-
type: 'string',
29-
enum: ['capabilities'],
30-
},
31-
id: { $ref: '#/components/schemas/CapabilityType' },
32-
},
33-
required: ['id', 'type'],
51+
data: {
52+
type: 'object',
53+
properties: {
54+
type: {
55+
type: 'string',
56+
enum: ['capabilities'],
57+
},
58+
id: { $ref: '#/components/schemas/CapabilityType' },
3459
},
60+
required: ['id', 'type'],
61+
},
3562
},
3663
required: ['data'],
37-
}
38-
capabilityCreateRelationships.required.push('capability');
39-
40-
// we don't use this but it triggers a deprecation warning. see:
41-
// https://github.com/apple/swift-openapi-generator/issues/715
42-
schemas.App.properties.relationships.properties.inAppPurchases.deprecated = false;
43-
44-
// openapi-generator expects response enums to be exhaustive. Apple's ASC OpenAPI spec
45-
// misses some cases that they do, actually, return.
46-
// https://swiftpackageindex.com/apple/swift-openapi-generator/1.7.2/documentation/swift-openapi-generator/useful-openapi-patterns#Open-enums-and-oneOfs
47-
makeOpen(schemas.BundleIdPlatform);
48-
makeOpen(schemas.CapabilityType);
49-
makeOpen(schemas.CertificateType);
50-
makeOpen(schemas.Device.properties.attributes.properties.deviceClass);
51-
52-
return schema;
64+
}
65+
},
66+
required: ['capability'],
67+
})
68+
69+
// we don't use this but it triggers a deprecation warning. see:
70+
// https://github.com/apple/swift-openapi-generator/issues/715
71+
schemas.App.properties.relationships.properties.inAppPurchases.deprecated = false;
72+
73+
// openapi-generator expects response enums to be exhaustive. Apple's ASC OpenAPI spec
74+
// misses some cases that they do, actually, return.
75+
// https://swiftpackageindex.com/apple/swift-openapi-generator/1.7.2/documentation/swift-openapi-generator/useful-openapi-patterns#Open-enums-and-oneOfs
76+
makeOpen(schemas.BundleIdPlatform);
77+
makeOpen(schemas.CapabilityType);
78+
makeOpen(schemas.CertificateType);
79+
makeOpen(schemas.Device.properties.attributes.properties.deviceClass);
80+
81+
return schema;
5382
}
5483

5584
const text = fs.readFileSync(process.stdin.fd, 'utf8');
5685
const json = JSON.parse(text);
57-
const formatted = format(json);
58-
const formattedText = JSON.stringify(formatted);
59-
console.log(formattedText);
86+
const patched = patch(json);
87+
const patchedText = JSON.stringify(patched);
88+
console.log(patchedText);

0 commit comments

Comments
 (0)