@trayio/cdk-cli 2.16.0 → 2.18.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/README.md CHANGED
@@ -19,7 +19,7 @@ $ npm install -g @trayio/cdk-cli
19
19
  $ tray-cdk COMMAND
20
20
  running command...
21
21
  $ tray-cdk (--version|-v)
22
- @trayio/cdk-cli/2.16.0 linux-x64 node-v18.19.0
22
+ @trayio/cdk-cli/2.18.0 linux-x64 node-v18.19.0
23
23
  $ tray-cdk --help [COMMAND]
24
24
  USAGE
25
25
  $ tray-cdk COMMAND
@@ -39,6 +39,7 @@ USAGE
39
39
  * [`tray-cdk help [COMMANDS]`](#tray-cdk-help-commands)
40
40
  * [`tray-cdk import-openapi-spec [OPENAPISPEC] [CONNECTORNAME]`](#tray-cdk-import-openapi-spec-openapispec-connectorname)
41
41
  * [`tray-cdk init [CONNECTORNAME]`](#tray-cdk-init-connectorname)
42
+ * [`tray-cdk share [CONNECTORNAME] [CONNECTORVERSION]`](#tray-cdk-share-connectorname-connectorversion)
42
43
  * [`tray-cdk test [OPERATIONNAME]`](#tray-cdk-test-operationname)
43
44
  * [`tray-cdk version`](#tray-cdk-version)
44
45
 
@@ -191,6 +192,41 @@ DESCRIPTION
191
192
  Initialize a connector project
192
193
  ```
193
194
 
195
+ ## `tray-cdk share [CONNECTORNAME] [CONNECTORVERSION]`
196
+
197
+ Share your connector version with other users in your organization
198
+
199
+ ```
200
+ USAGE
201
+ $ tray-cdk share [CONNECTORNAME] [CONNECTORVERSION] [-e <value>] [-w <value>]
202
+
203
+ ARGUMENTS
204
+ CONNECTORNAME The name of the connector
205
+ CONNECTORVERSION The version of the connector
206
+
207
+ FLAGS
208
+ -e, --email=<value> Share with users by providing a list of emails
209
+ -w, --workspaces=<value> Share with the emails of users in a workspace by providing a list of workspace IDs
210
+
211
+ DESCRIPTION
212
+ Share your connector version with other users in your organization
213
+
214
+ EXAMPLES
215
+ $ tray-cdk share
216
+
217
+ $ tray-cdk share my-connector
218
+
219
+ $ tray-cdk share my-connector 1.0
220
+
221
+ $ tray-cdk share my-connector 1.0 --email="my.email@domain.com, your.email@domain.com"
222
+
223
+ $ tray-cdk share my-connector 1.0 -e="my.email@domain.com, your.email@domain.com"
224
+
225
+ $ tray-cdk share my-connector 1.0 --workspace="<workspace-id>, <another-workspace-id>"
226
+
227
+ $ tray-cdk share my-connector 1.0 -w="<workspace-id>, <another-workspace-id>"
228
+ ```
229
+
194
230
  ## `tray-cdk test [OPERATIONNAME]`
195
231
 
196
232
  Build and test connector project or an operation
@@ -0,0 +1,20 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Share extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ connectorName: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ connectorVersion: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ email: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ workspaces: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ };
13
+ private connectorPermissions;
14
+ run(): Promise<void>;
15
+ private handleShareByEmail;
16
+ private handleShareByWorkspace;
17
+ private splitList;
18
+ private truncateVersion;
19
+ }
20
+ //# sourceMappingURL=share.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../../src/commands/share.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAa,MAAM,aAAa,CAAC;AAMvD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,OAAO;IACzC,MAAM,CAAC,WAAW,SACoD;IAEtE,MAAM,CAAC,QAAQ,WAQb;IAEF,MAAM,CAAC,IAAI;;;MAWT;IAEF,MAAM,CAAC,KAAK;;;MAYV;IAEF,OAAO,CAAC,oBAAoB,CAK1B;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YA6EnB,kBAAkB;YA+BlB,sBAAsB;IAoCpC,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,eAAe;CAGvB"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const core_1 = require("@oclif/core");
16
+ const inquirer_1 = __importDefault(require("inquirer"));
17
+ const AxiosHttpClient_1 = require("@trayio/axios/http/AxiosHttpClient");
18
+ const ConnectorPermissionsHttpClient_1 = require("@trayio/tray-client/connector/permissions/ConnectorPermissionsHttpClient");
19
+ const colorizeString_1 = require("../utils/colorizeString");
20
+ class Share extends core_1.Command {
21
+ constructor() {
22
+ super(...arguments);
23
+ this.connectorPermissions = new ConnectorPermissionsHttpClient_1.ConnectorPermissionsHttpClient({
24
+ baseUrl: process.env.TRAY_API_URL,
25
+ }, new AxiosHttpClient_1.AxiosHttpClient());
26
+ }
27
+ run() {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const { args, flags } = yield this.parse(Share);
30
+ const TRAY_API_TOKEN = process.env.TRAY_API_TOKEN;
31
+ const promptRes = yield inquirer_1.default.prompt([
32
+ {
33
+ name: 'connectorName',
34
+ message: 'The name of the connector to share',
35
+ type: 'input',
36
+ when: !args.connectorName,
37
+ },
38
+ {
39
+ name: 'connectorVersion',
40
+ message: 'The version of the connector to share',
41
+ type: 'input',
42
+ when: !args.connectorVersion,
43
+ },
44
+ {
45
+ name: 'shareMethod',
46
+ message: 'How would you like to share the connector?',
47
+ type: 'list',
48
+ choices: [{ name: 'email' }, { name: 'workspace' }],
49
+ when: !flags.email && !flags.workspaces,
50
+ },
51
+ ]);
52
+ const shareTargetPrompt = yield inquirer_1.default.prompt([
53
+ {
54
+ name: 'emails',
55
+ message: 'Enter a comma separated list of emails to share the connector version with',
56
+ type: 'input',
57
+ when: !flags.email &&
58
+ !flags.workspaces &&
59
+ promptRes.shareMethod === 'email',
60
+ },
61
+ {
62
+ name: 'workspaceIds',
63
+ message: 'Enter the workspace IDs to share the connector version with',
64
+ type: 'input',
65
+ when: !flags.email &&
66
+ !flags.workspaces &&
67
+ promptRes.shareMethod === 'workspace',
68
+ },
69
+ ]);
70
+ const connectorName = args.connectorName || promptRes.connectorName;
71
+ const connectorVersion = this.truncateVersion(args.connectorVersion || promptRes.connectorVersion);
72
+ const emails = flags.email || shareTargetPrompt.emails;
73
+ const workspaceIds = flags.workspaces || shareTargetPrompt.workspaceIds;
74
+ if (emails && workspaceIds) {
75
+ this.log((0, colorizeString_1.error)('Please provide either emails or workspace IDs, not both'));
76
+ }
77
+ else if (emails && !workspaceIds) {
78
+ this.handleShareByEmail(connectorName, connectorVersion, TRAY_API_TOKEN, emails);
79
+ }
80
+ else if (workspaceIds && !emails) {
81
+ this.handleShareByWorkspace(connectorName, connectorVersion, TRAY_API_TOKEN, workspaceIds);
82
+ }
83
+ else {
84
+ this.log((0, colorizeString_1.error)('Please provide either emails or workspace IDs'));
85
+ }
86
+ });
87
+ }
88
+ handleShareByEmail(connectorName, connectorVersion, token, emails) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ core_1.ux.action.start(`Sharing ${connectorName} ${connectorVersion} with emails`);
91
+ const input = {
92
+ connectorName,
93
+ connectorVersion,
94
+ emails: this.splitList(emails),
95
+ token,
96
+ };
97
+ const response = yield this.connectorPermissions.shareWithEmails(input);
98
+ core_1.ux.action.stop();
99
+ if (response.isSuccess) {
100
+ this.log((0, colorizeString_1.success)(response.value.message));
101
+ }
102
+ if (response.isFailure) {
103
+ this.log((0, colorizeString_1.error)(`Connector Share By Email Failed, please try again or contact support`));
104
+ this.log(response.error.message);
105
+ }
106
+ });
107
+ }
108
+ handleShareByWorkspace(connectorName, connectorVersion, token, workspaceIds) {
109
+ return __awaiter(this, void 0, void 0, function* () {
110
+ core_1.ux.action.start(`Sharing ${connectorName} ${connectorVersion} with emails assigned to the given workspaces`);
111
+ const input = {
112
+ connectorName,
113
+ connectorVersion,
114
+ workspaceIds: this.splitList(workspaceIds),
115
+ token,
116
+ };
117
+ const response = yield this.connectorPermissions.shareWithWorkspaces(input);
118
+ core_1.ux.action.stop();
119
+ if (response.isSuccess) {
120
+ this.log((0, colorizeString_1.success)(response.value.success.message));
121
+ if (response.value.warnings.emptyWorkspaces.length > 0) {
122
+ this.log((0, colorizeString_1.error)(response.value.warnings.emptyWorkspaces.join(', ')));
123
+ }
124
+ }
125
+ if (response.isFailure) {
126
+ this.log((0, colorizeString_1.error)(`Connector Share By Workspace Failed, please try again or contact support`));
127
+ this.log(response.error.message);
128
+ }
129
+ });
130
+ }
131
+ splitList(list) {
132
+ return list
133
+ .replace(/['"]+/g, '')
134
+ .split(',')
135
+ .map((item) => item.trim());
136
+ }
137
+ truncateVersion(version) {
138
+ return version.split('.').slice(0, 2).join('.');
139
+ }
140
+ }
141
+ Share.description = 'Share your connector version with other users in your organization';
142
+ Share.examples = [
143
+ '<%= config.bin %> <%= command.id %>',
144
+ '<%= config.bin %> <%= command.id %> my-connector',
145
+ '<%= config.bin %> <%= command.id %> my-connector 1.0',
146
+ '<%= config.bin %> <%= command.id %> my-connector 1.0 --email="my.email@domain.com, your.email@domain.com"',
147
+ '<%= config.bin %> <%= command.id %> my-connector 1.0 -e="my.email@domain.com, your.email@domain.com"',
148
+ '<%= config.bin %> <%= command.id %> my-connector 1.0 --workspace="<workspace-id>, <another-workspace-id>"',
149
+ '<%= config.bin %> <%= command.id %> my-connector 1.0 -w="<workspace-id>, <another-workspace-id>"',
150
+ ];
151
+ Share.args = {
152
+ connectorName: core_1.Args.string({
153
+ name: 'Connector Name',
154
+ required: false,
155
+ description: 'The name of the connector',
156
+ }),
157
+ connectorVersion: core_1.Args.string({
158
+ name: 'Connector Version',
159
+ required: false,
160
+ description: 'The version of the connector',
161
+ }),
162
+ };
163
+ Share.flags = {
164
+ email: core_1.Flags.string({
165
+ char: 'e',
166
+ aliases: ['emails', 'email'],
167
+ description: 'Share with users by providing a list of emails',
168
+ }),
169
+ workspaces: core_1.Flags.string({
170
+ char: 'w',
171
+ aliases: ['workspaces', 'workspace'],
172
+ description: 'Share with the emails of users in a workspace by providing a list of workspace IDs',
173
+ }),
174
+ };
175
+ exports.default = Share;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=share.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.unit.test.d.ts","sourceRoot":"","sources":["../../src/commands/share.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const stdout_stderr_1 = require("stdout-stderr");
16
+ const ConnectorPermissionsHttpClient_1 = require("@trayio/tray-client/connector/permissions/ConnectorPermissionsHttpClient");
17
+ const share_1 = __importDefault(require("./share"));
18
+ jest.mock('@trayio/tray-client/connector/permissions/ConnectorPermissionsHttpClient', () => ({
19
+ ConnectorPermissionsHttpClient: jest.fn(),
20
+ }));
21
+ describe('Share', () => {
22
+ let success = true;
23
+ const connectorName = 'some-connector-name';
24
+ const connectorVersion = '1.0';
25
+ const emails = 'test.user@tray.io, another.user@tray.io';
26
+ const workspaceIds = 'workspace-id,another-workspace-id';
27
+ const mockedShareWithEmailsSuccess = jest.fn().mockReturnValue({
28
+ isSuccess: true,
29
+ value: {
30
+ message: '1 permissions added',
31
+ },
32
+ });
33
+ const mockedShareWithEmailsFailure = jest.fn().mockReturnValue({
34
+ isFailure: true,
35
+ error: {
36
+ message: `The connector (Left(some-connector-name~1.1)) was not found or you don't have permission to access it`,
37
+ },
38
+ });
39
+ const mockedShareWithWorkspacesSuccess = jest.fn().mockReturnValue({
40
+ isSuccess: true,
41
+ value: {
42
+ success: { message: '5 permissions added' },
43
+ warnings: {
44
+ emptyWorkspaces: [
45
+ 'No permissions to add for workspace: 9b31dc75-3217-458b-923a-8a48ff5b5e',
46
+ ],
47
+ },
48
+ },
49
+ });
50
+ const mockedShareWithWorkspacesFailure = jest.fn().mockReturnValue({
51
+ isFailure: true,
52
+ error: {
53
+ message: `The connector (Left(some-connector-name~1.1)) was not found or you don't have permission to access it`,
54
+ },
55
+ });
56
+ beforeEach(() => {
57
+ ConnectorPermissionsHttpClient_1.ConnectorPermissionsHttpClient.mockImplementation(() => ({
58
+ shareWithEmails: success
59
+ ? mockedShareWithEmailsSuccess
60
+ : mockedShareWithEmailsFailure,
61
+ shareWithWorkspaces: success
62
+ ? mockedShareWithWorkspacesSuccess
63
+ : mockedShareWithWorkspacesFailure,
64
+ }));
65
+ });
66
+ afterAll(() => {
67
+ jest.clearAllMocks();
68
+ });
69
+ it('should log success message when connector is shared by email', () => __awaiter(void 0, void 0, void 0, function* () {
70
+ success = true;
71
+ stdout_stderr_1.stdout.start();
72
+ yield share_1.default.run([connectorName, connectorVersion, `--email='${emails}'`]);
73
+ stdout_stderr_1.stdout.stop();
74
+ expect(mockedShareWithEmailsSuccess).toHaveBeenCalledWith({
75
+ connectorName,
76
+ connectorVersion,
77
+ emails: ['test.user@tray.io', 'another.user@tray.io'],
78
+ token: undefined,
79
+ });
80
+ expect(stdout_stderr_1.stdout.output).toEqual(expect.stringContaining('1 permissions added'));
81
+ }));
82
+ it('should log error messages when share with emails fails', () => __awaiter(void 0, void 0, void 0, function* () {
83
+ success = false;
84
+ stdout_stderr_1.stdout.start();
85
+ yield share_1.default.run([connectorName, connectorVersion, `--emails='${emails}'`]);
86
+ stdout_stderr_1.stdout.stop();
87
+ expect(stdout_stderr_1.stdout.output).toEqual(expect.stringContaining('Connector Share By Email Failed, please try again or contact support'));
88
+ expect(stdout_stderr_1.stdout.output).toEqual(expect.stringContaining(`The connector (Left(some-connector-name~1.1)) was not found or you don't have permission to access it`));
89
+ }));
90
+ it('should log success message when connector is shared by workspaces and warn of empty workspaces', () => __awaiter(void 0, void 0, void 0, function* () {
91
+ success = true;
92
+ stdout_stderr_1.stdout.start();
93
+ yield share_1.default.run([
94
+ connectorName,
95
+ connectorVersion,
96
+ `--workspaces='${workspaceIds}'`,
97
+ ]);
98
+ stdout_stderr_1.stdout.stop();
99
+ expect(mockedShareWithWorkspacesSuccess).toHaveBeenCalledWith({
100
+ connectorName,
101
+ connectorVersion,
102
+ workspaceIds: ['workspace-id', 'another-workspace-id'],
103
+ token: undefined,
104
+ });
105
+ expect(stdout_stderr_1.stdout.output).toEqual(expect.stringContaining('5 permissions added'));
106
+ expect(stdout_stderr_1.stdout.output).toEqual(expect.stringContaining('No permissions to add for workspace: 9b31dc75-3217-458b-923a-8a48ff5b5e'));
107
+ }));
108
+ it('should log error message when connector share by workspaces fails', () => __awaiter(void 0, void 0, void 0, function* () {
109
+ success = false;
110
+ stdout_stderr_1.stdout.start();
111
+ yield share_1.default.run([
112
+ connectorName,
113
+ connectorVersion,
114
+ `--workspaces='${workspaceIds}'`,
115
+ ]);
116
+ stdout_stderr_1.stdout.stop();
117
+ expect(stdout_stderr_1.stdout.output).toEqual(expect.stringContaining(`The connector (Left(some-connector-name~1.1)) was not found or you don't have permission to access it`));
118
+ }));
119
+ });
@@ -193,6 +193,71 @@
193
193
  "init.js"
194
194
  ]
