mirror of https://gitee.com/bigwinds/arangodb
177 lines
5.2 KiB
JavaScript
177 lines
5.2 KiB
JavaScript
'use strict';
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / DISCLAIMER
|
|
// /
|
|
// / Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
|
// /
|
|
// / Licensed under the Apache License, Version 2.0 (the "License")
|
|
// / you may not use this file except in compliance with the License.
|
|
// / You may obtain a copy of the License at
|
|
// /
|
|
// / http://www.apache.org/licenses/LICENSE-2.0
|
|
// /
|
|
// / Unless required by applicable law or agreed to in writing, software
|
|
// / distributed under the License is distributed on an "AS IS" BASIS,
|
|
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// / See the License for the specific language governing permissions and
|
|
// / limitations under the License.
|
|
// /
|
|
// / Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
// /
|
|
// / @author Alan Plum
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
const _ = require('lodash');
|
|
const fs = require('fs');
|
|
const inflect = require('i')();
|
|
const assert = require('assert');
|
|
const internal = require('internal');
|
|
const pluck = require('@arangodb/util').pluck;
|
|
|
|
const template = (filename) => _.template(
|
|
fs.read(fs.join(
|
|
internal.startupPath,
|
|
'server',
|
|
'modules',
|
|
'@arangodb',
|
|
'foxx',
|
|
'templates',
|
|
`${filename}.tmpl`
|
|
))
|
|
);
|
|
|
|
const TEMPLATES = [
|
|
'main',
|
|
'dcModel',
|
|
'ecModel',
|
|
'dcRouter',
|
|
'ecRouter',
|
|
'setup',
|
|
'teardown',
|
|
'test'
|
|
].reduce(function (obj, name) {
|
|
obj[name] = template(`${name}.js`);
|
|
return obj;
|
|
}, {readme: template('README.md')});
|
|
|
|
exports.generate = function (opts) {
|
|
const dcNames = generateNames(opts.documentCollections);
|
|
const ecNames = generateNames(opts.edgeCollections);
|
|
const files = [];
|
|
const folders = [];
|
|
|
|
for (const names1 of dcNames) {
|
|
for (const names2 of ecNames) {
|
|
assert(
|
|
names1.routerFile !== names2.routerFile,
|
|
`Collection names ${names1.collection} and ${names2.collection} are indistinguishable`
|
|
);
|
|
}
|
|
}
|
|
|
|
const manifest = JSON.stringify({
|
|
name: opts.name,
|
|
version: '0.0.0',
|
|
description: opts.description,
|
|
engines: {
|
|
arangodb: '^3.0.0'
|
|
},
|
|
author: opts.author,
|
|
license: opts.license,
|
|
main: 'main.js',
|
|
scripts: {
|
|
setup: 'scripts/setup.js',
|
|
teardown: 'scripts/teardown.js'
|
|
},
|
|
tests: 'test/**/*.js'
|
|
}, null, 4);
|
|
files.push({name: 'manifest.json', content: manifest});
|
|
|
|
const main = TEMPLATES.main({routePaths: [].concat(
|
|
pluck(dcNames, 'routerFile'),
|
|
pluck(ecNames, 'routerFile')
|
|
)});
|
|
files.push({name: 'main.js', content: main});
|
|
|
|
const readme = TEMPLATES.readme(opts);
|
|
files.push({name: 'README.md', content: readme});
|
|
|
|
folders.push('routes');
|
|
folders.push('models');
|
|
dcNames.forEach(function (names) {
|
|
const router = TEMPLATES.dcRouter(names);
|
|
const model = TEMPLATES.dcModel(names);
|
|
files.push({name: fs.join('routes', `${names.routerFile}.js`), content: router});
|
|
files.push({name: fs.join('models', `${names.modelFile}.js`), content: model});
|
|
});
|
|
ecNames.forEach(function (names) {
|
|
const router = TEMPLATES.ecRouter(names);
|
|
const model = TEMPLATES.ecModel(names);
|
|
files.push({name: fs.join('routes', `${names.routerFile}.js`), content: router});
|
|
files.push({name: fs.join('models', `${names.modelFile}.js`), content: model});
|
|
});
|
|
|
|
folders.push('scripts');
|
|
const setup = TEMPLATES.setup({
|
|
documentCollections: pluck(dcNames, 'collection'),
|
|
edgeCollections: pluck(ecNames, 'collection')
|
|
});
|
|
files.push({name: fs.join('scripts', 'setup.js'), content: setup});
|
|
const teardown = TEMPLATES.teardown({collections: [].concat(
|
|
pluck(dcNames, 'collection'),
|
|
pluck(ecNames, 'collection')
|
|
)});
|
|
files.push({name: fs.join('scripts', 'teardown.js'), content: teardown});
|
|
|
|
const test = TEMPLATES.test({});
|
|
folders.push('test');
|
|
files.push({name: fs.join('test', 'example.js'), content: test});
|
|
|
|
return {files, folders};
|
|
};
|
|
|
|
exports.write = function (path, files, folders) {
|
|
fs.makeDirectory(path);
|
|
for (const folder of folders) {
|
|
fs.makeDirectory(fs.join(path, folder));
|
|
}
|
|
for (const file of files) {
|
|
fs.write(fs.join(path, file.name), file.content);
|
|
}
|
|
};
|
|
|
|
function generateNames (collectionNames) {
|
|
return collectionNames.map(function (collectionName, i) {
|
|
const routerFileName = collectionName.toLowerCase();
|
|
collectionNames.forEach(function (next, j) {
|
|
if (i === j) {
|
|
return;
|
|
}
|
|
assert(
|
|
routerFileName !== next.toLowerCase(),
|
|
`Collection names "${collectionName}" and "${next}" are indistinguishable`
|
|
);
|
|
});
|
|
|
|
const documentName = inflect.singularize(collectionName);
|
|
let documentsName = collectionName;
|
|
const initial = collectionName.charAt(0);
|
|
assert(
|
|
initial.toLowerCase() !== initial.toUpperCase(),
|
|
`Collection name "${collectionName}" starts with a case-insensitive character`
|
|
);
|
|
if (documentsName === documentName) {
|
|
documentsName += 'Items';
|
|
}
|
|
return {
|
|
collection: collectionName,
|
|
model: initial.toUpperCase() + documentName.slice(1),
|
|
document: initial.toLowerCase() + documentName.slice(1),
|
|
documents: documentsName,
|
|
routerFile: routerFileName,
|
|
modelFile: documentName.toLowerCase()
|
|
};
|
|
});
|
|
}
|