autoforce 0.1.17 → 0.1.18

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.
Files changed (74) hide show
  1. package/.autoforce.json +8 -4
  2. package/CHANGELOG.md +10 -1
  3. package/lib/auto.js +5 -5
  4. package/lib/helpers/class.js +10 -3
  5. package/lib/helpers/context.d.ts +5 -2
  6. package/lib/helpers/context.js +5 -6
  7. package/lib/helpers/lwc.js +11 -4
  8. package/lib/helpers/metadata.js +1 -2
  9. package/lib/helpers/object.js +11 -4
  10. package/lib/helpers/taskFunctions.js +5 -5
  11. package/lib/helpers/tasks.d.ts +2 -5
  12. package/lib/helpers/tasks.js +33 -28
  13. package/lib/helpers/template.d.ts +9 -5
  14. package/lib/helpers/template.js +27 -18
  15. package/lib/helpers/util.d.ts +5 -5
  16. package/lib/helpers/util.js +43 -42
  17. package/models/dev/models.json +19 -0
  18. package/models/doc/models.json +9 -0
  19. package/models/git/models.json +9 -0
  20. package/models/project/models.json +9 -0
  21. package/package.json +2 -3
  22. package/commands/modelC/new/issue.json +0 -24
  23. package/commands/models.json +0 -18
  24. package/templates/modelB/openIssues.bash +0 -4
  25. package/templates/modelB/viewIssue.bash +0 -8
  26. package/templates/models.json +0 -12
  27. /package/{commands/modelA → models/dev/npm}/subtasks/checkout-branch.json +0 -0
  28. /package/{commands/modelA → models/dev/npm}/subtasks/create-pull.json +0 -0
  29. /package/{commands/modelC → models/dev/npm}/subtasks/pack.json +0 -0
  30. /package/{commands/modelA → models/dev/npm}/subtasks/publish-branch.json +0 -0
  31. /package/{commands/modelA → models/dev/npm}/tasks/cancel.json +0 -0
  32. /package/{commands/modelA → models/dev/npm}/tasks/finish.json +0 -0
  33. /package/{commands/modelC → models/dev/npm}/tasks/list.json +0 -0
  34. /package/{commands/modelC → models/dev/npm}/tasks/publish.json +0 -0
  35. /package/{commands/modelC → models/dev/npm}/tasks/start.json +0 -0
  36. /package/{commands/modelA → models/dev/npm}/tasks/stop.json +0 -0
  37. /package/{commands/modelA → models/dev/npm}/tasks/switch.json +0 -0
  38. /package/{commands/modelA → models/dev/npm}/tasks/view.json +0 -0
  39. /package/{commands/modelA → models/dev/scratchs}/subtasks/create-scratch.json +0 -0
  40. /package/{commands/modelA → models/dev/scratchs}/subtasks/deploy-code.json +0 -0
  41. /package/{commands/modelA → models/dev/scratchs}/subtasks/drop-scratch.json +0 -0
  42. /package/{commands/modelA → models/dev/scratchs}/subtasks/package-code.json +0 -0
  43. /package/{commands/modelA → models/dev/scratchs}/subtasks/validate-code.json +0 -0
  44. /package/{commands/modelA → models/dev/scratchs}/subtasks/validate-scratch.json +0 -0
  45. /package/{commands/modelC → models/dev/scratchs}/tasks/cancel.json +0 -0
  46. /package/{commands/modelA → models/dev/scratchs}/tasks/deploy.json +0 -0
  47. /package/{commands/modelC → models/dev/scratchs}/tasks/finish.json +0 -0
  48. /package/{commands/modelA → models/dev/scratchs}/tasks/rollback.json +0 -0
  49. /package/{commands/modelA → models/dev/scratchs}/tasks/start.json +0 -0
  50. /package/{commands/modelC → models/dev/scratchs}/tasks/stop.json +0 -0
  51. /package/{commands/modelC → models/dev/scratchs}/tasks/switch.json +0 -0
  52. /package/{commands/modelA → models/doc/processes}/new/process.json +0 -0
  53. /package/{commands/modelA/subtasks → models/doc/processes/subtask}/update-documentation.json +0 -0
  54. /package/{templates/modelA → models/doc/processes/templates}/dictionary/class-all.md +0 -0
  55. /package/{templates/modelA → models/doc/processes/templates}/dictionary/class-diagrama.md +0 -0
  56. /package/{templates/modelA → models/doc/processes/templates}/dictionary/class-inner.md +0 -0
  57. /package/{templates/modelA → models/doc/processes/templates}/dictionary/class-metodos.md +0 -0
  58. /package/{templates/modelA → models/doc/processes/templates}/dictionary/class-public.md +0 -0
  59. /package/{templates/modelA → models/doc/processes/templates}/dictionary/class-referencias.md +0 -0
  60. /package/{templates/modelA → models/doc/processes/templates}/dictionary/class.md +0 -0
  61. /package/{templates/modelA → models/doc/processes/templates}/dictionary/classes.md +0 -0
  62. /package/{templates/modelA → models/doc/processes/templates}/dictionary/object.md +0 -0
  63. /package/{templates/modelA → models/doc/processes/templates}/dictionary/objects.md +0 -0
  64. /package/{templates/modelA → models/doc/processes/templates}/intro.md +0 -0
  65. /package/{templates/modelA → models/doc/processes/templates}/process.md +0 -0
  66. /package/{commands/modelC/subtasks → models/git/githubflow/subtask}/checkout-branch.json +0 -0
  67. /package/{commands/modelC/subtasks → models/git/githubflow/subtask}/create-pull.json +0 -0
  68. /package/{commands/modelC/subtasks → models/git/githubflow/subtask}/publish-branch.json +0 -0
  69. /package/{commands/modelA → models/project/github-releases}/new/issue.json +0 -0
  70. /package/{commands/modelA/tasks → models/project/github-releases/task}/list.json +0 -0
  71. /package/{commands/modelC/tasks → models/project/github-releases/task}/view.json +0 -0
  72. /package/{templates/modelB → models/project/github-releases/templates}/changelog.md +0 -0
  73. /package/{templates/modelA → models/project/github-releases/templates}/openIssues.bash +0 -0
  74. /package/{templates/modelA → models/project/github-releases/templates}/viewIssue.bash +0 -0
