@promptbook/markdown-utils 0.86.22 → 0.86.31

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
@@ -25,7 +25,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
25
25
  * @generated
26
26
  * @see https://github.com/webgptorg/promptbook
27
27
  */
28
- const PROMPTBOOK_ENGINE_VERSION = '0.86.22';
28
+ const PROMPTBOOK_ENGINE_VERSION = '0.86.31';
29
29
  /**
30
30
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
31
31
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -3721,119 +3721,60 @@ function valueToString(value) {
3721
3721
  }
3722
3722
 
3723
3723
  /**
3724
- * Extract all used variable names from ginen JavaScript/TypeScript script
3724
+ * Parses the given script and returns the list of all used variables that are not defined in the script
3725
3725
  *
3726
- * @param script JavaScript/TypeScript script
3727
- * @returns Set of variable names
3726
+ * @param script from which to extract the variables
3727
+ * @returns the list of variable names
3728
3728
  * @throws {ParseError} if the script is invalid
3729
- * @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
3729
+ * @public exported from `@promptbook/execute-javascript`
3730
3730
  */
3731
- function extractVariablesFromScript(script) {
3732
- if (script.trim() === '') {
3733
- return new Set();
3734
- }
3731
+ function extractVariablesFromJavascript(script) {
3735
3732
  const variables = new Set();
3736
- // JS keywords and builtins to exclude
3737
- const exclude = new Set([
3738
- // Keywords
3739
- 'break',
3740
- 'case',
3741
- 'catch',
3742
- 'class',
3743
- 'const',
3744
- 'continue',
3745
- 'debugger',
3746
- 'default',
3747
- 'delete',
3748
- 'do',
3749
- 'else',
3750
- 'export',
3751
- 'extends',
3752
- 'false',
3753
- 'finally',
3754
- 'for',
3755
- 'function',
3756
- 'if',
3757
- 'import',
3758
- 'in',
3759
- 'instanceof',
3760
- 'let',
3761
- 'new',
3762
- 'null',
3763
- 'return',
3764
- 'super',
3765
- 'switch',
3766
- 'this',
3767
- 'throw',
3768
- 'true',
3769
- 'try',
3770
- 'typeof',
3771
- 'var',
3772
- 'void',
3773
- 'while',
3774
- 'with',
3775
- 'yield',
3776
- // Common globals
3777
- 'console',
3778
- 'JSON',
3779
- 'Error',
3780
- // Typescript types
3781
- 'string',
3782
- 'number',
3783
- 'boolean',
3784
- 'object',
3785
- 'symbol',
3786
- // Common methods on built-in objects
3787
- 'test',
3788
- 'match',
3789
- 'exec',
3790
- 'replace',
3791
- 'search',
3792
- 'split',
3793
- ]);
3733
+ const originalScript = script;
3734
+ script = `(()=>{${script}})()`;
3794
3735
  try {
3795
- // Note: Extract variables from template literals like ${variable}
3796
- const templateRegex = /\$\{([a-zA-Z_$][a-zA-Z0-9_$]*)\}/g;
3797
- let match;
3798
- while ((match = templateRegex.exec(script)) !== null) {
3799
- const varName = match[1];
3800
- if (!exclude.has(varName)) {
3801
- variables.add(varName);
3736
+ for (let i = 0; i < LOOP_LIMIT; i++)
3737
+ try {
3738
+ eval(script); // <- TODO: Use `JavascriptExecutionTools.execute` here
3802
3739
  }
3803
- }
3804
- // Note: Process the script to handle normal variable usage
3805
- const processedScript = script
3806
- .replace(/'(?:\\.|[^'\\])*'/g, "''") // <- Note: Remove string literals
3807
- .replace(/"(?:\\.|[^"\\])*"/g, '""')
3808
- .replace(/`(?:\\.|[^`\\])*`/g, '``')
3809
- .replace(/\/(?:\\.|[^/\\])*\/[gimsuy]*/g, '{}'); // <- Note: Remove regex literals
3810
- // Note: Find identifiers in function arguments
3811
- const funcArgRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g;
3812
- const funcNames = new Set();
3813
- while ((match = funcArgRegex.exec(processedScript)) !== null) {
3814
- funcNames.add(match[1]);
3815
- }
3816
- // Find variable declarations to exclude them
3817
- const declaredVars = new Set();
3818
- const declRegex = /\b(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
3819
- while ((match = declRegex.exec(processedScript)) !== null) {
3820
- declaredVars.add(match[2]);
3821
- }
3822
- // Note: Find identifiers in the script
3823
- const identifierRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
3824
- while ((match = identifierRegex.exec(processedScript)) !== null) {
3825
- const name = match[1];
3826
- // Add if not excluded, not a function name, and not a declared variable
3827
- if (!exclude.has(name) && !funcNames.has(name) && !declaredVars.has(name)) {
3828
- variables.add(name);
3740
+ catch (error) {
3741
+ if (!(error instanceof ReferenceError)) {
3742
+ throw error;
3743
+ }
3744
+ /*
3745
+ Note: Parsing the error
3746
+ 🌟 Most devices:
3747
+ [PipelineUrlError: thing is not defined]
3748
+
3749
+ 🍏 iPhone`s Safari:
3750
+ [PipelineUrlError: Can't find variable: thing]
3751
+ */
3752
+ let variableName = undefined;
3753
+ if (error.message.startsWith(`Can't`)) {
3754
+ // 🍏 Case
3755
+ variableName = error.message.split(' ').pop();
3756
+ }
3757
+ else {
3758
+ // 🌟 Case
3759
+ variableName = error.message.split(' ').shift();
3760
+ }
3761
+ if (variableName === undefined) {
3762
+ throw error;
3763
+ }
3764
+ if (script.includes(variableName + '(')) {
3765
+ script = `const ${variableName} = ()=>'';` + script;
3766
+ }
3767
+ else {
3768
+ variables.add(variableName);
3769
+ script = `const ${variableName} = '';` + script;
3770
+ }
3829
3771
  }
3830
- }
3831
3772
  }
