Simplify interface of main export (§1)
Fixes #21
diff --git a/README.md b/README.md
index 6768763..160eceb 100644
--- a/README.md
+++ b/README.md
@@ -29,27 +29,31 @@
## Usage:
```
-var create = require('cordova-create');
+const create = require('cordova-create');
-create(dir, id, name, cfg, extEvents);
+await create(dest, opts);
```
-- `dir` - directory where the project will be created. Required.
-- `id` - app id. Required (but can be "undefined").
-- `name` - app name. Required (but can be "undefined").
-- `cfg` - extra config to be saved in .cordova/config.json Required (but can be "{}").
-- `extEvents` - An EventEmitter instance that will be used for logging purposes. Required (but can be "undefined").
+### Parameters
-An example of `cfg` which would fetch a cordova template from npm (or git):
+#### `dest`
+_Required_. Path to the destination where the project will be created. Must be an empty dir if it exists.
+
+#### `opts`
+_Optional_. Supports following properties.
```
-var cfg = {
- lib: {
- www: {
- template: true,
- url: 'cordova-app-hello-world',
- version: ''
- }
- }
-};
+{
+ // Attributes to be set in package.json & config.xml
+ id: String,
+ name: String,
+ version: String,
+
+ // The path/url/package-name to the template that should be used
+ template: String,
+
+ // An EventEmitter instance that will be used for logging purposes
+ // (actually it only needs to implement a compatible `emit` method)
+ events: EventEmitter
+}
```
diff --git a/index.js b/index.js
index 3f039ee..3c12573 100644
--- a/index.js
+++ b/index.js
@@ -32,21 +32,7 @@
var CordovaError = require('cordova-common').CordovaError;
var ConfigParser = require('cordova-common').ConfigParser;
-module.exports = cordovaCreateLegacyAdapter;
-
-/**
-* Legacy interface. See README for documentation
-*/
-function cordovaCreateLegacyAdapter (dir, id, name, cfg, extEvents) {
- // Unwrap and shallow-clone that nasty nested config object
- const opts = Object.assign({}, ((cfg || {}).lib || {}).www);
-
- if (id) opts.id = id;
- if (name) opts.name = name;
- if (extEvents) opts.events = extEvents;
-
- return cordovaCreate(dir, opts);
-}
+module.exports = cordovaCreate;
/**
* Creates a new cordova project in the given directory.
@@ -86,18 +72,14 @@
throw new CordovaError('App id contains a reserved word, or is not a valid identifier.');
}
- // This was changed from "uri" to "url", but checking uri for backwards compatibility.
- opts.url = opts.url || opts.uri;
-
- if (!opts.url) {
- opts.url = require.resolve('cordova-app-hello-world');
- opts.template = true;
+ if (!opts.template) {
+ opts.template = require.resolve('cordova-app-hello-world');
}
// Ensure that the destination is outside the template location
- if (pathIsInside(dir, opts.url)) {
+ if (pathIsInside(dir, opts.template)) {
throw new CordovaError(
- `Cannot create project "${dir}" inside the template used to create it "${opts.url}".`
+ `Cannot create project "${dir}" inside the template used to create it "${opts.template}".`
);
}
})
@@ -106,13 +88,13 @@
emit('log', 'Creating a new cordova project.');
// Use cordova-fetch to obtain npm or git templates
- if (opts.template && isRemoteUri(opts.url)) {
- var target = opts.url;
+ if (isRemoteUri(opts.template)) {
+ var target = opts.template;
emit('verbose', 'Using cordova-fetch for ' + target);
return fetch(target, getSelfDestructingTempDir(), {});
} else {
// If assets are not online, resolve as a relative path on local computer
- return path.resolve(opts.url);
+ return path.resolve(opts.template);
}
})
.then(function (templatePath) {
@@ -136,10 +118,8 @@
try {
// Copy files from template to project
- if (opts.template) {
- emit('verbose', 'Copying assets.');
- fs.copySync(import_from_path, dir);
- }
+ emit('verbose', 'Copying assets.');
+ fs.copySync(import_from_path, dir);
} catch (e) {
if (!dirAlreadyExisted) {
fs.removeSync(dir);
diff --git a/spec/create.spec.js b/spec/create.spec.js
index 7d7e06d..821ed37 100644
--- a/spec/create.spec.js
+++ b/spec/create.spec.js
@@ -24,7 +24,6 @@
var requireFresh = require('import-fresh');
var create = require('..');
-var events = require('cordova-common').events;
var CordovaError = require('cordova-common').CordovaError;
var ConfigParser = require('cordova-common').ConfigParser;
const { tmpDir, createWith, createWithMockFetch, expectRejection } = require('./helpers');
@@ -34,9 +33,11 @@
const appVersion = '1.0.0';
const project = path.join(tmpDir, appName);
-// Setup and teardown test dirs
+let opts;
+
beforeEach(function () {
fs.emptyDirSync(tmpDir);
+ opts = { name: appName, id: appId };
});
afterAll(function () {
process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
@@ -47,11 +48,13 @@
const error = new CordovaError('is not a valid identifier');
it('should reject reserved words from start of id', function () {
- return expectRejection(create(project, 'int.bob', appName, {}, events), error);
+ opts.id = 'int.bob';
+ return expectRejection(create(project, opts), error);
});
it('should reject reserved words from end of id', function () {
- return expectRejection(create(project, 'bob.class', appName, {}, events), error);
+ opts.id = 'bob.class';
+ return expectRejection(create(project, opts), error);
});
});
@@ -120,89 +123,54 @@
it('should successfully run without template and use default hello-world app', function () {
// Create a real project with no template
// use default cordova-app-hello-world app
- return create(project, appId, appName, {}, events)
+ return create(project, opts)
.then(checkProjectCreatedWithDefaultTemplate);
});
it('should successfully run with Git URL', function () {
// Create a real project with git URL as template
- var config = {
- lib: {
- www: {
- url: 'https://github.com/apache/cordova-app-hello-world',
- template: true
- }
- }
- };
- return createWithMockFetch(project, appId, appName, config, events)
+ opts.template = 'https://github.com/apache/cordova-app-hello-world';
+ return createWithMockFetch(project, opts)
.then(fetchSpy => {
expect(fetchSpy).toHaveBeenCalledTimes(1);
- expect(fetchSpy.calls.argsFor(0)[0]).toBe(config.lib.www.url);
+ expect(fetchSpy.calls.argsFor(0)[0]).toBe(opts.template);
})
.then(checkProjectCreatedWithDefaultTemplate);
});
it('should successfully run with NPM package (specific version)', function () {
// Create a real project with npm module as template
- var config = {
- lib: {
- www: {
- template: true,
- url: 'phonegap-template-vue-f7-tabs@1'
- }
- }
- };
- return createWithMockFetch(project, appId, appName, config, events)
+ opts.template = 'phonegap-template-vue-f7-tabs@1';
+ return createWithMockFetch(project, opts)
.then(fetchSpy => {
expect(fetchSpy).toHaveBeenCalledTimes(1);
- expect(fetchSpy.calls.argsFor(0)[0]).toBe(config.lib.www.url);
+ expect(fetchSpy.calls.argsFor(0)[0]).toBe(opts.template);
})
.then(checkProjectCreatedWithDefaultTemplate);
});
it('should successfully run with NPM package (no specific version)', function () {
// Create a real project with npm module as template
- var config = {
- lib: {
- www: {
- template: true,
- url: 'phonegap-template-vue-f7-tabs'
- }
- }
- };
- return createWithMockFetch(project, appId, appName, config, events)
+ opts.template = 'phonegap-template-vue-f7-tabs';
+ return createWithMockFetch(project, opts)
.then(fetchSpy => {
expect(fetchSpy).toHaveBeenCalledTimes(1);
- expect(fetchSpy.calls.argsFor(0)[0]).toBe(config.lib.www.url);
+ expect(fetchSpy.calls.argsFor(0)[0]).toBe(opts.template);
})
.then(checkProjectCreatedWithDefaultTemplate);
});
it('should successfully run with local template having no package.json in template dir', function () {
- var config = {
- lib: {
- www: {
- template: true,
- url: path.join(__dirname, 'templates', 'withsubdirectory')
- }
- }
- };
- return create(project, appId, appName, config, events)
+ opts.template = path.join(__dirname, 'templates/withsubdirectory');
+ return create(project, opts)
.then(checkCommonArtifacts)
.then(checkNoPackageJson)
.then(checkNotDefaultTemplate);
});
it('should successfully run with local template having package.json in template dir', function () {
- var config = {
- lib: {
- www: {
- template: true,
- url: path.join(__dirname, 'templates', 'withsubdirectory_package_json')
- }
- }
- };
- return create(project, appId, appName, config, events)
+ opts.template = path.join(__dirname, 'templates/withsubdirectory_package_json');
+ return create(project, opts)
.then(checkCommonArtifacts)
.then(checkPackageJson)
.then(checkNotDefaultTemplate);
@@ -210,7 +178,7 @@
it('should successfully run with existing, empty destination', function () {
fs.ensureDirSync(project);
- return create(project, appId, appName, {}, events)
+ return create(project, opts)
.then(checkProjectCreatedWithDefaultTemplate);
});
});
@@ -218,62 +186,43 @@
describe('when shit happens', function () {
it('should fail when dir is missing', function () {
return expectRejection(
- create(null, appId, appName, {}, events),
+ create(null, opts),
new CordovaError('Directory not specified')
);
});
it('should fail when dir already exists', function () {
return expectRejection(
- create(__dirname, appId, appName, {}, events),
+ create(__dirname, opts),
new CordovaError('Path already exists and is not empty')
);
});
it('should fail when destination is inside template', function () {
- const config = {
- lib: {
- www: {
- url: path.join(tmpDir, 'template')
- }
- }
- };
- const destination = path.join(config.lib.www.url, 'destination');
+ opts.template = path.join(tmpDir, 'template');
return expectRejection(
- create(destination, appId, appName, config, events),
+ create(path.join(opts.template, 'destination'), opts),
new CordovaError('inside the template')
);
});
it('should fail when fetch fails', function () {
- const config = {
- lib: {
- www: {
- template: true,
- url: 'http://localhost:123456789/cordova-create'
- }
- }
- };
const fetchError = new Error('Fetch fail');
const failingFetch = jasmine.createSpy('failingFetch')
.and.callFake(() => Promise.reject(fetchError));
+
+ opts.template = 'http://localhost:123456789/cordova-create';
return expectRejection(
- createWith({ fetch: failingFetch })(project, appId, appName, config),
+ createWith({ fetch: failingFetch })(project, opts),
fetchError
);
-
});
- it('should fail when template does not exist', function () {
- const config = {
- lib: {
- www: {
- url: path.join(__dirname, 'doesnotexist')
- }
- }
- };
+ // FIXME: we need to improve isRemote to make this different from the test above
+ xit('should fail when template does not exist', function () {
+ opts.template = path.join(__dirname, 'doesnotexist');
return expectRejection(
- create(project, appId, appName, config, events),
+ create(project, opts),
new CordovaError('not a valid template')
);
});