diff --git a/.gitignore b/.gitignore index ff288c3..6e23e54 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ coverage typings .nyc_output *.map -.env \ No newline at end of file +.env +*.yml \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index cbdb85a..f5d9adf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ # CHANGELOG +## [2.0.2] - 2018/12/13 +### Fixed : +- Switch team error +- Create team error namespace +- Add or remove member to team + +### Added : +- Pull with revision +- Version type when create-deployment + ## [2.0.1] - 2018/12/05 ### Fixed : - Fix .gitignore diff --git a/components/bots/bot.ts b/components/bots/bot.ts index be6a727..dd0e1b8 100644 --- a/components/bots/bot.ts +++ b/components/bots/bot.ts @@ -380,38 +380,58 @@ export default class Bot extends Component { throw new Error("Sync only accept promises"); } - public async pull(name: string, version: string, options: JsonObject) { - let isGettingBot = false; + public async pull(revision: string, options: JsonObject) { + + let projectId; + let bots; + let botDesc; + try { - const { data, response } = await this.helper.toPromise(this.api.botApi, this.api.botApi.botsGet, {}); - let found = false; - let selectedBot: any; - for (const bot of data.items) { - const botName = bot.name; - if (botName === name) { - found = true; - selectedBot = bot; - break; - } - } - if (found) { - // Get specific bot version - isGettingBot = true; - const botId = selectedBot.id + ":" + version; - const getBot = await this.helper.toPromise(this.api.botApi, this.api.botApi.botsBotIdGet, botId); - const botDesc = getBot.data; - this.helper.dumpYaml("./bot.yml", botDesc); - console.log(`SUCCESS PULL BOT ${name} WITH VERSION ${version}`); - } else { - console.log(`BOT NOT FOUND`); + projectId = this.getProject(); + } catch (e) { + console.log(this.helper.wrapError(e)); + return; + } + try { + const { response: { body } } = await this.helper.toPromise( + this.api.botApi, this.api.botApi.projectsProjectIdBotRevisionsGet, projectId); + bots = body.data; + + } catch (e) { + console.log("INVALID PROJECT"); + return; + } + try { + if (!revision) { + revision = bots[0].revision; } + const { response: { body } } = await this.helper.toPromise( + this.api.botApi, this.api.botApi.projectsProjectIdBotRevisionsRevisionGet, projectId, revision); + botDesc = body; + } catch (e) { - if (isGettingBot) { - console.log(`CANNOT PULL BOT ${name} WITH VERSION ${version}`); - } else { - console.log(this.helper.wrapError(e)); + console.log("INVALID PROJECT REVISION"); + return; + } + + // remove data + delete botDesc.id; + delete botDesc.revision; + delete botDesc.changelog; + for (const flow in botDesc.flows) { + if (botDesc.flows[flow]) { + for (const state in botDesc.flows[flow].states) { + if (botDesc.flows[flow].states[state]) { + delete botDesc.flows[flow].states[state].style; + } + } } } + + console.log(`Pull bot revision ${revision.substring(0, 6)} to bot.yml`); + this.helper.dumpYaml("./bot.yml", botDesc); + + return; } private getProject() { diff --git a/components/bots/deployment.ts b/components/bots/deployment.ts index 1bd573f..adb5aa0 100644 --- a/components/bots/deployment.ts +++ b/components/bots/deployment.ts @@ -7,13 +7,12 @@ export default class Deployment { constructor(private helper: IHelper, private api: any) { } - public async create() { + public async create(versionType?: string) { const projectId = this.helper.getProjectId(); const { response: { body: project } } = await this.helper.toPromise( this.api.projectApi, this.api.projectApi.projectsProjectIdGet, projectId ); - // TODO: {page:1, limit:1} let botRevision: string; let nluRevision: string; @@ -53,13 +52,26 @@ export default class Deployment { } let targetVersion; + try { + // get previous deployment version const { response: { body: latestDeployment } } = await this.helper.toPromise(this.api.projectApi, this.api.projectApi.projectsProjectIdDeploymentGet, projectId); const prevVersion = latestDeployment.version; - const [major, minor, patch] = prevVersion.split("."); - const updatedPatch = Number(patch) + 1; - targetVersion = `${major}.${minor}.${updatedPatch}`; + let [major, minor, patch] = prevVersion.split("."); + + if (versionType === "major") { + major = Number(major) + 1; + minor = 0; + patch = 0; + } else if (versionType === "minor") { + minor = Number(minor) + 1; + patch = 0; + } else { + patch = Number(patch) + 1; + } + targetVersion = `${major}.${minor}.${patch}`; + } catch (e) { targetVersion = "0.0.1"; } diff --git a/components/projects/project.ts b/components/projects/project.ts index 53ff759..2579316 100644 --- a/components/projects/project.ts +++ b/components/projects/project.ts @@ -55,7 +55,7 @@ export default class Project { delete nluOptions.privateNlu; } - const requestBody = { ...projectData, options: { ...options, nluOptions } }; + const requestBody = { ...projectData, options: { ...options, ...nluOptions } }; try { const { response } = await this.helper.toPromise( diff --git a/components/users/team.ts b/components/users/team.ts index 29753ef..7a1ac57 100644 --- a/components/users/team.ts +++ b/components/users/team.ts @@ -16,8 +16,7 @@ export default class Team extends Component { if (this.checkUser(userInfo.id, teamMember)) { throw new Error(`User ${username} already on this team`); } - - const { response } = await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdPost, teamInfo.data.id, userInfo.id, { roleId: role } ); + const { response } = await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdPost, teamInfo.id, userInfo.id, { roleId: role } ); if (!response.body) { throw new Error("Error adding user to team: invalid roleId"); } @@ -31,7 +30,7 @@ export default class Team extends Component { } } - public async removeMember(username : string) { + public async removeMember(username: string) { const answer = await this.helper.inquirerPrompt([ { type: "confirm", @@ -52,7 +51,7 @@ export default class Team extends Component { throw new Error(`User ${username} not a member of this team`); } - const { response } = await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdDelete, teamInfo.data.id, userInfo.id); + const { response } = await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdDelete, teamInfo.id, userInfo.id); console.log(`Success remove ${username} from ${currentLogin}`); } else { @@ -64,28 +63,54 @@ export default class Team extends Component { } } - private async getInfo(username : string) { + private async getInfo(username: string) { const currentLogin = this.helper.getProp("current_login") as string; const currentUserType = this.helper.getProp("current_user_type") as string; if (currentUserType !== "team") { throw new Error("Must be on team to do this operation"); } + + const requestTeamData = + await this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, currentLogin); + + let teamInfo: any; + if (requestTeamData.response && requestTeamData.response.body) { + teamInfo = requestTeamData.response.body; + } else { + throw new Error("Cannot add user to team"); + } - const team = await this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, currentLogin); - const { data } = await this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, username); - const member = await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersGet, team.data.id); + const requestUserData = + await this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, username); + + let userInfo: any; + if (requestUserData && requestUserData.response) { + userInfo = requestUserData.response.body; + } else { + throw new Error("Cannot add user to team"); + } + + const requestTeamMember = + await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersGet, teamInfo.id); + + let teamMember: any[]; + if (requestTeamMember && requestTeamMember.response) { + teamMember = requestTeamMember.response.body; + } else { + throw new Error("Cannot add user to team"); + } return { - teamInfo: team, - userInfo: data, - teamMember: member, + teamInfo, + userInfo, + teamMember, currentLogin }; } - private checkUser(userId : string, member : any) : boolean { - const teamMember = member.response.body.map((x : JsonObject) => x.userId); + private checkUser(userId: string, member: any[]): boolean { + const teamMember = member.map((x: JsonObject) => x.userId); if (teamMember.indexOf(userId) > -1) { return true; } diff --git a/components/users/user.ts b/components/users/user.ts index 7fed980..838d056 100644 --- a/components/users/user.ts +++ b/components/users/user.ts @@ -119,14 +119,22 @@ export default class User extends Component { try { const firstLogin = this.helper.getProp("first_login") as JsonObject; const currentType = this.helper.getProp("current_user_type"); + const currentLogin = this.helper.getProp("current_login"); + const username = name ? name : currentLogin; - if (currentType === type) { - throw new Error(`Unable to switch : already on ${type}`); + if (currentType === type && username === currentLogin) { + throw new Error(`Unable to switch : already on ${currentLogin} ${type}`); } + if (type === "team") { - const info = await this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, firstLogin.id); - const teams = info ? info.data.teams.filter((team: any) => team.username === name) : []; + const { response } = await this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, firstLogin.id); + + if (!response) { + throw new Error("Unable to switch team"); + } + + const teams = response && response.body ? response.body.teams.filter((team: any) => team.username === name) : []; if (teams.length > 0) { const result = await this.helper.toPromise(this.api.authApi, this.api.authApi.tokensPost, { type: "team", teamId: teams[0].teamId }); const token = result.data.id; @@ -187,9 +195,6 @@ export default class User extends Component { const { response } = await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsPost, { username: name, password: "", roleId: "teamAdmin" }); if (response && response.body.id) { - const { data } = await this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, currentLogin); - const result = await this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdPost, response.body.id, data.id, { roleId: "teamAdmin" }); - console.log(`Team ${name} created !`); } else { console.log(`Team ${name} exist !`); diff --git a/lib/components/bots/bot.js b/lib/components/bots/bot.js index fb948a0..b06265e 100644 --- a/lib/components/bots/bot.js +++ b/lib/components/bots/bot.js @@ -364,42 +364,53 @@ class Bot extends merapi_1.Component { } throw new Error("Sync only accept promises"); } - pull(name, version, options) { + pull(revision, options) { return __awaiter(this, void 0, void 0, function* () { - let isGettingBot = false; + let projectId; + let bots; + let botDesc; try { - const { data, response } = yield this.helper.toPromise(this.api.botApi, this.api.botApi.botsGet, {}); - let found = false; - let selectedBot; - for (const bot of data.items) { - const botName = bot.name; - if (botName === name) { - found = true; - selectedBot = bot; - break; - } - } - if (found) { - // Get specific bot version - isGettingBot = true; - const botId = selectedBot.id + ":" + version; - const getBot = yield this.helper.toPromise(this.api.botApi, this.api.botApi.botsBotIdGet, botId); - const botDesc = getBot.data; - this.helper.dumpYaml("./bot.yml", botDesc); - console.log(`SUCCESS PULL BOT ${name} WITH VERSION ${version}`); - } - else { - console.log(`BOT NOT FOUND`); - } + projectId = this.getProject(); + } + catch (e) { + console.log(this.helper.wrapError(e)); + return; + } + try { + const { response: { body } } = yield this.helper.toPromise(this.api.botApi, this.api.botApi.projectsProjectIdBotRevisionsGet, projectId); + bots = body.data; } catch (e) { - if (isGettingBot) { - console.log(`CANNOT PULL BOT ${name} WITH VERSION ${version}`); + console.log("INVALID PROJECT"); + return; + } + try { + if (!revision) { + revision = bots[0].revision; } - else { - console.log(this.helper.wrapError(e)); + const { response: { body } } = yield this.helper.toPromise(this.api.botApi, this.api.botApi.projectsProjectIdBotRevisionsRevisionGet, projectId, revision); + botDesc = body; + } + catch (e) { + console.log("INVALID PROJECT REVISION"); + return; + } + // remove data + delete botDesc.id; + delete botDesc.revision; + delete botDesc.changelog; + for (const flow in botDesc.flows) { + if (botDesc.flows[flow]) { + for (const state in botDesc.flows[flow].states) { + if (botDesc.flows[flow].states[state]) { + delete botDesc.flows[flow].states[state].style; + } + } } } + console.log(`Pull bot revision ${revision.substring(0, 6)} to bot.yml`); + this.helper.dumpYaml("./bot.yml", botDesc); + return; }); } getProject() { diff --git a/lib/components/bots/deployment.js b/lib/components/bots/deployment.js index a856e3c..67b90aa 100644 --- a/lib/components/bots/deployment.js +++ b/lib/components/bots/deployment.js @@ -14,7 +14,7 @@ class Deployment { this.helper = helper; this.api = api; } - create() { + create(versionType) { return __awaiter(this, void 0, void 0, function* () { const projectId = this.helper.getProjectId(); const { response: { body: project } } = yield this.helper.toPromise(this.api.projectApi, this.api.projectApi.projectsProjectIdGet, projectId); @@ -54,11 +54,23 @@ class Deployment { } let targetVersion; try { + // get previous deployment version const { response: { body: latestDeployment } } = yield this.helper.toPromise(this.api.projectApi, this.api.projectApi.projectsProjectIdDeploymentGet, projectId); const prevVersion = latestDeployment.version; - const [major, minor, patch] = prevVersion.split("."); - const updatedPatch = Number(patch) + 1; - targetVersion = `${major}.${minor}.${updatedPatch}`; + let [major, minor, patch] = prevVersion.split("."); + if (versionType === "major") { + major = Number(major) + 1; + minor = 0; + patch = 0; + } + else if (versionType === "minor") { + minor = Number(minor) + 1; + patch = 0; + } + else { + patch = Number(patch) + 1; + } + targetVersion = `${major}.${minor}.${patch}`; } catch (e) { targetVersion = "0.0.1"; diff --git a/lib/components/projects/project.js b/lib/components/projects/project.js index a844a66..05b0e5a 100644 --- a/lib/components/projects/project.js +++ b/lib/components/projects/project.js @@ -58,7 +58,7 @@ class Project { nluOptions.nluVisibility = nluOptions.privateNlu ? "private" : "public"; delete nluOptions.privateNlu; } - const requestBody = Object.assign({}, projectData, { options: Object.assign({}, options, { nluOptions }) }); + const requestBody = Object.assign({}, projectData, { options: Object.assign({}, options, nluOptions) }); try { const { response } = yield this.helper.toPromise(this.api.projectApi, this.api.projectApi.projectsPost, requestBody); if (response && response.body && response.body.id) { diff --git a/lib/components/users/team.js b/lib/components/users/team.js index 4341710..64da88f 100644 --- a/lib/components/users/team.js +++ b/lib/components/users/team.js @@ -24,7 +24,7 @@ class Team extends merapi_1.Component { if (this.checkUser(userInfo.id, teamMember)) { throw new Error(`User ${username} already on this team`); } - const { response } = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdPost, teamInfo.data.id, userInfo.id, { roleId: role }); + const { response } = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdPost, teamInfo.id, userInfo.id, { roleId: role }); if (!response.body) { throw new Error("Error adding user to team: invalid roleId"); } @@ -58,7 +58,7 @@ class Team extends merapi_1.Component { if (!this.checkUser(userInfo.id, teamMember)) { throw new Error(`User ${username} not a member of this team`); } - const { response } = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdDelete, teamInfo.data.id, userInfo.id); + const { response } = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdDelete, teamInfo.id, userInfo.id); console.log(`Success remove ${username} from ${currentLogin}`); } else { @@ -77,19 +77,40 @@ class Team extends merapi_1.Component { if (currentUserType !== "team") { throw new Error("Must be on team to do this operation"); } - const team = yield this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, currentLogin); - const { data } = yield this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, username); - const member = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersGet, team.data.id); + const requestTeamData = yield this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, currentLogin); + let teamInfo; + if (requestTeamData.response && requestTeamData.response.body) { + teamInfo = requestTeamData.response.body; + } + else { + throw new Error("Cannot add user to team"); + } + const requestUserData = yield this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, username); + let userInfo; + if (requestUserData && requestUserData.response) { + userInfo = requestUserData.response.body; + } + else { + throw new Error("Cannot add user to team"); + } + const requestTeamMember = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersGet, teamInfo.id); + let teamMember; + if (requestTeamMember && requestTeamMember.response) { + teamMember = requestTeamMember.response.body; + } + else { + throw new Error("Cannot add user to team"); + } return { - teamInfo: team, - userInfo: data, - teamMember: member, + teamInfo, + userInfo, + teamMember, currentLogin }; }); } checkUser(userId, member) { - const teamMember = member.response.body.map((x) => x.userId); + const teamMember = member.map((x) => x.userId); if (teamMember.indexOf(userId) > -1) { return true; } diff --git a/lib/components/users/user.js b/lib/components/users/user.js index 4609f53..0b4256b 100644 --- a/lib/components/users/user.js +++ b/lib/components/users/user.js @@ -124,12 +124,17 @@ class User extends merapi_1.Component { try { const firstLogin = this.helper.getProp("first_login"); const currentType = this.helper.getProp("current_user_type"); - if (currentType === type) { - throw new Error(`Unable to switch : already on ${type}`); + const currentLogin = this.helper.getProp("current_login"); + const username = name ? name : currentLogin; + if (currentType === type && username === currentLogin) { + throw new Error(`Unable to switch : already on ${currentLogin} ${type}`); } if (type === "team") { - const info = yield this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, firstLogin.id); - const teams = info ? info.data.teams.filter((team) => team.username === name) : []; + const { response } = yield this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, firstLogin.id); + if (!response) { + throw new Error("Unable to switch team"); + } + const teams = response && response.body ? response.body.teams.filter((team) => team.username === name) : []; if (teams.length > 0) { const result = yield this.helper.toPromise(this.api.authApi, this.api.authApi.tokensPost, { type: "team", teamId: teams[0].teamId }); const token = result.data.id; @@ -190,8 +195,6 @@ class User extends merapi_1.Component { } const { response } = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsPost, { username: name, password: "", roleId: "teamAdmin" }); if (response && response.body.id) { - const { data } = yield this.helper.toPromise(this.api.userApi, this.api.userApi.usersUserIdGet, currentLogin); - const result = yield this.helper.toPromise(this.api.teamApi, this.api.teamApi.teamsTeamIdUsersUserIdPost, response.body.id, data.id, { roleId: "teamAdmin" }); console.log(`Team ${name} created !`); } else { diff --git a/package.json b/package.json index 4683887..c77dec8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kata-cli", - "version": "2.0.1", + "version": "2.0.2", "description": "Kata AI Command Line Tools", "main": "index.js", "bin": { diff --git a/service.yml b/service.yml index 4646d59..62f8b3d 100644 --- a/service.yml +++ b/service.yml @@ -80,8 +80,8 @@ commands: handler: bot.push alias: push pull: - desc: pull bot with specified name and version - args: " " + desc: pull bot with specific revision + args: "[revision]" handler: bot.pull alias: pull discard: @@ -115,6 +115,7 @@ commands: subcommands: create: desc: Create a Deployment of the selected project + args: "[versionType]" handler: deployment.create alias: create-deployment list: @@ -181,7 +182,7 @@ commands: desc: list all project handler: project.list alias: list-project - + session: type: group desc: Commands for session management