@promptbook/cli 0.47.0 → 0.48.0-1

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 (46) hide show
  1. package/README.md +12 -1
  2. package/esm/index.es.js +449 -363
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/_packages/core.index.d.ts +2 -1
  5. package/esm/typings/_packages/utils.index.d.ts +2 -1
  6. package/esm/typings/conversion/prettify/prettifyPromptbookStringCli.d.ts +1 -1
  7. package/esm/typings/conversion/promptbookJsonToString.d.ts +8 -0
  8. package/esm/typings/conversion/utils/titleToName.d.ts +4 -0
  9. package/esm/typings/conversion/utils/titleToName.test.d.ts +1 -0
  10. package/esm/typings/execution/ExecutionTools.d.ts +1 -1
  11. package/esm/typings/execution/LlmExecutionTools.d.ts +1 -0
  12. package/esm/typings/execution/plugins/llm-execution-tools/langtail/LangtailExecutionTools.d.ts +1 -1
  13. package/esm/typings/execution/plugins/llm-execution-tools/openai/OpenAiExecutionTools.d.ts +1 -1
  14. package/esm/typings/execution/plugins/llm-execution-tools/openai/computeOpenaiUsage.d.ts +4 -1
  15. package/esm/typings/execution/plugins/llm-execution-tools/remote/RemoteLlmExecutionTools.d.ts +1 -0
  16. package/esm/typings/library/SimplePromptbookLibrary.d.ts +2 -1
  17. package/esm/typings/library/constructors/createPromptbookLibraryFromDirectory.d.ts +10 -1
  18. package/esm/typings/library/constructors/createPromptbookLibraryFromPromise.d.ts +20 -1
  19. package/esm/typings/library/constructors/createPromptbookLibraryFromSources.d.ts +5 -6
  20. package/esm/typings/library/constructors/createPromptbookLibraryFromUrl.d.ts +13 -0
  21. package/esm/typings/library/constructors/createPromptbookSublibrary.d.ts +10 -1
  22. package/esm/typings/utils/markdown/extractOneBlockFromMarkdown.d.ts +1 -1
  23. package/package.json +2 -2
  24. package/umd/index.umd.js +449 -363
  25. package/umd/index.umd.js.map +1 -1
  26. package/umd/typings/_packages/core.index.d.ts +2 -1
  27. package/umd/typings/_packages/utils.index.d.ts +2 -1
  28. package/umd/typings/conversion/prettify/prettifyPromptbookStringCli.d.ts +1 -1
  29. package/umd/typings/conversion/promptbookJsonToString.d.ts +8 -0
  30. package/umd/typings/conversion/utils/titleToName.d.ts +4 -0
  31. package/umd/typings/conversion/utils/titleToName.test.d.ts +1 -0
  32. package/umd/typings/execution/ExecutionTools.d.ts +1 -1
  33. package/umd/typings/execution/LlmExecutionTools.d.ts +1 -0
  34. package/umd/typings/execution/plugins/llm-execution-tools/langtail/LangtailExecutionTools.d.ts +1 -1
  35. package/umd/typings/execution/plugins/llm-execution-tools/openai/OpenAiExecutionTools.d.ts +1 -1
  36. package/umd/typings/execution/plugins/llm-execution-tools/openai/computeOpenaiUsage.d.ts +4 -1
  37. package/umd/typings/execution/plugins/llm-execution-tools/remote/RemoteLlmExecutionTools.d.ts +1 -0
  38. package/umd/typings/library/SimplePromptbookLibrary.d.ts +2 -1
  39. package/umd/typings/library/constructors/createPromptbookLibraryFromDirectory.d.ts +10 -1
  40. package/umd/typings/library/constructors/createPromptbookLibraryFromPromise.d.ts +20 -1
  41. package/umd/typings/library/constructors/createPromptbookLibraryFromSources.d.ts +5 -6
  42. package/umd/typings/library/constructors/createPromptbookLibraryFromUrl.d.ts +13 -0
  43. package/umd/typings/library/constructors/createPromptbookSublibrary.d.ts +10 -1
  44. package/umd/typings/utils/markdown/extractOneBlockFromMarkdown.d.ts +1 -1
  45. package/esm/typings/library/constructors/createPromptbookLibraryFromList.d.ts +0 -5
  46. package/umd/typings/library/constructors/createPromptbookLibraryFromList.d.ts +0 -5
package/umd/index.umd.js CHANGED
@@ -146,7 +146,86 @@
146
146
  /**
147
147
  * The version of the Promptbook library
148
148
  */
