a127-magic
Advanced tools
Comparing version 0.5.0 to 0.5.1
@@ -46,3 +46,5 @@ /**************************************************************************** | ||
var sourceString = fs.readFileSync(file, 'utf8'); | ||
var replacementString = doConfigReplacements(sourceString, config); | ||
var sourceLines = sourceString.split('\n'); | ||
verify(sourceLines); | ||
var replacementString = doConfigReplacements(sourceLines, config); | ||
cached.yaml = yaml.parse(replacementString); | ||
@@ -54,57 +56,59 @@ } | ||
function doConfigReplacements(source, config) { | ||
var sourceLines = source.split('\n'); | ||
function verify(sourceLines) { | ||
var sectionFilter = new SectionFilter('x-volos-resources:'); | ||
var names = {}; | ||
var indent; | ||
sourceLines.filter(sectionFilter).forEach(function(line) { | ||
var name = line.trim().split(' ')[0]; | ||
if (!indent) { indent = line.indexOf(name) } // set the expected indent for keys | ||
if (line.indexOf(name) !== indent) { return; } | ||
if (names[name]) { | ||
var nameNoColon = name.substring(0, name.length - 1); | ||
throw new Error("duplicate resource named '" + nameNoColon + "' in 'x-volos-resources'"); | ||
} | ||
names[name] = true; | ||
}); | ||
} | ||
function doConfigReplacements(sourceLines, config) { | ||
var returnLines = []; | ||
var inConfig, anchorIndent, finished; | ||
var sectionFilter = new SectionFilter('x-a127-config:'); | ||
var anchorIndent; | ||
sourceLines.forEach(function(line) { | ||
if (finished) { | ||
returnLines.push(line); | ||
} else { | ||
if (inConfig && line[0] !== ' ') { // back to 0 indent after x-a127-config == we're done | ||
finished = true; | ||
returnLines.push(line); | ||
} else { | ||
var tokens = line.trim().split(' '); | ||
var keyToken = tokens[0]; | ||
if (inConfig) { // this is potential config stuff, let's do it | ||
var indent = line.indexOf(tokens[0]); | ||
if (anchorIndent) { // we're inside a tag | ||
if (indent <= anchorIndent) { anchorIndent = null; } | ||
} | ||
if (!anchorIndent) { // start a tag? | ||
var key = keyToken.slice(0, keyToken.length - 1); | ||
var anchor = getAnchor(tokens); | ||
if (anchor) { | ||
var configValue = config[key]; | ||
if (configValue) { // we need to do a replacement | ||
anchorIndent = indent; | ||
var upTo = line.lastIndexOf(anchor) + anchor.length; | ||
var partialLine = line.slice(0, upTo); // cut off anything after the reference | ||
var configYaml = yaml.stringify(configValue); | ||
if (typeof(configValue) === 'string') { // string goes inline | ||
partialLine += ' ' + configYaml; | ||
returnLines.push(partialLine); | ||
} else { | ||
returnLines.push(partialLine); // anything else on following lines | ||
var yamlLines = configYaml.split('\n'); | ||
var spaces = Array(indent + 3).join(' '); | ||
for (var i = 0; i < yamlLines.length - 1; i++) { // length - 1 because last line is empty (was \n) | ||
returnLines.push(spaces + yamlLines[i]); | ||
} | ||
} | ||
} else { | ||
returnLines.push(line); | ||
var tokens = line.trim().split(' '); | ||
var keyToken = tokens[0]; | ||
if (sectionFilter(line)) { | ||
var indent = line.indexOf(tokens[0]); | ||
if (anchorIndent) { // we're inside a tag | ||
if (indent <= anchorIndent) { anchorIndent = null; } | ||
} | ||
if (!anchorIndent) { // start a tag? | ||
var key = keyToken.slice(0, keyToken.length - 1); | ||
var anchor = getAnchor(tokens); | ||
if (anchor) { | ||
var configValue = config[key]; | ||
if (configValue) { // we need to do a replacement | ||
anchorIndent = indent; | ||
var upTo = line.lastIndexOf(anchor) + anchor.length; | ||
var partialLine = line.slice(0, upTo); // cut off anything after the reference | ||
var configYaml = yaml.stringify(configValue); | ||
if (typeof(configValue) === 'string') { // string goes inline | ||
partialLine += ' ' + configYaml; | ||
line = partialLine; | ||
} else { | ||
returnLines.push(partialLine); // anything else on following lines | ||
var yamlLines = configYaml.split('\n'); | ||
var spaces = Array(indent + 3).join(' '); | ||
for (var i = 0; i < yamlLines.length - 1; i++) { // length - 1 because last line is empty (was \n) | ||
returnLines.push(spaces + yamlLines[i]); | ||
} | ||
} else { | ||
returnLines.push(line); | ||
return; | ||
} | ||
} | ||
} else if (keyToken.indexOf('x-a127-config') === 0) { | ||
inConfig = true; | ||
returnLines.push(line); | ||
} else { | ||
returnLines.push(line); | ||
} | ||
} else { | ||
return; | ||
} | ||
} | ||
returnLines.push(line); | ||
}); | ||
@@ -114,2 +118,19 @@ return returnLines.join('\n'); | ||
function SectionFilter(sectionKey) { | ||
var sectionIndent = -1; | ||
return function(value) { | ||
if (!sectionKey) { return false; } | ||
if (sectionIndent >= 0) { | ||
if (value.indexOf(value.trim()) < sectionIndent) { // we're out of the section | ||
sectionKey = null; | ||
} else { | ||
return true; | ||
} | ||
} else { | ||
sectionIndent = value.indexOf(sectionKey); | ||
} | ||
return false; | ||
} | ||
} | ||
function getAnchor(tokens) { | ||
@@ -116,0 +137,0 @@ for (var i = tokens.length - 1; i > 0; i--) { |
{ | ||
"name": "a127-magic", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"description": "Apigee 127 Swagger Loader and Middleware", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -9,49 +9,68 @@ var should = require('should'); | ||
process.env.A127_APPROOT = __dirname; | ||
var SWAGGER_FILE = path.resolve(__dirname, 'api', 'swagger', 'swagger.yaml'); | ||
describe('swagger.yaml replacement', function(done) { | ||
describe('loader', function() { | ||
it('must load yaml', function(done) { | ||
describe('proper swagger', function() { | ||
var swaggerObject = yaml.load(SWAGGER_FILE); | ||
var swaggerConfig = swaggerObject['x-a127-config']; | ||
var SWAGGER_FILE = path.resolve(__dirname, 'api', 'swagger', 'swagger.yaml'); | ||
swaggerConfig.testString1.should.equal('value'); | ||
swaggerConfig.testArray1.should.eql([ 'one', 'two' ]); | ||
swaggerConfig.testHash1.should.eql({ one: 'one', two: 'two'}); | ||
it('must load yaml', function(done) { | ||
done(); | ||
}); | ||
var swaggerObject = yaml.load(SWAGGER_FILE); | ||
var swaggerConfig = swaggerObject['x-a127-config']; | ||
it('empty config must not change the structure', function(done) { | ||
swaggerConfig.testString1.should.equal('value'); | ||
swaggerConfig.testArray1.should.eql([ 'one', 'two' ]); | ||
swaggerConfig.testHash1.should.eql({ one: 'one', two: 'two'}); | ||
var config = a127config.load(); | ||
var originalSwagger = yaml.load(SWAGGER_FILE); | ||
var convertedSwagger = loader.load(SWAGGER_FILE, {}); | ||
done(); | ||
}); | ||
originalSwagger.should.eql(convertedSwagger); | ||
it('empty config must not change the structure', function(done) { | ||
done(); | ||
}); | ||
var config = a127config.load(); | ||
var originalSwagger = yaml.load(SWAGGER_FILE); | ||
var convertedSwagger = loader.load(SWAGGER_FILE, {}); | ||
it('must load and replace config', function(done) { | ||
originalSwagger.should.eql(convertedSwagger); | ||
var config = a127config.reload(); | ||
var swaggerObject = loader.load(SWAGGER_FILE, config); | ||
done(); | ||
}); | ||
var swaggerConfig = swaggerObject['x-a127-config']; | ||
it('must load and replace config', function(done) { | ||
swaggerConfig.testString1.should.equal('defaultString'); | ||
swaggerConfig.testArray1.should.eql([ 'default1', 'default2' ]); | ||
swaggerConfig.testHash1.should.eql({ test1: 'defaultHash1', test2: 'defaultHash2'}); | ||
var config = a127config.reload(); | ||
var swaggerObject = loader.load(SWAGGER_FILE, config); | ||
swaggerConfig['a127.account.password'].should.equal('PASSWORD'); | ||
var swaggerConfig = swaggerObject['x-a127-config']; | ||
var swaggerReference = swaggerObject['x-volos-test']; | ||
swaggerReference.testReference1.should.equal('defaultString'); | ||
swaggerReference.testReference2.should.eql([ 'default1', 'default2' ]); | ||
swaggerReference.testReference3.should.eql({ test1: 'defaultHash1', test2: 'defaultHash2'}); | ||
swaggerConfig.testString1.should.equal('defaultString'); | ||
swaggerConfig.testArray1.should.eql([ 'default1', 'default2' ]); | ||
swaggerConfig.testHash1.should.eql({ test1: 'defaultHash1', test2: 'defaultHash2'}); | ||
done(); | ||
swaggerConfig['a127.account.password'].should.equal('PASSWORD'); | ||
var swaggerReference = swaggerObject['x-volos-test']; | ||
swaggerReference.testReference1.should.equal('defaultString'); | ||
swaggerReference.testReference2.should.eql([ 'default1', 'default2' ]); | ||
swaggerReference.testReference3.should.eql({ test1: 'defaultHash1', test2: 'defaultHash2'}); | ||
done(); | ||
}); | ||
}); | ||
describe('broken swagger', function() { | ||
it('with duplicate volos resources must fail on load', function(done) { | ||
var SWAGGER_FILE = path.resolve(__dirname, 'api', 'swagger', 'swagger_with_dup_resource.yaml'); | ||
(function() { | ||
var swaggerObject = loader.load(SWAGGER_FILE, {}); | ||
}).should.throw("duplicate resource named 'cache' in 'x-volos-resources'"); | ||
done(); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
33
539
93813