195
195
  },
196
+ "share": {
197
+ "aliases": [],
198
+ "args": {
199
+ "connectorName": {
200
+ "description": "The name of the connector",
201
+ "name": "connectorName",
202
+ "required": false
203
+ },
204
+ "connectorVersion": {
205
+ "description": "The version of the connector",
206
+ "name": "connectorVersion",
207
+ "required": false
208
+ }
209
+ },
210
+ "description": "Share your connector version with other users in your organization",
211
+ "examples": [
212
+ "<%= config.bin %> <%= command.id %>",
213
+ "<%= config.bin %> <%= command.id %> my-connector",
214
+ "<%= config.bin %> <%= command.id %> my-connector 1.0",
215
+ "<%= config.bin %> <%= command.id %> my-connector 1.0 --email=\"my.email@domain.com, your.email@domain.com\"",
216
+ "<%= config.bin %> <%= command.id %> my-connector 1.0 -e=\"my.email@domain.com, your.email@domain.com\"",
217
+ "<%= config.bin %> <%= command.id %> my-connector 1.0 --workspace=\"<workspace-id>, <another-workspace-id>\"",
218
+ "<%= config.bin %> <%= command.id %> my-connector 1.0 -w=\"<workspace-id>, <another-workspace-id>\""
219
+ ],
220
+ "flags": {
221
+ "email": {
222
+ "aliases": [
223
+ "emails",
224
+ "email"
225
+ ],
226
+ "char": "e",
227
+ "description": "Share with users by providing a list of emails",
228
+ "name": "email",
229
+ "hasDynamicHelp": false,
230
+ "multiple": false,
231
+ "type": "option"
232
+ },
233
+ "workspaces": {
234
+ "aliases": [
235
+ "workspaces",
236
+ "workspace"
237
+ ],
238
+ "char": "w",
239
+ "description": "Share with the emails of users in a workspace by providing a list of workspace IDs",
240
+ "name": "workspaces",
241
+ "hasDynamicHelp": false,
242
+ "multiple": false,
243
+ "type": "option"
244
+ }
245
+ },
246
+ "hasDynamicHelp": false,
247
+ "hiddenAliases": [],
248
+ "id": "share",
249
+ "pluginAlias": "@trayio/cdk-cli",
250
+ "pluginName": "@trayio/cdk-cli",
251
+ "pluginType": "core",
252
+ "strict": true,
253
+ "enableJsonFlag": false,
254
+ "isESM": false,
255
+ "relativePath": [
256
+ "dist",
257
+ "commands",
258
+ "share.js"
259
+ ]
260
+ },
196
261
  "test": {
197
262
  "aliases": [],
198
263
  "args": {
@@ -228,5 +293,5 @@
228
293
  ]
229
294
  }
