@promptbook/core 0.48.0-0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/index.es.js CHANGED
@@ -123,15 +123,84 @@ function __spreadArray(to, from, pack) {
123
123
  }
124
124
 
125
125
  /**
126
- * Removes HTML or Markdown comments from a string.
126
+ * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
127
+ */
128
+ var PromptbookSyntaxError = /** @class */ (function (_super) {
129
+ __extends(PromptbookSyntaxError, _super);
130
+ function PromptbookSyntaxError(message) {
131
+ var _this = _super.call(this, message) || this;
132
+ _this.name = 'PromptbookSyntaxError';
133
+ Object.setPrototypeOf(_this, PromptbookSyntaxError.prototype);
134
+ return _this;
135
+ }
136
+ return PromptbookSyntaxError;
137
+ }(Error));
138
+
139
+ /**
140
+ * Supported script languages
141
+ */
142
+ var SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
143
+
144
+ /**
145
+ * Parses the template and returns the list of all parameter names
127
146
  *
128
- * @param {string} content - The string to remove comments from.
129
- * @returns {string} The input string with all comments removed.
147
+ * @param template the template with parameters in {curly} braces
148
+ * @returns the list of parameter names
149
+ *
150
+ * @private within the library
130
151
  */
131
- function removeContentComments(content) {
132
- return spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
152
+ function extractParameters(template) {
153
+ var e_1, _a;
154
+ var matches = template.matchAll(/{\w+}/g);
155
+ var parameterNames = [];
156
+ try {
157
+ for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
158
+ var match = matches_1_1.value;
159
+ var parameterName = match[0].slice(1, -1);
160
+ if (!parameterNames.includes(parameterName)) {
161
+ parameterNames.push(parameterName);
162
+ }
163
+ }
164
+ }
165
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
166
+ finally {
167
+ try {
168
+ if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
169
+ }
170
+ finally { if (e_1) throw e_1.error; }
171
+ }
172
+ return parameterNames;
173
+ }
174
+
175
+ /**
176
+ * Computes the deepness of the markdown structure.
177
+ *
178
+ * @private within the library
179
+ */
180
+ function countMarkdownStructureDeepness(markdownStructure) {
181
+ var e_1, _a;
182
+ var maxDeepness = 0;
183
+ try {
184
+ for (var _b = __values(markdownStructure.sections), _c = _b.next(); !_c.done; _c = _b.next()) {
185
+ var section = _c.value;
186
+ maxDeepness = Math.max(maxDeepness, countMarkdownStructureDeepness(section));
187
+ }
188
+ }
189
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
190
+ finally {
191
+ try {
192
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
193
+ }
194
+ finally { if (e_1) throw e_1.error; }
195
+ }
196
+ return maxDeepness + 1;
133
197
  }
134
198
 
199
+ /**
200
+ * The maximum number of iterations for a loops
201
+ */
202
+ var LOOP_LIMIT = 1000;
203
+
135
204
  /**
136
205
  * This error type indicates that the error should not happen and its last check before crashing with some other error
137
206
  */
@@ -147,18 +216,304 @@ var UnexpectedError = /** @class */ (function (_super) {
147
216
  }(Error));
148
217
 
149
218
  /**
150
- * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
219
+ * Parse a markdown string into a MarkdownStructure object.
220
+ *
221
+ * Note: This function does work with code blocks
222
+ * Note: This function does not work with markdown comments
223
+ *
224
+ * @param markdown The markdown string to parse.
225
+ * @returns The MarkdownStructure object.
226
+ *
227
+ * @private within the library
151
228
  */
