mirror of
https://github.com/sourcey/spectacle.git
synced 2024-10-05 17:38:59 +03:00
Integrated resolve-references into the preprocessor.
This commit is contained in:
parent
f41c5d5440
commit
edccddb1c9
@ -1,12 +1,18 @@
|
||||
var path = require('path'),
|
||||
_ = require('lodash');
|
||||
|
||||
var httpMethods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'];
|
||||
var httpMethods = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', '$ref'];
|
||||
|
||||
// Preprocessor for the Swagger JSON so that some of the logic can be taken
|
||||
// out of the template.
|
||||
|
||||
module.exports = function(options, specData) {
|
||||
if(!options.specFile) {
|
||||
console.warn("[WARNING] preprocessor must be given 'options.specFile'. Defaulting to 'cwd'.");
|
||||
options.specFile = process.cwd();
|
||||
}
|
||||
specData["x-spec-path"] = options.specFile;
|
||||
|
||||
var copy = _.cloneDeep(specData);
|
||||
var tagsByName = _.keyBy(copy.tags, 'name');
|
||||
|
||||
@ -66,19 +72,8 @@ module.exports = function(options, specData) {
|
||||
copy.showTagSummary = copy.tags.length > 1
|
||||
}
|
||||
|
||||
// Resolve references to external files.
|
||||
function resolveReferences(obj) {
|
||||
for (var k in obj) {
|
||||
var val = obj[k];
|
||||
if (typeof val === "object" && val !== null) {
|
||||
resolveReferences(val);
|
||||
}
|
||||
else {
|
||||
// #TODO: resolve references
|
||||
}
|
||||
}
|
||||
}
|
||||
resolveReferences(copy);
|
||||
var replaceRefs = require("./resolve-references").replaceRefs;
|
||||
replaceRefs(path.dirname(copy["x-spec-path"]), copy, copy, "");
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ var TreeWalkError = require("./errors").TreeWalkError;
|
||||
* @return {boolean} `true` if the reference points to the current file.
|
||||
*/
|
||||
function localReference(ref) {
|
||||
return typeof ref.trim === "function" && ref.trim().indexOf("#") === 0;
|
||||
return (typeof ref.trim === "function" && ref.trim().indexOf("#") === 0) ||
|
||||
(typeof ref.indexOf === "function" && ref.indexOf("#") === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,7 +77,9 @@ function replaceReference(cwd, top, obj, context) {
|
||||
var external = pathUtils.relative(path.dirname(top["x-spec-path"]), ref);
|
||||
var referenced = module.exports.fetchReference(ref);
|
||||
referenced["x-external"] = external;
|
||||
module.exports.replaceRefs(path.dirname(ref), top, referenced, context);
|
||||
if(typeof referenced === "object") {
|
||||
module.exports.replaceRefs(path.dirname(ref), top, referenced, context);
|
||||
}
|
||||
//TODO use other merge mechanisms besides `Object.assign(obj, ...)` depending on the path.
|
||||
Object.assign(obj, referenced);
|
||||
delete obj.$ref;
|
||||
@ -97,7 +100,12 @@ function replaceReference(cwd, top, obj, context) {
|
||||
*/
|
||||
function replaceRefs(cwd, top, obj, context) {
|
||||
|
||||
if(typeof obj !== "object") { return; }
|
||||
if(typeof cwd !== "string" || cwd.length < 1) {
|
||||
throw new Error("replaceRefs must be given a 'cwd'. Given '"+cwd+"'");
|
||||
}
|
||||
if(typeof obj !== "object") {
|
||||
console.warn("[WARN] replaceRefs() must be given an object for 'obj'. Given "+typeof obj+" ("+obj+")");
|
||||
return; }
|
||||
|
||||
if(obj.$ref) {
|
||||
throw new TreeWalkError("Walked too deep in the tree looking for references. Can't resolve reference " +
|
||||
@ -111,11 +119,18 @@ function replaceRefs(cwd, top, obj, context) {
|
||||
if(val.$ref) {
|
||||
|
||||
if(localReference(val.$ref)) {
|
||||
if(cwd === top["x-spec-path"]) { continue; }
|
||||
throw new Error("Can't deal with internal references in external files yet.");
|
||||
if((cwd === top["x-spec-path"]) || (cwd === path.dirname(top["x-spec-path"]))) { continue; }
|
||||
throw new Error(
|
||||
"Can't deal with internal references in external files yet. Got: '"+val.$ref+"'.");
|
||||
}
|
||||
|
||||
module.exports.replaceReference(cwd, top, val, context);
|
||||
try {
|
||||
module.exports.replaceReference(cwd, top, val, context);
|
||||
}
|
||||
catch (e) {
|
||||
console.error("Couldn't replace reference to '"+val.$ref+"' from '"+cwd+"'. Reference path: #/"+context);
|
||||
throw e;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
<button class="close-button" aria-label="Close menu" type="button" data-drawer-close>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<div id="logo">
|
||||
<img src="images/cheese.png" title="Cheese Store" /> </div>
|
||||
<nav id="nav" role="navigation">
|
||||
<h5>API Reference</h5>
|
||||
<a href="#introduction">Introduction</a>
|
||||
|
16
test/fixtures/User.yml
vendored
Normal file
16
test/fixtures/User.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: The user's unique identifer.
|
||||
name:
|
||||
type: string
|
||||
description: The user's full name.
|
||||
email:
|
||||
type: string
|
||||
description: |
|
||||
The user's email address.
|
||||
Only included in documents for the current user.
|
@ -26,26 +26,28 @@ describe("preprocessor referencing", function() {
|
||||
},
|
||||
},
|
||||
});
|
||||
processed = preprocessor({}, spec);
|
||||
processed = preprocessor({
|
||||
specFile: __dirname + "/spec.json",
|
||||
}, spec);
|
||||
});
|
||||
|
||||
it("should include the path section", function() {
|
||||
processed.paths.should.have.key("/");
|
||||
processed.paths.should.have.property("/");
|
||||
processed.paths["/"].should.be.an.object;
|
||||
});
|
||||
|
||||
it.skip("should include the imported paths", function() {
|
||||
processed.paths["/"].should.have.key("get");
|
||||
processed.paths["/"].should.have.key("post");
|
||||
it("should include the imported paths", function() {
|
||||
processed.paths["/"].should.have.property("get");
|
||||
processed.paths["/"].should.have.property("post");
|
||||
});
|
||||
|
||||
it.skip("should include the reference path ('/' path)", function() {
|
||||
processed.paths["/"].should.have.property("x-external", "./fixtures/basic-path.yaml");
|
||||
it("should include the reference path ('/' path)", function() {
|
||||
processed.paths["/"].should.have.property("x-external", "fixtures/basic-path.yaml");
|
||||
});
|
||||
|
||||
it.skip("should include the reference path ('get', 'post')", function() {
|
||||
processed.paths["/"].get.should.have.property("x-external", "./fixtures/basic-path.yaml#get");
|
||||
processed.paths["/"].post.should.have.property("x-external", "./fixtures/basic-path.yaml#post");
|
||||
processed.paths["/"].get.should.have.property("x-external", "fixtures/basic-path.yaml#get");
|
||||
processed.paths["/"].post.should.have.property("x-external", "fixtures/basic-path.yaml#post");
|
||||
});
|
||||
|
||||
});
|
||||
@ -61,11 +63,13 @@ describe("preprocessor referencing", function() {
|
||||
responses: { "200": {
|
||||
description: "Current user",
|
||||
schema: {
|
||||
"$ref": "fixtures/User.yaml"
|
||||
"$ref": "fixtures/User.yml"
|
||||
}
|
||||
}
|
||||
}}}}});
|
||||
processed = preprocessor({}, spec);
|
||||
processed = preprocessor({
|
||||
specFile: __dirname + "/spec.json",
|
||||
}, spec);
|
||||
response = processed.paths["/"].get.responses["200"];
|
||||
});
|
||||
|
||||
@ -78,10 +82,11 @@ describe("preprocessor referencing", function() {
|
||||
});
|
||||
|
||||
it.skip("should update '$ref'", function() {
|
||||
response.schema.should.have.key("$ref", "#/definitions/.%2Ffixtures%2FUser.yaml");
|
||||
response.schema.should.have.property("$ref", "#/definitions/.%2Ffixtures%2FUser.yaml");
|
||||
});
|
||||
|
||||
it.skip("should include the definition globally", function() {
|
||||
processed.should.have.property("definitions");
|
||||
processed.definitions.should.be.an.object;
|
||||
processed.definitions.should.have.property("./fixtures/User.yaml");
|
||||
var schema = processed.definitions["./fixtures/User.yaml"];
|
||||
|
@ -12,7 +12,9 @@ describe("preprocessor", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
spec = Object.assign({}, minimal);
|
||||
processed = preprocessor({}, spec);
|
||||
processed = preprocessor({
|
||||
specFile: __dirname + "/spec.json"
|
||||
}, spec);
|
||||
});
|
||||
|
||||
describe("with minimal spec", function() {
|
||||
|
Loading…
Reference in New Issue
Block a user