package/.autoforce.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
- "version": "0.1.17",
2
+ "version": "0.1.18",
3
3
  "backlogColumn": "Todo",
4
- "model": "modelC",
5
- "modelTemplates": "modelB",
6
4
  "gitServices": "github",
5
+ "gitModel": "githubflow",
6
+ "projectModel": "github-releases",
7
7
  "projectServices": "github",
8
8
  "projectId": "4",
9
9
  "listFilter": "mios",
10
- "listTemplate": "openIssues"
10
+ "listTemplate": "openIssues",
11
+ "devModel": "npm",
12
+ "docModel": "processes",
13
+ "filter": "{states: OPEN}",
14
+ "template": "openIssues"
11
15
  }
package/CHANGELOG.md CHANGED
@@ -1,7 +1,16 @@
1
1
  # Versiones
2
2
 
3
+ ## Version 0.1.17
4
+ - Fecha: 13 Dic 2024
5
+ - Paquete: [Descargar](https://www.npmjs.com/package/autoforce/v/0.1.17)
6
+ - Cambios:
7
+ * [new] cuando se quiere crear un issue y se le manda --milestone=v0.1.17 manda el title y no el id
8
+ - https://github.com/sebastianclaros/autoforce/issues/44
9
+ * Poder ejecutar autoforce en un subdirectorio, hoy tira un config como que no encuentra el autoforce.json
10
+ - https://github.com/sebastianclaros/autoforce/issues/45
11
+
3
12
  ## Version 0.1.16
4
- - Fecha:
13
+ - Fecha: 12 Dic 2024
5
14
  - Paquete: [Descargar](https://www.npmjs.com/package/autoforce/v/0.1.16)
6
15
  - Cambios:
7
16
  * [new] new milestone
package/lib/auto.js CHANGED
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  // Comandos validos
11
- import { createObject, validateTask, getTasks, helpTask, runTask, getTaskFolder } from "./helpers/tasks.js";
11
+ import { createObject, validateTask, getTasks, helpTask, runTask } from "./helpers/tasks.js";
12
12
  import { logError } from "./helpers/color.js";
13
13
  import prompts from "prompts";
14
14
  import { createConfigurationFile, getConfigFile } from "./helpers/util.js";
@@ -39,7 +39,7 @@ export default function main() {
39
39
  const config = getConfigFromArgs(process.argv.slice(2));
40
40
  const taskCommandKeys = Object.keys(taskCommand);
41
41
  if (taskCommandKeys.includes(config.command)) {
42
- const tasks = getTasks(config.taskFolder);
42
+ const tasks = getTasks(config.subfolder);
43
43
  const taskName = yield askForTaskName(config.taskName, tasks);
44
44
  if (taskName) {
45
45
  const task = tasks[taskName];
@@ -65,7 +65,7 @@ export default function main() {
65
65
  });
66
66
  }
67
67
  export function getConfigFromArgs(processArgs) {
68
- const config = { options: {}, taskName: '', command: '', taskFolder: '' };
68
+ const config = { options: {}, taskName: '', command: '', subfolder: '', arguments: [] };
69
69
  const args = [];
70
70
  // Divide --xxx como options el resto como args
71
71
  for (const argName of processArgs) {
@@ -89,11 +89,11 @@ export function getConfigFromArgs(processArgs) {
89
89
  }
90
90
  // Setea el taskFolder segun si es un task o subtask
91
91
  if ((config.command == 'help' || config.command == 'preview') && (currentArgument == 'subtask' || currentArgument == 'task')) {
92
- config.taskFolder = getTaskFolder(currentArgument);
92
+ config.subfolder = currentArgument;
93
93
  currentArgument = args.shift();
94
94
  }
95
95
  else {
96
- config.taskFolder = getTaskFolder(config.command);
96
+ config.subfolder = config.command;
97
97
  }
98
98
  if (typeof currentArgument == 'string') {
99
99
  config.taskName = currentArgument;
@@ -8,9 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import sf from "./connect.js";
11
- import templateGenerator from "./template.js";
12
- import { DICTIONARY_FOLDER, TEMPLATE_MODEL_FOLDER } from "./util.js";
13
- const templateEngine = templateGenerator(`${TEMPLATE_MODEL_FOLDER}/dictionary`, "md");
11
+ import { default as templateGenerator } from "./template.js";
12
+ import { DICTIONARY_FOLDER, getModelFolders } from "./util.js";
13
+ let _templateEngine;
14
+ function getTemplateEngine() {
15
+ if (!_templateEngine) {
16
+ _templateEngine = templateGenerator(getModelFolders('dictionary'), "md");
17
+ }
18
+ return _templateEngine;
19
+ }
14
20
  import { sortByName, getNamesByExtension, verFecha, splitFilename } from "./util.js";
15
21
  function getMetadata(clases) {
16
22
  return __awaiter(this, void 0, void 0, function* () {
@@ -130,6 +136,7 @@ function getInnerClasses(classes) {
130
136
  }
131
137
  function executeClasses(items, filename, folder) {
132
138
  return __awaiter(this, void 0, void 0, function* () {
139
+ const templateEngine = getTemplateEngine();
133
140
  if (items.length === 0) {
134
141
  return;
135
142
  }
@@ -20,12 +20,15 @@ export declare enum ProjectServices {
20
20
  }
21
21
  declare class Context implements IObjectRecord {
22
22
  [s: string]: AnyValue | undefined;
23
- model: string;
24
- modelTemplates: string;
23
+ devModel: string | undefined;
24
+ gitModel: string | undefined;
25
+ docModel: string | undefined;
26
+ projectModel: string | undefined;
25
27
  gitServices: GitServices;
26
28
  isGitApi: boolean;
27
29
  gitApi: IGitApi | undefined;
28
30
  version: string | undefined;
31
+ dictionaryFolder: string;
29
32
  options: Record<string, AnyValue>;
30
33
  projectServices: ProjectServices;
31
34
  isProjectApi: boolean;
@@ -39,10 +39,9 @@ const filterProcesses = (fullPath) => fullPath.endsWith(".md"); // && !fullPath.
39
39
  const ISSUES_TYPES = [{ value: 'feature', title: 'feature' }, { value: 'bug', title: 'bug' }, { value: 'documentation', title: 'documentation' }, { value: 'automation', title: 'automation' }];
40
40
  class Context {
41
41
  constructor() {
42
- this.model = 'modelA'; // Default Model de commands
43
- this.modelTemplates = 'modelA'; // Default Model de templates
44
42
  this.gitServices = GitServices.None;
45
43
  this.isGitApi = false;
44
+ this.dictionaryFolder = process.cwd() + "/docs";
46
45
  this.options = {};
47
46
  this.projectServices = ProjectServices.None;
48
47
  this.isProjectApi = false;
@@ -253,9 +252,9 @@ class Context {
253
252
  get processesHeader() {
254
253
  if (!this._processesHeader) {
255
254
  this._processesHeader = {};
256
- const folders = getFiles(process.cwd() + "/docs", filterDirectory, true, ['diccionarios']);
255
+ const folders = getFiles(this.dictionaryFolder, filterDirectory, true, ['diccionarios']);
257
256
  for (const folder of folders) {
258
- const fullpath = `${process.cwd()}/docs/${folder}`;
257
+ const fullpath = `${this.dictionaryFolder}/${folder}`;
259
258
  const filenames = getFiles(fullpath, filterProcesses);
260
259
  for (const filename of filenames) {
261
260
  const header = this.getProcessHeader(fullpath + "/" + filename);
@@ -269,7 +268,7 @@ class Context {
269
268
  }
270
269
  // TODO: merge con getProcessFromDocs
271
270
  getProcessMetadata() {
272
- const folders = getFiles(process.cwd() + "/docs", filterDirectory, true, ['diccionarios']);
271
+ const folders = getFiles(this.dictionaryFolder, filterDirectory, true, ['diccionarios']);
273
272
  const retArray = [];
274
273
  for (const folder of folders) {
275
274
  const fullpath = `${process.cwd()}/docs/${folder}`;
@@ -285,7 +284,7 @@ class Context {
285
284
  return retArray;
286
285
  }
287
286
  getModules() {
288
- return getFiles(process.cwd() + "/docs", filterDirectory, false, ['diccionarios']);
287
+ return getFiles(this.dictionaryFolder, filterDirectory, false, ['diccionarios']);
289
288
  }
290
289
  get modules() {
291
290
  return this.getModules().map(module => { return { value: module, title: module }; });
@@ -8,9 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import sf from "./connect.js";
11
- import templateGenerator from "./template.js";
12
- import { DICTIONARY_FOLDER, TEMPLATE_MODEL_FOLDER } from "./util.js";
13
- const templateEngine = templateGenerator(`${TEMPLATE_MODEL_FOLDER}/dictionary`, "md");
11
+ import { default as templateGenerator } from "./template.js";
12
+ import { DICTIONARY_FOLDER, getModelFolders } from "./util.js";
13
+ let _templateEngine;
14
+ function getTemplateEngine() {
15
+ if (!_templateEngine) {
16
+ _templateEngine = templateGenerator(getModelFolders('dictionary'), "md");
17
+ }
18
+ return _templateEngine;
19
+ }
14
20
  import { sortByName, splitFilename } from "./util.js";
15
21
  function getMetadata(lwc) {
16
22
  return __awaiter(this, void 0, void 0, function* () {
@@ -37,6 +43,7 @@ function getLwc(files) {
37
43
  }
38
44
  function executeLwc(items, filename, folder) {
39
45
  return __awaiter(this, void 0, void 0, function* () {
46
+ const templateEngine = getTemplateEngine();
40
47
  if (items.length === 0) {
41
48
  return;
42
49
  }
@@ -60,7 +67,7 @@ function executeLwc(items, filename, folder) {
60
67
  templateEngine.render(lwcContext, {
61
68
  helpers: {}
62
69
  });
63
- templateEngine.save(filename, TEMPLATE_MODEL_FOLDER + "/" + folder);
70
+ templateEngine.save(filename, folder);
64
71
  });
65
72
  }
66
73
  const lwcModule = {
@@ -10,7 +10,6 @@ const helpers = {
10
10
  export default helpers;
11
11
  /*
12
12
  import context from "./context.js";
13
- import { TEMPLATE_MODEL_FOLDER } from "./util.js";
14
13
  import type { DocumentationModule, IProcessInfo, IMetadataNode, IMetadataComponentNode } from "../types/auto.js";
15
14
  function getMetadataFromContext(components: string[]) {
16
15
  return getMetadataArray(context.getProcessMetadata(), components);
@@ -66,7 +65,7 @@ function getMetadataArray(metadata: IProcessInfo[], props: string[]) {
66
65
  return items;
67
66
  };
68
67
 
69
- return getItemsFromTree({ folder: TEMPLATE_MODEL_FOLDER, childs: metadata });
68
+ return getItemsFromTree({ folder: TEMPLATE_FOLDER, childs: metadata });
70
69
  }
71
70
 
72
71
  export async function execute() {
@@ -8,9 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import sf from "./connect.js";
11
- import templateGenerator from "./template.js";
12
- import { DICTIONARY_FOLDER, TEMPLATE_MODEL_FOLDER } from "./util.js";
13
- const templateEngine = templateGenerator(`${TEMPLATE_MODEL_FOLDER}/dictionary`, "md");
11
+ import { default as templateGenerator } from "./template.js";
12
+ import { DICTIONARY_FOLDER, getModelFolders } from "./util.js";
13
+ let _templateEngine;
14
+ function getTemplateEngine() {
15
+ if (!_templateEngine) {
16
+ _templateEngine = templateGenerator(getModelFolders('dictionary'), "md");
17
+ }
18
+ return _templateEngine;
19
+ }
14
20
  import { sortByLabel } from "./util.js";
15
21
  function getMetadata(objetos) {
16
22
  return __awaiter(this, void 0, void 0, function* () {
@@ -99,6 +105,7 @@ function getObjects(files) {
99
105
  }
100
106
  function executeObjects(items, filename, folder) {
101
107
  return __awaiter(this, void 0, void 0, function* () {
108
+ const templateEngine = getTemplateEngine();
102
109
  if (items.length === 0) {
103
110
  return;
104
111
  }
@@ -124,7 +131,7 @@ function executeObjects(items, filename, folder) {
124
131
  templateEngine.render(objectContext, {
125
132
  helpers: { isManaged, isMetadataFormula, attributesFormula }
126
133
  });
127
- templateEngine.save(filename, TEMPLATE_MODEL_FOLDER + "/" + folder);
134
+ templateEngine.save(filename, folder);
128
135
  });
129
136
  }
130
137
  const objectModule = {
@@ -13,7 +13,7 @@ import { logError, logInfo } from "./color.js";
13
13
  import metadata from './metadata.js';
14
14
  import prompts from "prompts";
15
15
  import templateGenerator from "./template.js";
16
- import { filterBash, getFiles, storeConfig, TEMPLATE_MODEL_FOLDER, valuesToChoices } from "./util.js";
16
+ import { filterBash, getFilesInFolders, getModelFolders, storeConfig, valuesToChoices } from "./util.js";
17
17
  function generateTemplate(templateFolder, templateExtension, template, context) {
18
18
  if (!template || !templateFolder || !templateExtension) {
19
19
  return;
@@ -31,7 +31,7 @@ function createTemplate(templateFolder, templateExtension, template, filename, f
31
31
  if (!template || !filename || !templateFolder || !templateExtension) {
32
32
  return;
33
33
  }
34
- const templateEngine = templateGenerator(templateFolder, templateExtension);
34
+ const templateEngine = templateGenerator([templateFolder], templateExtension);
35
35
  const formulas = {
36
36
  today: Date.now(),
37
37
  filename
@@ -484,7 +484,7 @@ export const taskFunctions = {
484
484
  return false;
485
485
  }
486
486
  const result = yield context.projectApi.getIssue(issueNumber);
487
- const rendered = generateTemplate(TEMPLATE_MODEL_FOLDER, 'bash', template, Object.assign({ issue: result }, context));
487
+ const rendered = generateTemplate(getModelFolders('templates'), 'bash', template, Object.assign({ issue: result }, context));
488
488
  console.log(rendered);
489
489
  return true;
490
490
  });
@@ -562,7 +562,7 @@ export const taskFunctions = {
562
562
  }
563
563
  }
564
564
  if (!listTemplate) {
565
- const files = getFiles(TEMPLATE_MODEL_FOLDER, filterBash).map(filename => filename.split(".")[0]);
565
+ const files = getFilesInFolders(getModelFolders('templates'), filterBash).map(filename => filename.split(".")[0]);
566
566
  const templates = valuesToChoices(files);
567
567
  const answer = yield prompts([
568
568
  {
@@ -579,7 +579,7 @@ export const taskFunctions = {
579
579
  }
580
580
  const result = yield context.projectApi.getIssuesWithFilter(filter);
581
581
  console.log(context.version);
582
- const rendered = generateTemplate(TEMPLATE_MODEL_FOLDER, extension, listTemplate, { issues: result, context });
582
+ const rendered = generateTemplate(getModelFolders('templates'), extension, listTemplate, { issues: result, context });
583
583
  console.log(rendered);
584
584
  return true;
585
585
  });
@@ -1,10 +1,7 @@
1
1
  import { ITask } from "../types/helpers/tasks.js";
2
2
  import { AnyValue, CommandOptions, ObjectRecord } from "../types/auto.js";
3
- export declare const TASKS_FOLDER: string;
4
- export declare const SUBTASKS_FOLDER: string;
5
- export declare const NEW_FOLDER: string;
6
- export declare function getTaskFolder(command: string): string;
7
- export declare function getTasks(folder?: string): Record<string, ITask>;
3
+ export declare function getTaskFolders(command?: string): string[];
4
+ export declare function getTasks(command?: string): Record<string, ITask>;
8
5
  export declare function helpTask(task: ITask): Promise<boolean>;
9
6
  export declare function validateTask(task: ITask): boolean;
10
7
  export declare function runTask(task: ITask, taskContext: CommandOptions, tabs?: string): Promise<boolean>;
@@ -9,22 +9,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import context, { initializeContext } from "./context.js";
11
11
  import { logError, logStep } from "./color.js";
12
- import fs from "fs";
13
- import { getFiles, filterJson, searchInFolderHierarchy } from "./util.js";
12
+ import { getModelFolders, getFiles, filterJson, readJsonSync } from "./util.js";
14
13
  import { validateCommand, validateFunction, executeFunction, executeCommand, taskFunctions } from "./taskFunctions.js";
15
14
  import prompts from "prompts";
16
- import { fileURLToPath } from 'url';
17
- const COMMAND_FOLDER = searchInFolderHierarchy('commands', fileURLToPath(import.meta.url));
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
- export function getTaskFolder(command) {
15
+ export function getTaskFolders(command = 'task') {
22
16
  const folders = {
23
- 'task': TASKS_FOLDER,
24
- 'subtask': SUBTASKS_FOLDER,
25
- 'tasks': TASKS_FOLDER,
26
- 'subtasks': SUBTASKS_FOLDER,
27
- 'new': NEW_FOLDER
17
+ 'task': getModelFolders('tasks'),
18
+ 'subtask': getModelFolders('subtasks'),
19
+ 'tasks': getModelFolders('tasks'),
20
+ 'subtasks': getModelFolders('subtasks'),
21
+ 'new': getModelFolders('new')
28
22
  };
29
23
  return folders[command.toLowerCase()] || folders.tasks;
30
24
  }
@@ -32,22 +26,33 @@ function getTaskLists(folder) {
32
26
  const files = getFiles(folder, filterJson);
33
27
  return files.map(filename => filename.split(".")[0]);
34
28
  }
35
- export function getTasks(folder = TASKS_FOLDER) {
29
+ export function getTasks(command = 'tasks') {
30
+ const folders = getTaskFolders(command);
36
31
  const tasks = {};
37
- for (const taskName of getTaskLists(folder)) {
38
- tasks[taskName] = getTask(taskName, folder);
32
+ for (const folder of folders) {
33
+ for (const taskName of getTaskLists(folder)) {
34
+ const filename = folder + "/" + taskName + ".json";
35
+ const task = readJsonSync(filename);
36
+ tasks[taskName] = tasks[taskName] ? mergeTask(tasks[taskName], task) : task;
37
+ }
39
38
  }
40
39
  return tasks;
41
40
  }
42
- function getTask(taskName, folder) {
43
- const filename = folder + "/" + taskName + ".json";
44
- const content = fs.readFileSync(filename, "utf8");
45
- try {
46
- return JSON.parse(content);
47
- }
48
- catch (_a) {
49
- throw new Error(`Verifique que el ${filename} sea json valido`);
41
+ function mergeTask(newTask, oldTask) {
42
+ const newSteps = newTask.steps ? [...newTask.steps, ...oldTask.steps] : oldTask.steps;
43
+ const newArguments = newTask.arguments ? Object.assign(Object.assign({}, newTask.arguments), oldTask.arguments) : oldTask.arguments;
44
+ const newGuards = newTask.guards ? [...newTask.guards, ...oldTask.guards] : oldTask.guards;
45
+ const newVerbose = newTask.verbose || oldTask.verbose;
46
+ const newDescription = newTask.description ? newTask.description + ' ' + oldTask.description : oldTask.description;
47
+ const mergedTask = { name: newTask.name, verbose: newVerbose, description: newDescription, arguments: newArguments, guards: newGuards, steps: newSteps };
48
+ return mergedTask;
49
+ }
50
+ function getTask(taskName, subfolder) {
51
+ const tasks = getTasks(subfolder);
52
+ if (!tasks[taskName]) {
53
+ throw new Error(`Verifique que el ${taskName} exista en alguno las subcarpetas de ${subfolder}`);
50
54
  }
55
+ return tasks[taskName];
51
56
  }
52
57
  function isCriteriaMet(criteria) {
53
58
  if (!criteria) {
@@ -92,11 +97,11 @@ export function validateTask(task) {
92
97
  validateStep = validateFunction(step);
93
98
  }
94
99
  else if (typeof step.subtask === 'string') {
95
- const subtask = getTask(step.subtask, SUBTASKS_FOLDER);
100
+ const subtask = getTask(step.subtask, 'subtasks');
96
101
  validateStep = validateTask(subtask);
97
102
  }
98
103
  else if (typeof step.task === 'string') {
99
- const subtask = getTask(step.task, TASKS_FOLDER);
104
+ const subtask = getTask(step.task, 'tasks');
100
105
  validateStep = validateTask(subtask);
101
106
  }
102
107
  else {
@@ -154,7 +159,7 @@ function previewStep(step, tabs = '') {
154
159
  }
155
160
  if (step.subtask) {
156
161
  tabs += '\t';
157
- const subtask = getTask(step.subtask, SUBTASKS_FOLDER);
162
+ const subtask = getTask(step.subtask, 'subtasks');
158
163
  previewTask(subtask, tabs);
159
164
  }
160
165
  else {
@@ -181,7 +186,7 @@ function runStep(step, tabs) {
181
186
  return yield executeFunction(step);
182
187
  }
183
188
  else if (typeof step.subtask === 'string' || typeof step.task === 'string') {
184
- const subtask = typeof step.subtask === 'string' ? getTask(step.subtask, SUBTASKS_FOLDER) : getTask(step.task, TASKS_FOLDER);
189
+ const subtask = typeof step.subtask === 'string' ? getTask(step.subtask, 'subtask') : getTask(step.task, 'tasks');
185
190
  let stepContext = step.arguments ? context.mergeArgs(step.arguments) : {};
186
191
  if (Array.isArray(stepContext)) {
187
192
  stepContext = createObject(subtask.arguments, stepContext);
@@ -1,15 +1,19 @@
1
- declare class TemplateEngine {
1
+ export declare class TemplateEngine {
2
2
  _template: HandlebarsTemplateDelegate | undefined;
3
3
  _rendered: string | undefined;
4
4
  _extension: string;
5
- _sourceFolder: string;
6
- constructor(source: string, extension?: string);
5
+ _sourceFolders: string[];
6
+ constructor(sources: string[], extension?: string);
7
7
  getTemplates(): string[];
8
- getNameAndExtension(templateName: string): string[];
8
+ findTemplateByName(templateName: string): {
9
+ folder: string;
10
+ name: string;
11
+ extension: string;
12
+ };
9
13
  read(templateName: string): void;
10
14
  render(context: object, options?: RuntimeOptions): void;
11
15
  get rendered(): string | undefined;
12
16
  save(filename: string, folder: string, options?: SaveTemplateOptions): void;
13
17
  }
14
- declare const _default: (source: string, extension: string) => TemplateEngine;
18
+ declare const _default: (source: string[], extension: string) => TemplateEngine;
15
19
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import Handlebars from "handlebars";
3
3
  import { merge } from "./merge.js";
4
- import { getFiles } from "./util.js";
4
+ import { getFiles, getFilesInFolders } from "./util.js";
5
5
  function isObjectEmpty(objectName) {
6
6
  return (objectName &&
7
7
  Object.keys(objectName).length === 0 &&
@@ -22,44 +22,53 @@ function openTemplate(sourceFolder, templateName, extension) {
22
22
  }
23
23
  return content;
24
24
  }
25
- class TemplateEngine {
26
- constructor(source, extension = '*') {
27
- this._sourceFolder = source;
28
- if (!fs.existsSync(this._sourceFolder)) {
29
- throw new Error(`La carpeta source ${this._sourceFolder} no existe!`);
30
- }
25
+ export class TemplateEngine {
26
+ constructor(sources, extension = '*') {
27
+ this._sourceFolders = sources;
31
28
  this._extension = extension;
29
+ for (const sourceFolder of this._sourceFolders) {
30
+ if (!fs.existsSync(sourceFolder)) {
31
+ throw new Error(`La carpeta source ${sourceFolder} no existe!`);
32
+ }
33
+ }
32
34
  }
33
35
  ;
34
36
  getTemplates() {
35
37
  const filterThisExtension = (file) => file.endsWith(`.${this._extension}`) || this._extension === '*';
36
38
  const templates = [];
37
- const files = getFiles(this._sourceFolder, filterThisExtension, true, ['dictionary']);
39
+ const files = getFilesInFolders(this._sourceFolders, filterThisExtension, true, ['dictionary']);
38
40
  for (const filename of files) {
39
41
  const [name] = filename.split(".");
40
42
  templates.push(name);
41
43
  }
42
44
  return templates;
43
45
  }
44
- getNameAndExtension(templateName) {
46
+ findTemplateByName(templateName) {
47
+ let folder;
48
+ let name = templateName;
49
+ let extension = this._extension;
45
50
  // Si viene la extension en el nombre la extrae
46
51
  if (templateName.split(".").length > 1) {
47
- return templateName.split(".");
52
+ [name, extension] = templateName.split(".");
48
53
  }
49
- // Si viene la extension * busca cual puede ser en el directorio
50
- if (this._extension === '*' || this._extension === '') {
51
- const fileNames = getFiles(this._sourceFolder, fileName => fileName.split(".")[0].endsWith(templateName));
54
+ // Busca en las carpetas el archivo
55
+ for (const currentFolder of this._sourceFolders) {
56
+ folder = currentFolder;
57
+ const filterWithExtension = (fileName) => fileName === `${name}.${extension}`;
58
+ const filterWithoutExtension = (fileName) => fileName.split(".")[0].endsWith(name);
59
+ const filter = (extension === '*' || extension === '') ? filterWithoutExtension : filterWithExtension;
60
+ const fileNames = getFiles(folder, filter);
52
61
  if (fileNames.length > 0) {
53
- return fileNames[0].split(".");
62
+ [name, extension] = fileNames[0].split(".");
63
+ return { folder, name, extension };
54
64
  }
55
65
  }
56
- // Por defecto usa el templateName como nombre y la extension
57
- return [templateName, this._extension];
66
+ throw new Error(`No se encontro el template ${templateName} en ninguna de las carpetas ${this._sourceFolders}`);
58
67
  }
59
68
  read(templateName) {
60
69
  // Por defecto usa el templateName como nombre y la extension
61
- const [name, extension] = this.getNameAndExtension(templateName);
62
- const rawTemplate = openTemplate(this._sourceFolder, name, extension);
70
+ const { folder, name, extension } = this.findTemplateByName(templateName);
71
+ const rawTemplate = openTemplate(folder, name, extension);
63
72
  this._template = Handlebars.compile(rawTemplate);
64
73
  }
65
74
  render(context, options = {}) {
@@ -1,10 +1,8 @@
1
- import prompts, { Choice } from "prompts";
1
+ import { Choice } from "prompts";
2
2
  import { AnyValue } from "../types/auto.js";
3
+ export declare const WORKING_FOLDER: string;
3
4
  export declare const CONFIG_FILE: string;
4
- export declare const TEMPLATES_FOLDER: string;
5
- export declare const TEMPLATE_MODEL_FOLDER: string;
6
5
  export declare const DICTIONARY_FOLDER: string;
7
- export declare const WORKING_FOLDER: string;
8
6
  export declare const filterJson: (fullPath: string) => boolean;
9
7
  export declare const filterDirectory: (fullPath: string) => boolean;
10
8
  export declare const filterFiles: (fullPath: string) => boolean;
@@ -22,6 +20,8 @@ export declare function titlesToChoices(list: string[], titleToValue?: (title: s
22
20
  }[];
23
21
  export declare function getDataFromPackage(): Record<string, string>;
24
22
  export declare function findChoicesPosition(choices: Choice[], value: string): number;
23
+ export declare function getFilesInFolders(folders: string[], filter: (fullPath: string) => boolean, recursive?: boolean, ignoreList?: string[]): string[];
24
+ export declare function getModelFolders(subfolder: string): string[];
25
25
  export declare function createConfigurationFile(taskName?: string): Promise<boolean>;
26
26
  export declare function getConfigFile(file: string, variable: string, defaultValue: AnyValue): any;
27
27
  export declare function getConfig(variable: string, defaultValue: AnyValue): any;
@@ -52,4 +52,4 @@ export declare function searchInFolderHierarchy(element: string, parentFolder: s
52
52
  export declare function getFiles(source: string, filter?: (file: string) => boolean, recursive?: boolean, ignoreList?: string[]): string[];
53
53
  export declare function convertNameToKey(name: string): string;
54
54
  export declare function convertKeyToName(key: string): string;
55
- export declare function readJsonSync(filename: string): prompts.Choice[];
55
+ export declare function readJsonSync<T>(filename: string): T;
@@ -12,12 +12,10 @@ import { fileURLToPath } from 'url';
12
12
  import prompts from "prompts";
13
13
  import context, { ProjectServices, GitServices } from "./context.js";
14
14
  import { logInfo, logWarning } from "./color.js";
15
- const COMMAND_FOLDER = searchInFolderHierarchy('commands', fileURLToPath(import.meta.url));
16
- export const CONFIG_FILE = searchInFolderHierarchy('.autoforce.json', fileURLToPath(import.meta.url));
17
- export const TEMPLATES_FOLDER = searchInFolderHierarchy('templates', fileURLToPath(import.meta.url));
18
- export const TEMPLATE_MODEL_FOLDER = TEMPLATES_FOLDER + '/' + getConfig('modelTemplates', 'modelA');
19
- export const DICTIONARY_FOLDER = TEMPLATE_MODEL_FOLDER + "/diccionarios";
15
+ const MODELS_FOLDER = searchInFolderHierarchy('models', fileURLToPath(import.meta.url));
20
16
  export const WORKING_FOLDER = process.env.INIT_CWD || ".";
17
+ export const CONFIG_FILE = searchInFolderHierarchy('.autoforce.json', WORKING_FOLDER);
18
+ export const DICTIONARY_FOLDER = process.cwd() + "/docs"; // context.dictionaryFolder;
21
19
  export const filterJson = (fullPath) => fullPath.endsWith(".json");
22
20
  export const filterDirectory = (fullPath) => fs.lstatSync(fullPath).isDirectory();
23
21
  export const filterFiles = (fullPath) => !fs.lstatSync(fullPath).isDirectory();
@@ -77,6 +75,27 @@ export function findChoicesPosition(choices, value) {
77
75
  const index = choices.findIndex(choice => choice.value === value);
78
76
  return index === -1 ? 0 : index;
79
77
  }
78
+ export function getFilesInFolders(folders, filter, recursive = false, ignoreList = []) {
79
+ const files = new Set();
80
+ for (const folder of folders) {
81
+ getFiles(folder, filter, recursive, ignoreList)
82
+ .forEach(file => files.add(file));
83
+ }
84
+ return Array.from(files);
85
+ }
86
+ export function getModelFolders(subfolder) {
87
+ const folder = [
88
+ `${MODELS_FOLDER}/dev/${context.devModel}/${subfolder}`,
89
+ `${MODELS_FOLDER}/git/${context.gitModel}/${subfolder}`,
90
+ `${MODELS_FOLDER}/doc/${context.docModel}/${subfolder}`,
91
+ `${MODELS_FOLDER}/project/${context.projectModel}/${subfolder}`,
92
+ ];
93
+ // Filter only folders that exists
94
+ return folder.filter(folder => fs.existsSync(folder));
95
+ }
96
+ function getTemplates(filter) {
97
+ return getFilesInFolders(getModelFolders('templates'), filter);
98
+ }
80
99
  function getTaskConfig(config) {
81
100
  return __awaiter(this, void 0, void 0, function* () {
82
101
  // TODO: Ver si esto se mueve a un config list
@@ -94,7 +113,7 @@ function getTaskConfig(config) {
94
113
  if (listFilter.filter === undefined)
95
114
  return;
96
115
  config.listFilter = listFilter.filter;
97
- const files = getFiles(`${TEMPLATES_FOLDER}/${config.modelTemplates}`, filterBash).map(filename => filename.split(".")[0]);
116
+ const files = getTemplates(filterBash).map(filename => filename.split(".")[0]);
98
117
  if (files.length > 0) {
99
118
  const templates = valuesToChoices(files);
100
119
  const template = yield prompts([
@@ -135,30 +154,20 @@ function getBaseConfig(config) {
135
154
  if (gitServices.git === GitServices.GitLab && !process.env.GITLAB_TOKEN) {
136
155
  logWarning('A fin de que la herramienta funcione debe configurar una variable de entorno GITLAB_TOKEN');
137
156
  }
138
- // Selecciona el modelo de automatizacion
139
- const models = readJsonSync(`${COMMAND_FOLDER}/models.json`);
140
- 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' });
141
- const automationModel = yield prompts([{
142
- type: "select",
143
- name: "model",
144
- message: "Elija un modelo de automatizacion",
145
- initial: findChoicesPosition(models, config.model),
146
- choices: models
147
- }]);
148
- if (automationModel.model === undefined)
149
- return;
150
- config.model = automationModel.model;
151
- // Si es custom pregunta si quiere tomar de base alguno existente
152
- if (automationModel.model === 'custom') {
153
- const baseModel = yield prompts([{
157
+ // Selecciona los modelos de automatizacion
158
+ for (const prefix of ['dev', 'git', 'doc', 'project']) {
159
+ const contextProperty = prefix + 'Model';
160
+ const models = readJsonSync(`${MODELS_FOLDER}/${prefix}/models.json`);
161
+ const automationModel = yield prompts([{
154
162
  type: "select",
155
163
  name: "model",
156
- message: "Quiere tomar algun modelo existente de base ? Este se copiara a la carpeta ",
157
- choices: models.concat([{ title: 'No quiero usar ningun modelo', value: 'none' }])
164
+ message: `Elija un modelo de automatizacion para ${prefix}`,
165
+ initial: findChoicesPosition(models, config[contextProperty]),
166
+ choices: models
158
167
  }]);
159
- if (baseModel.model !== 'none') {
160
- console.log('copy archivos..');
161
- }
168
+ if (automationModel.model === undefined)
169
+ return;
170
+ config[contextProperty] = automationModel.model;
162
171
  }
163
172
  // Gestion del Proyecto
164
173
  const projectChoices = [{ title: 'Github Projects', value: ProjectServices.GitHub }, { title: 'GitLab Projects', value: ProjectServices.GitLab }, { title: 'Jira', value: ProjectServices.Jira }, { title: 'None', value: ProjectServices.None }];
@@ -196,24 +205,12 @@ function getBaseConfig(config) {
196
205
  if (projectId.projectId === undefined)
197
206
  return;
198
207
  config.projectId = projectId.projectId;
199
- // Modelo de Dcumentacion
200
- const modelsTemplates = readJsonSync(`${TEMPLATES_FOLDER}/models.json`);
201
- const modelTemplates = yield prompts([{
202
- type: "select",
203
- name: "model",
204
- message: "Elija un modelo de documentacion",
205
- initial: findChoicesPosition(modelsTemplates, config.modelTemplates),
206
- choices: modelsTemplates
207
- }]);
208
- if (modelTemplates.model === undefined)
209
- return;
210
- config.modelTemplates = modelTemplates.model;
211
208
  return config;
212
209
  });
213
210
  }
214
211
  export function createConfigurationFile(taskName) {
215
212
  return __awaiter(this, void 0, void 0, function* () {
216
- const baseConfig = { backlogColumn: context.backlogColumn, model: context.model, modelTemplates: context.modelTemplates, gitServices: context.gitServices, projectServices: context.projectServices, projectId: context.projectId, listFilter: context.listFilter, listTemplate: context.listTemplate };
213
+ const baseConfig = { backlogColumn: context.backlogColumn, devModel: context.devModel, docModel: context.docModel, projectModel: context.projectModel, gitModel: context.gitModel, gitServices: context.gitServices, projectServices: context.projectServices, projectId: context.projectId, listFilter: context.listFilter, listTemplate: context.listTemplate };
217
214
  let config = taskName ? yield getTaskConfig(baseConfig) : yield getBaseConfig(baseConfig);
218
215
  if (!config)
219
216
  return false;
@@ -355,6 +352,10 @@ export function convertKeyToName(key) {
355
352
  }
356
353
  export function readJsonSync(filename) {
357
354
  const content = fs.readFileSync(filename, "utf8");
358
- const data = JSON.parse(content);
359
- return data;
355
+ try {
356
+ return JSON.parse(content);
357
+ }
358
+ catch (_a) {
359
+ throw new Error(`Verifique que el ${filename} sea json valido`);
360
+ }
360
361
  }
@@ -0,0 +1,19 @@
1
+ [
2
+ {
3
+ "title": "Salesforce con scratchs",
4
+ "value": "scratchs",
5
+ "default": true,
6
+ "description": "Desarrollos empresariales sobre Salesforce, usando una scracth para desarrollo de cada requerimiento"
7
+ },
8
+ {
9
+ "title": "Second Generation Packages con Scratch Orgs",
10
+ "value": "packages",
11
+ "description": "ISV o desarrollos de aplicaciones en Salesforce"
12
+ },
13
+ {
14
+ "title": "Paquetes de NPM",
15
+ "value": "npm",
16
+ "description": "Para herramientas complementarias como autoforce"
17
+ }
18
+ ]
19
+
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "title": "Procesos de Negocio en Salesforce",
4
+ "value": "processes",
5
+ "default": true,
6
+ "description": "Documentacion Tecnica de procesos de negocio en Salesforce"
7
+ }
8
+ ]
9
+
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "title": "Github flow branching model",
4
+ "value": "githubflow",
5
+ "default": true,
6
+ "description": "Cada feature se desarrolla en una feature branch y se mergea en main"
7
+ }
8
+ ]
9
+
@@ -0,0 +1,9 @@
1
+ [
2
+ {
3
+ "title": "Proyectos con releases",
4
+ "value": "github-releases",
5
+ "default": true,
6
+ "description": "Manejo de releases en Github proyects"
7
+ }
8
+ ]
9
+
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.17",
5
+ "version": "0.1.18",
6
6
  "keywords": [
7
7
  "Salesforce",
8
8
  "Automation",
@@ -15,8 +15,7 @@
15
15
  },
16
16
  "main": "./bin/index.js",
17
17
  "files": [
18
- "commands/**/*",
19
- "templates/**/*",
18
+ "models/**/*",
20
19
  "lib/**/*",
21
20
  ".autoforce.json",
22
21
  "bin/**/*"
@@ -1,24 +0,0 @@
1
- {
2
- "name": "issue",
3
- "guards": ["isGitApi"],
4
- "arguments": {
5
- "title": { "required": true },
6
- "label": {
7
- "type": "select",
8
- "values": "labels"
9
- },
10
- "milestone": {
11
- "type": "select",
12
- "values": "milestones"
13
- },
14
- "body": { "required": false }
15
- },
16
- "description": "Comando para crear un requerimiento nuevo",
17
- "steps": [
18
- {
19
- "name": "Crear un issue nuevo",
20
- "function": "createIssue",
21
- "arguments": ["${title}", "${label}", "${body}", "${milestone}"]
22
- }
23
- ]
24
- }
@@ -1,18 +0,0 @@
1
- [
2
- {
3
- "title": "Continious Delivery con Scratch Orgs",
4
- "value": "modelA",
5
- "description": "Github workflow pensado en soluciones para Clientes finales"
6
- },
7
- {
8
- "title": "Second Generation Packages con Scratch Orgs",
9
- "value": "modelB",
10
- "description": "Gitflow workflow pensado para ISV"
11
- },
12
- {
13
- "title": "Paquetes de NPM",
14
- "value": "modelC",
15
- "description": "Para herramientas complementarias como autoforce"
16
- }
17
- ]
18
-
@@ -1,4 +0,0 @@
1
- {{#each issues}}
2
- * #{{number}}: {{title}}
3
- {{milestone.title}}
4
- {{/each}}
@@ -1,8 +0,0 @@
1
- {{#with issue}}
2
- #{{number}}: {{title}}
3
- {{state}}
4
- {{#each labels}}{{this}}{{/each}}
5
- {{url}}
6
- {{milestone.title}}
7
- {{body}}
8
- {{/with}}
@@ -1,12 +0,0 @@
1
- [
2
- {
3
- "title": "Procesos de Negocio en Salesforce",
4
- "value": "modelA",
5
- "description": "Documenta Clases, Objetos y LWC a traves de procesos de negocios. Se basa en docusaurus"
6
- },
7
- {
8
- "title": "Proyecto simple en Github Docs",
9
- "value": "modelB",
10
- "description": "Github pages con changelog, readme y carpeta docs de Markdowns"
11
- }
12
- ]