autoforce 0.1.10 → 0.1.11

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/CHANGELOG.md CHANGED
@@ -1,4 +1,21 @@
1
+ # Versiones
1
2
 
2
- Version 0.1.9
3
- * Comando de new issue para crear un issue nuevo en el backlog
4
- * Comando de list para ver issues en backlog o ver los detalles de uno
3
+ ## Version 0.1.10
4
+ - Fecha: 28/11/2024
5
+ - Cambios:
6
+ * [publish deberia pedir la version, y asignarla en el autoforce version](https://github.com/sebastianclaros/autoforce/issues/12)
7
+ * [Models en config que lea un json descriptivo](https://github.com/sebastianclaros/autoforce/issues/9)
8
+ * [comando list](https://github.com/sebastianclaros/autoforce/issues/1)
9
+ * [Guard para verificar existencia de Variables de Entorno por ejemplo NPM_TOKEN con un $NPM_TOKEN ?
10
+ (https://github.com/sebastianclaros/autoforce/issues/10)
11
+ ]
12
+ * [New issue con Body optativo](https://github.com/sebastianclaros/autoforce/issues/3)
13
+ * [Parametros adicionales tipo npx autoforce start XXX](https://github.com/sebastianclaros/autoforce/issues/5)
14
+ * [Modelos en los Templates](https://github.com/sebastianclaros/autoforce/issues/8)
15
+
16
+
17
+ ## Version 0.1.9
18
+
19
+ - Cambios:
20
+ * Comando de new issue para crear un issue nuevo en el backlog
21
+ * Comando de list para ver issues en backlog o ver los detalles de uno
@@ -49,10 +49,11 @@ declare class Context implements IObjectRecord {
49
49
  repositoryRepo: string | undefined;
50
50
  projectId: string | undefined;
51
51
  backlogColumn: string;
52
+ constructor();
52
53
  loadProjectApi(): void;
53
54
  loadGitApi(): void;
54
55
  loadPackage(): void;
55
- loadConfig(): void;
56
+ loadConfig(): Promise<boolean>;
56
57
  init(): void;
57
58
  get targetOrg(): string;
58
59
  get existBranchScratch(): boolean;
@@ -21,14 +21,14 @@ export var GitServices;
21
21
  GitServices["GitHub"] = "github";
22
22
  GitServices["GitLab"] = "gitlab";
23
23
  GitServices["None"] = "none";
24
- })(GitServices = GitServices || (GitServices = {}));
24
+ })(GitServices || (GitServices = {}));
25
25
  export var ProjectServices;
26
26
  (function (ProjectServices) {
27
27
  ProjectServices["GitHub"] = "github";
28
28
  ProjectServices["GitLab"] = "gitlab";
29
29
  ProjectServices["Jira"] = "Jira";
30
30
  ProjectServices["None"] = "none";
31
- })(ProjectServices = ProjectServices || (ProjectServices = {}));
31
+ })(ProjectServices || (ProjectServices = {}));
32
32
  const filterProcesses = (fullPath) => fullPath.endsWith(".md"); // && !fullPath.endsWith("intro.md")
33
33
  const ISSUES_TYPES = [{ value: 'feature', title: 'feature' }, { value: 'bug', title: 'bug' }, { value: 'documentation', title: 'documentation' }, { value: 'automation', title: 'automation' }];
34
34
  class Context {
@@ -47,6 +47,8 @@ class Context {
47
47
  // Ultima salida del shell
48
48
  this.salida = '';
49
49
  this.backlogColumn = 'Todo';
50
+ this.loadConfig();
51
+ this.loadPackage();
50
52
  }
51
53
  loadProjectApi() {
52
54
  if (!this.isProjectApi) {
@@ -119,28 +121,38 @@ class Context {
119
121
  this.repositoryRepo = data.repositoryRepo;
120
122
  }
121
123
  loadConfig() {
122
- if (!fs.existsSync(CONFIG_FILE)) {
123
- logWarning('Bienvenido! Antes de usar la herramienta, tenemos que configurarla.');
124
- logWarning('Lo puedes hacer mas tarde manualmente leyendo la documentacion y creando .autoforce.json en el root del proyecto');
125
- logWarning('O bien ahora con el asistente, el mismo lo puedes llamar todas las veces que necesites corriendo npx autoforce config!');
126
- createConfigurationFile();
127
- return;
128
- }
129
- const content = fs.readFileSync(CONFIG_FILE, "utf8");
130
- try {
131
- const config = JSON.parse(content);
132
- for (const key in config) {
133
- this.set(key, config[key]);
124
+ return __awaiter(this, void 0, void 0, function* () {
125
+ if (!fs.existsSync(CONFIG_FILE)) {
126
+ logWarning('Bienvenido! La herramienta Autoforce necesita un primer paso de configuracion antes de usarla.');
127
+ logWarning('- Podes usar el asistente ejecutando npx autoforce config');
128
+ logWarning('- Podes hacerlo manualmente leyendo la documentacion y creando .autoforce.json manualmente en el root del proyecto (https://sebastianclaros.github.io/autoforce/docs/configuracion)');
129
+ const answer = yield prompts([
130
+ {
131
+ type: "confirm",
132
+ name: "asistente",
133
+ message: "Queres ejecutar el asistente ahora?"
134
+ }
135
+ ]);
136
+ if (answer.asistente) {
137
+ yield createConfigurationFile();
138
+ return true;
139
+ }
140
+ return false;
134
141
  }
135
- }
136
- catch (_a) {
137
- throw new Error(`Verifique que el ${CONFIG_FILE} sea json valido`);
138
- }
142
+ const content = fs.readFileSync(CONFIG_FILE, "utf8");
143
+ try {
144
+ const config = JSON.parse(content);
145
+ for (const key in config) {
146
+ this.set(key, config[key]);
147
+ }
148
+ }
149
+ catch (_a) {
150
+ throw new Error(`Verifique que el ${CONFIG_FILE} sea json valido`);
151
+ }
152
+ return true;
153
+ });
139
154
  }
140
155
  init() {
141
- // Busca variables de entorno
142
- this.loadConfig();
143
- this.loadPackage();
144
156
  this.loadProjectApi();
145
157
  this.loadGitApi();
146
158
  //
@@ -518,7 +530,6 @@ class Context {
518
530
  }
519
531
  }
520
532
  const context = new Context();
521
- context.loadConfig();
522
533
  let initialized = false;
523
534
  export function initializeContext() {
524
535
  try {
@@ -14,7 +14,7 @@ export declare class GitHubApi implements IGitApi {
14
14
  id: string;
15
15
  label?: {
16
16
  id: string;
17
- } | undefined;
17
+ };
18
18
  projectV2: {
19
19
  id: string;
20
20
  field: {
@@ -95,8 +95,8 @@ export class GitHubApi {
95
95
  });
96
96
  }
97
97
  assignBranchToIssue(issueNumber, branchName, commitSha) {
98
- var _a;
99
98
  return __awaiter(this, void 0, void 0, function* () {
99
+ var _a;
100
100
  const issue = yield this.getIssue(issueNumber);
101
101
  const commit = yield this.getCommit(commitSha);
102
102
  const mutation = `
@@ -43,8 +43,8 @@ export class GitHubProjectApi extends GitHubApi {
43
43
  });
44
44
  }
45
45
  createIssue(title, state, label, body, milestone) {
46
- var _a;
47
46
  return __awaiter(this, void 0, void 0, function* () {
47
+ var _a;
48
48
  const user = yield this.getUser();
49
49
  const repository = yield this.getRepository(label);
50
50
  const repositoryId = repository.id;
@@ -115,8 +115,8 @@ export class GitHubProjectApi extends GitHubApi {
115
115
  });
116
116
  }
117
117
  getIssueState(issueNumber) {
118
- var _a, _b, _c;
119
118
  return __awaiter(this, void 0, void 0, function* () {
119
+ var _a, _b, _c;
120
120
  const issue = yield this.getIssue(issueNumber);
121
121
  return (_c = (_b = (_a = issue.projectItems) === null || _a === void 0 ? void 0 : _a.nodes[0]) === null || _b === void 0 ? void 0 : _b.fieldValueByName) === null || _c === void 0 ? void 0 : _c.name;
122
122
  });
@@ -12,8 +12,8 @@ const client = new OpenAI({
12
12
  apiKey: process.env['OPENAI_API_KEY'], // This is the default and can be omitted
13
13
  });
14
14
  export function getCommitMessage() {
15
- var _a;
16
15
  return __awaiter(this, void 0, void 0, function* () {
16
+ var _a;
17
17
  if (process.env['OPENAI_API_KEY']) {
18
18
  const params = {
19
19
  messages: [{ role: 'user', content: 'Say this is a test' }],
@@ -14,7 +14,20 @@ import metadata from './metadata.js';
14
14
  import prompts from "prompts";
15
15
  import templateGenerator from "./template.js";
16
16
  import { getColored } from "./color.js";
17
- import { storeConfig } from "./util.js";
17
+ import { storeConfig, TEMPLATE_MODEL_FOLDER } from "./util.js";
18
+ function generateTemplate(templateFolder, templateExtension, template, context) {
19
+ if (!template || !templateFolder || !templateExtension) {
20
+ return;
21
+ }
22
+ const templateEngine = templateGenerator(templateFolder, templateExtension);
23
+ const formulas = {
24
+ today: Date.now(),
25
+ };
26
+ const view = Object.assign(Object.assign({}, formulas), context);
27
+ templateEngine.read(template);
28
+ templateEngine.render(view);
29
+ return templateEngine.rendered;
30
+ }
18
31
  function createTemplate(templateFolder, templateExtension, template, filename, folder, context) {
19
32
  if (!template || !filename || !templateFolder || !templateExtension) {
20
33
  return;
@@ -457,20 +470,19 @@ export const taskFunctions = {
457
470
  });
458
471
  },
459
472
  listIssues() {
460
- return __awaiter(this, void 0, void 0, function* () {
473
+ return __awaiter(this, arguments, void 0, function* (filter = '{state: OPEN}', template = 'openIssues') {
461
474
  if (!context.projectApi) {
462
475
  return false;
463
476
  }
464
477
  const result = yield context.projectApi.getIssues();
465
- for (const issue of result) {
466
- console.log(issue.title);
467
- }
478
+ const rendered = generateTemplate(TEMPLATE_MODEL_FOLDER, 'md', template, Object.assign({ issues: result }, context));
479
+ console.log(rendered);
468
480
  return true;
469
481
  });
470
482
  },
471
483
  checkIssueType(issueNumber) {
472
- var _a;
473
484
  return __awaiter(this, void 0, void 0, function* () {
485
+ var _a;
474
486
  if (!context.projectApi) {
475
487
  return false;
476
488
  }
@@ -104,8 +104,8 @@ export function validateTask(task) {
104
104
  }
105
105
  return true;
106
106
  }
107
- export function runTask(task, taskContext, tabs = '') {
108
- return __awaiter(this, void 0, void 0, function* () {
107
+ export function runTask(task_1, taskContext_1) {
108
+ return __awaiter(this, arguments, void 0, function* (task, taskContext, tabs = '') {
109
109
  initializeContext();
110
110
  // Valida que este ya esten las variables de enotorno y configuracion
111
111
  if (task.guards) {
@@ -134,8 +134,8 @@ export function runTask(task, taskContext, tabs = '') {
134
134
  return true;
135
135
  });
136
136
  }
137
- export function previewTask(task, tabs = '') {
138
- return __awaiter(this, void 0, void 0, function* () {
137
+ export function previewTask(task_1) {
138
+ return __awaiter(this, arguments, void 0, function* (task, tabs = '') {
139
139
  initializeContext();
140
140
  logStep(`${task.name}: ${task.description}`, tabs);
141
141
  for (const step of task.steps) {
@@ -206,8 +206,8 @@ function askForContinueOrRetry() {
206
206
  function getStepError(step, stepName) {
207
207
  return step.errorMessage ? context.merge(step.errorMessage) : stepName ? `Fallo el step ${stepName}` : '';
208
208
  }
209
- function executeStep(step, tabs, verbose = false) {
210
- return __awaiter(this, void 0, void 0, function* () {
209
+ function executeStep(step_1, tabs_1) {
210
+ return __awaiter(this, arguments, void 0, function* (step, tabs, verbose = false) {
211
211
  const stepName = step.name ? context.merge(step.name) : undefined;
212
212
  if (verbose && stepName) {
213
213
  logStep(`[INICIO] ${stepName}`, tabs);
@@ -1,4 +1,3 @@
1
- /// <reference types="handlebars" />
2
1
  declare class TemplateEngine {
3
2
  _template: HandlebarsTemplateDelegate | undefined;
4
3
  _rendered: string | undefined;
@@ -8,6 +7,7 @@ declare class TemplateEngine {
8
7
  getTemplates(): string[];
9
8
  read(templateName: string): void;
10
9
  render(context: object, options?: RuntimeOptions): void;
10
+ get rendered(): string | undefined;
11
11
  save(filename: string, folder: string, options?: SaveTemplateOptions): void;
12
12
  }
13
13
  declare const _default: (source: string, extension: string) => TemplateEngine;
@@ -51,6 +51,9 @@ class TemplateEngine {
51
51
  }
52
52
  this._rendered = this._template(context, options);
53
53
  }
54
+ get rendered() {
55
+ return this._rendered;
56
+ }
54
57
  save(filename, folder, options = { create: true, overwrite: true }) {
55
58
  let accion = "creo";
56
59
  if (folder && !fs.existsSync(folder)) {
@@ -1,4 +1,4 @@
1
- import prompts from "prompts";
1
+ import prompts, { Choice } from "prompts";
2
2
  import { AnyValue } from "../types/auto.js";
3
3
  export declare const CONFIG_FILE: string;
4
4
  export declare const TEMPLATES_FOLDER: string;
@@ -20,6 +20,7 @@ export declare function titlesToChoices(list: string[], titleToValue?: (title: s
20
20
  value: string;
21
21
  }[];
22
22
  export declare function getDataFromPackage(): Record<string, string>;
23
+ export declare function findChoicesPosition(choices: Choice[], value: string): number;
23
24
  export declare function createConfigurationFile(): Promise<boolean>;
24
25
  export declare function getConfig(variable: string, defaultValue: AnyValue): any;
25
26
  export declare function storeConfig(variable: string, value: AnyValue): void;
@@ -10,7 +10,7 @@ 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 { ProjectServices, GitServices } from "./context.js";
13
+ import context, { ProjectServices, GitServices } from "./context.js";
14
14
  import { logInfo, logWarning } from "./color.js";
15
15
  const COMMAND_FOLDER = searchInFolderHierarchy('commands', fileURLToPath(import.meta.url));
16
16
  export const CONFIG_FILE = process.cwd() + '/.autoforce.json';
@@ -69,23 +69,26 @@ export function getDataFromPackage() {
69
69
  }
70
70
  return data;
71
71
  }
72
+ export function findChoicesPosition(choices, value) {
73
+ const index = choices.findIndex(choice => choice.value === value);
74
+ return index === -1 ? 0 : index;
75
+ }
72
76
  export function createConfigurationFile() {
73
77
  return __awaiter(this, void 0, void 0, function* () {
74
78
  // Todo: Chequear el repoOwner y repo
75
- const data = getDataFromPackage();
76
- const optionals = {};
77
- if (!data.repositoryOwner || !data.repositoryRepo) {
78
- throw new Error('No se encontro repository en el package.json ! Por favor agreguelo y vuelva a intentar');
79
- }
80
- const initialServices = data.repositoryUrl.includes("github.com") ? 0 : 1;
79
+ const config = { backlogColumn: context.backlogColumn, model: context.model, modelTemplates: context.modelTemplates, gitServices: context.gitServices, projectServices: context.projectServices, projectId: context.projectId };
80
+ const gitChoices = [{ title: 'Github', value: GitServices.GitHub }, { title: 'Gitlab', value: GitServices.GitLab }];
81
81
  // Preguntar por GitHub o GitLab
82
82
  const gitServices = yield prompts([{
83
83
  type: "select",
84
84
  name: "git",
85
- initial: initialServices,
86
85
  message: "Elija un servicio de Git",
87
- choices: [{ title: 'Github', value: GitServices.GitHub }, { title: 'Gitlab', value: GitServices.GitLab }]
86
+ initial: findChoicesPosition(gitChoices, config.gitServices),
87
+ choices: gitChoices
88
88
  }]);
89
+ if (gitServices.git === undefined)
90
+ return false;
91
+ config.gitServices = gitServices.git;
89
92
  // Chequear las variables de entorno
90
93
  if (gitServices.git === GitServices.GitHub && !process.env.GITHUB_TOKEN) {
91
94
  logWarning('A fin de que la herramienta funcione debe configurar una variable de entorno GITHUB_TOKEN');
@@ -93,13 +96,19 @@ export function createConfigurationFile() {
93
96
  if (gitServices.git === GitServices.GitLab && !process.env.GITLAB_TOKEN) {
94
97
  logWarning('A fin de que la herramienta funcione debe configurar una variable de entorno GITLAB_TOKEN');
95
98
  }
99
+ // Selecciona el modelo de automatizacion
96
100
  const models = readJsonSync(`${COMMAND_FOLDER}/models.json`);
101
+ models.push({ 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' });
97
102
  const automationModel = yield prompts([{
98
103
  type: "select",
99
104
  name: "model",
100
105
  message: "Elija un modelo de automatizacion",
101
- 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' }])
106
+ initial: findChoicesPosition(models, config.model),
107
+ choices: models
102
108
  }]);
109
+ if (automationModel.model === undefined)
110
+ return false;
111
+ config.model = automationModel.model;
103
112
  // Si es custom pregunta si quiere tomar de base alguno existente
104
113
  if (automationModel.model === 'custom') {
105
114
  const baseModel = yield prompts([{
@@ -113,39 +122,53 @@ export function createConfigurationFile() {
113
122
  }
114
123
  }
115
124
  // Gestion del Proyecto
125
+ const projectChoices = [{ title: 'Github Projects', value: ProjectServices.GitHub }, { title: 'GitLab Projects', value: ProjectServices.GitLab }, { title: 'Jira', value: ProjectServices.Jira }, { title: 'None', value: ProjectServices.None }];
116
126
  const projectServices = yield prompts([{
117
127
  type: "select",
118
128
  name: "project",
119
- initial: initialServices,
120
129
  message: "Gestion de proyecto",
121
- choices: [{ title: 'Github Projects', value: ProjectServices.GitHub }, { title: 'GitLab Projects', value: ProjectServices.GitLab }, { title: 'Jira', value: ProjectServices.Jira }, { title: 'None', value: ProjectServices.None }]
130
+ initial: findChoicesPosition(projectChoices, config.projectServices),
131
+ choices: projectChoices
122
132
  }]);
133
+ if (projectServices.project === undefined)
134
+ return false;
135
+ config.projectServices = projectServices.project;
136
+ ;
123
137
  if (projectServices.project === ProjectServices.GitHub || projectServices.project === ProjectServices.GitLab) {
124
138
  // Gestion del Proyecto
125
139
  const backlogColumn = yield prompts([{
126
140
  type: "text",
127
141
  name: "backlogColumn",
128
- initial: 'Todo',
142
+ initial: config.backlogColumn,
129
143
  message: "Nombre de la columna donde se crean nuevos issues"
130
144
  }]);
131
- optionals['backlogColumn'] = backlogColumn.backlogColumn;
132
- logInfo(`Por omision ser utilizan proyectos dentro de ${data.repositoryOwner} y ${data.repositoryRepo} `);
145
+ if (backlogColumn.backlogColumn === undefined)
146
+ return false;
147
+ config.backlogColumn = backlogColumn.backlogColumn;
148
+ logInfo(`Por omision ser utilizan proyectos dentro de ${context.repositoryOwner} y ${context.repositoryRepo} `);
133
149
  }
150
+ // Id de Projecto
134
151
  const projectId = yield prompts([{
135
152
  type: "text",
136
153
  name: "projectId",
154
+ initial: config.projectId,
137
155
  message: "Id del proyecto"
138
156
  }]);
157
+ if (projectId.projectId === undefined)
158
+ return false;
159
+ config.projectId = projectId.projectId;
139
160
  // Modelo de Dcumentacion
140
161
  const modelsTemplates = readJsonSync(`${TEMPLATES_FOLDER}/models.json`);
141
162
  const modelTemplates = yield prompts([{
142
163
  type: "select",
143
164
  name: "model",
144
165
  message: "Elija un modelo de documentacion",
166
+ initial: findChoicesPosition(modelsTemplates, config.modelTemplates),
145
167
  choices: modelsTemplates
146
168
  }]);
147
- // console.log('Genera documentacion');
148
- const config = Object.assign({ model: automationModel.model, modelTemplates: modelTemplates.model, gitServices: gitServices.git, projectServices: projectServices.project, projectId: projectId.projectId }, optionals);
169
+ if (modelTemplates.model === undefined)
170
+ return false;
171
+ config.modelTemplates = modelTemplates.model;
149
172
  try {
150
173
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
151
174
  }
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.10",
5
+ "version": "0.1.11",
6
6
  "keywords": [
7
7
  "Salesforce",
8
8
  "Automation",
@@ -2,12 +2,11 @@
2
2
  {
3
3
  "title": "Procesos de Negocio en Salesforce",
4
4
  "value": "modelA",
5
- "description": "Documenta Clases, Objetos y LWC a traves de procesos de negocios. Se basa en docusaurus"0
5
+ "description": "Documenta Clases, Objetos y LWC a traves de procesos de negocios. Se basa en docusaurus"
6
6
  },
7
7
  {
8
8
  "title": "Proyecto simple en Github Docs",
9
9
  "value": "modelB",
10
10
  "description": "Github pages con changelog, readme y carpeta docs de Markdowns"
11
11
  }
12
- ]
13
-
12
+ ]