...
 
Commits (2)
......@@ -15,12 +15,13 @@ class OpenJacClient {
this.loaded_queue = [];
this.is_load_finished = false;
this.definitions = [];
this.definitions_by_path = [];
this.paths = [];
this.tags = [];
this.auth = this.config.auth;
this.api_prefix = '/';
this.api_prefix = '';
if (this.config.schema !== undefined) {
this.load(this.config.schema);
......@@ -29,6 +30,10 @@ class OpenJacClient {
}
}
auth () {
return this.auth;
}
/**
* Retrieve the openapi schema for the application from a url.
*
......@@ -45,7 +50,7 @@ class OpenJacClient {
/**
* Parse and load the definitions and endpoints from a schema blob.
*/
load (schema) {
load(schema) {
this.schema = schema;
if (this.schema.host !== undefined) {
......@@ -66,9 +71,11 @@ class OpenJacClient {
}
}
}
this.api_prefix = this.api_prefix.replace(/(,\s*$)/g, '');
// Setup schema.
this.definitions = [];
this.definitions_by_path = [];
this.paths = [];
this.tags = [];
for (let tag of schema.tags) {
......@@ -78,26 +85,23 @@ class OpenJacClient {
this.paths.push(new Path(this, path, schema.paths[path]));
}
for (let definition_name in schema.definitions) {
this.definitions[definition_name] = new Definition(schema.definitions[definition_name]);
this.definitions[definition_name] = new Definition(this, schema.definitions[definition_name]);
}
// @TODO: Move '?_format=json' to variable so we don't have Drupalisms.
this.fetch(this.api_prefix + '?_format=json').then(jsonapi_links => {
this.fetch(this.api_prefix).then(jsonapi_links => {
for (let type in jsonapi_links.links) {
if (type == 'self') {
continue;
}
// @TODO: This is a workaround for a Drupal issue, and can be removed
// once https://www.drupal.org/project/openapi/issues/2948927 is fixed.
var definition_id = type.replace('--', ':');
if (this.definitions[definition_id] !== undefined) {
var defintion = this.definitions[definition_id];
if (this.definitions[type] !== undefined) {
var definition = this.definitions[type];
var root_path = jsonapi_links.links[type];
if (root_path.startsWith(this.api_prefix)) {
root_path = root_path.substring(this.api_prefix.length);
}
// Map back root paths to definitions.
this.definitions_by_path[root_path] = definition;
var defintion_paths = {};
for (let path of this.paths) {
if (path.uri.startsWith(root_path)) {
......@@ -105,10 +109,10 @@ class OpenJacClient {
if (root_path === path.uri) {
defintion_paths.collection = path;
path.action = 'collection';
} else if(path.uri.includes('/relationships/')) {
} else if (path.uri.includes('/relationships/')) {
defintion_paths.relationships = path;
path.action = 'relationships';
} else if(path.uri.includes('/{related}/')) {
} else if (path.uri.includes('/{related}')) {
defintion_paths.related = path;
path.action = 'related';
} else {
......@@ -117,12 +121,11 @@ class OpenJacClient {
}
}
}
defintion.setPaths(defintion_paths);
definition.setPaths(defintion_paths);
}
}
})
.then(() => {
console.log(this.loaded_queue);
var callback = this.loaded_queue.shift();
while (typeof callback !== 'undefined') {
callback(this);
......@@ -132,18 +135,28 @@ class OpenJacClient {
});
}
defintionForPath(path) {
for (root_path in this.definitions_by_path) {
if (path.startsWith(root_path)) {
return this.definitions_by_path[root_path];
}
}
return undefined;
}
/**
* Construct init parameter for fetch.
*/
buildRequest(data, method) {
// @TODO add auth headers.
method = method.toUpperCase();
var request = {
method: method,
redirect: 'follow',
headers: {}
}
if (method !== 'GET' && method !== 'HEAD') {
if (!(['GET', 'HEAD'].includes(method))) {
request.body = JSON.stringify(data);
}
return request;
......@@ -154,7 +167,7 @@ class OpenJacClient {
*/
fetchFrom(path, method, data = {}) {
var uri = path.buildUri(method, data);
return this.fetch(uri, method, data);
return this.fetch(this.api_prefix + uri, method, data);
}
/**
......@@ -176,7 +189,6 @@ class OpenJacClient {
});
})
.then(res => {
console.log(res);
if (res.status !== 200) {
throw 'Authentication Requied';
Promise.reject();
......@@ -205,6 +217,7 @@ class OpenJacClient {
* Get the definition type.
*/
on(type) {
console.log("ON" + type);
return this.definitions[type];
}
......
......@@ -16,17 +16,16 @@ class Path {
* Construct a uri injecting param data into the uri.
*/
buildUri(method, data) {
console.log(method);
if (this.methods.hasOwnProperty(method)) {
var uri = this.uri;
var schema = this.methods[method];
for (param of schema.parameters) {
for (let param of schema.parameters) {
if (param.in === 'path') {
if (data[param.name] === undefined) {
if (typeof data[param.name] === 'undefined') {
throw 'Path parameter "' + param.name + '" is missing.';
}
delete data[param.name];
uri = uri.replace('{' + param.name + '}', data[param.name]);
delete data[param.name];
} else if (param.required) {
throw 'Required parameter "' + param.name +'" is missing.';
}
......@@ -45,15 +44,19 @@ class Path {
* based upon the action.
*/
execute(method, data) {
console.log(data);
method = method.toUpperCase();
var url = '';
if (this.methods.hasOwnProperty(method)) {
method = method.toLowerCase();
if (!this.methods.hasOwnProperty(method)) {
throw 'Invalid Method ' + method + ' for ' + this.action + ' action.'
}
if (['GET', 'DELETE']) {
if (['get', 'delete'].includes(method) && this.action === 'individual') {
var param_regex = /{([^}]*:?)}/i;
var key_match = this.uri.match(param_regex);
if (key_match.length > 1) {
let uuid = data;
data = {};
data[key_match[1]] = uuid;
}
}
return this.client.fetchFrom(this, method, data);
......