149
- var PROMPTBOOK_VERSION = '0.47.0-0';
149
+ var PROMPTBOOK_VERSION = '0.48.0-0';
150
+
151
+ /**
152
+ * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
153
+ */
154
+ var PromptbookSyntaxError = /** @class */ (function (_super) {
155
+ __extends(PromptbookSyntaxError, _super);
156
+ function PromptbookSyntaxError(message) {
157
+ var _this = _super.call(this, message) || this;
158
+ _this.name = 'PromptbookSyntaxError';
159
+ Object.setPrototypeOf(_this, PromptbookSyntaxError.prototype);
160
+ return _this;
161
+ }
162
+ return PromptbookSyntaxError;
163
+ }(Error));
164
+
165
+ /**
166
+ * Supported script languages
167
+ */
168
+ var SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
169
+
170
+ /**
171
+ * Parses the template and returns the list of all parameter names
172
+ *
173
+ * @param template the template with parameters in {curly} braces
174
+ * @returns the list of parameter names
175
+ *
176
+ * @private within the library
177
+ */
178
+ function extractParameters(template) {
179
+ var e_1, _a;
180
+ var matches = template.matchAll(/{\w+}/g);
181
+ var parameterNames = [];
182
+ try {
183
+ for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
184
+ var match = matches_1_1.value;
185
+ var parameterName = match[0].slice(1, -1);
186
+ if (!parameterNames.includes(parameterName)) {
187
+ parameterNames.push(parameterName);
188
+ }
189
+ }
190
+ }
191
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
192
+ finally {
193
+ try {
194
+ if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
195
+ }
196
+ finally { if (e_1) throw e_1.error; }
197
+ }
198
+ return parameterNames;
199
+ }
200
+
201
+ /**
202
+ * Computes the deepness of the markdown structure.
203
+ *
204
+ * @private within the library
205
+ */
206
+ function countMarkdownStructureDeepness(markdownStructure) {
207
+ var e_1, _a;
208
+ var maxDeepness = 0;
209
+ try {
210
+ for (var _b = __values(markdownStructure.sections), _c = _b.next(); !_c.done; _c = _b.next()) {
211
+ var section = _c.value;
212
+ maxDeepness = Math.max(maxDeepness, countMarkdownStructureDeepness(section));
213
+ }
214
+ }
215
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
216
+ finally {
217
+ try {
218
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
219
+ }
220
+ finally { if (e_1) throw e_1.error; }
221
+ }
222
+ return maxDeepness + 1;
223
+ }
224
+
225
+ /**
226
+ * The maximum number of iterations for a loops
227
+ */
228
+ var LOOP_LIMIT = 1000;
150
229
 
