windmill-utils-internal 1.3.5 → 1.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.
@@ -29,6 +29,7 @@ export declare const EXTENSION_TO_LANGUAGE: Record<string, SupportedLanguage>;
29
29
  * @returns The language, or undefined if not recognized
30
30
  */
31
31
  export declare function getLanguageFromExtension(ext: string, defaultTs?: "bun" | "deno"): SupportedLanguage | undefined;
32
+ export declare function sanitizeForFilesystem(summary: string): string;
32
33
  export interface PathAssigner {
33
34
  assignPath(summary: string | undefined, language: SupportedLanguage): [string, string];
34
35
  }
@@ -93,6 +93,26 @@ export function getLanguageFromExtension(ext, defaultTs = "bun") {
93
93
  }
94
94
  return undefined;
95
95
  }
96
+ /**
97
+ * Sanitizes a summary string for use as a filesystem-safe name.
98
+ * Removes or replaces characters that are invalid on common filesystems.
99
+ */
100
+ const WINDOWS_RESERVED = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/;
101
+ export function sanitizeForFilesystem(summary) {
102
+ const name = summary
103
+ .toLowerCase()
104
+ .replaceAll(" ", "_")
105
+ // Remove characters invalid on Windows/Unix/Mac: / \ : * ? " < > |
106
+ // Also remove control characters (0x00-0x1F) and DEL (0x7F)
107
+ // deno-lint-ignore no-control-regex
108
+ .replace(/[/\\:*?"<>|\x00-\x1f\x7f]/g, "")
109
+ // Collapse consecutive underscores
110
+ .replace(/_+/g, "_")
111
+ // Trim leading/trailing dots and underscores (hidden files, Windows edge cases)
112
+ .replace(/^[._]+|[._]+$/g, "");
113
+ // Prefix Windows reserved device names (CON, PRN, AUX, NUL, COM0-9, LPT0-9)
114
+ return WINDOWS_RESERVED.test(name) ? `_${name}` : name;
115
+ }
96
116
  /**
97
117
  * Creates a new path assigner for inline scripts.
98
118
  *
@@ -110,7 +130,7 @@ export function newPathAssigner(defaultTs, options) {
110
130
  const seen_names = new Set();
111
131
  function assignPath(summary, language) {
112
132
  let name;
113
- name = summary?.toLowerCase()?.replaceAll(" ", "_") ?? "";
133
+ name = summary ? sanitizeForFilesystem(summary) : "";
114
134
  let original_name = name;
115
135
  if (name == "") {
116
136
  original_name = INLINE_SCRIPT_PREFIX;
@@ -141,7 +161,7 @@ export function newRawAppPathAssigner(defaultTs) {
141
161
  const seen_names = new Set();
142
162
  function assignPath(summary, language) {
143
163
  let name;
144
- name = summary?.toLowerCase()?.replaceAll(" ", "_") ?? "";
164
+ name = summary ? sanitizeForFilesystem(summary) : "";
145
165
  let original_name = name;
146
166
  if (name == "") {
147
167
  original_name = "runnable";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-utils-internal",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "Internal utility functions for Windmill",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",