230
295
  },
231
- "version": "2.16.0"
296
+ "version": "2.18.0"
232
297
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trayio/cdk-cli",
3
- "version": "2.16.0",
3
+ "version": "2.18.0",
4
4
  "description": "A CLI for connector development",
5
5
  "exports": {
6
6
  "./*": "./dist/*.js"
@@ -19,12 +19,12 @@
19
19
  "@oclif/plugin-help": "6.0.12",
20
20
  "@oclif/plugin-version": "2.0.11",
21
21
  "@oclif/test": "3.1.12",
22
- "@trayio/axios": "2.16.0",
23
- "@trayio/cdk-build": "2.16.0",
24
- "@trayio/commons": "2.16.0",
25
- "@trayio/generator": "2.16.0",
26
- "@trayio/tray-client": "2.16.0",
27
- "@trayio/tray-openapi": "2.16.0",
22
+ "@trayio/axios": "2.18.0",
23
+ "@trayio/cdk-build": "2.18.0",
24
+ "@trayio/commons": "2.18.0",
25
+ "@trayio/generator": "2.18.0",
26
+ "@trayio/tray-client": "2.18.0",
27
+ "@trayio/tray-openapi": "2.18.0",
28
28
  "@types/inquirer": "8.2.6",
29
29
  "chalk": "4.1.2",
30
30
  "inquirer": "8.2.5"