151
230
  /**
152
231
  * This error type indicates that the error should not happen and its last check before crashing with some other error
@@ -162,6 +241,301 @@
162
241
  return UnexpectedError;
163
242
  }(Error));
164
243
 
244
+ /**
245
+ * Parse a markdown string into a MarkdownStructure object.
246
+ *
247
+ * Note: This function does work with code blocks
248
+ * Note: This function does not work with markdown comments
249
+ *
250
+ * @param markdown The markdown string to parse.
251
+ * @returns The MarkdownStructure object.
252
+ *
253
+ * @private within the library
254
+ */
255
+ function markdownToMarkdownStructure(markdown) {
256
+ var e_1, _a;
257
+ var lines = markdown.split('\n');
258
+ var root = { level: 0, title: '', contentLines: [], sections: [], parent: null };
259
+ var current = root;
260
+ var isInsideCodeBlock = false;
261
+ try {
262
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
263
+ var line = lines_1_1.value;
264
+ var headingMatch = line.match(/^(?<mark>#{1,6})\s(?<title>.*)/);
265
+ if (isInsideCodeBlock || !headingMatch) {
266
+ if (line.startsWith('```')) {
267
+ isInsideCodeBlock = !isInsideCodeBlock;
268
+ }
269
+ current.contentLines.push(line);
270
+ }
271
+ else {
272
+ var level = headingMatch.groups.mark.length;
273
+ var title = headingMatch.groups.title.trim();
274
+ var parent_1 = void 0;
275
+ if (level > current.level) {
276
+ // Note: Going deeper (next section is child of current)
277
+ parent_1 = current;
278
+ }
279
+ else {
280
+ // Note: Going up or staying at the same level (next section is sibling or parent or grandparent,... of current)
281
+ parent_1 = current;
282
+ var loopLimit = LOOP_LIMIT;
283
+ while (parent_1.level !== level - 1) {
284
+ if (loopLimit-- < 0) {
285
+ throw new UnexpectedError('Loop limit reached during parsing of markdown structure in `markdownToMarkdownStructure`');
286
+ }
287
+ if (parent_1.parent === null /* <- Note: We are in root */) {
288
+ // [🌻]
289
+ throw new Error(spacetrim.spaceTrim("\n The file has an invalid structure.\n The markdown file must have exactly one top-level section.\n "));
290
+ }
291
+ parent_1 = parent_1.parent;
292
+ }
293
+ }
294
+ var section = { level: level, title: title, contentLines: [], sections: [], parent: parent_1 };
295
+ parent_1.sections.push(section);
296
+ current = section;
297
+ }
298
+ }
299
+ }
300
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
301
+ finally {
302
+ try {
303
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
304
+ }
305
+ finally { if (e_1) throw e_1.error; }
306
+ }
307
+ if (root.sections.length === 1) {
308
+ var markdownStructure = parsingMarkdownStructureToMarkdownStructure(root.sections[0]);
309
+ return markdownStructure;
310
+ }
311
+ // [🌻]
312
+ throw new Error('The markdown file must have exactly one top-level section.');
313
+ // return root;
314
+ }
315
+ /**
316
+ * @private
317
+ */
318
+ function parsingMarkdownStructureToMarkdownStructure(parsingMarkdownStructure) {
319
+ var level = parsingMarkdownStructure.level, title = parsingMarkdownStructure.title, contentLines = parsingMarkdownStructure.contentLines, sections = parsingMarkdownStructure.sections;
320
+ return {
321
+ level: level,
322
+ title: title,
323
+ content: spacetrim.spaceTrim(contentLines.join('\n')),
324
+ sections: sections.map(parsingMarkdownStructureToMarkdownStructure),
325
+ };
326
+ }
327
+
328
+ /**
329
+ * Utility function to extract all list items from markdown
330
+ *
331
+ * Note: It works with both ul and ol
332
+ * Note: It omits list items in code blocks
333
+ * Note: It flattens nested lists
334
+ * Note: It can not work with html syntax and comments
335
+ *
336
+ * @param markdown any valid markdown
337
+ * @returns
338
+ */
339
+ function extractAllListItemsFromMarkdown(markdown) {
340
+ var e_1, _a;
341
+ var lines = markdown.split('\n');
342
+ var listItems = [];
343
+ var isInCodeBlock = false;
344
+ try {
345
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
346
+ var line = lines_1_1.value;
347
+ var trimmedLine = line.trim();
348
+ if (trimmedLine.startsWith('```')) {
349
+ isInCodeBlock = !isInCodeBlock;
350
+ }
351
+ if (!isInCodeBlock && (trimmedLine.startsWith('-') || trimmedLine.match(/^\d+\./))) {
352
+ var listItem = trimmedLine.replace(/^-|\d+\./, '').trim();
353
+ listItems.push(listItem);
354
+ }
355
+ }
356
+ }
357
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
358
+ finally {
359
+ try {
360
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
361
+ }
362
+ finally { if (e_1) throw e_1.error; }
363
+ }
364
+ return listItems;
365
+ }
366
+
367
+ /**
368
+ * Makes first letter of a string uppercase
369
+ *
370
+ */
371
+ function capitalize(word) {
372
+ return word.substring(0, 1).toUpperCase() + word.substring(1);
373
+ }
374
+
375
+ /**
376
+ * Extracts all code blocks from markdown.
377
+ *
378
+ * Note: There are 3 simmilar function:
379
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
380
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
381
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
382
+ *
383
+ * @param markdown any valid markdown
384
+ * @returns code blocks with language and content
385
+ *
386
+ */
387
+ function extractAllBlocksFromMarkdown(markdown) {
388
+ var e_1, _a;
389
+ var codeBlocks = [];
390
+ var lines = markdown.split('\n');
391
+ var currentCodeBlock = null;
392
+ try {
393
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
394
+ var line = lines_1_1.value;
395
+ if (line.startsWith('```')) {
396
+ var language = line.slice(3).trim() || null;
397
+ if (currentCodeBlock === null) {
398
+ currentCodeBlock = { language: language, content: '' };
399
+ }
400
+ else {
401
+ if (language !== null) {
402
+ // [🌻]
403
+ throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
404
+ }
405
+ codeBlocks.push(currentCodeBlock);
406
+ currentCodeBlock = null;
407
+ }
408
+ }
409
+ else if (currentCodeBlock !== null) {
410
+ if (currentCodeBlock.content !== '') {
411
+ currentCodeBlock.content += '\n';
412
+ }
413
+ currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
414
+ }
415
+ }
416
+ }
417
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
418
+ finally {
419
+ try {
420
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
421
+ }
422
+ finally { if (e_1) throw e_1.error; }
423
+ }
424
+ if (currentCodeBlock !== null) {
425
+ // [🌻]
426
+ throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
427
+ }
428
+ return codeBlocks;
429
+ }
430
+
431
+ /**
432
+ * Extracts exactly ONE code block from markdown.
433
+ *
434
+ * Note: If there are multiple or no code blocks the function throws an error
435
+ *
436
+ * Note: There are 3 simmilar function:
437
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
438
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
439
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
440
+ *
441
+ * @param markdown any valid markdown
442
+ * @returns code block with language and content
443
+ */
444
+ function extractOneBlockFromMarkdown(markdown) {
445
+ var codeBlocks = extractAllBlocksFromMarkdown(markdown);
446
+ if (codeBlocks.length !== 1) {
447
+ // TODO: Report more specific place where the error happened
448
+ throw new Error(/* <- [🌻] */ 'There should be exactly one code block in the markdown');
449
+ }
450
+ return codeBlocks[0];
451
+ }
452
+ /***
453
+ * TODO: [🍓][🌻] !!! Decide of this is internal util, external util OR validator/postprocessor
454
+ */
455
+
456
+ /**
457
+ * Removes HTML or Markdown comments from a string.
458
+ *
459
+ * @param {string} content - The string to remove comments from.
460
+ * @returns {string} The input string with all comments removed.
461
+ */
462
+ function removeContentComments(content) {
463
+ return spacetrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
464
+ }
465
+
466
+ /**
467
+ * Parses the given script and returns the list of all used variables that are not defined in the script
468
+ *
469
+ * @param script from which to extract the variables
470
+ * @returns the list of variable names
471
+ * @throws {PromptbookSyntaxError} if the script is invalid
472
+ *
473
+ * @private within the promptbookStringToJson
474
+ */
475
+ function extractVariables(script) {
476
+ var variables = [];
477
+ script = "(()=>{".concat(script, "})()");
478
+ try {
479
+ for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
480
+ try {
481
+ eval(script);
482
+ }
483
+ catch (error) {
484
+ if (!(error instanceof ReferenceError)) {
485
+ throw error;
486
+ }
487
+ var undefinedName = error.message.split(' ')[0];
488
+ /*
489
+ Note: Remapping error
490
+ From: [ReferenceError: thing is not defined],
491
+ To: [Error: Parameter {thing} is not defined],
492
+ */
493
+ if (!undefinedName) {
494
+ throw error;
495
+ }
496
+ if (script.includes(undefinedName + '(')) {
497
+ script = "const ".concat(undefinedName, " = ()=>'';") + script;
498
+ }
499
+ else {
500
+ variables.push(undefinedName);
501
+ script = "const ".concat(undefinedName, " = '';") + script;
502
+ }
503
+ }
504
+ }
505
+ catch (error) {
506
+ if (!(error instanceof Error)) {
507
+ throw error;
508
+ }
509
+ throw new PromptbookSyntaxError(spacetrim.spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
510
+ }
511
+ return variables;
512
+ }
513
+
514
+ /**
515
+ * Removes emojis from a string and fix whitespaces
516
+ *
517
+ * @param text with emojis
518
+ * @returns text without emojis
519
+ */
520
+ function removeEmojis(text) {
521
+ // Replace emojis (and also ZWJ sequence) with hyphens
522
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
523
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
524
+ text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
525
+ text = text.replace(/\p{Extended_Pictographic}/gu, '');
526
+ return text;
527
+ }
528
+
529
+ /**
530
+ * Function normalizes title to name which can be used as identifier
531
+ */
532
+ function titleToName(value) {
533
+ value = removeEmojis(value);
534
+ value = normalizeToKebabCase(value);
535
+ // TODO: [🧠] Maybe warn or add some padding to short name which are not good identifiers
536
+ return value;
537
+ }
538
+
165
539
  /**
166
540
  * Creates a Mermaid graph based on the promptbook
167
541
  *
@@ -180,7 +554,7 @@
180
554
  if (!template) {
181
555
  throw new Error("Could not find template for {".concat(parameterName, "}"));
182
556
  }
183
- return 'template' + normalizeTo_PascalCase(template.title);
557
+ return normalizeTo_camelCase('template-' + titleToName(template.title));
184
558
  };
185
559
  var promptbookMermaid = spacetrim.spaceTrim(function (block) { return "\n\n %% \uD83D\uDD2E Tip: Open this on GitHub or in the VSCode website to see the Mermaid graph visually\n\n flowchart LR\n subgraph \"".concat(promptbookJson.title, "\"\n\n direction TB\n\n input((Input)):::input\n ").concat(block(promptbookJson.promptTemplates
186
560
  .flatMap(function (_a) {
@@ -201,6 +575,7 @@
201
575
  return "".concat(parameterNameToTemplateName(name), "--\"{").concat(name, "}\"-->output");
202
576
  })
203
577
  .join('\n')), "\n output((Output)):::output\n\n classDef input color: grey;\n classDef output color: grey;\n\n end;\n\n "); });
578
+ // TODO: !!!!! Allow to put link callback into `renderPromptbookMermaid`
204
579
  return promptbookMermaid;
205
580
  }
206
581
  /**
@@ -208,20 +583,6 @@
208
583
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
209
584
  */
210
585
 
211
- /**
212
- * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
213
- */
214
- var PromptbookSyntaxError = /** @class */ (function (_super) {
215
- __extends(PromptbookSyntaxError, _super);
216
- function PromptbookSyntaxError(message) {
217
- var _this = _super.call(this, message) || this;
218
- _this.name = 'PromptbookSyntaxError';
219
- Object.setPrototypeOf(_this, PromptbookSyntaxError.prototype);
220
- return _this;
221
- }
222
- return PromptbookSyntaxError;
223
- }(Error));
224
-
225
586
  /**
226
587
  * Function parseNumber will parse number from string
227
588
  *
@@ -543,11 +904,10 @@
543
904
  var letters = defaultDiacriticsRemovalMap[i].letters;
544
905
  // tslint:disable-next-line: prefer-for-of
545
906
  for (var j = 0; j < letters.length; j++) {
546
- DIACRITIC_VARIANTS_LETTERS[letters[j]] =
547
- defaultDiacriticsRemovalMap[i].base;
907
+ DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;
548
908
  }
549
909
  }
550
- // <- TODO: !!!! Put to maker function
910
+ // <- TODO: [🍓] Put to maker function to save execution time if not needed
551
911
  /*
552
912
  @see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
553
913
  Licensed under the Apache License, Version 2.0 (the "License");
@@ -564,9 +924,14 @@
564
924
  */
565
925
 
566
926
  /**
567
- * The maximum number of iterations for a loops
927
+ *
568
928
  */
569
- var LOOP_LIMIT = 1000;
929
+ function removeDiacritics(input) {
930
+ /*eslint no-control-regex: "off"*/
931
+ return input.replace(/[^\u0000-\u007E]/g, function (a) {
932
+ return DIACRITIC_VARIANTS_LETTERS[a] || a;
933
+ });
934
+ }
570
935
 
571
936
  /**
572
937
  * This error occurs during the parameter replacement in the template
@@ -603,155 +968,17 @@
603
968
  arrowParens: 'always',
604
969
  printWidth: 120,
605
970
  htmlWhitespaceSensitivity: 'ignore',
606
- jsxBracketSameLine: false,
607
- bracketSpacing: true,
608
- });
609
- }
610
- catch (error) {
611
- console.error('There was an error with prettifying the markdown, using the original as the fallback', {
612
- error: error,
613
- html: html,
614
- });
615
- return html;
616
- }
617
- }
618
-
619
- /**
620
- * Makes first letter of a string uppercase
621
- *
622
- */
623
- function capitalize(word) {
624
- return word.substring(0, 1).toUpperCase() + word.substring(1);
625
- }
626
-
627
- /**
628
- * Extracts all code blocks from markdown.
629
- *
630
- * Note: There are 3 simmilar function:
631
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
632
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
633
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
634
- *
635
- * @param markdown any valid markdown
636
- * @returns code blocks with language and content
637
- *
638
- */
639
- function extractAllBlocksFromMarkdown(markdown) {
640
- var e_1, _a;
641
- var codeBlocks = [];
642
- var lines = markdown.split('\n');
643
- var currentCodeBlock = null;
644
- try {
645
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
646
- var line = lines_1_1.value;
647
- if (line.startsWith('```')) {
648
- var language = line.slice(3).trim() || null;
649
- if (currentCodeBlock === null) {
650
- currentCodeBlock = { language: language, content: '' };
651
- }
652
- else {
653
- if (language !== null) {
654
- // [🌻]
655
- throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
656
- }
657
- codeBlocks.push(currentCodeBlock);
658
- currentCodeBlock = null;
659
- }
660
- }
661
- else if (currentCodeBlock !== null) {
662
- if (currentCodeBlock.content !== '') {
663
- currentCodeBlock.content += '\n';
664
- }
665
- currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
666
- }
667
- }
668
- }
669
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
670
- finally {
671
- try {
672
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
673
- }
674
- finally { if (e_1) throw e_1.error; }
675
- }
676
- if (currentCodeBlock !== null) {
677
- // [🌻]
678
- throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
679
- }
680
- return codeBlocks;
681
- }
682
-
683
- /**
684
- * Utility function to extract all list items from markdown
685
- *
686
- * Note: It works with both ul and ol
687
- * Note: It omits list items in code blocks
688
- * Note: It flattens nested lists
689
- * Note: It can not work with html syntax and comments
690
- *
691
- * @param markdown any valid markdown
692
- * @returns
693
- */
694
- function extractAllListItemsFromMarkdown(markdown) {
695
- var e_1, _a;
696
- var lines = markdown.split('\n');
697
- var listItems = [];
698
- var isInCodeBlock = false;
699
- try {
700
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
701
- var line = lines_1_1.value;
702
- var trimmedLine = line.trim();
703
- if (trimmedLine.startsWith('```')) {
704
- isInCodeBlock = !isInCodeBlock;
705
- }
706
- if (!isInCodeBlock && (trimmedLine.startsWith('-') || trimmedLine.match(/^\d+\./))) {
707
- var listItem = trimmedLine.replace(/^-|\d+\./, '').trim();
708
- listItems.push(listItem);
709
- }
710
- }
711
- }
712
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
713
- finally {
714
- try {
715
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
716
- }
717
- finally { if (e_1) throw e_1.error; }
718
- }
719
- return listItems;
720
- }
721
-
722
- /**
723
- * Extracts exactly ONE code block from markdown.
724
- *
725
- * Note: If there are multiple or no code blocks the function throws an error
726
- *
727
- * Note: There are 3 simmilar function:
728
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
729
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
730
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
731
- *
732
- * @param markdown any valid markdown
733
- * @returns code block with language and content
734
- */
735
- function extractOneBlockFromMarkdown(markdown) {
736
- var codeBlocks = extractAllBlocksFromMarkdown(markdown);
737
- if (codeBlocks.length !== 1) {
738
- // TODO: Report more specific place where the error happened
739
- throw new Error(/* <- [🌻] */ 'There should be exactly one code block in the markdown');
971
+ jsxBracketSameLine: false,
972
+ bracketSpacing: true,
973
+ });
974
+ }
975
+ catch (error) {
976
+ console.error('There was an error with prettifying the markdown, using the original as the fallback', {
977
+ error: error,
978
+ html: html,
979
+ });
980
+ return html;
740
981
  }
