particle-commands 0.2.12 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +68 -0
- package/.eslintrc +1 -2
- package/.nvmrc +1 -0
- package/CHANGELOG.md +11 -0
- package/README.md +93 -1
- package/dist/cmd/library_add.js +1 -14
- package/dist/cmd/library_contribute.js +0 -10
- package/dist/cmd/library_install.js +11 -26
- package/dist/cmd/library_migrate.js +3 -4
- package/dist/cmd/library_properties.js +3 -4
- package/dist/cmd/library_publish.js +0 -8
- package/dist/cmd/project_init.js +0 -3
- package/dist/cmd/project_properties.js +9 -12
- package/dist/cmd/templates/project/README.md +2 -2
- package/dist/index.js +9 -28
- package/package.json +20 -20
- package/src/cmd/library_add.js +2 -8
- package/src/cmd/library_contribute.js +0 -3
- package/src/cmd/library_install.js +7 -16
- package/src/cmd/library_publish.js +0 -3
- package/src/cmd/project_init.js +1 -3
- package/src/cmd/templates/project/README.md +2 -2
- package/src/index.js +0 -8
- package/test/cmd/library_install.spec.js +1 -1
- package/test/cmd/library_list.spec.js +5 -9
- package/test/cmd/library_publish.spec.js +1 -1
- package/test/cmd/project_init.spec.js +1 -4
- package/test/cmd/projects_spec.js +4 -4
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/misc.xml +0 -13
- package/.idea/modules.xml +0 -8
- package/.idea/particle-commands.iml +0 -12
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -222
- package/.npmignore +0 -1
- package/.travis.yml +0 -2
- package/dist/lib/analytics.js +0 -229
- package/dist/lib/settings.js +0 -410
- package/dist/lib/utilities.js +0 -27
- package/src/lib/analytics.js +0 -182
- package/src/lib/settings.js +0 -359
- package/src/lib/utilities.js +0 -24
- package/test/lib/analytics.spec.js +0 -158
- package/test/lib/settings.spec.js +0 -27
- package/yarn.lock +0 -4690
package/src/lib/analytics.js
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const Analytics = require('analytics-node');
|
|
3
|
-
const promisify = require('es6-promisify');
|
|
4
|
-
const _ = require('lodash');
|
|
5
|
-
|
|
6
|
-
const pipeline = require('when/pipeline');
|
|
7
|
-
|
|
8
|
-
class CommandContext {
|
|
9
|
-
|
|
10
|
-
identifyUser(particleApiClient) {
|
|
11
|
-
if (particleApiClient.ready()) {
|
|
12
|
-
return particleApiClient.trackingIdentity();
|
|
13
|
-
} else {
|
|
14
|
-
return Promise.reject();
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Determine if the given user descriptor has the requisite identification for a tracking request.
|
|
20
|
-
* @param {object} user The user object to check.
|
|
21
|
-
* @returns {boolean} true if the identity contains the requisite fields (id, email)
|
|
22
|
-
*/
|
|
23
|
-
isIdentity(user) {
|
|
24
|
-
return Boolean(user && user.id && user.email);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Retrieves the tracking details for the current logged in user.
|
|
29
|
-
* @param {function(newValue)} trackingIdentity a fetch-update function for the cached tracking identity for the
|
|
30
|
-
* current profile.
|
|
31
|
-
* @param {object} apiClient The API Client that provides the tracking identity via "
|
|
32
|
-
* @param {function(opts)} clientFactory synchronously create a client
|
|
33
|
-
* @return {Promise<object>} promise to retrieve the tracking identity
|
|
34
|
-
*/
|
|
35
|
-
trackingUser(trackingIdentity, apiClient) {
|
|
36
|
-
const ident = trackingIdentity();
|
|
37
|
-
if (this.isIdentity(ident)) {
|
|
38
|
-
return Promise.resolve(ident);
|
|
39
|
-
} else {
|
|
40
|
-
return this.identifyUser(apiClient)
|
|
41
|
-
.then(user => {
|
|
42
|
-
if (this.isIdentity(user)) {
|
|
43
|
-
trackingIdentity(user);
|
|
44
|
-
return user;
|
|
45
|
-
} else {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
buildContext({ tool, api, trackingIdentity, apiClient }) {
|
|
53
|
-
// todo - allow the API key to be overridden in the environment so that CLI use during development/testing
|
|
54
|
-
// is tracked against a distinct source
|
|
55
|
-
return pipeline([
|
|
56
|
-
() => this.trackingUser(trackingIdentity, apiClient),
|
|
57
|
-
(user) => {
|
|
58
|
-
return {
|
|
59
|
-
user,
|
|
60
|
-
tool,
|
|
61
|
-
api
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
]);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const test = {
|
|
69
|
-
CommandContext
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
* @param {object} tool The tool definition { name, version }
|
|
75
|
-
* @param {object} api The tracking api details { key }
|
|
76
|
-
* @param {function(newValue)} trackingIdentity function to retrieve or update the cached user identity
|
|
77
|
-
* @param {object} apiClient The Particle api client that provides a `trackingIdentity` method.
|
|
78
|
-
* @returns {Promise<object>} promise to build the command context object containing the tool, api and user attributes.
|
|
79
|
-
*/
|
|
80
|
-
function buildContext({ tool, api, trackingIdentity, apiClient }) {
|
|
81
|
-
return new CommandContext().buildContext({ tool, api, trackingIdentity, apiClient });
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Provides command oriented tracking for analytics. This establishes a convention for how
|
|
86
|
-
* the calling tool specifies the user, any user traits, the tool name, event date time.
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
const analyticsCache = {};
|
|
90
|
-
|
|
91
|
-
function analyticsFor(key) {
|
|
92
|
-
let analytics = analyticsCache[key];
|
|
93
|
-
if (!analytics) {
|
|
94
|
-
analytics = new Analytics(key, { flushAfter: 10 });
|
|
95
|
-
analyticsCache[key] = analytics;
|
|
96
|
-
}
|
|
97
|
-
return analytics;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function buildProperties(context, properties) {
|
|
101
|
-
const tool = _.mapKeys((context.tool || {}), (value, key) => 'tool'+key);
|
|
102
|
-
return Object.assign(properties, tool);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function checkApiKey(context) {
|
|
106
|
-
if (!context || !context.api || !context.api.key) {
|
|
107
|
-
throw new Error('context.api.key not provided'); // todo - distinguish programming/caller errors from runtime errors?
|
|
108
|
-
}
|
|
109
|
-
return context.api.key;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function checkUserId(context) {
|
|
113
|
-
const userId = context && context.user && context.user.id;
|
|
114
|
-
const track = context && context.user && context.user.track;
|
|
115
|
-
if (!userId && track!==false) {
|
|
116
|
-
throw new Error('context.user.id not provided'); // todo - distinguish programming/caller errors from runtime errors?
|
|
117
|
-
}
|
|
118
|
-
return userId;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function makeAnalytics(context) {
|
|
122
|
-
const key = checkApiKey(context);
|
|
123
|
-
return analyticsFor(key);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
*
|
|
128
|
-
* @param {Command} command The command being executed. May be null for tracking events outside of a command
|
|
129
|
-
* execution context.
|
|
130
|
-
* @param {Object} context The command invocation context. The analytics property should contain
|
|
131
|
-
* {tool, user, api}. The api property should include `key` as a minimum, to specify the Segment write key.
|
|
132
|
-
* THe tool object must contain at least a `name` property to identify the tool being used. User traits must include
|
|
133
|
-
* at least `id` and `name` properties, which are opaque and natural keys used to identify the current user.
|
|
134
|
-
* If userTraits is falsey the event is logged anonymously.
|
|
135
|
-
* @param {CommandSite} site The command site. This is presently unused but may be later used for context-specific
|
|
136
|
-
* functionality.
|
|
137
|
-
* @param {String} event The event name to track.
|
|
138
|
-
* @param {Object} properties Additional data to log with the event.
|
|
139
|
-
* @return {Promise} promise to track
|
|
140
|
-
*/
|
|
141
|
-
function track({ command, context, site, event, properties }) {
|
|
142
|
-
const userId = checkUserId(context);
|
|
143
|
-
if (!userId) {
|
|
144
|
-
return Promise.resolve();
|
|
145
|
-
}
|
|
146
|
-
const analytics = makeAnalytics(context);
|
|
147
|
-
const allProperties = buildProperties(context, properties);
|
|
148
|
-
|
|
149
|
-
const track = promisify(analytics.track, { thisArg: analytics });
|
|
150
|
-
return track({
|
|
151
|
-
userId,
|
|
152
|
-
event,
|
|
153
|
-
allProperties
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function identify({ command, context, site, traits }) {
|
|
158
|
-
const analytics = makeAnalytics(context);
|
|
159
|
-
const userId = checkUserId(context);
|
|
160
|
-
const identify = promisify(analytics.identify, { thisArg: analytics });
|
|
161
|
-
return identify({
|
|
162
|
-
userId,
|
|
163
|
-
traits
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Ensure that any events have been sent. Returns a promise.
|
|
169
|
-
* @return {Promise} to eventually flush
|
|
170
|
-
*/
|
|
171
|
-
function flush() {
|
|
172
|
-
return Promise.resolve();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export {
|
|
176
|
-
identify,
|
|
177
|
-
track,
|
|
178
|
-
flush,
|
|
179
|
-
buildProperties,
|
|
180
|
-
buildContext,
|
|
181
|
-
test
|
|
182
|
-
};
|
package/src/lib/settings.js
DELETED
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const _ = require('underscore');
|
|
3
|
-
const utilities = require('./utilities');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
|
|
6
|
-
class Settings {
|
|
7
|
-
|
|
8
|
-
constructor({ separateSettings=true, settings=[] }={}) {
|
|
9
|
-
this.settings = separateSettings ? {} : this; // current configuration settings
|
|
10
|
-
this.profile = null; // current profile name
|
|
11
|
-
this.profile_json = {}; // parsed contents of profile.json
|
|
12
|
-
this.overrides = {}; // current overrides from the profile config file
|
|
13
|
-
settings.unshift(this.settings); // add target as first argument
|
|
14
|
-
_.extend.apply(_, settings);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
get(name) {
|
|
18
|
-
return (name===undefined) ? this.settings : this.settings[name];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
set(key, value) {
|
|
22
|
-
return this.override(null, key, value);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Retrieve a value from the environment
|
|
27
|
-
* @param {string} varName The name of the environment variable to retrieve
|
|
28
|
-
* @param {string} defaultValue The value to return when the environment variable is not defined
|
|
29
|
-
* @return {string} the value of the environment, or defaultValue if not defined
|
|
30
|
-
*/
|
|
31
|
-
envValue(varName, defaultValue) {
|
|
32
|
-
const value = process.env[varName];
|
|
33
|
-
return (typeof value === 'undefined') ? defaultValue : value;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Fetches the value of an environment varaible interpreted as a boolean
|
|
38
|
-
* @param {string} varName The environment variable name
|
|
39
|
-
* @param {string} defaultValue The default boolean value to return when the environment
|
|
40
|
-
* variable is not defined ir is not recognized as a boolean
|
|
41
|
-
* @returns {boolean} The value of the environment variable when defined. defaultValue when not defined, or not
|
|
42
|
-
* one of true, TRUE, 1, false, FALSE, 0
|
|
43
|
-
*/
|
|
44
|
-
envValueBoolean(varName, defaultValue) {
|
|
45
|
-
const value = this.envValue(varName);
|
|
46
|
-
if (value === 'true' || value === 'TRUE' || value === '1') {
|
|
47
|
-
return true;
|
|
48
|
-
} else if (value === 'false' || value === 'FALSE' || value === '0') {
|
|
49
|
-
return false;
|
|
50
|
-
} else {
|
|
51
|
-
return defaultValue;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Determine the user home path from the environment
|
|
57
|
-
* @returns {string} The home path of the current user, or
|
|
58
|
-
* the directory containing this file if it could not be determined.
|
|
59
|
-
*/
|
|
60
|
-
findHomePath(fs=require('fs')) {
|
|
61
|
-
const envVars = [
|
|
62
|
-
'home',
|
|
63
|
-
'HOME',
|
|
64
|
-
'HOMEPATH',
|
|
65
|
-
'USERPROFILE'
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
for (let i=0;i<envVars.length;i++) {
|
|
69
|
-
const dir = this.envValue(envVars[i]);
|
|
70
|
-
if (dir && fs.existsSync(dir)) {
|
|
71
|
-
return dir;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return __dirname;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Ensures that the particle folder in the home directory exists.
|
|
79
|
-
* @returns {string} The location of the particle folder.
|
|
80
|
-
*/
|
|
81
|
-
ensureFolder() {
|
|
82
|
-
const particleDir = path.join(this.findHomePath(), '.particle');
|
|
83
|
-
if (!fs.existsSync(particleDir)) {
|
|
84
|
-
fs.mkdirSync(particleDir);
|
|
85
|
-
}
|
|
86
|
-
return particleDir;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Determine the location of a given profile configuratino file
|
|
91
|
-
* @param {string} profile The name of the profile
|
|
92
|
-
* @returns {string} the path of the overrides file
|
|
93
|
-
*/
|
|
94
|
-
findOverridesFile(profile) {
|
|
95
|
-
profile = this.defaultProfile(profile);
|
|
96
|
-
const particleDir = this.ensureFolder();
|
|
97
|
-
return path.join(particleDir, profile + '.config.json');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
defaultProfile(profile) {
|
|
101
|
-
return profile || this.profile || 'particle';
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
loadOverrides(profile) {
|
|
105
|
-
profile = this.defaultProfile(profile);
|
|
106
|
-
|
|
107
|
-
const filename = this.findOverridesFile(profile);
|
|
108
|
-
try {
|
|
109
|
-
if (fs.existsSync(filename)) {
|
|
110
|
-
this.overrides = JSON.parse(fs.readFileSync(filename));
|
|
111
|
-
// need to do an in-situ extend since external clients may have already obtained the settings object
|
|
112
|
-
// this.settings = extend(this.settings, this.overrides);
|
|
113
|
-
_.extend(this.settings, this.overrides);
|
|
114
|
-
}
|
|
115
|
-
} catch (ex) {
|
|
116
|
-
console.error('There was an error reading ' + filename + ': ', ex);
|
|
117
|
-
}
|
|
118
|
-
return this;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* ?? Reads the default profile
|
|
123
|
-
*/
|
|
124
|
-
whichProfile() {
|
|
125
|
-
this.profile = 'particle';
|
|
126
|
-
this.readProfileData();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* in another file in our user dir, we store a profile name that switches between setting override files
|
|
131
|
-
* @param {string} profileName The name of the profile to switch to
|
|
132
|
-
*/
|
|
133
|
-
switchProfile(profileName) {
|
|
134
|
-
this.profile_json.name = profileName;
|
|
135
|
-
this.saveProfileData();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Reads "profile.json" and saves its content to profile_json
|
|
140
|
-
* @return {undefined} nothing but keep the linter happy
|
|
141
|
-
*/
|
|
142
|
-
readProfileData(fs=require('fs')) {
|
|
143
|
-
const particleDir = this.ensureFolder();
|
|
144
|
-
const proFile = path.join(particleDir, 'profile.json'); //proFile, get it?
|
|
145
|
-
if (fs.existsSync(proFile)) {
|
|
146
|
-
try {
|
|
147
|
-
const data = JSON.parse(fs.readFileSync(proFile));
|
|
148
|
-
this.profile = (data) ? data.name : 'particle';
|
|
149
|
-
this.profile_json = data;
|
|
150
|
-
} catch (err) {
|
|
151
|
-
throw new Error('Error parsing file '+proFile+': '+err);
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
154
|
-
this.profile = 'particle';
|
|
155
|
-
this.profile_json = {};
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Saves profile.json
|
|
161
|
-
*/
|
|
162
|
-
saveProfileData(fs=require('fs')) {
|
|
163
|
-
const particleDir = this.ensureFolder();
|
|
164
|
-
const proFile = path.join(particleDir, 'profile.json'); //proFile, get it?
|
|
165
|
-
fs.writeFileSync(proFile, JSON.stringify(this.profile_json, null, 2), { mode: '600' });
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// this is here instead of utilities to prevent a require-loop
|
|
170
|
-
// when files that utilties requires need settings
|
|
171
|
-
matchKey(needle, obj, caseInsensitive) {
|
|
172
|
-
needle = (caseInsensitive) ? needle.toLowerCase() : needle;
|
|
173
|
-
for (let key in obj) {
|
|
174
|
-
const keyCopy = (caseInsensitive) ? key.toLowerCase() : key;
|
|
175
|
-
if (keyCopy === needle) {
|
|
176
|
-
return key; //return the original
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
override(profile, key, value) {
|
|
184
|
-
if (!this.overrides) {
|
|
185
|
-
this.overrides = {};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (this.settings[key]===undefined) {
|
|
189
|
-
// find any key that matches our key, regardless of case
|
|
190
|
-
const realKey = this.matchKey(key, this.settings, true);
|
|
191
|
-
if (realKey) {
|
|
192
|
-
//console.log("Using the setting \"" + realKey + "\" instead ");
|
|
193
|
-
key = realKey;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (value===undefined) {
|
|
198
|
-
delete this.settings[key];
|
|
199
|
-
delete this.overrides[key];
|
|
200
|
-
} else {
|
|
201
|
-
//store the new value (redundant)
|
|
202
|
-
this.settings[key] = value;
|
|
203
|
-
|
|
204
|
-
//store that in overrides
|
|
205
|
-
this.overrides[key] = value;
|
|
206
|
-
}
|
|
207
|
-
//make sure our overrides are in sync
|
|
208
|
-
_.extend(this.settings, this.overrides);
|
|
209
|
-
|
|
210
|
-
const filename = this.findOverridesFile(profile);
|
|
211
|
-
try {
|
|
212
|
-
fs.writeFileSync(filename, JSON.stringify(this.overrides, null, 2), { mode: '600' });
|
|
213
|
-
} catch (ex) {
|
|
214
|
-
console.error('There was an error writing ' + filename + ': ', ex);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
transitionSparkProfiles(fs=require('fs'), notifyTranslate) {
|
|
219
|
-
const sparkDir = path.join(this.findHomePath(), '.spark');
|
|
220
|
-
const particleDir = path.join(this.findHomePath(), '.particle');
|
|
221
|
-
if (fs.existsSync(sparkDir) && !fs.existsSync(particleDir)) {
|
|
222
|
-
fs.mkdirSync(particleDir);
|
|
223
|
-
|
|
224
|
-
if (notifyTranslate) {
|
|
225
|
-
notifyTranslate(sparkDir, particleDir);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const files = fs.readdirSync(sparkDir);
|
|
229
|
-
files.forEach((filename) => {
|
|
230
|
-
const data = fs.readFileSync(path.join(sparkDir, filename));
|
|
231
|
-
let jsonData;
|
|
232
|
-
try {
|
|
233
|
-
jsonData = JSON.parse(data);
|
|
234
|
-
} catch (ex) {
|
|
235
|
-
// invalid JSON, don't transition
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (filename === 'profile.json') {
|
|
240
|
-
if (jsonData.name === 'spark') {
|
|
241
|
-
jsonData.name = 'particle';
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (filename === 'spark.config.json') {
|
|
246
|
-
filename = 'particle.config.json';
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (jsonData.apiUrl && jsonData.apiUrl.indexOf('.spark.io') > 0) {
|
|
250
|
-
jsonData.apiUrl = jsonData.apiUrl.replace('.spark.io', '.particle.io');
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const jsonString = JSON.stringify(jsonData, null, 2);
|
|
254
|
-
fs.writeFileSync(path.join(particleDir, filename), jsonString, { mode: '600' });
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
listConfigs(particleDir = this.ensureFolder()) {
|
|
260
|
-
const files = utilities.globList(null, [
|
|
261
|
-
path.join(particleDir, '*.config.json')
|
|
262
|
-
]);
|
|
263
|
-
|
|
264
|
-
return files.map(item => {
|
|
265
|
-
const filename = path.basename(item);
|
|
266
|
-
//strip the extension
|
|
267
|
-
const name = filename.replace('.config.json', '');
|
|
268
|
-
return name;
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Retrieves a function that can retrieve or set a value.
|
|
274
|
-
* @param {string} key The key of the setting to fetch/update
|
|
275
|
-
* @returns {function(newValue)} A function that fetches the current value, or updates if an argument
|
|
276
|
-
* is defined.
|
|
277
|
-
*/
|
|
278
|
-
fetchUpdate(key) {
|
|
279
|
-
function fetchUpdateKey(key, value) {
|
|
280
|
-
if (value!==undefined) {
|
|
281
|
-
this.set(key, value);
|
|
282
|
-
return value;
|
|
283
|
-
} else {
|
|
284
|
-
return this.get(key);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return fetchUpdateKey.bind(this, key);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const defaultSettings = {
|
|
292
|
-
apiUrl: 'https://api.particle.io',
|
|
293
|
-
buildUrl: 'https://build.particle.io',
|
|
294
|
-
access_token: null,
|
|
295
|
-
|
|
296
|
-
notSourceExtensions: [
|
|
297
|
-
'.ds_store',
|
|
298
|
-
'.jpg',
|
|
299
|
-
'.gif',
|
|
300
|
-
'.png',
|
|
301
|
-
'.include',
|
|
302
|
-
'.ignore',
|
|
303
|
-
'.ds_store',
|
|
304
|
-
'.git',
|
|
305
|
-
'.bin'
|
|
306
|
-
],
|
|
307
|
-
|
|
308
|
-
dirIncludeFilename: 'particle.include',
|
|
309
|
-
dirExcludeFilename: 'particle.ignore',
|
|
310
|
-
|
|
311
|
-
knownApps: {
|
|
312
|
-
'deep_update_2014_06': true,
|
|
313
|
-
'cc3000': true,
|
|
314
|
-
'cc3000_1_14': true,
|
|
315
|
-
'tinker': true,
|
|
316
|
-
'voodoo': true
|
|
317
|
-
},
|
|
318
|
-
knownPlatforms: {
|
|
319
|
-
0: 'Core',
|
|
320
|
-
6: 'Photon',
|
|
321
|
-
8: 'P1',
|
|
322
|
-
10: 'Electron',
|
|
323
|
-
88: 'Duo',
|
|
324
|
-
103: 'Bluz'
|
|
325
|
-
},
|
|
326
|
-
updates: {
|
|
327
|
-
'2b04:d006': {
|
|
328
|
-
systemFirmwareOne: 'system-part1-0.6.1-photon.bin',
|
|
329
|
-
systemFirmwareTwo: 'system-part2-0.6.1-photon.bin'
|
|
330
|
-
},
|
|
331
|
-
'2b04:d008': {
|
|
332
|
-
systemFirmwareOne: 'system-part1-0.6.1-p1.bin',
|
|
333
|
-
systemFirmwareTwo: 'system-part2-0.6.1-p1.bin'
|
|
334
|
-
},
|
|
335
|
-
'2b04:d00a': {
|
|
336
|
-
// The bin files MUST be in this order to be flashed to the correct memory locations
|
|
337
|
-
systemFirmwareOne: 'system-part2-0.6.1-electron.bin',
|
|
338
|
-
systemFirmwareTwo: 'system-part3-0.6.1-electron.bin',
|
|
339
|
-
systemFirmwareThree: 'system-part1-0.6.1-electron.bin'
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
function buildSettings(separateSettings, initialSettings, skipLoadProfile) {
|
|
345
|
-
const settings = new Settings({ separateSettings, settings:[defaultSettings, initialSettings] });
|
|
346
|
-
if (!skipLoadProfile) {
|
|
347
|
-
settings.transitionSparkProfiles();
|
|
348
|
-
settings.whichProfile();
|
|
349
|
-
settings.loadOverrides();
|
|
350
|
-
}
|
|
351
|
-
return settings;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
export {
|
|
356
|
-
buildSettings,
|
|
357
|
-
defaultSettings,
|
|
358
|
-
Settings
|
|
359
|
-
};
|
package/src/lib/utilities.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const glob = require('glob');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
function globList(basepath, arr) {
|
|
5
|
-
let line, found, files = [];
|
|
6
|
-
for (let i=0;i<arr.length;i++) {
|
|
7
|
-
line = arr[i];
|
|
8
|
-
if (basepath) {
|
|
9
|
-
line = path.join(basepath, line);
|
|
10
|
-
}
|
|
11
|
-
found = glob.sync(line, { nodir: true, follow: true });
|
|
12
|
-
|
|
13
|
-
if (found && (found.length > 0)) {
|
|
14
|
-
files = files.concat(found);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return files;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
-
globList
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
|