152
- var PromptbookSyntaxError = /** @class */ (function (_super) {
153
- __extends(PromptbookSyntaxError, _super);
154
- function PromptbookSyntaxError(message) {
155
- var _this = _super.call(this, message) || this;
156
- _this.name = 'PromptbookSyntaxError';
157
- Object.setPrototypeOf(_this, PromptbookSyntaxError.prototype);
158
- return _this;
229
+ function markdownToMarkdownStructure(markdown) {
230
+ var e_1, _a;
231
+ var lines = markdown.split('\n');
232
+ var root = { level: 0, title: '', contentLines: [], sections: [], parent: null };
233
+ var current = root;
234
+ var isInsideCodeBlock = false;
235
+ try {
236
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
237
+ var line = lines_1_1.value;
238
+ var headingMatch = line.match(/^(?<mark>#{1,6})\s(?<title>.*)/);
239
+ if (isInsideCodeBlock || !headingMatch) {
240
+ if (line.startsWith('```')) {
241
+ isInsideCodeBlock = !isInsideCodeBlock;
242
+ }
243
+ current.contentLines.push(line);
244
+ }
245
+ else {
246
+ var level = headingMatch.groups.mark.length;
247
+ var title = headingMatch.groups.title.trim();
248
+ var parent_1 = void 0;
249
+ if (level > current.level) {
250
+ // Note: Going deeper (next section is child of current)
251
+ parent_1 = current;
252
+ }
253
+ else {
254
+ // Note: Going up or staying at the same level (next section is sibling or parent or grandparent,... of current)
255
+ parent_1 = current;
256
+ var loopLimit = LOOP_LIMIT;
257
+ while (parent_1.level !== level - 1) {
258
+ if (loopLimit-- < 0) {
259
+ throw new UnexpectedError('Loop limit reached during parsing of markdown structure in `markdownToMarkdownStructure`');
260
+ }
261
+ if (parent_1.parent === null /* <- Note: We are in root */) {
262
+ // [🌻]
263
+ throw new Error(spaceTrim("\n The file has an invalid structure.\n The markdown file must have exactly one top-level section.\n "));
264
+ }
265
+ parent_1 = parent_1.parent;
266
+ }
267
+ }
268
+ var section = { level: level, title: title, contentLines: [], sections: [], parent: parent_1 };
269
+ parent_1.sections.push(section);
270
+ current = section;
271
+ }
272
+ }
159
273
  }
160
- return PromptbookSyntaxError;
161
- }(Error));
274
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
275
+ finally {
276
+ try {
277
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
278
+ }
279
+ finally { if (e_1) throw e_1.error; }
280
+ }
281
+ if (root.sections.length === 1) {
282
+ var markdownStructure = parsingMarkdownStructureToMarkdownStructure(root.sections[0]);
283
+ return markdownStructure;
284
+ }
285
+ // [🌻]
286
+ throw new Error('The markdown file must have exactly one top-level section.');
287
+ // return root;
288
+ }
289
+ /**
290
+ * @private
291
+ */
292
+ function parsingMarkdownStructureToMarkdownStructure(parsingMarkdownStructure) {
293
+ var level = parsingMarkdownStructure.level, title = parsingMarkdownStructure.title, contentLines = parsingMarkdownStructure.contentLines, sections = parsingMarkdownStructure.sections;
294
+ return {
295
+ level: level,
296
+ title: title,
297
+ content: spaceTrim(contentLines.join('\n')),
298
+ sections: sections.map(parsingMarkdownStructureToMarkdownStructure),
299
+ };
300
+ }
301
+
302
+ /**
303
+ * Utility function to extract all list items from markdown
304
+ *
305
+ * Note: It works with both ul and ol
306
+ * Note: It omits list items in code blocks
307
+ * Note: It flattens nested lists
308
+ * Note: It can not work with html syntax and comments
309
+ *
310
+ * @param markdown any valid markdown
311
+ * @returns
312
+ */
313
+ function extractAllListItemsFromMarkdown(markdown) {
314
+ var e_1, _a;
315
+ var lines = markdown.split('\n');
316
+ var listItems = [];
317
+ var isInCodeBlock = false;
318
+ try {
319
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
320
+ var line = lines_1_1.value;
321
+ var trimmedLine = line.trim();
322
+ if (trimmedLine.startsWith('```')) {
323
+ isInCodeBlock = !isInCodeBlock;
324
+ }
325
+ if (!isInCodeBlock && (trimmedLine.startsWith('-') || trimmedLine.match(/^\d+\./))) {
326
+ var listItem = trimmedLine.replace(/^-|\d+\./, '').trim();
327
+ listItems.push(listItem);
328
+ }
329
+ }
330
+ }
331
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
332
+ finally {
333
+ try {
334
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
335
+ }
336
+ finally { if (e_1) throw e_1.error; }
337
+ }
338
+ return listItems;
339
+ }
340
+
341
+ /**
342
+ * Makes first letter of a string uppercase
343
+ *
344
+ */
345
+ function capitalize(word) {
346
+ return word.substring(0, 1).toUpperCase() + word.substring(1);
347
+ }
348
+
349
+ /**
350
+ * Extracts all code blocks from markdown.
351
+ *
352
+ * Note: There are 3 simmilar function:
353
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
354
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
355
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
356
+ *
357
+ * @param markdown any valid markdown
358
+ * @returns code blocks with language and content
359
+ *
360
+ */
361
+ function extractAllBlocksFromMarkdown(markdown) {
362
+ var e_1, _a;
363
+ var codeBlocks = [];
364
+ var lines = markdown.split('\n');
365
+ var currentCodeBlock = null;
366
+ try {
367
+ for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
368
+ var line = lines_1_1.value;
369
+ if (line.startsWith('```')) {
370
+ var language = line.slice(3).trim() || null;
371
+ if (currentCodeBlock === null) {
372
+ currentCodeBlock = { language: language, content: '' };
373
+ }
374
+ else {
375
+ if (language !== null) {
376
+ // [🌻]
377
+ throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
378
+ }
379
+ codeBlocks.push(currentCodeBlock);
380
+ currentCodeBlock = null;
381
+ }
382
+ }
383
+ else if (currentCodeBlock !== null) {
384
+ if (currentCodeBlock.content !== '') {
385
+ currentCodeBlock.content += '\n';
386
+ }
387
+ currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
388
+ }
389
+ }
390
+ }
391
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
392
+ finally {
393
+ try {
394
+ if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
395
+ }
396
+ finally { if (e_1) throw e_1.error; }
397
+ }
398
+ if (currentCodeBlock !== null) {
399
+ // [🌻]
400
+ throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
401
+ }
402
+ return codeBlocks;
403
+ }
404
+
405
+ /**
406
+ * Extracts exactly ONE code block from markdown.
407
+ *
408
+ * Note: If there are multiple or no code blocks the function throws an error
409
+ *
410
+ * Note: There are 3 simmilar function:
411
+ * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
412
+ * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
413
+ * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
414
+ *
415
+ * @param markdown any valid markdown
416
+ * @returns code block with language and content
417
+ */
418
+ function extractOneBlockFromMarkdown(markdown) {
419
+ var codeBlocks = extractAllBlocksFromMarkdown(markdown);
420
+ if (codeBlocks.length !== 1) {
421
+ // TODO: Report more specific place where the error happened
422
+ throw new Error(/* <- [🌻] */ 'There should be exactly one code block in the markdown');
423
+ }
424
+ return codeBlocks[0];
425
+ }
426
+ /***
427
+ * TODO: [🍓][🌻] !!! Decide of this is internal util, external util OR validator/postprocessor
428
+ */
429
+
430
+ /**
431
+ * Removes HTML or Markdown comments from a string.
432
+ *
433
+ * @param {string} content - The string to remove comments from.
434
+ * @returns {string} The input string with all comments removed.
435
+ */
436
+ function removeContentComments(content) {
437
+ return spaceTrim(content.replace(/<!--(.*?)-->/gs, ''));
438
+ }
439
+
440
+ /**
441
+ * The version of the Promptbook library
442
+ */
443
+ var PROMPTBOOK_VERSION = '0.48.0-1';
444
+
445
+ /**
446
+ * Parses the given script and returns the list of all used variables that are not defined in the script
447
+ *
448
+ * @param script from which to extract the variables
449
+ * @returns the list of variable names
450
+ * @throws {PromptbookSyntaxError} if the script is invalid
451
+ *
452
+ * @private within the promptbookStringToJson
453
+ */
454
+ function extractVariables(script) {
455
+ var variables = [];
456
+ script = "(()=>{".concat(script, "})()");
457
+ try {
458
+ for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
459
+ try {
460
+ eval(script);
461
+ }
462
+ catch (error) {
463
+ if (!(error instanceof ReferenceError)) {
464
+ throw error;
465
+ }
466
+ var undefinedName = error.message.split(' ')[0];
467
+ /*
468
+ Note: Remapping error
469
+ From: [ReferenceError: thing is not defined],
470
+ To: [Error: Parameter {thing} is not defined],
471
+ */
472
+ if (!undefinedName) {
473
+ throw error;
474
+ }
475
+ if (script.includes(undefinedName + '(')) {
476
+ script = "const ".concat(undefinedName, " = ()=>'';") + script;
477
+ }
478
+ else {
479
+ variables.push(undefinedName);
480
+ script = "const ".concat(undefinedName, " = '';") + script;
481
+ }
482
+ }
483
+ }
484
+ catch (error) {
485
+ if (!(error instanceof Error)) {
486
+ throw error;
487
+ }
488
+ throw new PromptbookSyntaxError(spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
489
+ }
490
+ return variables;
491
+ }
492
+
493
+ /**
494
+ * Removes emojis from a string and fix whitespaces
495
+ *
496
+ * @param text with emojis
497
+ * @returns text without emojis
498
+ */
499
+ function removeEmojis(text) {
500
+ // Replace emojis (and also ZWJ sequence) with hyphens
501
+ text = text.replace(/(\p{Extended_Pictographic})\p{Modifier_Symbol}/gu, '$1');
502
+ text = text.replace(/(\p{Extended_Pictographic})[\u{FE00}-\u{FE0F}]/gu, '$1');
503
+ text = text.replace(/(\p{Extended_Pictographic})(\u{200D}\p{Extended_Pictographic})*/gu, '$1');
504
+ text = text.replace(/\p{Extended_Pictographic}/gu, '');
505
+ return text;
506
+ }
507
+
508
+ /**
509
+ * Function normalizes title to name which can be used as identifier
510
+ */
511
+ function titleToName(value) {
512
+ value = removeEmojis(value);
513
+ value = normalizeToKebabCase(value);
514
+ // TODO: [🧠] Maybe warn or add some padding to short name which are not good identifiers
515
+ return value;
516
+ }
162
517
 
163
518
  /**
164
519
  * Function parseNumber will parse number from string
@@ -620,11 +975,6 @@ function checkExpectations(expectations, value) {
620
975
  * TODO: [💝] Unite object for expecting amount and format
621
976
  */
622
977
 
623
- /**
624
- * The maximum number of iterations for a loops
625
- */
626
- var LOOP_LIMIT = 1000;
627
-
628
978
  /**
629
979
  * This error occurs during the parameter replacement in the template
630
980
  *
@@ -692,161 +1042,33 @@ function replaceParameters(template, parameters) {
692
1042
  }
693
1043
  // [💫] Check if there are parameters that are not closed properly
694
1044
  if (/{\w+$/.test(replacedTemplate)) {
695
- throw new TemplateError('Parameter is not closed');
696
- }
697
- // [💫] Check if there are parameters that are not opened properly
698
- if (/^\w+}/.test(replacedTemplate)) {
699
- throw new TemplateError('Parameter is not opened');
700
- }
701
- return replacedTemplate;
702
- }
703
-
704
- /**
705
- * Function isValidJsonString will tell you if the string is valid JSON or not
706
- */
707
- function isValidJsonString(value) {
708
- try {
709
- JSON.parse(value);
710
- return true;
711
- }
712
- catch (error) {
713
- if (!(error instanceof Error)) {
714
- throw error;
715
- }
716
- if (error.message.includes('Unexpected token')) {
717
- return false;
718
- }
719
- return false;
720
- }
721
- }
722
-
723
- /**
724
- * Makes first letter of a string uppercase
725
- *
726
- */
727
- function capitalize(word) {
728
- return word.substring(0, 1).toUpperCase() + word.substring(1);
729
- }
730
-
731
- /**
732
- * Extracts all code blocks from markdown.
733
- *
734
- * Note: There are 3 simmilar function:
735
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
736
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
737
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
738
- *
739
- * @param markdown any valid markdown
740
- * @returns code blocks with language and content
741
- *
742
- */
743
- function extractAllBlocksFromMarkdown(markdown) {
744
- var e_1, _a;
745
- var codeBlocks = [];
746
- var lines = markdown.split('\n');
747
- var currentCodeBlock = null;
748
- try {
749
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
750
- var line = lines_1_1.value;
751
- if (line.startsWith('```')) {
752
- var language = line.slice(3).trim() || null;
753
- if (currentCodeBlock === null) {
754
- currentCodeBlock = { language: language, content: '' };
755
- }
756
- else {
757
- if (language !== null) {
758
- // [🌻]
759
- throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed and already opening new ").concat(language, " code block"));
760
- }
761
- codeBlocks.push(currentCodeBlock);
762
- currentCodeBlock = null;
763
- }
764
- }
765
- else if (currentCodeBlock !== null) {
766
- if (currentCodeBlock.content !== '') {
767
- currentCodeBlock.content += '\n';
768
- }
769
- currentCodeBlock.content += line.split('\\`\\`\\`').join('```') /* <- TODO: Maybe make propper unescape */;
770
- }
771
- }
772
- }
773
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
774
- finally {
775
- try {
776
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
777
- }
778
- finally { if (e_1) throw e_1.error; }
779
- }
780
- if (currentCodeBlock !== null) {
781
- // [🌻]
782
- throw new Error("".concat(capitalize(currentCodeBlock.language || 'the'), " code block was not closed at the end of the markdown"));
783
- }
784
- return codeBlocks;
785
- }
786
-
787
- /**
788
- * Utility function to extract all list items from markdown
789
- *
790
- * Note: It works with both ul and ol
791
- * Note: It omits list items in code blocks
792
- * Note: It flattens nested lists
793
- * Note: It can not work with html syntax and comments
794
- *
795
- * @param markdown any valid markdown
796
- * @returns
797
- */
798
- function extractAllListItemsFromMarkdown(markdown) {
799
- var e_1, _a;
800
- var lines = markdown.split('\n');
801
- var listItems = [];
802
- var isInCodeBlock = false;
803
- try {
804
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
805
- var line = lines_1_1.value;
806
- var trimmedLine = line.trim();
807
- if (trimmedLine.startsWith('```')) {
808
- isInCodeBlock = !isInCodeBlock;
809
- }
810
- if (!isInCodeBlock && (trimmedLine.startsWith('-') || trimmedLine.match(/^\d+\./))) {
811
- var listItem = trimmedLine.replace(/^-|\d+\./, '').trim();
812
- listItems.push(listItem);
813
- }
814
- }
1045
+ throw new TemplateError('Parameter is not closed');
815
1046
  }
