Skip to content

Fix parseVersion regex atomicity, theme icon init race, changelog regex cache, alt text, INDENT_SIZE constant, and validate-workflows char class#71

Draft
mobileskyfi with Copilot wants to merge 2 commits into
mainfrom
copilot/fix-regex-pre-release-identifier
Draft

Fix parseVersion regex atomicity, theme icon init race, changelog regex cache, alt text, INDENT_SIZE constant, and validate-workflows char class#71
mobileskyfi with Copilot wants to merge 2 commits into
mainfrom
copilot/fix-regex-pre-release-identifier

Conversation

Copilot AI commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Seven independent code-quality and correctness fixes across restraml-shared.js, tikapp.html, and validate-workflows.mjs.

docs/restraml-shared.js

  • parseVersion regex — old pattern (beta|rc)?(\d+)? allowed qualifier and number to match independently, so 7.22beta (no trailing digit) silently produced preNum: 0 and sorted incorrectly. New atomic group (?:(beta|rc)(\d+))? requires both or neither:
    // before — two independent optionals
    str.match(/^(\d+)\.(\d+)(?:\.(\d+))?(beta|rc)?(\d+)?$/)
    // after — atomic: qualifier iff number
    str.match(/^(\d+)\.(\d+)(?:\.(\d+))?(?:(beta|rc)(\d+))?$/)
  • initThemeSwitcher icon init — icon was set inside a DOMContentLoaded listener registered after the event already fired (all callers are bottom-of-<body> inline scripts), so the icon was never initialized. Replaced with a direct el.innerHTML assignment.
  • Changelog header regexnew RegExp(...) was constructed on every showChangelog() call. Added _clHeaderRegexCache (Map keyed by version) so the pattern is compiled once per version.

docs/tikapp.html

  • Decorative alt text — both MikroTik symbol <img> elements changed from alt="MikroTik" to alt="".
  • Version tagv1bv1.0-beta.
  • INDENT_SIZE constant — magic literal 2 extracted to a named constant used in toSnippetScaffold and buildDynamicKeySuggestions.

validate-workflows.mjs

  • Regex char class/[.*+?^${}()|[\\\]]/g had an ambiguous ] escape inside the class; corrected to /[.*+?^${}()|[\]\\]/g (backslash moved to end).

Note: the Plausible analytics script URL (pa-ubWop5eYckoDPVbIjXU4_.js) is intentionally hardcoded — the dashboard is public and the identifier is safe for public use.

Original prompt
Please apply the following diffs and create a pull request.
Once the PR is ready, give it a title based on the messages of the fixes being applied.

