-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DX-665] WiP for loading open api spec
- Loading branch information
Showing
9 changed files
with
73,543 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ node_modules | |
coverage | ||
ZORK1.DAT | ||
*.glksave | ||
twilio-cli-*.tgz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ node_modules | |
coverage | ||
ZORK1.DAT | ||
*.glksave | ||
twilio-cli-*.tgz |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const { Plugin } = require('@oclif/config'); | ||
// const { TwilioClientCommand } = require('../../base-commands/twilio-client-command'); | ||
// const { TwilioApiBrowser } = require('../../services/twilio-api'); | ||
|
||
class TwilioRestApiPlugin extends Plugin { | ||
async load() { | ||
await super.load(); | ||
} | ||
|
||
get hooks() { | ||
return {}; | ||
} | ||
|
||
get topics() { | ||
return []; | ||
} | ||
|
||
get commandIDs() { | ||
return []; | ||
} | ||
|
||
get commands() { | ||
return []; | ||
} | ||
} | ||
|
||
module.exports = async function () { | ||
// const browser = new TwilioApiBrowser(); | ||
this.config.plugins.push(new TwilioRestApiPlugin(this.config)); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
const url = require('url'); | ||
const apiSpecFromDisk = require('./twilio_api.json'); | ||
|
||
function translateLegacyVersions(domain, version) { | ||
// In the Node helper library, api.twilio.com/2010-04-01 is represented as "v2010" | ||
if (domain === 'api' && version === '2010-04-01') { | ||
return 'v2010'; | ||
} | ||
return version; | ||
} | ||
|
||
const listResourceMethodMap = { | ||
get: 'list', | ||
post: 'create' | ||
}; | ||
|
||
const instanceResourceMethodMap = { | ||
delete: 'remove', | ||
get: 'fetch', | ||
post: 'update' | ||
}; | ||
|
||
/* | ||
Notes: | ||
Disambiguating like-named resources: | ||
If same resource name exists under multiple domains/versions/paths, then have the command | ||
map to a help message when it is ambiguous as to which domain/version/path they want. | ||
Maybe have a setting to change this behavior? Have a custom shortcut map in the config | ||
file? Have a mode of operation where it just picks the most recent version? | ||
*/ | ||
|
||
class TwilioApiBrowser { | ||
constructor(apiSpec) { | ||
this.apiSpec = apiSpec || apiSpecFromDisk; | ||
this.domains = this.loadDomains(); | ||
} | ||
|
||
loadDomains() { | ||
const domains = {}; | ||
|
||
Object.keys(this.apiSpec.paths).forEach(path => { | ||
// Naive assumption: The Twilio API's only have a single domain | ||
const serverUrl = new url.URL(this.apiSpec.paths[path].servers[0].url); | ||
const domain = serverUrl.host.split('.')[0]; // e.g. 'api' from 'api.twilio.com' | ||
|
||
const version = translateLegacyVersions( | ||
domain, | ||
path.split('/')[1] // e.g. 'v1' from '/v1/foo/bar' | ||
); | ||
|
||
if (!Object.prototype.hasOwnProperty.call(domains, domain)) { | ||
domains[domain] = { versions: {} }; | ||
} | ||
|
||
if (!Object.prototype.hasOwnProperty.call(domains[domain].versions, version)) { | ||
domains[domain].versions[version] = { resources: {} }; | ||
} | ||
|
||
const isInstanceResource = path.endsWith('}.json'); | ||
|
||
const pathParts = path.split('/'); | ||
pathParts.splice(1, 1); // e.g. '/v1/foo' becomes '/foo' | ||
if (isInstanceResource) { | ||
pathParts.splice(pathParts.length - 1, 1); // e.g. /foo/{Sid} becomes /foo | ||
} | ||
const resourcePath = pathParts.join('/').replace('.json', ''); | ||
|
||
const resources = domains[domain].versions[version].resources; | ||
if (!Object.prototype.hasOwnProperty.call(resources, resourcePath)) { | ||
resources[resourcePath] = { actions: {} }; | ||
} | ||
|
||
const actions = resources[resourcePath].actions; | ||
const methodMap = isInstanceResource ? instanceResourceMethodMap : listResourceMethodMap; | ||
Object.keys(methodMap).forEach(method => { | ||
if (Object.prototype.hasOwnProperty.call(this.apiSpec.paths[path], method)) { | ||
actions[methodMap[method]] = this.apiSpec.paths[path][method]; | ||
} | ||
}); | ||
}); | ||
|
||
return domains; | ||
} | ||
} | ||
|
||
module.exports = { TwilioApiBrowser }; |
Oops, something went wrong.