autoforce 0.1.18 → 0.1.19

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.
@@ -1,14 +1,5 @@
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
1
  import { executeShell, getOrganizationObject, getCurrentOrganization, getBranchName, getTargetOrg } from "./taskFunctions.js";
11
- import { convertNameToKey, convertKeyToName, getFiles, filterDirectory, addNewItems, CONFIG_FILE, createConfigurationFile, getDataFromPackage } from "./util.js";
2
+ import { convertNameToKey, convertKeyToName, getFiles, filterDirectory, addNewItems, CONFIG_FILE, createConfigurationFile } from "./util.js";
12
3
  import { GitHubApi } from "./github-graphql.js";
13
4
  import { GitHubProjectApi } from "./github-project-graphql.js";
14
5
  import { GitLabApi } from "./gitlab-graphql.js";
@@ -37,64 +28,141 @@ export var ProjectServices;
37
28
  })(ProjectServices || (ProjectServices = {}));
38
29
  const filterProcesses = (fullPath) => fullPath.endsWith(".md"); // && !fullPath.endsWith("intro.md")
39
30
  const ISSUES_TYPES = [{ value: 'feature', title: 'feature' }, { value: 'bug', title: 'bug' }, { value: 'documentation', title: 'documentation' }, { value: 'automation', title: 'automation' }];
