autoforce 0.1.7 → 0.1.8

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
@@ -91,6 +91,11 @@ Si no se ingresa ningun comando asume que es task
91
91
  Y si no se ingresan parametros, tiene un modo asistido que los va a ir preguntando. Por ejemplo para el comando new, dara una lista de opciones de acuerdo a los templates.
92
92
 
93
93
 
94
+ Hay un proyecto de test para analizar y probar la herramienta.
95
+
96
+ https://github.com/sebastianclaros/autoforce-test
97
+
98
+ La guia del readme sirve de ejemplo.
94
99
 
95
100
 
96
101
  ## Testear una version
@@ -1,4 +1,5 @@
1
1
  export declare function logError(message: string, tabs?: string): void;
2
2
  export declare function logWarning(message: string, tabs?: string): void;
3
+ export declare function logInfo(message: string, tabs?: string): void;
3
4
  export declare function logStep(message: string, tabs?: string): void;
4
5
  export declare function getColored(text: string, colorName: string): string;
@@ -29,6 +29,9 @@ export function logError(message, tabs = '') {
29
29
  export function logWarning(message, tabs = '') {
30
30
  console.error(getColored(`[Warning] ${tabs}${message}`, "yellow"));
31
31
  }
32
+ export function logInfo(message, tabs = '') {
33
+ console.info(getColored(`${tabs}${message}`, "green"));
34
+ }
32
35
  export function logStep(message, tabs = '') {
33
36
  console.info(getColored(`${tabs}${message}`, "green"));
34
37
  }
@@ -6,7 +6,7 @@ export declare enum GitServices {
6
6
  GitLab = "gitlab",
7
7
  None = "none"
8
8
  }
9
- export declare enum GitProjects {
9
+ export declare enum ProjectServices {
10
10
  GitHub = "github",
11
11
  GitLab = "gitlab",
12
12
  Jira = "Jira",
@@ -14,9 +14,12 @@ export declare enum GitProjects {
14
14
  }
15
15
  declare class Context implements IObjectRecord {
16
16
  [s: string]: AnyValue | undefined;
17
+ model: string;
17
18
  gitServices: GitServices;
18
19
  isGitApi: boolean;
19
20
  gitApi: IGitApi | undefined;
21
+ projectServices: ProjectServices;
22
+ isProjectApi: boolean;
20
23
  projectApi: IProjectApi | undefined;
21
24
  sfInstalled: boolean;
22
25
  sfToken: boolean;
@@ -32,7 +35,6 @@ declare class Context implements IObjectRecord {
32
35
  permissionSet: string | undefined;
33
36
  issueTitle: string | undefined;
34
37
  isVerbose: boolean;
35
- projectPath: string;
36
38
  _scratch: OrganizationInfo | undefined;
37
39
  _branchScratch: OrganizationInfo | undefined;
38
40
  existNewBranch: boolean;
@@ -44,6 +46,8 @@ declare class Context implements IObjectRecord {
44
46
  repositoryOwner: string | undefined;
45
47
  repositoryRepo: string | undefined;
46
48
  projectId: string | undefined;
49
+ backlogColumn: string;
50
+ loadProjectApi(): void;
47
51
  loadGitApi(): void;
48
52
  loadPackage(): void;
49
53
  loadConfig(): void;
@@ -8,8 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { executeShell, getOrganizationObject, getCurrentOrganization, getBranchName, getTargetOrg } from "./taskFunctions.js";
11
- import { convertNameToKey, convertKeyToName, getFiles, filterDirectory, addNewItems, CONFIG_FILE, createConfigurationFile } from "./util.js";
11
+ import { convertNameToKey, convertKeyToName, getFiles, filterDirectory, addNewItems, CONFIG_FILE, createConfigurationFile, getDataFromPackage } from "./util.js";
12
12
  import { GitHubApi } from "./github-graphql.js";
13
+ import { GitHubProjectApi } from "./github-project-graphql.js";
13
14
  import { GitLabApi } from "./gitlab-graphql.js";
14
15
  import prompts from "prompts";
15
16
  import matter from 'gray-matter';
@@ -21,88 +22,100 @@ export var GitServices;
21
22
  GitServices["GitLab"] = "gitlab";
22
23
  GitServices["None"] = "none";
23
24
  })(GitServices = GitServices || (GitServices = {}));
24
- export var GitProjects;
25
- (function (GitProjects) {
26
- GitProjects["GitHub"] = "github";
27
- GitProjects["GitLab"] = "gitlab";
28
- GitProjects["Jira"] = "Jira";
29
- GitProjects["None"] = "none";
30
- })(GitProjects = GitProjects || (GitProjects = {}));
25
+ export var ProjectServices;
26
+ (function (ProjectServices) {
27
+ ProjectServices["GitHub"] = "github";
28
+ ProjectServices["GitLab"] = "gitlab";
29
+ ProjectServices["Jira"] = "Jira";
30
+ ProjectServices["None"] = "none";
31
+ })(ProjectServices = ProjectServices || (ProjectServices = {}));
31
32
  const filterProcesses = (fullPath) => fullPath.endsWith(".md"); // && !fullPath.endsWith("intro.md")
32
33
  const ISSUES_TYPES = [{ value: 'feature', title: 'feature' }, { value: 'bug', title: 'bug' }, { value: 'documentation', title: 'documentation' }, { value: 'automation', title: 'automation' }];
33
34
  class Context {
34
35
  constructor() {
36
+ this.model = 'modelA'; // Default Model
35
37
  this.gitServices = GitServices.None;
36
38
  this.isGitApi = false;
39
+ this.projectServices = ProjectServices.None;
40
+ this.isProjectApi = false;
37
41
  this.sfInstalled = true;
38
42
  this.sfToken = true;
39
43
  this.defaultDias = 7;
40
44
  this.isVerbose = false;
41
- this.projectPath = process.cwd();
42
45
  this.existNewBranch = false;
43
46
  // Ultima salida del shell
44
47
  this.salida = '';
45
- }
46
- loadGitApi() {
47
- if (!this.gitServices && this.repositoryUrl) {
48
- if (this.repositoryUrl.indexOf('github') > 0) {
49
- this.gitServices = GitServices.GitHub;
50
- }
51
- else if (this.repositoryUrl.indexOf('gitlab') > 0) {
52
- this.gitServices = GitServices.GitLab;
53
- }
54
- }
55
- if (this.gitServices == GitServices.GitHub && process.env.GITHUB_TOKEN) {
56
- if (this.repositoryOwner && this.repositoryRepo && this.projectId && Number.isInteger(this.projectId)) {
57
- const token = process.env.GITHUB_TOKEN;
58
- this.gitApi = new GitHubApi(token, this.repositoryOwner, this.repositoryRepo, Number.parseInt(this.projectId));
59
- this.isGitApi = true;
60
- }
61
- else {
62
- logWarning(`No se pudo inicializar el conector a GitHub, Verifique repositoryOwner: ${this.repositoryOwner} o repositoryRepo: ${this.repositoryRepo} o projectId: ${this.projectId}`);
63
- }
64
- }
65
- if (this.gitServices == GitServices.GitLab && process.env.GITLAB_TOKEN) {
66
- if (this.repositoryOwner && this.repositoryRepo && this.projectId && Number.isInteger(this.projectId)) {
67
- const token = process.env.GITLAB_TOKEN;
68
- this.gitApi = new GitLabApi(token, this.repositoryOwner, this.repositoryRepo, Number.parseInt(this.projectId));
69
- this.isGitApi = true;
48
+ this.backlogColumn = 'Backlog';
49
+ }
50
+ loadProjectApi() {
51
+ if (!this.isProjectApi) {
52
+ if (this.projectServices == ProjectServices.GitHub && process.env.GITHUB_TOKEN) {
53
+ if (this.repositoryOwner && this.repositoryRepo) {
54
+ const token = process.env.GITHUB_TOKEN;
55
+ const projectId = this.projectId && !Number.isNaN(this.projectId) ? Number.parseInt(this.projectId) : undefined;
56
+ if (!projectId) {
57
+ throw Error('Para gestionar proyectos en Github se necesita el projectId. npx autoforce config');
58
+ }
59
+ this.gitApi = this.projectApi = new GitHubProjectApi(token, this.repositoryOwner, this.repositoryRepo, projectId);
60
+ this.isProjectApi = true;
61
+ if (this, this.gitServices == GitServices.GitHub) {
62
+ this.isGitApi = true;
63
+ }
64
+ }
65
+ else {
66
+ logWarning(`No se pudo inicializar el conector a GitHub, Verifique repositoryOwner: ${this.repositoryOwner} o repositoryRepo: ${this.repositoryRepo} o projectId: ${this.projectId}`);
67
+ }
70
68
  }
71
- else {
72
- logWarning(`No se pudo inicializar el conector a GitLab, Verifique repositoryOwner: ${this.repositoryOwner} o repositoryRepo: ${this.repositoryRepo} o projectId: ${this.projectId}`);
69
+ if (this.projectServices == ProjectServices.GitLab && process.env.GITLAB_TOKEN) {
70
+ if (this.repositoryOwner && this.repositoryRepo) {
71
+ const token = process.env.GITLAB_TOKEN;
72
+ const projectId = this.projectId && Number.isInteger(this.projectId) ? Number.parseInt(this.projectId) : undefined;
73
+ this.gitApi = this.projectApi = new GitLabApi(token, this.repositoryOwner, this.repositoryRepo, projectId);
74
+ this.isProjectApi = true;
75
+ }
76
+ else {
77
+ logWarning(`No se pudo inicializar el conector a GitLab, Verifique repositoryOwner: ${this.repositoryOwner} o repositoryRepo: ${this.repositoryRepo} o projectId: ${this.projectId}`);
78
+ }
73
79
  }
74
80
  }
75
81
  }
76
- loadPackage() {
77
- try {
78
- const filename = this.projectPath + "/package.json";
79
- const content = fs.readFileSync(filename, "utf8");
80
- const packageJson = JSON.parse(content);
81
- if (packageJson.repository) {
82
- if (packageJson.repository.url) {
83
- this.repositoryUrl = packageJson.repository.url;
84
- this.repositoryType = packageJson.repository.type;
85
- // Ver de sacar repo y owner
86
- if (this.repositoryUrl && this.repositoryUrl.includes("github.com")) {
87
- const repositoryArray = this.repositoryUrl.split('github.com/');
88
- [this.repositoryOwner, this.repositoryRepo] = repositoryArray[1].split('/');
89
- }
82
+ loadGitApi() {
83
+ if (!this.isGitApi) {
84
+ if (!this.gitServices && this.repositoryUrl) {
85
+ if (this.repositoryUrl.indexOf('github') > 0) {
86
+ this.gitServices = GitServices.GitHub;
87
+ }
88
+ else if (this.repositoryUrl.indexOf('gitlab') > 0) {
89
+ this.gitServices = GitServices.GitLab;
90
90
  }
91
- else if (typeof packageJson.repository === 'string') {
92
- this.repositoryUrl = packageJson.repository;
93
- const repositoryArray = this.repositoryUrl.split(':');
94
- this.repositoryType = repositoryArray[0];
95
- [this.repositoryOwner, this.repositoryRepo] = repositoryArray[1].split('/');
91
+ }
92
+ if (this.gitServices == GitServices.GitHub && process.env.GITHUB_TOKEN) {
93
+ if (this.repositoryOwner && this.repositoryRepo) {
94
+ const token = process.env.GITHUB_TOKEN;
95
+ this.gitApi = new GitHubApi(token, this.repositoryOwner, this.repositoryRepo);
96
+ this.isGitApi = true;
96
97
  }
97
- if (this.repositoryRepo && this.repositoryRepo.endsWith('.git')) {
98
- this.repositoryRepo = this.repositoryRepo.replace('.git', '');
98
+ else {
99
+ logWarning(`No se pudo inicializar el conector a GitHub, Verifique repositoryOwner: ${this.repositoryOwner} o repositoryRepo: ${this.repositoryRepo} o projectId: ${this.projectId}`);
100
+ }
101
+ }
102
+ if (this.gitServices == GitServices.GitLab && process.env.GITLAB_TOKEN) {
103
+ if (this.repositoryOwner && this.repositoryRepo) {
104
+ const token = process.env.GITLAB_TOKEN;
105
+ this.gitApi = new GitLabApi(token, this.repositoryOwner, this.repositoryRepo);
106
+ this.isGitApi = true;
107
+ }
108
+ else {
109
+ logWarning(`No se pudo inicializar el conector a GitLab, Verifique repositoryOwner: ${this.repositoryOwner} o repositoryRepo: ${this.repositoryRepo} o projectId: ${this.projectId}`);
99
110
  }
100
111
  }
101
112
  }
102
- catch (error) {
103
- console.log(error);
104
- throw new Error(`Verifique que exista y sea valido el package.json`);
105
- }
113
+ }
114
+ loadPackage() {
115
+ const data = getDataFromPackage();
116
+ this.repositoryUrl = data.repositoryUrl;
117
+ this.repositoryOwner = data.repositoryOwner;
118
+ this.repositoryRepo = data.repositoryRepo;
106
119
  }
107
120
  loadConfig() {
108
121
  if (!fs.existsSync(CONFIG_FILE)) {
@@ -127,6 +140,7 @@ class Context {
127
140
  // Busca variables de entorno
128
141
  this.loadConfig();
129
142
  this.loadPackage();
143
+ this.loadProjectApi();
130
144
  this.loadGitApi();
131
145
  //
132
146
  this.branchName = getBranchName();
@@ -1,4 +1,4 @@
1
- export declare class GitHubApi implements IGitApi, IProjectApi {
1
+ export declare class GitHubApi implements IGitApi {
2
2
  repoVar: {
3
3
  owner: string;
4
4
  repo: string;
@@ -28,14 +28,6 @@ export declare class GitHubApi implements IGitApi, IProjectApi {
28
28
  };
29
29
  }>;
30
30
  createPullRequest(branchName: string, title: string, body: string): Promise<boolean>;
31
- getColumnValueMap(): Promise<Record<string, string>>;
32
- createIssue(title: string, state?: string, label?: string, milestone?: string, body?: string): Promise<number>;
33
- moveIssue(issueNumber: number, state: string): Promise<boolean>;
34
- assignIssueToMe(issueNumber: number): Promise<boolean>;
35
- getCommit(commitSha: string): Promise<{
36
- id: string;
37
- oid: string;
38
- }>;
39
31
  assignBranchToIssue(issueNumber: number, branchName: string, commitSha: string): Promise<boolean>;
40
32
  getIssueState(issueNumber: number): Promise<string>;
41
33
  getIssueName(title: string): string;
@@ -73,4 +65,8 @@ export declare class GitHubApi implements IGitApi, IProjectApi {
73
65
  }[];
74
66
  };
75
67
  }>;
68
+ getCommit(commitSha: string): Promise<{
69
+ id: string;
70
+ oid: string;
71
+ }>;
76
72
  }
@@ -94,170 +94,6 @@ export class GitHubApi {
94
94
  return false;
95
95
  });
96
96
  }
97
- getColumnValueMap() {
98
- return __awaiter(this, void 0, void 0, function* () {
99
- const query = `
100
- query getFieldOptions($owner:String!, $repo: String!, $projectNumber: Int!) {
101
- repository(owner: $owner, name: $repo) {
102
- projectV2(number: $projectNumber) {
103
- field(name: "Status") {
104
- ... on ProjectV2SingleSelectField {
105
- id
106
- name
107
- options {
108
- name
109
- id
110
- }
111
- }
112
- }
113
- }
114
- }
115
- }
116
- `;
117
- const { repository } = yield this.graphqlAuth(query, Object.assign({ projectNumber: this.projectNumber }, this.repoVar));
118
- const mapValues = {};
119
- for (const option of repository.projectV2.field.options) {
120
- mapValues[option.name] = option.id;
121
- }
122
- return mapValues;
123
- });
124
- }
125
- createIssue(title, state, label, milestone, body) {
126
- var _a;
127
- return __awaiter(this, void 0, void 0, function* () {
128
- const user = yield this.getUser();
129
- const repository = yield this.getRepository(label);
130
- const repositoryId = repository.id;
131
- const labelId = (_a = repository.label) === null || _a === void 0 ? void 0 : _a.id;
132
- const projectId = repository.projectV2.id;
133
- const mutationIssue = `
134
- mutation createIssue($repositoryId: ID!, $assignId: ID!, $title: String!, $body: String, ${labelId ? '$labelId: ID!' : ''} , $milestoneId: ID ) {
135
- createIssue(
136
- input: {
137
- repositoryId: $repositoryId,
138
- assigneeIds: [$assignId],
139
- ${labelId ? 'labelIds: [$labelId],' : ''}
140
- title: $title,
141
- milestoneId: $milestoneId,
142
- body: $body
143
- }
144
- ) {
145
- issue {
146
- id
147
- number
148
- }
149
- }
150
- }`;
151
- const { createIssue } = yield this.graphqlAuth(mutationIssue, { labelId, body, assignId: user.id, projectId, repositoryId, title, label: label ? [label] : null });
152
- const issue = createIssue.issue;
153
- if (!state || !issue.number) {
154
- return issue.number;
155
- }
156
- const mutationItem = `
157
- mutation addProjectV2ItemById($projectId: ID!, $contentId: ID! ) {
158
- addProjectV2ItemById(
159
- input: {
160
- projectId: $projectId
161
- contentId: $contentId
162
- }
163
- ) {
164
- clientMutationId,
165
- item {
166
- id
167
- }
168
- }
169
- }`;
170
- const { addProjectV2ItemById } = yield this.graphqlAuth(mutationItem, { projectId, contentId: issue.id });
171
- const itemId = addProjectV2ItemById.item.id;
172
- const fieldId = repository.projectV2.field.id;
173
- const mapValues = yield this.getColumnValueMap();
174
- const columnValue = mapValues[state];
175
- const mutationColumn = `
176
- mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $columnValue: String!) {
177
- updateProjectV2ItemFieldValue(
178
- input: {
179
- projectId: $projectId,
180
- itemId: $itemId,
181
- fieldId: $fieldId,
182
- value: {singleSelectOptionId: $columnValue}
183
- }
184
- ) {
185
- clientMutationId
186
- }
187
- }`;
188
- const { updateProjectV2ItemFieldValue } = yield this.graphqlAuth(mutationColumn, { projectId, itemId, fieldId, columnValue });
189
- if (!updateProjectV2ItemFieldValue.clientMutationId) {
190
- return 0;
191
- }
192
- return issue.number;
193
- });
194
- }
195
- moveIssue(issueNumber, state) {
196
- return __awaiter(this, void 0, void 0, function* () {
197
- const issue = yield this.getIssue(issueNumber);
198
- const itemId = issue.projectItems.nodes[0].id;
199
- const projectId = issue.projectItems.nodes[0].project.id;
200
- const fieldId = issue.projectItems.nodes[0].fieldValueByName.field.id;
201
- const mapValues = yield this.getColumnValueMap();
202
- const columnValue = mapValues[state];
203
- const mutation = `
204
- mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $columnValue: String!) {
205
- updateProjectV2ItemFieldValue(
206
- input: {
207
- projectId: $projectId,
208
- itemId: $itemId,
209
- fieldId: $fieldId,
210
- value: {singleSelectOptionId: $columnValue}
211
- }
212
- ) {
213
- projectV2Item {
214
- id
215
- }
216
- }
217
- }`;
218
- const { updateProjectV2ItemFieldValue } = yield this.graphqlAuth(mutation, { projectId, itemId, fieldId, columnValue });
219
- return (updateProjectV2ItemFieldValue === null || updateProjectV2ItemFieldValue === void 0 ? void 0 : updateProjectV2ItemFieldValue.projectV2Item) ? true : false;
220
- });
221
- }
222
- assignIssueToMe(issueNumber) {
223
- return __awaiter(this, void 0, void 0, function* () {
224
- const user = yield this.getUser();
225
- const issue = yield this.getIssue(issueNumber);
226
- const mutation = `
227
- mutation assignUser( $issueId: ID!, $userId: ID!) {
228
- addAssigneesToAssignable(input: {
229
- assignableId: $issueId
230
- assigneeIds: [ $userId ]
231
- }) {
232
- assignable {
233
- assignees {
234
- totalCount
235
- }
236
- }
237
- }
238
- }
239
- `;
240
- const { addAssigneesToAssignable } = yield this.graphqlAuth(mutation, { issueId: issue.id, userId: user.id });
241
- return addAssigneesToAssignable.assignable.assignees.totalCount > 0;
242
- });
243
- }
244
- getCommit(commitSha) {
245
- return __awaiter(this, void 0, void 0, function* () {
246
- const query = `
247
- query getCommit($owner:String!, $repo: String!, $commitSha: String!) {
248
- repository(owner: $owner, name: $repo) {
249
- object(expression: $commitSha) {
250
- ... on Commit {
251
- id
252
- oid
253
- }
254
- }
255
- }
256
- } `;
257
- const { repository } = yield this.graphqlAuth(query, Object.assign({ commitSha }, this.repoVar));
258
- return repository.object;
259
- });
260
- }
261
97
  assignBranchToIssue(issueNumber, branchName, commitSha) {
262
98
  var _a;
263
99
  return __awaiter(this, void 0, void 0, function* () {
@@ -277,7 +113,6 @@ export class GitHubApi {
277
113
  }
278
114
  }`;
279
115
  const { createLinkedBranch } = yield this.graphqlAuth(mutation, { issueId: issue.id, oid: commit.oid, branchName });
280
- console.log(createLinkedBranch);
281
116
  return ((_a = createLinkedBranch === null || createLinkedBranch === void 0 ? void 0 : createLinkedBranch.issue) === null || _a === void 0 ? void 0 : _a.id) ? true : false;
282
117
  });
283
118
  }
@@ -360,4 +195,21 @@ export class GitHubApi {
360
195
  return repository.issue;
361
196
  });
362
197
  }
198
+ getCommit(commitSha) {
199
+ return __awaiter(this, void 0, void 0, function* () {
200
+ const query = `
201
+ query getCommit($owner:String!, $repo: String!, $commitSha: String!) {
202
+ repository(owner: $owner, name: $repo) {
203
+ object(expression: $commitSha) {
204
+ ... on Commit {
205
+ id
206
+ oid
207
+ }
208
+ }
209
+ }
210
+ } `;
211
+ const { repository } = yield this.graphqlAuth(query, Object.assign({ commitSha }, this.repoVar));
212
+ return repository.object;
213
+ });
214
+ }
363
215
  }
@@ -0,0 +1,9 @@
1
+ import { GitHubApi } from "./github-graphql.js";
2
+ export declare class GitHubProjectApi extends GitHubApi implements IProjectApi {
3
+ projectNumber: number;
4
+ constructor(token: string, owner: string, repo: string, projectNumber: number);
5
+ getColumnValueMap(): Promise<Record<string, string>>;
6
+ createIssue(title: string, state?: string, label?: string, milestone?: string, body?: string): Promise<number>;
7
+ moveIssue(issueNumber: number, state: string): Promise<boolean>;
8
+ assignIssueToMe(issueNumber: number): Promise<boolean>;
9
+ }
@@ -0,0 +1,170 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { logWarning } from "./color.js";
11
+ import { GitHubApi } from "./github-graphql.js";
12
+ export class GitHubProjectApi extends GitHubApi {
13
+ constructor(token, owner, repo, projectNumber) {
14
+ super(token, owner, repo);
15
+ this.projectNumber = projectNumber;
16
+ }
17
+ getColumnValueMap() {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ const query = `
20
+ query getFieldOptions($owner:String!, $repo: String!, $projectNumber: Int!) {
21
+ repository(owner: $owner, name: $repo) {
22
+ projectV2(number: $projectNumber) {
23
+ field(name: "Status") {
24
+ ... on ProjectV2SingleSelectField {
25
+ id
26
+ name
27
+ options {
28
+ name
29
+ id
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ `;
37
+ const { repository } = yield this.graphqlAuth(query, Object.assign({ projectNumber: this.projectNumber }, this.repoVar));
38
+ const mapValues = {};
39
+ for (const option of repository.projectV2.field.options) {
40
+ mapValues[option.name] = option.id;
41
+ }
42
+ return mapValues;
43
+ });
44
+ }
45
+ createIssue(title, state, label, milestone, body) {
46
+ var _a;
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ const user = yield this.getUser();
49
+ const repository = yield this.getRepository(label);
50
+ const repositoryId = repository.id;
51
+ const labelId = (_a = repository.label) === null || _a === void 0 ? void 0 : _a.id;
52
+ const projectId = repository.projectV2.id;
53
+ const mutationIssue = `
54
+ mutation createIssue($repositoryId: ID!, $assignId: ID!, $title: String!, $body: String, ${labelId ? '$labelId: ID!' : ''} , $milestoneId: ID ) {
55
+ createIssue(
56
+ input: {
57
+ repositoryId: $repositoryId,
58
+ assigneeIds: [$assignId],
59
+ ${labelId ? 'labelIds: [$labelId],' : ''}
60
+ title: $title,
61
+ milestoneId: $milestoneId,
62
+ body: $body
63
+ }
64
+ ) {
65
+ issue {
66
+ id
67
+ number
68
+ }
69
+ }
70
+ }`;
71
+ const { createIssue } = yield this.graphqlAuth(mutationIssue, { labelId, body, assignId: user.id, projectId, repositoryId, title, label: label ? [label] : null });
72
+ const issue = createIssue.issue;
73
+ if (!state || !issue.number) {
74
+ return issue.number;
75
+ }
76
+ const mutationItem = `
77
+ mutation addProjectV2ItemById($projectId: ID!, $contentId: ID! ) {
78
+ addProjectV2ItemById(
79
+ input: {
80
+ projectId: $projectId
81
+ contentId: $contentId
82
+ }
83
+ ) {
84
+ clientMutationId,
85
+ item {
86
+ id
87
+ }
88
+ }
89
+ }`;
90
+ const { addProjectV2ItemById } = yield this.graphqlAuth(mutationItem, { projectId, contentId: issue.id });
91
+ const itemId = addProjectV2ItemById.item.id;
92
+ const fieldId = repository.projectV2.field.id;
93
+ const mapValues = yield this.getColumnValueMap();
94
+ const columnValue = mapValues[state];
95
+ if (!columnValue) {
96
+ logWarning(`No se encontro la columna ${state} en las lista de columnas del proyecto ${Object.keys(mapValues).join(",")}`);
97
+ }
98
+ else {
99
+ const mutationColumn = `
100
+ mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $columnValue: String!) {
101
+ updateProjectV2ItemFieldValue(
102
+ input: {
103
+ projectId: $projectId,
104
+ itemId: $itemId,
105
+ fieldId: $fieldId,
106
+ value: {singleSelectOptionId: $columnValue}
107
+ }
108
+ ) {
109
+ clientMutationId
110
+ }
111
+ }`;
112
+ console.log(mutationColumn);
113
+ const { updateProjectV2ItemFieldValue } = yield this.graphqlAuth(mutationColumn, { projectId, itemId, fieldId, columnValue });
114
+ if (!updateProjectV2ItemFieldValue.clientMutationId) {
115
+ return 0;
116
+ }
117
+ }
118
+ return issue.number;
119
+ });
120
+ }
121
+ moveIssue(issueNumber, state) {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ const issue = yield this.getIssue(issueNumber);
124
+ const itemId = issue.projectItems.nodes[0].id;
125
+ const projectId = issue.projectItems.nodes[0].project.id;
126
+ const fieldId = issue.projectItems.nodes[0].fieldValueByName.field.id;
127
+ const mapValues = yield this.getColumnValueMap();
128
+ const columnValue = mapValues[state];
129
+ const mutation = `
130
+ mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $columnValue: String!) {
131
+ updateProjectV2ItemFieldValue(
132
+ input: {
133
+ projectId: $projectId,
134
+ itemId: $itemId,
135
+ fieldId: $fieldId,
136
+ value: {singleSelectOptionId: $columnValue}
137
+ }
138
+ ) {
139
+ projectV2Item {
140
+ id
141
+ }
142
+ }
143
+ }`;
144
+ const { updateProjectV2ItemFieldValue } = yield this.graphqlAuth(mutation, { projectId, itemId, fieldId, columnValue });
145
+ return (updateProjectV2ItemFieldValue === null || updateProjectV2ItemFieldValue === void 0 ? void 0 : updateProjectV2ItemFieldValue.projectV2Item) ? true : false;
146
+ });
147
+ }
148
+ assignIssueToMe(issueNumber) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ const user = yield this.getUser();
151
+ const issue = yield this.getIssue(issueNumber);
152
+ const mutation = `
153
+ mutation assignUser( $issueId: ID!, $userId: ID!) {
154
+ addAssigneesToAssignable(input: {
155
+ assignableId: $issueId
156
+ assigneeIds: [ $userId ]
157
+ }) {
158
+ assignable {
159
+ assignees {
160
+ totalCount
161
+ }
162
+ }
163
+ }
164
+ }
165
+ `;
166
+ const { addAssigneesToAssignable } = yield this.graphqlAuth(mutation, { issueId: issue.id, userId: user.id });
167
+ return addAssigneesToAssignable.assignable.assignees.totalCount > 0;
168
+ });
169
+ }
170
+ }
@@ -1,6 +1,6 @@
1
1
  import { GraphQLClient } from 'graphql-request';
2
2
  import { AnyValue } from '../types/auto.js';
3
- export declare class GitLabApi implements IGitApi {
3
+ export declare class GitLabApi implements IGitApi, IProjectApi {
4
4
  repoVar: {
5
5
  owner: string;
6
6
  repo: string;
@@ -8,6 +8,10 @@ export declare class GitLabApi implements IGitApi {
8
8
  projectNumber: number | undefined;
9
9
  graphqlAuth: GraphQLClient;
10
10
  constructor(token: string, owner: string, repo: string, projectNumber?: number);
11
+ getIssueObject(issueNumber: number): Promise<{}>;
12
+ createIssue(title: string, state?: string, label?: string, milestone?: string, body?: string): Promise<number>;
13
+ moveIssue(issueNumber: number, state: string): Promise<boolean>;
14
+ assignIssueToMe(issueNumber: number): Promise<boolean>;
11
15
  getUser(): Promise<{
12
16
  login: string;
13
17
  id: number;
@@ -16,6 +16,30 @@ export class GitLabApi {
16
16
  this.projectNumber = projectNumber;
17
17
  this.graphqlAuth.setHeaders({ authorization: `Bearer ${token}` });
18
18
  }
19
+ getIssueObject(issueNumber) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ console.log(issueNumber);
22
+ return {};
23
+ });
24
+ }
25
+ createIssue(title, state, label, milestone, body) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ console.log(title, label, milestone, body);
28
+ return 1;
29
+ });
30
+ }
31
+ moveIssue(issueNumber, state) {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ console.log(issueNumber, state);
34
+ return true;
35
+ });
36
+ }
37
+ assignIssueToMe(issueNumber) {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ console.log(issueNumber);
40
+ return true;
41
+ });
42
+ }
19
43
  getUser() {
20
44
  return __awaiter(this, void 0, void 0, function* () {
21
45
  const query = `{
@@ -317,9 +317,9 @@ export const taskFunctions = {
317
317
  if (context.projectApi === undefined) {
318
318
  return false;
319
319
  }
320
- const issueNumber = yield context.projectApi.createIssue(title, 'Backlog', label);
320
+ const issueNumber = yield context.projectApi.createIssue(title, context.backlogColumn, label);
321
321
  if (issueNumber) {
322
- console.log(`Se creao el issue ${issueNumber}`);
322
+ console.log(`Se creo el issue ${issueNumber}`);
323
323
  return true;
324
324
  }
325
325
  return false;
@@ -15,9 +15,9 @@ import { validateCommand, validateFunction, executeFunction, executeCommand, tas
15
15
  import prompts from "prompts";
16
16
  import { fileURLToPath } from 'url';
17
17
  const COMMAND_FOLDER = searchInFolderHierarchy('commands', fileURLToPath(import.meta.url));
18
- export const TASKS_FOLDER = `${COMMAND_FOLDER}/tasks`;
19
- export const SUBTASKS_FOLDER = `${COMMAND_FOLDER}/subtasks`;
20
- export const NEW_FOLDER = `${COMMAND_FOLDER}/new`;
18
+ export const TASKS_FOLDER = `${COMMAND_FOLDER}/${context.model}/tasks`;
19
+ export const SUBTASKS_FOLDER = `${COMMAND_FOLDER}/${context.model}/subtasks`;
20
+ export const NEW_FOLDER = `${COMMAND_FOLDER}/${context.model}/new`;
21
21
  export function getTaskFolder(command) {
22
22
  const folders = {
23
23
  'task': TASKS_FOLDER,
@@ -16,6 +16,7 @@ export declare function titlesToChoices(list: string[], titleToValue?: (title: s
16
16
  title: string;
17
17
  value: string;
18
18
  }[];
19
+ export declare function getDataFromPackage(): Record<string, string>;
19
20
  export declare function createConfigurationFile(): Promise<boolean>;
20
21
  export declare function sortByName(objA: {
21
22
  Name: string;
@@ -10,8 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import fs from "fs";
11
11
  import { fileURLToPath } from 'url';
12
12
  import prompts from "prompts";
13
- import { GitProjects, GitServices } from "./context.js";
14
- import { logWarning } from "./color.js";
13
+ import { ProjectServices, GitServices } from "./context.js";
14
+ import { logInfo, logWarning } from "./color.js";
15
15
  const COMMAND_FOLDER = searchInFolderHierarchy('commands', fileURLToPath(import.meta.url));
16
16
  export const TEMPLATES_FOLDER = searchInFolderHierarchy('templates', fileURLToPath(import.meta.url));
17
17
  export const DICTIONARY_FOLDER = TEMPLATES_FOLDER + "/diccionarios";
@@ -29,17 +29,75 @@ export function valuesToChoices(list, valueToTitle = (value) => value) {
29
29
  export function titlesToChoices(list, titleToValue = (title) => title) {
30
30
  return list.map(title => { return { title, value: titleToValue(title) }; });
31
31
  }
32
+ export function getDataFromPackage() {
33
+ const data = {};
34
+ try {
35
+ const filename = process.cwd() + "/package.json";
36
+ const content = fs.readFileSync(filename, "utf8");
37
+ const packageJson = JSON.parse(content);
38
+ if (packageJson.repository) {
39
+ if (packageJson.repository.url) {
40
+ data.repositoryUrl = packageJson.repository.url;
41
+ data.repositoryType = packageJson.repository.type;
42
+ // Ver de sacar repo y owner
43
+ if (data.repositoryUrl) {
44
+ if (data.repositoryUrl.includes("github.com")) {
45
+ const repositoryArray = data.repositoryUrl.split('github.com/');
46
+ [data.repositoryOwner, data.repositoryRepo] = repositoryArray[1].split('/');
47
+ }
48
+ if (data.repositoryUrl.includes("gitlab.com")) {
49
+ const repositoryArray = data.repositoryUrl.split('gitlab.com/');
50
+ [data.repositoryOwner, data.repositoryRepo] = repositoryArray[1].split('/');
51
+ }
52
+ }
53
+ }
54
+ else if (typeof packageJson.repository === 'string') {
55
+ data.repositoryUrl = packageJson.repository;
56
+ const repositoryArray = data.repositoryUrl.split(':');
57
+ data.repositoryType = repositoryArray[0];
58
+ [data.repositoryOwner, data.repositoryRepo] = repositoryArray[1].split('/');
59
+ }
60
+ if (data.repositoryRepo && data.repositoryRepo.endsWith('.git')) {
61
+ data.repositoryRepo = data.repositoryRepo.replace('.git', '');
62
+ }
63
+ }
64
+ }
65
+ catch (error) {
66
+ console.log(error);
67
+ throw new Error(`Verifique que exista y sea valido el package.json`);
68
+ }
69
+ return data;
70
+ }
32
71
  export function createConfigurationFile() {
33
72
  return __awaiter(this, void 0, void 0, function* () {
73
+ // Todo: Chequear el repoOwner y repo
74
+ const data = getDataFromPackage();
75
+ const optionals = {};
76
+ if (!data.repositoryOwner || !data.repositoryRepo) {
77
+ throw new Error('No se encontro repository en el package.json ! Por favor agreguelo y vuelva a intentar');
78
+ }
79
+ const initialServices = data.repositoryUrl.includes("github.com") ? 0 : 1;
80
+ // Preguntar por GitHub o GitLab
81
+ const gitServices = yield prompts([{
82
+ type: "select",
83
+ name: "git",
84
+ initial: initialServices,
85
+ message: "Elija un servicio de Git",
86
+ choices: [{ title: 'Github', value: GitServices.GitHub }, { title: 'Gitlab', value: GitServices.GitLab }]
87
+ }]);
88
+ // Chequear las variables de entorno
89
+ if (gitServices.git === GitServices.GitHub && !process.env.GITHUB_TOKEN) {
90
+ logWarning('A fin de que la herramienta funcione debe configurar una variable de entorno GITHUB_TOKEN');
91
+ }
92
+ if (gitServices.git === GitServices.GitLab && !process.env.GITLAB_TOKEN) {
93
+ logWarning('A fin de que la herramienta funcione debe configurar una variable de entorno GITLAB_TOKEN');
94
+ }
34
95
  const models = valuesToChoices(getFiles(COMMAND_FOLDER, filterDirectory));
35
96
  const automationModel = yield prompts([{
36
97
  type: "select",
37
98
  name: "model",
38
99
  message: "Elija un modelo de automatizacion",
39
- choices: [
40
- { title: 'Orgs con Procesos de Negocio usando scratchs', value: 'modelA' },
41
- { title: 'Custom', value: 'custom', description: 'En este caso los comandos son configurados fuera de la herramienta y los lee de la carpeta commands en el root del repo' }
42
- ]
100
+ choices: models.concat([{ title: 'Personalizado', value: 'custom', description: 'En este caso los comandos son configurados fuera de la herramienta y los lee de la carpeta commands en el root del repo' }])
43
101
  }]);
44
102
  // Si es custom pregunta si quiere tomar de base alguno existente
45
103
  if (automationModel.model === 'custom') {
@@ -47,39 +105,38 @@ export function createConfigurationFile() {
47
105
  type: "select",
48
106
  name: "model",
49
107
  message: "Quiere tomar algun modelo existente de base ? Este se copiara a la carpeta ",
50
- choices: [
51
- { title: 'Orgs con Procesos de Negocio usando scratchs', value: 'modelA' },
52
- { title: 'Custom', value: 'custom' }
53
- ]
108
+ choices: models.concat([{ title: 'No quiero usar ningun modelo', value: 'none' }])
54
109
  }]);
110
+ if (baseModel.model !== 'none') {
111
+ console.log('copy archivos..');
112
+ }
55
113
  }
56
- // Preguntar por GitHub o GitLab
57
- const gitServices = yield prompts([{
58
- type: "select",
59
- name: "git",
60
- message: "Elija un servicio de Git",
61
- choices: [{ title: 'Github', value: GitServices.GitHub }, { title: 'Gitlab', value: GitServices.GitLab }]
62
- }]);
63
- // Chequear las variables de entorno
64
- if (gitServices.git === GitServices.GitHub && !process.env.GITHUB_TOKEN) {
65
- logWarning('Debe configurar una variable de entorno GITHUB_TOKEN');
66
- }
67
- if (gitServices.git === GitServices.GitLab && !process.env.GITLAB_TOKEN) {
68
- logWarning('Debe configurar una variable de entorno GITLAB_TOKEN');
69
- }
114
+ // Gestion del Proyecto
70
115
  const projectServices = yield prompts([{
71
116
  type: "select",
72
117
  name: "project",
118
+ initial: initialServices,
73
119
  message: "Gestion de proyecto",
74
- choices: [{ title: 'Github Projects', value: GitProjects.GitHub }, { title: 'GitLab Projects', value: GitProjects.GitLab }, { title: 'Jira', value: GitProjects.Jira }, { title: 'None', value: GitProjects.None }]
120
+ choices: [{ title: 'Github Projects', value: ProjectServices.GitHub }, { title: 'GitLab Projects', value: ProjectServices.GitLab }, { title: 'Jira', value: ProjectServices.Jira }, { title: 'None', value: ProjectServices.None }]
75
121
  }]);
122
+ if (projectServices.project === ProjectServices.GitHub || projectServices.project === ProjectServices.GitLab) {
123
+ // Gestion del Proyecto
124
+ const backlogColumn = yield prompts([{
125
+ type: "text",
126
+ name: "backlogColumn",
127
+ initial: 'Backlog',
128
+ message: "Nombre de la columna donde se crean nuevos issues"
129
+ }]);
130
+ optionals['backlogColumn'] = backlogColumn.backlogColumn;
131
+ logInfo(`Por omision ser utilizan proyectos dentro de ${data.repositoryOwner} y ${data.repositoryRepo} `);
132
+ }
76
133
  const projectId = yield prompts([{
77
134
  type: "text",
78
135
  name: "projectId",
79
136
  message: "Id del proyecto"
80
137
  }]);
81
138
  // console.log('Genera documentacion');
82
- const config = { model: automationModel.model, gitServices: gitServices.git, projectServices: projectServices.project, projectId: projectId.projectId };
139
+ const config = Object.assign({ model: automationModel.model, gitServices: gitServices.git, projectServices: projectServices.project, projectId: projectId.projectId }, optionals);
83
140
  try {
84
141
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
85
142
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "autoforce",
3
3
  "homepage": "https://sebastianclaros.github.io/autoforce",
4
4
  "private": false,
5
- "version": "0.1.7",
5
+ "version": "0.1.8",
6
6
  "keywords": [
7
7
  "Salesforce",
8
8
  "Automation",