741
- return codeBlocks[0];
742
- }
743
- /***
744
- * TODO: [🌻] !!! Decide of this is internal util, external util OR validator/postprocessor
745
- */
746
-
747
- /**
748
- * Removes HTML or Markdown comments from a string.
749
- *
750
- * @param {string} content - The string to remove comments from.
751
- * @returns {string} The input string with all comments removed.
752
- */
753
- function removeContentComments(content) {
754
- return spacetrim.spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
755
982
  }
756
983
 
757
984
  /**
@@ -835,11 +1062,11 @@
835
1062
  */
836
1063
 
837
1064
  /* tslint:disable */
838
- function normalizeTo_camelCase(sentence, __firstLetterCapital) {
1065
+ function normalizeToKebabCase(sentence) {
839
1066
  var e_1, _a;
840
- if (__firstLetterCapital === void 0) { __firstLetterCapital = false; }
1067
+ sentence = removeDiacritics(sentence);
841
1068
  var charType;
842
- var lastCharType = null;
1069
+ var lastCharType = 'OTHER';
843
1070
  var normalizedName = '';
844
1071
  try {
845
1072
  for (var sentence_1 = __values(sentence), sentence_1_1 = sentence_1.next(); !sentence_1_1.done; sentence_1_1 = sentence_1.next()) {
@@ -857,20 +1084,19 @@
857
1084
  charType = 'NUMBER';
858
1085
  normalizedChar = char;
859
1086
  }
1087
+ else if (/^\/$/.test(char)) {
1088
+ charType = 'SLASH';
1089
+ normalizedChar = char;
1090
+ }
860
1091
  else {
861
1092
  charType = 'OTHER';
862
- normalizedChar = '';
1093
+ normalizedChar = '-';
863
1094
  }
864
- if (!lastCharType) {
865
- if (__firstLetterCapital) {
866
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
867
- }
868
- }
869
- else if (charType !== lastCharType &&
870
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
1095
+ if (charType !== lastCharType &&
1096
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
871
1097
  !(lastCharType === 'NUMBER') &&
872
1098
  !(charType === 'NUMBER')) {
873
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
1099
+ normalizedName += '-';
874
1100
  }
875
1101
  normalizedName += normalizedChar;
876
1102
  lastCharType = charType;
@@ -883,207 +1109,67 @@
883
1109
  }
884
1110
  finally { if (e_1) throw e_1.error; }
885
1111
  }
1112
+ normalizedName = normalizedName.split(/-+/g).join('-');
1113
+ normalizedName = normalizedName.split(/-?\/-?/g).join('/');
1114
+ normalizedName = normalizedName.replace(/^-/, '');
1115
+ normalizedName = normalizedName.replace(/-$/, '');
886
1116
  return normalizedName;
887
1117
  }
888
- /**
889
- * TODO: [🌺] Use some intermediate util splitWords
890
- */
891
-
892
- function normalizeTo_PascalCase(sentence) {
893
- return normalizeTo_camelCase(sentence, true);
894
- }
895
-
896
- /**
897
- * Supported script languages
898
- */
899
- var SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
900
1118
 
901
- /**
902
- * Parses the template and returns the list of all parameter names
903
- *
904
- * @param template the template with parameters in {curly} braces
905
- * @returns the list of parameter names
906
- *
907
- * @private within the library
908
- */
909
- function extractParameters(template) {
1119
+ /* tslint:disable */
1120
+ function normalizeTo_camelCase(sentence, __firstLetterCapital) {
910
1121
  var e_1, _a;
911
- var matches = template.matchAll(/{\w+}/g);
912
- var parameterNames = [];
1122
+ if (__firstLetterCapital === void 0) { __firstLetterCapital = false; }
1123
+ var charType;
1124
+ var lastCharType = null;
1125
+ var normalizedName = '';
913
1126
  try {
914
- for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
915
- var match = matches_1_1.value;
916
- var parameterName = match[0].slice(1, -1);
917
- if (!parameterNames.includes(parameterName)) {
918
- parameterNames.push(parameterName);
1127
+ for (var sentence_1 = __values(sentence), sentence_1_1 = sentence_1.next(); !sentence_1_1.done; sentence_1_1 = sentence_1.next()) {
1128
+ var char = sentence_1_1.value;
1129
+ var normalizedChar = void 0;
1130
+ if (/^[a-z]$/.test(char)) {
1131
+ charType = 'LOWERCASE';
1132
+ normalizedChar = char;
919
1133
  }
920
- }
921
- }
922
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
923
- finally {
924
- try {
925
- if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
926
- }
927
- finally { if (e_1) throw e_1.error; }
928
- }
929
- return parameterNames;
930
- }
931
-
932
- /**
933
- * Computes the deepness of the markdown structure.
934
- *
935
- * @private within the library
936
- */
937
- function countMarkdownStructureDeepness(markdownStructure) {
938
- var e_1, _a;
939
- var maxDeepness = 0;
940
- try {
941
- for (var _b = __values(markdownStructure.sections), _c = _b.next(); !_c.done; _c = _b.next()) {
942
- var section = _c.value;
943
- maxDeepness = Math.max(maxDeepness, countMarkdownStructureDeepness(section));
944
- }
945
- }
946
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
947
- finally {
948
- try {
949
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
950
- }
951
- finally { if (e_1) throw e_1.error; }
952
- }
953
- return maxDeepness + 1;
954
- }
955
-
956
- /**
957
- * Parse a markdown string into a MarkdownStructure object.
958
- *
959
- * Note: This function does work with code blocks
960
- * Note: This function does not work with markdown comments
961
- *
962
- * @param markdown The markdown string to parse.
963
- * @returns The MarkdownStructure object.
964
- *
965
- * @private within the library
966
- */
967
- function markdownToMarkdownStructure(markdown) {
968
- var e_1, _a;
969
- var lines = markdown.split('\n');
970
- var root = { level: 0, title: '', contentLines: [], sections: [], parent: null };
971
- var current = root;
972
- var isInsideCodeBlock = false;
973
- try {
974
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
975
- var line = lines_1_1.value;
976
- var headingMatch = line.match(/^(?<mark>#{1,6})\s(?<title>.*)/);
977
- if (isInsideCodeBlock || !headingMatch) {
978
- if (line.startsWith('```')) {
979
- isInsideCodeBlock = !isInsideCodeBlock;
980
- }
981
- current.contentLines.push(line);
1134
+ else if (/^[A-Z]$/.test(char)) {
1135
+ charType = 'UPPERCASE';
1136
+ normalizedChar = char.toLowerCase();
1137
+ }
1138
+ else if (/^[0-9]$/.test(char)) {
1139
+ charType = 'NUMBER';
1140
+ normalizedChar = char;
982
1141
  }
983
1142
  else {
984
- var level = headingMatch.groups.mark.length;
985
- var title = headingMatch.groups.title.trim();
986
- var parent_1 = void 0;
987
- if (level > current.level) {
988
- // Note: Going deeper (next section is child of current)
989
- parent_1 = current;
990
- }
991
- else {
992
- // Note: Going up or staying at the same level (next section is sibling or parent or grandparent,... of current)
993
- parent_1 = current;
994
- var loopLimit = LOOP_LIMIT;
995
- while (parent_1.level !== level - 1) {
996
- if (loopLimit-- < 0) {
997
- throw new UnexpectedError('Loop limit reached during parsing of markdown structure in `markdownToMarkdownStructure`');
998
- }
999
- if (parent_1.parent === null /* <- Note: We are in root */) {
1000
- // [🌻]
1001
- throw new Error(spacetrim.spaceTrim("\n The file has an invalid structure.\n The markdown file must have exactly one top-level section.\n "));
1002
- }
1003
- parent_1 = parent_1.parent;
1004
- }
1143
+ charType = 'OTHER';
1144
+ normalizedChar = '';
1145
+ }
1146
+ if (!lastCharType) {
1147
+ if (__firstLetterCapital) {
1148
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
1005
1149
  }
1006
- var section = { level: level, title: title, contentLines: [], sections: [], parent: parent_1 };
1007
- parent_1.sections.push(section);
1008
- current = section;
1009
1150
  }
1151
+ else if (charType !== lastCharType &&
1152
+ !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
1153
+ !(lastCharType === 'NUMBER') &&
1154
+ !(charType === 'NUMBER')) {
1155
+ normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
1156
+ }
1157
+ normalizedName += normalizedChar;
1158
+ lastCharType = charType;
1010
1159
  }
1011
1160
  }
1012
1161
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
1013
1162
  finally {
1014
1163
  try {
1015
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
1164
+ if (sentence_1_1 && !sentence_1_1.done && (_a = sentence_1.return)) _a.call(sentence_1);
1016
1165
  }
1017
1166
  finally { if (e_1) throw e_1.error; }
1018
1167
  }
1019
- if (root.sections.length === 1) {
1020
- var markdownStructure = parsingMarkdownStructureToMarkdownStructure(root.sections[0]);
1021
- return markdownStructure;
1022
- }
1023
- // [🌻]
1024
- throw new Error('The markdown file must have exactly one top-level section.');
1025
- // return root;
1026
- }
1027
- /**
1028
- * @private
1029
- */
1030
- function parsingMarkdownStructureToMarkdownStructure(parsingMarkdownStructure) {
1031
- var level = parsingMarkdownStructure.level, title = parsingMarkdownStructure.title, contentLines = parsingMarkdownStructure.contentLines, sections = parsingMarkdownStructure.sections;
1032
- return {
1033
- level: level,
1034
- title: title,
1035
- content: spacetrim.spaceTrim(contentLines.join('\n')),
1036
- sections: sections.map(parsingMarkdownStructureToMarkdownStructure),
1037
- };
1168
+ return normalizedName;
1038
1169
  }
1039
-
1040
1170
  /**
1041
- * Parses the given script and returns the list of all used variables that are not defined in the script
1042
- *
1043
- * @param script from which to extract the variables
1044
- * @returns the list of variable names
1045
- * @throws {PromptbookSyntaxError} if the script is invalid
1046
- *
1047
- * @private within the promptbookStringToJson
1171
+ * TODO: [🌺] Use some intermediate util splitWords
1048
1172
  */
1049
- function extractVariables(script) {
1050
- var variables = [];
1051
- script = "(()=>{".concat(script, "})()");
1052
- try {
1053
- for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
1054
- try {
1055
- eval(script);
1056
- }
1057
- catch (error) {
1058
- if (!(error instanceof ReferenceError)) {
1059
- throw error;
1060
- }
1061
- var undefinedName = error.message.split(' ')[0];
1062
- /*
1063
- Note: Remapping error
1064
- From: [ReferenceError: thing is not defined],
1065
- To: [Error: Parameter {thing} is not defined],
1066
- */
1067
- if (!undefinedName) {
1068
- throw error;
1069
- }
1070
- if (script.includes(undefinedName + '(')) {
1071
- script = "const ".concat(undefinedName, " = ()=>'';") + script;
1072
- }
1073
- else {
1074
- variables.push(undefinedName);
1075
- script = "const ".concat(undefinedName, " = '';") + script;
1076
- }
1077
- }
1078
- }
1079
- catch (error) {
1080
- if (!(error instanceof Error)) {
1081
- throw error;
1082
- }
1083
- throw new PromptbookSyntaxError(spacetrim.spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
1084
- }
1085
- return variables;
1086
- }
1087
1173
 
1088
1174
  /**
1089
1175
  * Execution type describes the way how the block is executed
@@ -1593,7 +1679,7 @@
1593
1679
  }
1594
1680
  dependentParameterNames = __spreadArray([], __read(new Set(dependentParameterNames)), false);
1595
1681
  promptbookJson.promptTemplates.push({
1596
- name: normalizeTo_PascalCase(section.title),
1682
+ name: titleToName(section.title),
1597
1683
  title: section.title,
1598
1684
  description: description_1,
1599
1685
  dependentParameterNames: dependentParameterNames,
@@ -1676,7 +1762,7 @@
1676
1762
  */
1677
1763
 
1678
1764
  /**
1679
- * !!! Initialize
1765
+ * Runs CLI script for prettifying promptbooks
1680
1766
  */
1681
1767
  function prettifyPromptbookStringCli() {
1682
1768
  return __awaiter(this, void 0, void 0, function () {