@tadnt2003/n8n-nodes-infisical 0.3.6 → 0.3.7

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.
@@ -211,13 +211,25 @@ const CREDENTIAL_FIELD_MAPS = {
211
211
  { param: 'algorithm', secretKey: 'algorithm' },
212
212
  ],
213
213
  };
214
- function toSlug(name) {
215
- return name.trim().replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
214
+ // Lossless encoding: [A-Za-z0-9-] pass through, _ → __, everything else → _XX hex sequences.
215
+ // Infisical folder names only allow [a-zA-Z0-9_-], so % cannot be used as an escape character.
216
+ function toFolderName(name) {
217
+ return [...name].map(c => {
218
+ if (/[A-Za-z0-9-]/.test(c))
219
+ return c;
220
+ if (c === '_')
221
+ return '__';
222
+ return encodeURIComponent(c).replace(/%/g, '_');
223
+ }).join('');
224
+ }
225
+ function fromFolderName(slug) {
226
+ const restored = slug.replace(/_([0-9A-Fa-f]{2}|_)/g, (_, p1) => p1 === '_' ? '_' : '%' + p1);
227
+ return decodeURIComponent(restored);
216
228
  }
217
229
  function buildSecretPath(rootPath, credentialName) {
218
230
  const root = rootPath.replace(/\/+$/, '') || '/';
219
- const slug = toSlug(credentialName);
220
- return root === '/' ? `/${slug}` : `${root}/${slug}`;
231
+ const folder = toFolderName(credentialName);
232
+ return root === '/' ? `/${folder}` : `${root}/${folder}`;
221
233
  }
222
234
  // Fix 7.4: handles `number` type (port, connectTimeout, maxConnections, etc.)
223
235
  // Fix 7.7: reads schema's own `default` before falling back to enum heuristic
@@ -580,7 +592,8 @@ async function autoSyncFromInfisical(ctx, apiUrl, baseHeaders, i) {
580
592
  credentialData[key] = coerceValue(raw, schemaInfo === null || schemaInfo === void 0 ? void 0 : schemaInfo.props[key]);
581
593
  }
582
594
  }
583
- const existing = credByName.get(folderName);
595
+ const credentialName = fromFolderName(folderName);
596
+ const existing = credByName.get(credentialName);
584
597
  if (existing) {
585
598
  // Fix 7.2: apply the same fullData build logic as the create path so that condition-key
586
599
  // changes (e.g. ssl:false→true) get their required fields filled and their prohibited
@@ -618,7 +631,7 @@ async function autoSyncFromInfisical(ctx, apiUrl, baseHeaders, i) {
618
631
  method: 'POST',
619
632
  url: `${n8nApiUrl}/api/v1/credentials`,
620
633
  headers: n8nHeaders,
621
- body: { name: folderName, type: credentialType, data: fullData },
634
+ body: { name: credentialName, type: credentialType, data: fullData },
622
635
  });
623
636
  results.push({
624
637
  json: Object.assign(Object.assign({}, created), { action: 'created', secretPath, secretCount: secrets.length }),
@@ -702,7 +715,7 @@ async function executeSyncOperation(ctx, apiUrl, baseHeaders, operation, i) {
702
715
  method: 'POST',
703
716
  url: `${apiUrl}/v2/folders`,
704
717
  headers: baseHeaders,
705
- body: { projectId, environment, name: toSlug(credentialName), path: folderPath },
718
+ body: { projectId, environment, name: toFolderName(credentialName), path: folderPath },
706
719
  });
707
720
  }
708
721
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tadnt2003/n8n-nodes-infisical",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "n8n community node for Infisical - Secret management platform",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",