3832
3773
  catch (error) {
3833
3774
  if (!(error instanceof Error)) {
3834
3775
  throw error;
3835
3776
  }
3836
- throw new ParseError(spaceTrim((block) => `
3777
+ throw new ParseError(spaceTrim$1((block) => `
3837
3778
  Can not extract variables from the script
3838
3779
  ${block(error.stack || error.message)}
3839
3780
 
@@ -3846,7 +3787,7 @@ function extractVariablesFromScript(script) {
3846
3787
  The script:
3847
3788
 
3848
3789
  \`\`\`javascript
3849
- ${block(script)}
3790
+ ${block(originalScript)}
3850
3791
  \`\`\`
3851
3792
  `));
3852
3793
  }
@@ -3867,19 +3808,24 @@ function extractVariablesFromScript(script) {
3867
3808
  function extractParameterNamesFromTask(task) {
3868
3809
  const { title, description, taskType, content, preparedContent, jokerParameterNames, foreach } = task;
3869
3810
  const parameterNames = new Set();
3811
+ let contentParameters;
3812
+ if (taskType !== 'SCRIPT_TASK') {
3813
+ contentParameters = extractParameterNames(content);
3814
+ }
3815
+ else {
3816
+ // TODO: What if script is not javascript?
3817
+ // const { contentLanguage } = task;
3818
+ // if (contentLanguage !== 'javascript') {
3819
+ contentParameters = extractVariablesFromJavascript(content);
3820
+ }
3870
3821
  for (const parameterName of [
3871
3822
  ...extractParameterNames(title),
3872
3823
  ...extractParameterNames(description || ''),
3873
- ...extractParameterNames(content),
3824
+ ...contentParameters,
3874
3825
  ...extractParameterNames(preparedContent || ''),
3875
3826
  ]) {
3876
3827
  parameterNames.add(parameterName);
3877
3828
  }
3878
- if (taskType === 'SCRIPT_TASK') {
3879
- for (const parameterName of extractVariablesFromScript(content)) {
3880
- parameterNames.add(parameterName);
3881
- }
3882
- }
3883
3829
  for (const jokerName of jokerParameterNames || []) {
3884
3830
  parameterNames.add(jokerName);
3885
3831
  }