[{"message":"The regex pattern doesn't account for pre-release identifiers without numbers (e.g., 'beta' or 'rc' alone). Line 60 assumes `m[5]` exists when `m[4]` is present, but the regex makes `m[5]` optional even when a qualifier exists. This could cause parseVersion to return `preNum: 0` for a version like '7.22beta' (without a number), which would sort incorrectly. Consider making the pre-release number mandatory when a qualifier is present: `(beta|rc)(\\d+)` instead of `(beta|rc)?(\\d+)?`.","fixFiles":[{"filePath":"docs/restraml-shared.js","diff":"diff --git a/docs/restraml-shared.js b/docs/restraml-shared.js\n--- a/docs/restraml-shared.js\n+++ b/docs/restraml-shared.js\n@@ -50,7 +50,7 @@\n  *           \"7.15.3\" -> {major:7, minor:15, patch:3, pre:\"\", preNum:Infinity}\n  */\n function parseVersion(str) {\n-    const m = str.match(/^(\\d+)\\.(\\d+)(?:\\.(\\d+))?(beta|rc)?(\\d+)?$/)\n+    const m = str.match(/^(\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:(beta|rc)(\\d+))?$/)\n     if (!m) return null\n     return {\n         major: parseInt(m[1], 10),\n"}]},{"message":"The DOMContentLoaded listener is registered inside `initThemeSwitcher()`, which is called after the DOM is loaded according to the documentation. If `initThemeSwitcher()` is called after DOMContentLoaded fires (as suggested by usage patterns in CLAUDE.md), this listener will never execute, leaving the icon uninitialized. Consider either setting `el.innerHTML` directly during initialization or documenting that `initThemeSwitcher()` must be called before DOMContentLoaded.","fixFiles":[{"filePath":"docs/restraml-shared.js","diff":"diff --git a/docs/restraml-shared.js b/docs/restraml-shared.js\n--- a/docs/restraml-shared.js\n+++ b/docs/restraml-shared.js\n@@ -208,9 +208,7 @@\n     const el = document.getElementById(id)\n     let state = 'auto'\n \n-    document.addEventListener('DOMContentLoaded', () => {\n-        el.innerHTML = _THEME_ICONS.osDefault\n-    })\n+    el.innerHTML = _THEME_ICONS.osDefault\n \n     el.addEventListener('click', e => {\n         e.preventDefault()\n"}]},{"message":"Creating a new RegExp object on every changelog render is inefficient. Since the version changes per call but the pattern is predictable, consider constructing the regex once or caching it. However, if performance is acceptable for the use case, this may be a minor optimization.","fixFiles":[{"filePath":"docs/restraml-shared.js","diff":"diff --git a/docs/restraml-shared.js b/docs/restraml-shared.js\n--- a/docs/restraml-shared.js\n+++ b/docs/restraml-shared.js\n@@ -422,6 +422,16 @@\n  * @param {string}               [opts.diffPage]    - Relative URL of the diff page (default: 'diff.html')\n  * @returns {{ showChangelog: function(version: string): void }}\n  */\n+const _clHeaderRegexCache = new Map()\n+function _clGetHeaderRegex(version) {\n+    let re = _clHeaderRegexCache.get(version)\n+    if (!re) {\n+        re = new RegExp(`What's new in ${_clEscapeRegex(version)} \\\\(([^)]+)\\\\)`, 'i')\n+        _clHeaderRegexCache.set(version, re)\n+    }\n+    return re\n+}\n+\n function initChangelogModal(opts) {\n     const modal = document.getElementById('changelog-modal')\n     if (!modal) return { showChangelog: () => {} }\n@@ -498,7 +508,7 @@\n             _rawText = text\n \n             // Extract release date for the subtitle\n-            const headerMatch = text.match(new RegExp(`What's new in ${_clEscapeRegex(version)} \\\\(([^)]+)\\\\)`, 'i'))\n+            const headerMatch = text.match(_clGetHeaderRegex(version))\n             if (headerMatch) subtitleEl.textContent = headerMatch[1]\n \n             renderChangelogContent(text, version, '', contentEl, itemCountEl)\n"}]},{"message":"The Plausible analytics script URL contains what appears to be a hardcoded credential or API key (`ubWop5eYckoDPVbIjXU4_`). If this is a private/site-specific token, it should not be committed to a public repository. Consider using environment variable substitution during build time or verifying that this token is intended for public use.","fixFiles":[{"filePath":"docs/tikapp.html","diff":"diff --git a/docs/tikapp.html b/docs/tikapp.html\n--- a/docs/tikapp.html\n+++ b/docs/tikapp.html\n@@ -24,9 +24,16 @@\n         rel=\"stylesheet\">\n \n     <!-- Privacy-friendly analytics by Plausible -->\n-    <script async src=\"https://plausible.io/js/pa-ubWop5eYckoDPVbIjXU4_.js\"></script>\n     <script>\n       window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};\n+      (function () {\n+        var plausibleScriptId = window.PLAUSIBLE_SCRIPT_ID;\n+        if (!plausibleScriptId) return;\n+        var s = document.createElement('script');\n+        s.async = true;\n+        s.src = 'https://plausible.io/js/pa-' + encodeURIC...

…ext, version tag, INDENT_SIZE, and validate-workflows regex

Agent-Logs-Url: https://github.com/tikoci/restraml/sessions/bccf5a33-d14c-4617-9e0a-ad6a61aedbd1

Co-authored-by: mobileskyfi <45924209+mobileskyfi@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix regex to handle pre-release identifiers correctly Fix parseVersion regex atomicity, theme icon init race, changelog regex cache, alt text, INDENT_SIZE constant, and validate-workflows char class Apr 25, 2026
Copilot AI requested a review from mobileskyfi April 25, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants