Skip to content

Commit d5a613d

Browse files
committed
feat(commandline): add experimental support for commander based cli
1 parent a86c462 commit d5a613d

File tree

6 files changed

+203
-45
lines changed

6 files changed

+203
-45
lines changed

README.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ There is a swagger.yaml available to generate bindings (https://launchdarkly.git
2525
## Example usage
2626
Please note that the api token is not the same as your sdk keys. You need to generate this for your account in LaunchDarkly console as above, and set it as the LAUNCHDARKLY_API_TOKEN env var.
2727

28-
### commandline usage
29-
Command line support is primarily for debugging api calls.
28+
### commandline usage OLD
29+
This command line support was primarily for debugging api calls. The NEW version below is aimed at general usage.
3030
```
3131
export LAUNCHDARKLY_API_TOKEN=<api-token>
3232
@@ -37,6 +37,18 @@ npm run api -- getFeatureFlags <myProjectId>
3737
npm run api -- upsertCustomRole <customRoleKey> <customRoleName> '[{"resources":["proj/*"],"actions":["*"],"effect":"allow"}]'
3838
```
3939

40+
### commandline usage NEW (in progress)
41+
A more complete commandline solution is underway - try it out using:
42+
43+
```
44+
chmod 755 ./ldutils
45+
./ldutils
46+
```
47+
48+
The above will display a help screen of instructions, thanks to https://github.com/tj/commander.js/
49+
50+
Make sure you have env var LAUNCHDARKLY_API_TOKEN set, and if piping output to another command, ensure that LAUNCHDARKLY_API_LOGLEVEL is not set to 'debug'.
51+
4052
### node app usage
4153
Assumes that you have set the LAUNCHDARKLY_API_TOKEN environment var.
4254
```
@@ -71,8 +83,10 @@ The command line modes and parameters map directly to the functions exposed for
7183
| updateCustomRole | customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription(optional) |
7284
| upsertCustomRole | customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription(optional) |
7385
| bulkUpsertCustomRoles | roleBulkLoadFile |
86+
| bulkUpsertCustomRoleFolder | roleFolder |
7487

75-
Bulk upsert iterates over a json file containing an array of role json and either creates or updates each. Promises are resolved sequentially to avoid rate limiting.
88+
- `bulkUpsertCustomRoles` mode iterates over a json file containing an array of role json and either creates or updates each. Promises are resolved sequentially to avoid rate limiting.
89+
- `bulkUpsertCustomRoleFolder` mode does the same on a folder of json files.
7690

7791
```
7892
npm run api -- bulkUpsertCustomRoles ./exampleRoleBulkLoad.json

ldutils

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env node
2+
let json = require('format-json');
3+
let program = require('commander');
4+
let LaunchDarklyUtils = require('./dist/src/LaunchDarklyUtils.js').LaunchDarklyUtils;
5+
require('dotenv').config();
6+
7+
if (!process.env.LAUNCHDARKLY_API_TOKEN) {
8+
console.log('missing environment var LAUNCHDARKLY_API_TOKEN - exiting..');
9+
process.exit(1);
10+
}
11+
12+
let log = console;
13+
if (process.env.LAUNCHDARKLY_API_LOGLEVEL === 'debug') log = undefined;
14+
new LaunchDarklyUtils().create(process.env.LAUNCHDARKLY_API_TOKEN, log).then(function(ldUtils) {
15+
16+
program
17+
.version('0.1.0');
18+
19+
program
20+
.command('getFeatureFlags <projectKey>')
21+
.description('get all flags for a given project')
22+
.action(function(projectKey) {
23+
ldUtils.flags.getFeatureFlags(projectKey).then(function(response) {
24+
console.log(json.plain(response));
25+
});
26+
});
27+
28+
program
29+
.command(`getFeatureFlag <projectKey> <featureFlagKey> [environmentKeyQuery]`)
30+
.description('get a single flag - with optional env')
31+
.action(function(projectKey, featureFlagKey) {
32+
ldUtils.flags.getFeatureFlag(projectKey, featureFlagKey).then(function(response) {
33+
console.log(json.plain(response));
34+
});
35+
});
36+
37+
program
38+
.command(`getFeatureFlagState <projectKey> <featureFlagKey> <environmentKeyQuery>`)
39+
.description('get boolean flag state')
40+
.action(function(projectKey, featureFlagKey, environmentKeyQuery) {
41+
ldUtils.flags.getFeatureFlagState(projectKey, featureFlagKey, environmentKeyQuery).then(function(response) {
42+
console.log(json.plain(response));
43+
});
44+
});
45+
46+
program
47+
.command(`toggleFeatureFlag <projectKey> <featureFlagKey> <environmentKeyQuery> <value>`)
48+
.description('set boolean flag state')
49+
.action(function(projectKey, featureFlagKey, environmentKeyQuery, value) {
50+
let enabled = value === 'true';
51+
ldUtils.flags.toggleFeatureFlag(projectKey, featureFlagKey, environmentKeyQuery, enabled).then(function(response) {
52+
console.log(json.plain(response));
53+
});
54+
});
55+
56+
program
57+
.command('getCustomRoles')
58+
.description('get all custom roles in account')
59+
.action(function() {
60+
ldUtils.roles.getCustomRoles().then(function(response) {
61+
console.log(json.plain(response));
62+
});
63+
});
64+
65+
program
66+
.command('getCustomRole <customRoleKey>')
67+
.description('get custom role by key')
68+
.action(function(customRoleKey) {
69+
ldUtils.roles.getCustomRole(customRoleKey).then(function(response) {
70+
console.log(json.plain(response));
71+
});
72+
});
73+
74+
program
75+
.command(`createCustomRole <customRoleKey> <customRoleName> <customRolePolicyArray> [customRoleDescription]`)
76+
.description('create custom role')
77+
.action(function(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription) {
78+
customRolePolicyArray = JSON.parse(customRolePolicyArray);
79+
ldUtils.roles.createCustomRole(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription).then(function(response) {
80+
console.log(json.plain(response));
81+
});
82+
});
83+
84+
program
85+
.command(`updateCustomRole <customRoleKey> <customRoleName> <customRolePolicyArray> [customRoleDescription]`)
86+
.description('update custom role')
87+
.action(function(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription) {
88+
customRolePolicyArray = JSON.parse(customRolePolicyArray);
89+
ldUtils.roles.updateCustomRole(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription).then(function(response) {
90+
console.log(json.plain(response));
91+
});
92+
});
93+
94+
program
95+
.command(`upsertCustomRole <customRoleKey> <customRoleName> <customRolePolicyArray> [customRoleDescription]`)
96+
.description('create or update custom role')
97+
.action(function(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription) {
98+
customRolePolicyArray = JSON.parse(customRolePolicyArray);
99+
ldUtils.roles.upsertCustomRole(customRoleKey, customRoleName, customRolePolicyArray, customRoleDescription).then(function(response) {
100+
console.log(json.plain(response));
101+
});
102+
});
103+
104+
program
105+
.command('bulkUpsertCustomRoles <roleBulkLoadFile>')
106+
.description('path to a file containing array of role json')
107+
.action(function(roleBulkLoadFile) {
108+
ldUtils.roles.bulkUpsertCustomRoles(roleBulkLoadFile).then(function(response) {
109+
console.log(json.plain(response));
110+
});
111+
});
112+
113+
program
114+
.command('bulkUpsertCustomRoleFolder <roleFolder>')
115+
.description('path to a directory containing multiple files of role json')
116+
.action(function(roleFolder) {
117+
ldUtils.roles.bulkUpsertCustomRoleFolder(roleFolder).then(function(response) {
118+
console.log(json.plain(response));
119+
});
120+
});
121+
122+
console.log(process.argv);
123+
if (process.argv.length < 3) {
124+
program.help();
125+
process.exit(1);
126+
}
127+
128+
program
129+
.parse(process.argv);
130+
131+
})
132+
.catch(function(e) {
133+
console.log(json.plain(e));
134+
});
135+

package-lock.json

Lines changed: 31 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"fast-json-patch": "^2.0.6",
3535
"globule": "^1.2.0",
3636
"js-yaml": "^3.10.0",
37+
"json-format": "^1.0.1",
3738
"ldclient-node": "^3.3.2",
3839
"swagger-client": "^3.4.7",
3940
"webpack": "^3.10.0"

src/LaunchDarklyUtils.js

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,25 @@ dotenv.config();
77

88
export class LaunchDarklyUtils {
99
async create(API_TOKEN, customLogger) {
10-
// setup logger
11-
this.log = customLogger ? customLogger : LaunchDarklyLogger.logger();
12-
this.log.debug('logger attached..');
10+
let that = this;
11+
return new Promise(async (resolve, reject) => {
12+
// setup logger
13+
that.log = customLogger ? customLogger : LaunchDarklyLogger.logger();
14+
that.log.debug('logger attached..');
1315

14-
// create LaunchDarkly apiClient
15-
this.apiClient = await LaunchDarklyApiClient.create(API_TOKEN, this.log);
16-
this.log.debug('api client instantiated..');
16+
// create LaunchDarkly apiClient
17+
try {
18+
that.apiClient = await LaunchDarklyApiClient.create(API_TOKEN, this.log);
19+
that.log.debug('api client instantiated..');
1720

18-
// attach flag utils
19-
this.flags = new LaunchDarklyUtilsFlags(this.apiClient, this.log);
20-
this.log.debug(`flag functions: ${this.flags}`);
21-
22-
// attach role utils
23-
this.roles = new LaunchDarklyUtilsRoles(this.apiClient, this.log);
24-
this.log.debug(`role functions: ${this.roles}`);
25-
26-
return this;
21+
// attach utils
22+
that.flags = new LaunchDarklyUtilsFlags(this.apiClient, this.log);
23+
that.roles = new LaunchDarklyUtilsRoles(this.apiClient, this.log);
24+
that.log.debug(`utils ready.`);
25+
} catch (e) {
26+
return reject(e);
27+
}
28+
return resolve(that);
29+
});
2730
}
2831
}

src/LaunchDarklyUtilsFlags.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class LaunchDarklyUtilsFlags {
3030
return this.apiClient.apis[this.API_GROUP].patchFeatureFlag({
3131
projectKey: projectKey,
3232
featureFlagKey: featureFlagKey,
33-
patchDelta: [{ op: 'replace', path: `/environments/${environmentKeyQuery}/on`, value: value }]
33+
patchComment: [{ op: 'replace', path: `/environments/${environmentKeyQuery}/on`, value: value }]
3434
});
3535
}
3636
}

0 commit comments

Comments
 (0)