mirror of https://gitee.com/bigwinds/arangodb
Added optional Foxx deps.
This commit is contained in:
parent
3029891405
commit
1031a3d4e9
|
@ -133,6 +133,10 @@ v2.7.0 (XXXX-XX-XX)
|
||||||
|
|
||||||
* fixed handling of optional parameters in Foxx manifest configurations
|
* fixed handling of optional parameters in Foxx manifest configurations
|
||||||
|
|
||||||
|
* added verbose Foxx manifest dependency format
|
||||||
|
|
||||||
|
* added optional Foxx dependencies
|
||||||
|
|
||||||
* updated chai to 3.0.
|
* updated chai to 3.0.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,12 @@ A more complete example for a Manifest file:
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sessions": "sessions@^1.0.0",
|
"sessions": "sessions@^1.0.0",
|
||||||
"systemUsers": "users"
|
"systemUsers": "users",
|
||||||
|
"mailer": {
|
||||||
|
"name": "mailer-postmark",
|
||||||
|
"version": "*",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -159,20 +164,26 @@ The **dependencies** object maps aliases to Foxx apps:
|
||||||
|
|
||||||
* The **value** is a dependency definition.
|
* The **value** is a dependency definition.
|
||||||
|
|
||||||
The dependency definition can use any of the following formats:
|
The dependency definition is an object with any of the following properties:
|
||||||
|
|
||||||
|
* **name** (optional): the name of the Foxx app this app depends on.
|
||||||
|
* **version** (Default: `"*"`): a [semver](http://semver.org) version or version range of the Foxx app this app depends on.
|
||||||
|
* **required** (Default: `true`): whether the dependency is required for this app to be usable or not.
|
||||||
|
|
||||||
|
Alternatively the dependency definition can be a string using any of the following formats:
|
||||||
|
|
||||||
* `*` will allow using any app to be used to meet the dependency.
|
* `*` will allow using any app to be used to meet the dependency.
|
||||||
* `sessions` or `sessions@*` will match any app with the name `sessions`
|
* `sessions` or `sessions:*` will match any app with the name `sessions`
|
||||||
(such as the *sessions* app in the Foxx application store).
|
(such as the *sessions* app in the Foxx application store).
|
||||||
* `sessions@1.0.0` will match the version `1.0.0` of any app with the name `sessions`.
|
* `sessions:1.0.0` will match the version `1.0.0` of any app with the name `sessions`.
|
||||||
|
|
||||||
Instead of using a specific version number, you can also use any expression supported by
|
Instead of using a specific version number, you can also use any expression supported by
|
||||||
the [semver](https://github.com/npm/node-semver) module.
|
the [semver](https://github.com/npm/node-semver) module.
|
||||||
|
|
||||||
Currently the dependency definitions are not enforced in ArangoDB
|
Currently the dependency definition names and versions are not enforced in ArangoDB
|
||||||
but this may change in a future version.
|
but this may change in a future version.
|
||||||
|
|
||||||
If an app declares any dependencies,
|
If an app declares any required dependencies,
|
||||||
you need to fulfill its dependencies before it becomes active.
|
you need to fulfill its dependencies before it becomes active.
|
||||||
In the meantime a fallback application will be mounted that responds to all
|
In the meantime a fallback application will be mounted that responds to all
|
||||||
requests with a HTTP 500 status code indicating a server-side error.
|
requests with a HTTP 500 status code indicating a server-side error.
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
|
|
||||||
hasUnconfiguredDependencies: function () {
|
hasUnconfiguredDependencies: function () {
|
||||||
return _.any(this.get('deps'), function (dep) {
|
return _.any(this.get('deps'), function (dep) {
|
||||||
return dep.current === undefined;
|
return dep.current === undefined && dep.definition.required !== false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -350,24 +350,27 @@
|
||||||
var tableContent = _.map(this.model.get('deps'), function(obj, name) {
|
var tableContent = _.map(this.model.get('deps'), function(obj, name) {
|
||||||
var currentValue = obj.current === undefined ? '' : String(obj.current);
|
var currentValue = obj.current === undefined ? '' : String(obj.current);
|
||||||
var defaultValue = '';
|
var defaultValue = '';
|
||||||
var description = obj.definition;
|
var description = obj.definition.name;
|
||||||
var checks = [
|
if (obj.definition.version !== '*') {
|
||||||
{
|
description += '@' + obj.definition.version;
|
||||||
rule: Joi.string().optional().allow(''),
|
}
|
||||||
msg: 'Has to be a string.'
|
var checks = [{
|
||||||
},
|
rule: Joi.string().optional().allow(''),
|
||||||
{
|
msg: 'Has to be a string.'
|
||||||
|
}];
|
||||||
|
if (obj.definition.required) {
|
||||||
|
checks.push({
|
||||||
rule: Joi.string().required(),
|
rule: Joi.string().required(),
|
||||||
msg: 'This value is required.'
|
msg: 'This value is required.'
|
||||||
}
|
});
|
||||||
];
|
}
|
||||||
return window.modalView.createTextEntry(
|
return window.modalView.createTextEntry(
|
||||||
'app_deps_' + name,
|
'app_deps_' + name,
|
||||||
obj.title,
|
obj.title,
|
||||||
currentValue,
|
currentValue,
|
||||||
description,
|
description,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
true,
|
obj.definition.required,
|
||||||
checks
|
checks
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -289,17 +289,19 @@ ArangoApp.prototype.updateDeps = function (deps) {
|
||||||
if (!expected[name]) {
|
if (!expected[name]) {
|
||||||
invalid.push("Unexpected dependency " + name);
|
invalid.push("Unexpected dependency " + name);
|
||||||
}
|
}
|
||||||
this._options.dependencies[name] = mount;
|
this._options.dependencies[name] = mount || undefined;
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
_.each(this._options.dependencies, function (mount, name) {
|
_.each(this._options.dependencies, function (mount, name) {
|
||||||
Object.defineProperty(this._dependencies, name, {
|
if (mount) {
|
||||||
configurable: true,
|
Object.defineProperty(this._dependencies, name, {
|
||||||
enumerable: true,
|
configurable: true,
|
||||||
get: function () {
|
enumerable: true,
|
||||||
return require("org/arangodb/foxx").requireApp(mount);
|
get: function () {
|
||||||
}
|
return require("org/arangodb/foxx").requireApp(mount);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
return invalid;
|
return invalid;
|
||||||
|
@ -406,7 +408,7 @@ ArangoApp.prototype.needsConfiguration = function() {
|
||||||
return _.any(config, function (cfg) {
|
return _.any(config, function (cfg) {
|
||||||
return cfg.current === undefined && cfg.required !== false;
|
return cfg.current === undefined && cfg.required !== false;
|
||||||
}) || _.any(deps, function (dep) {
|
}) || _.any(deps, function (dep) {
|
||||||
return dep.current === undefined;
|
return dep.current === undefined && dep.definition.required !== false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,15 @@ const manifestSchema = {
|
||||||
dependencies: (
|
dependencies: (
|
||||||
joi.object().optional()
|
joi.object().optional()
|
||||||
.pattern(RE_EMPTY, joi.forbidden())
|
.pattern(RE_EMPTY, joi.forbidden())
|
||||||
.pattern(RE_NOT_EMPTY, joi.string().required())
|
.pattern(RE_NOT_EMPTY, joi.alternatives().try(
|
||||||
|
joi.string().required(),
|
||||||
|
joi.object().required()
|
||||||
|
.keys({
|
||||||
|
name: joi.string().default('*'),
|
||||||
|
version: joi.string().default('*'),
|
||||||
|
required: joi.boolean().default(true)
|
||||||
|
})
|
||||||
|
))
|
||||||
),
|
),
|
||||||
description: joi.string().allow('').default(''),
|
description: joi.string().allow('').default(''),
|
||||||
engines: (
|
engines: (
|
||||||
|
@ -368,19 +376,33 @@ function checkManifest(filename, manifest) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (typeof manifest.controllers === 'string') {
|
|
||||||
manifest.controllers = {'/': manifest.controllers};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof manifest.tests === 'string') {
|
|
||||||
manifest.tests = [manifest.tests];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validationErrors.length) {
|
if (validationErrors.length) {
|
||||||
throw new ArangoError({
|
throw new ArangoError({
|
||||||
errorNum: errors.ERROR_INVALID_APPLICATION_MANIFEST.code,
|
errorNum: errors.ERROR_INVALID_APPLICATION_MANIFEST.code,
|
||||||
errorMessage: validationErrors.join('\n')
|
errorMessage: validationErrors.join('\n')
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (manifest.dependencies) {
|
||||||
|
Object.keys(manifest.dependencies).forEach(function (key) {
|
||||||
|
const dependency = manifest.dependencies[key];
|
||||||
|
if (typeof dependency === 'string') {
|
||||||
|
const tokens = dependency.split(':');
|
||||||
|
manifest.dependencies[key] = {
|
||||||
|
name: tokens[0] || '*',
|
||||||
|
version: tokens[1] || '*',
|
||||||
|
required: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof manifest.controllers === 'string') {
|
||||||
|
manifest.controllers = {'/': manifest.controllers};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof manifest.tests === 'string') {
|
||||||
|
manifest.tests = [manifest.tests];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue