@stackql/provider-utils 0.4.4 → 0.4.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackql/provider-utils",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Utilities for building StackQL providers from OpenAPI specifications.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -31,8 +31,15 @@ export function getIndefiniteArticle(resourceName) {
31
31
  export function sanitizeHtml(text) {
32
32
  if (!text) return '';
33
33
 
34
- // First apply the general sanitization
34
+ // Special handling for code tags - temporarily replace them with placeholders
35
+ // that won't get escaped in the general sanitization
35
36
  let result = text
37
+ // Replace <code> tags with a safe placeholder
38
+ .replace(/<code>/g, '___CODE_OPEN___')
39
+ .replace(/<\/code>/g, '___CODE_CLOSE___');
40
+
41
+ // Then apply the general sanitization
42
+ result = result
36
43
  .replace(/{/g, '&#123;')
37
44
  .replace(/}/g, '&#125;')
38
45
  .replace(/>/g, '&gt;')
@@ -58,6 +65,11 @@ export function sanitizeHtml(text) {
58
65
  return '`' + fixedContent + '`';
59
66
  });
60
67
 
68
+ // Finally, restore the code tags
69
+ result = result
70
+ .replace(/___CODE_OPEN___/g, '<code>')
71
+ .replace(/___CODE_CLOSE___/g, '</code>');
72
+
61
73
  return result;
62
74
  }
63
75
 
@@ -241,7 +253,12 @@ function formatProperties(respProps) {
241
253
  if (typeof fieldValue != 'string') {
242
254
  continue;
243
255
  } else {
244
- additionalDescriptionPaths.push(`${fieldName}: ${String(fieldValue)}`);
256
+ // Specifically wrap pattern fields in code tags
257
+ if (fieldName === 'pattern') {
258
+ additionalDescriptionPaths.push(`${fieldName}: <code>${String(fieldValue)}</code>`);
259
+ } else {
260
+ additionalDescriptionPaths.push(`${fieldName}: ${String(fieldValue)}`);
261
+ }
245
262
  }
246
263
  }
247
264
 
@@ -250,7 +267,6 @@ function formatProperties(respProps) {
250
267
  // Store formatted property details
251
268
  allProperties[propName] = {
252
269
  type: typeString,
253
- // description: escapeHtml(fullDescription),
254
270
  description: fullDescription
255
271
  };
256
272
  }
@@ -66,7 +66,7 @@ export function createDeleteExamples(providerName, serviceName, resourceName, re
66
66
  });
67
67
  }
68
68
 
69
- content += ';\n```\n</TabItem>\n';
69
+ content += '\n;\n```\n</TabItem>\n';
70
70
  });
71
71
 
72
72
  // Close tabs
@@ -113,7 +113,7 @@ export function createExecExamples(providerName, serviceName, resourceName, reso
113
113
  content += '}\'';
114
114
  }
115
115
 
116
- content += ';\n```\n</TabItem>\n';
116
+ content += '\n;\n```\n</TabItem>\n';
117
117
  });
118
118
 
119
119
  // Close tabs
@@ -87,9 +87,9 @@ export function createInsertExamples(providerName, serviceName, resourceName, re
87
87
  }
88
88
 
89
89
  if (isNumber || isBoolean) {
90
- return '{{ ' + paramName + ' }}' + (isRequiredBodyParam ? ' --required' : '');
90
+ return '{{ ' + paramName + ' }}' + (isRequiredBodyParam ? ' /* required */' : '');
91
91
  } else {
92
- return '\'{{ ' + paramName + ' }}\'' + (isRequiredBodyParam ? ' --required' : '');
92
+ return '\'{{ ' + paramName + ' }}\'' + (isRequiredBodyParam ? ' /* required */' : '');
93
93
  }
94
94
  });
95
95
 
@@ -67,7 +67,7 @@ export function createSelectExamples(providerName, serviceName, resourceName, re
67
67
  });
68
68
  }
69
69
 
70
- content += ';\n```\n</TabItem>\n';
70
+ content += '\n;\n```\n</TabItem>\n';
71
71
  });
72
72
 
73
73
  // Close tabs
@@ -148,7 +148,7 @@ export function createUpdateExamples(providerName, serviceName, resourceName, re
148
148
  });
149
149
  }
150
150
 
151
- content += ';\n```\n</TabItem>\n';
151
+ content += '\n;\n```\n</TabItem>\n';
152
152
  });
153
153
 
154
154
  // Close tabs
@@ -65,11 +65,11 @@ function retServiceNameAndDesc(providerName, opItem, pathKey, svcDiscriminator,
65
65
  else if (svcDiscriminator === "path") {
66
66
  const pathParts = pathKey.replace(/^\//, '').split('/');
67
67
  if (pathParts.length > 0) {
68
- // Find the first path segment that is not 'api' or 'v{number}'
68
+ // Find the first path segment that is not 'api', 'v{number}', or '{apiVersion}'
69
69
  for (const part of pathParts) {
70
70
  const lowerPart = part.toLowerCase();
71
- // Skip if it's 'api' or matches version pattern 'v1', 'v2', etc.
72
- if (lowerPart === 'api' || /^v\d+$/.test(lowerPart)) {
71
+ // Skip if it's 'api', matches version pattern 'v1', 'v2', etc., or is '{apiVersion}'
72
+ if (lowerPart === 'api' || /^v\d+$/.test(lowerPart) || /^\{.*version\}$/i.test(part)) {
73
73
  continue;
74
74
  }
75
75
  service = lowerPart.replace(/-/g, '_').replace(/ /g, '_').replace(/\./g, '_');
@@ -78,7 +78,7 @@ function retServiceNameAndDesc(providerName, opItem, pathKey, svcDiscriminator,
78
78
  serviceDesc = `${providerName} ${service} API`;
79
79
  }
80
80
  }
81
-
81
+
82
82
  // Check if service should be skipped
83
83
  if (service === "skip") {
84
84
  return ["skip", ""];
package/src/utils.js CHANGED
@@ -9,7 +9,7 @@ import logger from './logger.js';
9
9
  */
10
10
  export function camelToSnake(name) {
11
11
  const s1 = name.replace(/([a-z0-9])([A-Z][a-z]+)/g, '$1_$2');
12
- return s1.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();
12
+ return s1.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase().replace(/-/g, '_');
13
13
  }
14
14
 
15
15
  /**