816
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
817
- finally {
818
- try {
819
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
820
- }
821
- finally { if (e_1) throw e_1.error; }
1047
+ // [💫] Check if there are parameters that are not opened properly
1048
+ if (/^\w+}/.test(replacedTemplate)) {
1049
+ throw new TemplateError('Parameter is not opened');
822
1050
  }
823
- return listItems;
1051
+ return replacedTemplate;
824
1052
  }
825
1053
 
826
1054
  /**
827
- * Extracts exactly ONE code block from markdown.
828
- *
829
- * Note: If there are multiple or no code blocks the function throws an error
830
- *
831
- * Note: There are 3 simmilar function:
832
- * - `extractBlock` just extracts the content of the code block which is also used as build-in function for postprocessing
833
- * - `extractOneBlockFromMarkdown` extracts exactly one code block with language of the code block
834
- * - `extractAllBlocksFromMarkdown` extracts all code blocks with language of the code block
835
- *
836
- * @param markdown any valid markdown
837
- * @returns code block with language and content
1055
+ * Function isValidJsonString will tell you if the string is valid JSON or not
838
1056
  */
839
- function extractOneBlockFromMarkdown(markdown) {
840
- var codeBlocks = extractAllBlocksFromMarkdown(markdown);
841
- if (codeBlocks.length !== 1) {
842
- // TODO: Report more specific place where the error happened
843
- throw new Error(/* <- [🌻] */ 'There should be exactly one code block in the markdown');
1057
+ function isValidJsonString(value) {
1058
+ try {
1059
+ JSON.parse(value);
1060
+ return true;
1061
+ }
1062
+ catch (error) {
1063
+ if (!(error instanceof Error)) {
1064
+ throw error;
1065
+ }
1066
+ if (error.message.includes('Unexpected token')) {
1067
+ return false;
1068
+ }
1069
+ return false;
844
1070
  }
845
- return codeBlocks[0];
846
1071
  }
847
- /***
848
- * TODO: [🍓][🌻] !!! Decide of this is internal util, external util OR validator/postprocessor
849
- */
850
1072
 
851
1073
  /**
852
1074
  * Removes Markdown formatting tags from a string.
@@ -929,11 +1151,11 @@ function normalizeTo_SCREAMING_CASE(sentence) {
929
1151
  */
930
1152
 
931
1153
  /* tslint:disable */
932
- function normalizeTo_camelCase(sentence, __firstLetterCapital) {
1154
+ function normalizeToKebabCase(sentence) {
933
1155
  var e_1, _a;
934
- if (__firstLetterCapital === void 0) { __firstLetterCapital = false; }
1156
+ sentence = removeDiacritics(sentence);
935
1157
  var charType;
936
- var lastCharType = null;
1158
+ var lastCharType = 'OTHER';
937
1159
  var normalizedName = '';
938
1160
  try {
939
1161
  for (var sentence_1 = __values(sentence), sentence_1_1 = sentence_1.next(); !sentence_1_1.done; sentence_1_1 = sentence_1.next()) {
@@ -951,20 +1173,19 @@ function normalizeTo_camelCase(sentence, __firstLetterCapital) {
951
1173
  charType = 'NUMBER';
952
1174
  normalizedChar = char;
953
1175
  }
1176
+ else if (/^\/$/.test(char)) {
1177
+ charType = 'SLASH';
1178
+ normalizedChar = char;
1179
+ }
954
1180
  else {
955
1181
  charType = 'OTHER';
956
- normalizedChar = '';
957
- }
958
- if (!lastCharType) {
959
- if (__firstLetterCapital) {
960
- normalizedChar = normalizedChar.toUpperCase(); //TODO: DRY
961
- }
1182
+ normalizedChar = '-';
962
1183
  }
963
- else if (charType !== lastCharType &&
964
- !(charType === 'LOWERCASE' && lastCharType === 'UPPERCASE') &&
1184
+ if (charType !== lastCharType &&
1185
+ !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&
965
1186
  !(lastCharType === 'NUMBER') &&
966
1187
  !(charType === 'NUMBER')) {
967
- normalizedChar = normalizedChar.toUpperCase(); //TODO: [🌺] DRY
1188
+ normalizedName += '-';
968
1189
  }
969
1190
  normalizedName += normalizedChar;
970
1191
  lastCharType = charType;
@@ -977,212 +1198,12 @@ function normalizeTo_camelCase(sentence, __firstLetterCapital) {
977
1198
  }
978
1199
  finally { if (e_1) throw e_1.error; }
979
1200
  }
1201
+ normalizedName = normalizedName.split(/-+/g).join('-');
1202
+ normalizedName = normalizedName.split(/-?\/-?/g).join('/');
1203
+ normalizedName = normalizedName.replace(/^-/, '');
1204
+ normalizedName = normalizedName.replace(/-$/, '');
980
1205
  return normalizedName;
981
1206
  }
982
- /**
983
- * TODO: [🌺] Use some intermediate util splitWords
984
- */
985
-
986
- function normalizeTo_PascalCase(sentence) {
987
- return normalizeTo_camelCase(sentence, true);
988
- }
989
-
990
- /**
991
- * Supported script languages
992
- */
993
- var SUPPORTED_SCRIPT_LANGUAGES = ['javascript', 'typescript', 'python'];
994
-
995
- /**
996
- * Parses the template and returns the list of all parameter names
997
- *
998
- * @param template the template with parameters in {curly} braces
999
- * @returns the list of parameter names
1000
- *
1001
- * @private within the library
1002
- */
1003
- function extractParameters(template) {
1004
- var e_1, _a;
1005
- var matches = template.matchAll(/{\w+}/g);
1006
- var parameterNames = [];
1007
- try {
1008
- for (var matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
1009
- var match = matches_1_1.value;
1010
- var parameterName = match[0].slice(1, -1);
1011
- if (!parameterNames.includes(parameterName)) {
1012
- parameterNames.push(parameterName);
1013
- }
1014
- }
1015
- }
1016
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1017
- finally {
1018
- try {
1019
- if (matches_1_1 && !matches_1_1.done && (_a = matches_1.return)) _a.call(matches_1);
1020
- }
1021
- finally { if (e_1) throw e_1.error; }
1022
- }
1023
- return parameterNames;
1024
- }
1025
-
1026
- /**
1027
- * Computes the deepness of the markdown structure.
1028
- *
1029
- * @private within the library
1030
- */
1031
- function countMarkdownStructureDeepness(markdownStructure) {
1032
- var e_1, _a;
1033
- var maxDeepness = 0;
1034
- try {
1035
- for (var _b = __values(markdownStructure.sections), _c = _b.next(); !_c.done; _c = _b.next()) {
1036
- var section = _c.value;
1037
- maxDeepness = Math.max(maxDeepness, countMarkdownStructureDeepness(section));
1038
- }
1039
- }
1040
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1041
- finally {
1042
- try {
1043
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1044
- }
1045
- finally { if (e_1) throw e_1.error; }
1046
- }
1047
- return maxDeepness + 1;
1048
- }
1049
-
1050
- /**
1051
- * Parse a markdown string into a MarkdownStructure object.
1052
- *
1053
- * Note: This function does work with code blocks
1054
- * Note: This function does not work with markdown comments
1055
- *
1056
- * @param markdown The markdown string to parse.
1057
- * @returns The MarkdownStructure object.
1058
- *
1059
- * @private within the library
1060
- */
1061
- function markdownToMarkdownStructure(markdown) {
1062
- var e_1, _a;
1063
- var lines = markdown.split('\n');
1064
- var root = { level: 0, title: '', contentLines: [], sections: [], parent: null };
1065
- var current = root;
1066
- var isInsideCodeBlock = false;
1067
- try {
1068
- for (var lines_1 = __values(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
1069
- var line = lines_1_1.value;
1070
- var headingMatch = line.match(/^(?<mark>#{1,6})\s(?<title>.*)/);
1071
- if (isInsideCodeBlock || !headingMatch) {
1072
- if (line.startsWith('```')) {
1073
- isInsideCodeBlock = !isInsideCodeBlock;
1074
- }
1075
- current.contentLines.push(line);
1076
- }
1077
- else {
1078
- var level = headingMatch.groups.mark.length;
1079
- var title = headingMatch.groups.title.trim();
1080
- var parent_1 = void 0;
1081
- if (level > current.level) {
1082
- // Note: Going deeper (next section is child of current)
1083
- parent_1 = current;
1084
- }
1085
- else {
1086
- // Note: Going up or staying at the same level (next section is sibling or parent or grandparent,... of current)
1087
- parent_1 = current;
1088
- var loopLimit = LOOP_LIMIT;
1089
- while (parent_1.level !== level - 1) {
1090
- if (loopLimit-- < 0) {
1091
- throw new UnexpectedError('Loop limit reached during parsing of markdown structure in `markdownToMarkdownStructure`');
1092
- }
1093
- if (parent_1.parent === null /* <- Note: We are in root */) {
1094
- // [🌻]
1095
- throw new Error(spaceTrim("\n The file has an invalid structure.\n The markdown file must have exactly one top-level section.\n "));
1096
- }
1097
- parent_1 = parent_1.parent;
1098
- }
1099
- }
1100
- var section = { level: level, title: title, contentLines: [], sections: [], parent: parent_1 };
1101
- parent_1.sections.push(section);
1102
- current = section;
1103
- }
1104
- }
1105
- }
1106
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1107
- finally {
1108
- try {
1109
- if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
1110
- }
1111
- finally { if (e_1) throw e_1.error; }
1112
- }
1113
- if (root.sections.length === 1) {
1114
- var markdownStructure = parsingMarkdownStructureToMarkdownStructure(root.sections[0]);
1115
- return markdownStructure;
1116
- }
1117
- // [🌻]
1118
- throw new Error('The markdown file must have exactly one top-level section.');
1119
- // return root;
1120
- }
1121
- /**
1122
- * @private
1123
- */
1124
- function parsingMarkdownStructureToMarkdownStructure(parsingMarkdownStructure) {
1125
- var level = parsingMarkdownStructure.level, title = parsingMarkdownStructure.title, contentLines = parsingMarkdownStructure.contentLines, sections = parsingMarkdownStructure.sections;
1126
- return {
1127
- level: level,
1128
- title: title,
1129
- content: spaceTrim(contentLines.join('\n')),
1130
- sections: sections.map(parsingMarkdownStructureToMarkdownStructure),
1131
- };
1132
- }
1133
-
1134
- /**
1135
- * The version of the Promptbook library
1136
- */
1137
- var PROMPTBOOK_VERSION = '0.47.0';
1138
-
1139
- /**
1140
- * Parses the given script and returns the list of all used variables that are not defined in the script
1141
- *
1142
- * @param script from which to extract the variables
1143
- * @returns the list of variable names
1144
- * @throws {PromptbookSyntaxError} if the script is invalid
1145
- *
1146
- * @private within the promptbookStringToJson
1147
- */
1148
- function extractVariables(script) {
1149
- var variables = [];
1150
- script = "(()=>{".concat(script, "})()");
1151
- try {
1152
- for (var i = 0; i < 100 /* <- TODO: This limit to configuration */; i++)
1153
- try {
1154
- eval(script);
1155
- }
1156
- catch (error) {
1157
- if (!(error instanceof ReferenceError)) {
1158
- throw error;
1159
- }
1160
- var undefinedName = error.message.split(' ')[0];
1161
- /*
1162
- Note: Remapping error
1163
- From: [ReferenceError: thing is not defined],
1164
- To: [Error: Parameter {thing} is not defined],
1165
- */
1166
- if (!undefinedName) {
1167
- throw error;
1168
- }
1169
- if (script.includes(undefinedName + '(')) {
1170
- script = "const ".concat(undefinedName, " = ()=>'';") + script;
1171
- }
1172
- else {
1173
- variables.push(undefinedName);
1174
- script = "const ".concat(undefinedName, " = '';") + script;
1175
- }
1176
- }
1177
- }
1178
- catch (error) {
1179
- if (!(error instanceof Error)) {
1180
- throw error;
1181
- }
1182
- throw new PromptbookSyntaxError(spaceTrim(function (block) { return "\n Can not extract variables from the script\n\n ".concat(block(error.name), ": ").concat(block(error.message), "\n "); }));
1183
- }
1184
- return variables;
1185
- }
1186
1207
 
1187
1208
  /**
1188
1209
  * Execution type describes the way how the block is executed
@@ -1692,7 +1713,7 @@ function promptbookStringToJson(promptbookString) {
1692
1713
  }
1693
1714
  dependentParameterNames = __spreadArray([], __read(new Set(dependentParameterNames)), false);
1694
1715
  promptbookJson.promptTemplates.push({
1695
- name: normalizeTo_PascalCase(section.title),
1716
+ name: titleToName(section.title),
1696
1717
  title: section.title,
1697
1718
  description: description_1,
1698
1719
  dependentParameterNames: dependentParameterNames,
@@ -1733,9 +1754,9 @@ function promptbookJsonToString(promptbookJson) {
1733
1754
  return spaceTrim$1(function (block) { return "\n\n # ".concat(block(promptbookJson.title), "\n\n "); });
1734
1755
  }
1735
1756
  /**
1736
- * TODO: !!! Implement
1737
- * TODO: !!! Annotate and warn
1738
- * TODO: !!! Test + test together with promptbookStringToJson
1757
+ * TODO: !!!!! Implement
1758
+ * TODO: !!!!! Annotate and warn
1759
+ * TODO: !!!!! Test + test together with promptbookStringToJson
1739
1760
  */
1740
1761
 
1741
1762
  /**