31
+ function searchInFolderHierarchy(element, parentFolder) {
32
+ if (fs.existsSync(`${parentFolder}/${element}`)) {
33
+ return `${parentFolder}/${element}`;
34
+ }
35
+ else {
36
+ const lastIndex = parentFolder.lastIndexOf('/');
37
+ if (lastIndex !== -1) {
38
+ const newParentFolder = parentFolder.substring(0, lastIndex);
39
+ if (newParentFolder !== '') {
40
+ return searchInFolderHierarchy(element, newParentFolder);
41
+ }
42
+ }
43
+ }
44
+ return '';
45
+ }
46
+ function getDataFromPackage() {
47
+ const data = {};
48
+ try {
49
+ const filename = searchInFolderHierarchy("package.json", process.cwd());
50
+ if (!filename) {
51
+ throw new Error("No se encontro el package.json en " + process.cwd());
52
+ }
53
+ const content = fs.readFileSync(filename, "utf8");
54
+ const packageJson = JSON.parse(content);
55
+ if (packageJson.repository) {
56
+ if (packageJson.repository.url) {
57
+ data.repositoryUrl = packageJson.repository.url;
58
+ data.repositoryType = packageJson.repository.type;
59
+ // Ver de sacar repo y owner
60
+ if (data.repositoryUrl) {
61
+ if (data.repositoryUrl.includes("github.com")) {
62
+ const repositoryArray = data.repositoryUrl.split('github.com/');
63
+ [data.repositoryOwner, data.repositoryRepo] = repositoryArray[1].split('/');
64
+ }
65
+ if (data.repositoryUrl.includes("gitlab.com")) {
66
+ const repositoryArray = data.repositoryUrl.split('gitlab.com/');
67
+ [data.repositoryOwner, data.repositoryRepo] = repositoryArray[1].split('/');
68
+ }
69
+ }
70
+ }
71
+ else if (typeof packageJson.repository === 'string') {
72
+ data.repositoryUrl = packageJson.repository;
73
+ const repositoryArray = data.repositoryUrl.split(':');
74
+ data.repositoryType = repositoryArray[0];
75
+ [data.repositoryOwner, data.repositoryRepo] = repositoryArray[1].split('/');
76
+ }
77
+ if (data.repositoryRepo && data.repositoryRepo.endsWith('.git')) {
78
+ data.repositoryRepo = data.repositoryRepo.replace('.git', '');
79
+ }
80
+ }
81
+ }
82
+ catch (error) {
83
+ console.log(error);
84
+ throw new Error(`Verifique que exista y sea valido el package.json`);
85
+ }
86
+ return data;
87
+ }
40
88
  class Context {
89
+ devModel; // Default Model de commands
90
+ gitModel;
91
+ docModel;
92
+ projectModel;
93
+ gitServices = GitServices.None;
94
+ isGitApi = false;
95
+ gitApi;
96
+ version;
97
+ dictionaryFolder = process.cwd() + "/docs";
98
+ options = {};
99
+ projectServices = ProjectServices.None;
100
+ isProjectApi = false;
101
+ projectApi;
102
+ sfInstalled = true;
103
+ sfToken = true;
104
+ branchName;
105
+ issueNumber;
106
+ issueType;
107
+ _process;
108
+ _processesHeader;
109
+ _newIssueNumber;
110
+ _newIssueType;
111
+ newBranchName;
112
+ defaultDias = 7;
113
+ permissionSet;
114
+ issueTitle;
115
+ isVerbose = false;
116
+ _scratch;
117
+ _branchScratch;
118
+ existNewBranch = false;
119
+ _targetOrg;
120
+ // Documentacion
121
+ processes;
122
+ // Ultima salida del shell
123
+ salida = '';
124
+ // Git Repository
125
+ repositoryUrl;
126
+ repositoryType;
127
+ repositoryOwner;
128
+ repositoryRepo;
129
+ // Project Reference
130
+ projectId;
131
+ backlogColumn = 'Todo';
132
+ //Templates especiales
133
+ listFilter = ListFilters.Mios;
134
+ listTemplate = 'openIssues';
41
135
  constructor() {
42
- this.gitServices = GitServices.None;
43
- this.isGitApi = false;
44
- this.dictionaryFolder = process.cwd() + "/docs";
45
- this.options = {};
46
- this.projectServices = ProjectServices.None;
47
- this.isProjectApi = false;
48
- this.sfInstalled = true;
49
- this.sfToken = true;
50
- this.defaultDias = 7;
51
- this.isVerbose = false;
52
- this.existNewBranch = false;
53
- // Ultima salida del shell
54
- this.salida = '';
55
- this.backlogColumn = 'Todo';
56
- //Templates especiales
57
- this.listFilter = ListFilters.Mios;
58
- this.listTemplate = 'openIssues';
59
136
  this.loadConfig();
60
137
  this.loadPackage();
61
138
  }
62
- labels() {
63
- return __awaiter(this, void 0, void 0, function* () {
64
- var _a;
65
- const choices = [{ value: '', title: 'Ninguno' }, { value: 'new', title: 'Nuevo' }];
66
- const labels = yield ((_a = this.gitApi) === null || _a === void 0 ? void 0 : _a.getLabels());
67
- if (labels) {
68
- labels.forEach(label => choices.push({ value: label.name, title: label.name }));
69
- }
70
- return choices;
71
- });
139
+ async labels() {
140
+ const choices = [{ value: '', title: 'Ninguno' }, { value: 'new', title: 'Nuevo' }];
141
+ const labels = await this.gitApi?.getLabels();
142
+ if (labels) {
143
+ labels.forEach(label => choices.push({ value: label.name, title: label.name }));
144
+ }
145
+ return choices;
72
146
  }
73
147
  listFilters() {
74
148
  const filters = [{ title: 'Solo mios abiertos', value: ListFilters.Mios, description: 'Busca los issues donde este asignado y esten en state Open' }, { title: 'Por Milestone', value: ListFilters.PorMilestone, description: 'Busca los issues de un deterinado milestone' }, { title: 'Por Label', value: ListFilters.PorLabel, description: 'Busca los issues de un deterinado label' }];
75
149
  return filters;
76
150
  }
77
- milestoneNumbers() {
78
- return __awaiter(this, void 0, void 0, function* () {
79
- var _a;
80
- const choices = [{ value: '', title: 'Ninguno' }];
81
- const milestones = yield ((_a = this.gitApi) === null || _a === void 0 ? void 0 : _a.getMilestones());
82
- if (milestones) {
83
- milestones.forEach(milestone => choices.push({ value: milestone.number, title: milestone.title }));
84
- }
85
- return choices;
86
- });
151
+ async milestoneNumbers() {
152
+ const choices = [{ value: '', title: 'Ninguno' }];
153
+ const milestones = await this.gitApi?.getMilestones();
154
+ if (milestones) {
155
+ milestones.forEach(milestone => choices.push({ value: milestone.number, title: milestone.title }));
156
+ }
157
+ return choices;
87
158
  }
88
- milestones() {
89
- return __awaiter(this, void 0, void 0, function* () {
90
- var _a;
91
- const choices = [{ value: '', title: 'Ninguno' }, { value: 'new', title: 'Nuevo' }];
92
- const milestones = yield ((_a = this.gitApi) === null || _a === void 0 ? void 0 : _a.getMilestones());
93
- if (milestones) {
94
- milestones.forEach(milestone => choices.push({ value: milestone.id, title: milestone.title }));
95
- }
96
- return choices;
97
- });
159
+ async milestones() {
160
+ const choices = [{ value: '', title: 'Ninguno' }, { value: 'new', title: 'Nuevo' }];
161
+ const milestones = await this.gitApi?.getMilestones();
162
+ if (milestones) {
163
+ milestones.forEach(milestone => choices.push({ value: milestone.id, title: milestone.title }));
164
+ }
165
+ return choices;
98
166
  }
99
167
  loadProjectApi() {
100
168
  if (!this.isProjectApi) {
@@ -166,37 +234,35 @@ class Context {
166
234
  this.repositoryOwner = data.repositoryOwner;
167
235
  this.repositoryRepo = data.repositoryRepo;
168
236
  }
169
- loadConfig() {
170
- return __awaiter(this, void 0, void 0, function* () {
171
- if (!fs.existsSync(CONFIG_FILE)) {
172
- logWarning('Bienvenido! La herramienta Autoforce necesita un primer paso de configuracion antes de usarla.');
173
- logWarning('- Podes usar el asistente ejecutando npx autoforce config');
174
- logWarning('- Podes hacerlo manualmente leyendo la documentacion y creando .autoforce.json manualmente en el root del proyecto (https://sebastianclaros.github.io/autoforce/docs/configuracion)');
175
- const answer = yield prompts([
176
- {
177
- type: "confirm",
178
- name: "asistente",
179
- message: "Queres ejecutar el asistente ahora?"
180
- }
181
- ]);
182
- if (answer.asistente) {
183
- yield createConfigurationFile();
184
- return true;
185
- }
186
- return false;
187
- }
188
- const content = fs.readFileSync(CONFIG_FILE, "utf8");
189
- try {
190
- const config = JSON.parse(content);
191
- for (const key in config) {
192
- this.set(key, config[key]);
237
+ async loadConfig() {
238
+ if (!fs.existsSync(CONFIG_FILE)) {
239
+ logWarning('Bienvenido! La herramienta Autoforce necesita un primer paso de configuracion antes de usarla.');
240
+ logWarning('- Podes usar el asistente ejecutando npx autoforce config');
241
+ logWarning('- Podes hacerlo manualmente leyendo la documentacion y creando .autoforce.json manualmente en el root del proyecto (https://sebastianclaros.github.io/autoforce/docs/configuracion)');
242
+ const answer = await prompts([
243
+ {
244
+ type: "confirm",
245
+ name: "asistente",
246
+ message: "Queres ejecutar el asistente ahora?"
193
247
  }
248
+ ]);
249
+ if (answer.asistente) {
250
+ await createConfigurationFile();
251
+ return true;
194
252
  }
195
- catch (_a) {
196
- throw new Error(`Verifique que el ${CONFIG_FILE} sea json valido`);
253
+ return false;
254
+ }
255
+ const content = fs.readFileSync(CONFIG_FILE, "utf8");
256
+ try {
257
+ const config = JSON.parse(content);
258
+ for (const key in config) {
259
+ this.set(key, config[key]);
197
260
  }
198
- return true;
199
- });
261
+ }
262
+ catch {
263
+ throw new Error(`Verifique que el ${CONFIG_FILE} sea json valido`);
264
+ }
265
+ return true;
200
266
  }
201
267
  init() {
202
268
  this.loadProjectApi();
@@ -245,7 +311,7 @@ class Context {
245
311
  config.processes = processes;
246
312
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
247
313
  }
248
- catch (_a) {
314
+ catch {
249
315
  throw new Error(`No se pudo guardar la metadata`);
250
316
  }
251
317
  }
@@ -259,7 +325,7 @@ class Context {
259
325
  for (const filename of filenames) {
260
326
  const header = this.getProcessHeader(fullpath + "/" + filename);
261
327
  if (header.process) {
262
- this._processesHeader[header.process] = Object.assign(Object.assign({}, header), { folder: fullpath, filename });
328
+ this._processesHeader[header.process] = { ...header, folder: fullpath, filename };
263
329
  }
264
330
  }
265
331
  }
@@ -277,7 +343,11 @@ class Context {
277
343
  const header = this.getProcessHeader(fullpath + "/" + process);
278
344
  const processKey = convertNameToKey(header.slug || header.title || process);
279
345
  if (this.processes && this.processes[processKey]) {
280
- retArray.push(Object.assign({ folder, name: convertKeyToName(processKey) }, this.processes[processKey]));
346
+ retArray.push({
347
+ folder,
348
+ name: convertKeyToName(processKey),
349
+ ...this.processes[processKey]
350
+ });
281
351
  }
282
352
  }
283
353
  }
@@ -298,23 +368,21 @@ class Context {
298
368
  }
299
369
  return this._scratch;
300
370
  }
301
- validate(guards) {
302
- return __awaiter(this, void 0, void 0, function* () {
303
- for (const guard of guards) {
304
- // Chequeo de variables de entorno
305
- if (guard[0] === '$') {
306
- if (!process.env[guard.substring(1)]) {
307
- throw new Error(`La variable de entorno ${guard} no esta configurada.`);
308
- }
371
+ async validate(guards) {
372
+ for (const guard of guards) {
373
+ // Chequeo de variables de entorno
374
+ if (guard[0] === '$') {
375
+ if (!process.env[guard.substring(1)]) {
376
+ throw new Error(`La variable de entorno ${guard} no esta configurada.`);
309
377
  }
310
- else {
311
- const value = yield this.get(guard);
312
- if (!value) {
313
- throw new Error(`No se encontro la variable ${guard} en el contexto. Ejecute yarn auto config o lea el index.md para mas informacion.`);
314
- }
378
+ }
379
+ else {
380
+ const value = await this.get(guard);
381
+ if (!value) {
382
+ throw new Error(`No se encontro la variable ${guard} en el contexto. Ejecute yarn auto config o lea el index.md para mas informacion.`);
315
383
  }
316
384
  }
317
- });
385
+ }
318
386
  }
319
387
  issueFromBranch(branchName) {
320
388
  const branchSplit = branchName.split("/");
@@ -366,31 +434,27 @@ class Context {
366
434
  this.existNewBranch = typeof salida === 'string' && (salida.includes(this.newBranchName));
367
435
  }
368
436
  }
369
- askFornewBranchName() {
370
- return __awaiter(this, void 0, void 0, function* () {
371
- if (!this.newBranchName) {
372
- if (!this.newIssueType) {
373
- this.newIssueType = yield this.askFornewIssueType();
374
- }
375
- if (!this.newIssueNumber) {
376
- this.newIssueNumber = yield this.askFornewIssueNumber();
377
- }
378
- this.setNewBranchName();
437
+ async askFornewBranchName() {
438
+ if (!this.newBranchName) {
439
+ if (!this.newIssueType) {
440
+ this.newIssueType = await this.askFornewIssueType();
379
441
  }
380
- return this.newBranchName;
381
- });
442
+ if (!this.newIssueNumber) {
443
+ this.newIssueNumber = await this.askFornewIssueNumber();
444
+ }
445
+ this.setNewBranchName();
446
+ }
447
+ return this.newBranchName;
382
448
  }
383
- askFornewIssueNumber() {
384
- return __awaiter(this, void 0, void 0, function* () {
385
- const answer = yield prompts([
386
- {
387
- type: "text",
388
- name: "newIssueNumber",
389
- message: "Por favor ingrese el nuevo issueNumber?"
390
- }
391
- ]);
392
- return answer.newIssueNumber;
393
- });
449
+ async askFornewIssueNumber() {
450
+ const answer = await prompts([
451
+ {
452
+ type: "text",
453
+ name: "newIssueNumber",
454
+ message: "Por favor ingrese el nuevo issueNumber?"
455
+ }
456
+ ]);
457
+ return answer.newIssueNumber;
394
458
  }
395
459
  set process(value) {
396
460
  this._process = value;
@@ -412,83 +476,78 @@ class Context {
412
476
  }
413
477
  return this._process;
414
478
  }
415
- askForprocess() {
416
- return __awaiter(this, void 0, void 0, function* () {
417
- if (this.projectApi && !this.issueTitle && this.issueNumber) {
418
- const issue = yield this.projectApi.getIssue(this.issueNumber);
419
- this.issueTitle = issue.title;
420
- }
421
- if (this.issueTitle) {
422
- const process = this.getProcessFromTitle(this.issueTitle);
423
- if (process && this.processesHeader[process]) {
424
- return process;
425
- }
479
+ async askForprocess() {
480
+ if (this.projectApi && !this.issueTitle && this.issueNumber) {
481
+ const issue = await this.projectApi.getIssue(this.issueNumber);
482
+ this.issueTitle = issue.title;
483
+ }
484
+ if (this.issueTitle) {
485
+ const process = this.getProcessFromTitle(this.issueTitle);
486
+ if (process && this.processesHeader[process]) {
487
+ return process;
426
488
  }
427
- const choices = Object.values(this.processesHeader).map(header => {
428
- return { value: header.process, title: header.title };
429
- });
430
- const answer = yield prompts([{
431
- type: "select",
432
- name: "process",
433
- message: "Por favor seleccione el proceso",
434
- choices
435
- }]);
436
- return answer.process;
489
+ }
490
+ const choices = Object.values(this.processesHeader).map(header => {
491
+ return { value: header.process, title: header.title };
437
492
  });
438
- }
439
- askFornewIssueType() {
440
- return __awaiter(this, void 0, void 0, function* () {
441
- const answer = yield prompts([
442
- {
443
- type: "list",
444
- name: "newIssueType",
445
- initial: "feature",
446
- message: "Por favor ingrese el type del issue?",
447
- choices: ISSUES_TYPES
493
+ const answer = await prompts([{
494
+ type: "select",
495
+ name: "process",
496
+ message: "Por favor seleccione el proceso",
497
+ choices
498
+ }]);
499
+ return answer.process;
500
+ }
501
+ async askFornewIssueType() {
502
+ const answer = await prompts([
503
+ {
504
+ type: "list",
505
+ name: "newIssueType",
506
+ initial: "feature",
507
+ message: "Por favor ingrese el type del issue?",
508
+ choices: ISSUES_TYPES
509
+ }
510
+ ]);
511
+ return answer.newIssueType;
512
+ }
513
+ async convertToArrayOfInputs(inputs) {
514
+ let inputsArray = [];
515
+ if (Array.isArray(inputs)) {
516
+ // Si viene los args como ['name1', 'names] lo convierte a [{name: 'name1'}, {name: 'name2'}]
517
+ inputsArray = inputs.map(input => { return { name: input, type: 'text', message: `Por favor ingrese ${input}?` }; });
518
+ }
519
+ else {
520
+ // Si viene args como objeto { name1: {...}, name2: {...}} lo convierte a [{name: name1...}, {name: name2...}]
521
+ for (const key in inputs) {
522
+ if (typeof inputs[key].default === 'string') {
523
+ inputs[key].initial = this.merge(inputs[key].default);
448
524
  }
449
- ]);
450
- return answer.newIssueType;
451
- });
452
- }
453
- convertToArrayOfInputs(inputs) {
454
- return __awaiter(this, void 0, void 0, function* () {
455
- let inputsArray = [];
456
- if (Array.isArray(inputs)) {
457
- // Si viene los args como ['name1', 'names] lo convierte a [{name: 'name1'}, {name: 'name2'}]
458
- inputsArray = inputs.map(input => { return { name: input, type: 'text', message: `Por favor ingrese ${input}?` }; });
459
- }
460
- else {
461
- // Si viene args como objeto { name1: {...}, name2: {...}} lo convierte a [{name: name1...}, {name: name2...}]
462
- for (const key in inputs) {
463
- if (typeof inputs[key].default == 'string') {
464
- inputs[key].initial = this.merge(inputs[key].default);
465
- }
466
- if (typeof inputs[key].values == 'string' && typeof this[inputs[key].values] == 'function') {
467
- const choices = yield this[inputs[key].values]();
525
+ if (typeof inputs[key].values === 'string') {
526
+ const methodName = inputs[key].values;
527
+ if (typeof this[methodName] === 'function') {
528
+ const choices = await this[methodName]();
468
529
  if (Array.isArray(choices)) {
469
530
  inputs[key].choices = choices;
470
531
  }
471
532
  }
472
- inputsArray.push(Object.assign({ name: key, type: 'text', message: `Por favor ingrese ${key}?` }, inputs[key]));
473
- }
474
- }
475
- return inputsArray;
476
- });
477
- }
478
- askForExit() {
479
- return __awaiter(this, void 0, void 0, function* () {
480
- const answer = yield prompts([
481
- {
482
- type: "confirm",
483
- name: "exit",
484
- initial: true,
485
- message: "Desea salir?"
486
533
  }
487
- ]);
488
- if (answer.exit) {
489
- process.exit(-1);
534
+ inputsArray.push({ ...{ name: key, type: 'text', message: `Por favor ingrese ${key}?` }, ...inputs[key] });
490
535
  }
491
- });
536
+ }
537
+ return inputsArray;
538
+ }
539
+ async askForExit() {
540
+ const answer = await prompts([
541
+ {
542
+ type: "confirm",
543
+ name: "exit",
544
+ initial: true,
545
+ message: "Desea salir?"
546
+ }
547
+ ]);
548
+ if (answer.exit) {
549
+ process.exit(-1);
550
+ }
492
551
  }
493
552
  mergeArgs(args) {
494
553
  if (Array.isArray(args)) {
@@ -509,18 +568,16 @@ class Context {
509
568
  }
510
569
  throw new Error(`Los argumentos ${args} son incompatibles para el merge`);
511
570
  }
512
- askForArguments(inputs) {
513
- return __awaiter(this, void 0, void 0, function* () {
514
- // unifica los dos tipos de inputs (array y objeto) en un array de inputs
515
- const inputsArray = yield this.convertToArrayOfInputs(inputs);
516
- for (const input of inputsArray) {
517
- const hasValue = yield this.get(input.name);
518
- if (!hasValue) {
519
- const answer = yield prompts([input], { onCancel: this.askForExit });
520
- this[input.name] = answer[input.name];
521
- }
571
+ async askForArguments(inputs) {
572
+ // unifica los dos tipos de inputs (array y objeto) en un array de inputs
573
+ const inputsArray = await this.convertToArrayOfInputs(inputs);
574
+ for (const input of inputsArray) {
575
+ const hasValue = await this.get(input.name);
576
+ if (!hasValue) {
577
+ const answer = await prompts([input], { onCancel: this.askForExit });
578
+ this[input.name] = answer[input.name];
522
579
  }
523
- });
580
+ }
524
581
  }
525
582
  setObject(obj) {
526
583
  for (const field in obj) {
@@ -531,31 +588,29 @@ class Context {
531
588
  try {
532
589
  this[key] = value;
533
590
  }
534
- catch (_a) {
591
+ catch {
535
592
  throw new Error(`No se puede setear el ${key} con el valor ${value} en context`);
536
593
  }
537
594
  }
538
595
  // Devuelve el valor o hace un askFor si esta vacio
539
- get(key) {
540
- return __awaiter(this, void 0, void 0, function* () {
541
- try {
542
- const value = this[key];
543
- if (!value) {
544
- const askForMethod = 'askFor' + key;
545
- if (this[askForMethod] && typeof this[askForMethod] == 'function') {
546
- this[key] = yield this[askForMethod]();
547
- }
596
+ async get(key) {
597
+ try {
598
+ const value = this[key];
599
+ if (!value) {
600
+ const askForMethod = 'askFor' + key;
601
+ if (this[askForMethod] && typeof this[askForMethod] == 'function') {
602
+ this[key] = await this[askForMethod]();
548
603
  }
549
- return this[key];
550
604
  }
551
- catch (_a) {
552
- throw new Error(`No se puedo obtener la propiedad ${key} en context`);
553
- }
554
- });
605
+ return this[key];
606
+ }
607
+ catch {
608
+ throw new Error(`No se puedo obtener la propiedad ${key} en context`);
609
+ }
555
610
  }
556
611
  merge(text) {
557
612
  if (typeof text != 'string' || text.indexOf('${') === -1) {
558
- return text;
613
+ return text || '';
559
614
  }
560
615
  const matches = text.matchAll(/\$\{([^}]+)}/g);
561
616
  // si no tiene para merge