Skip to content

Fix validate config#878

Merged
hatemhosny merged 2 commits intodevelopfrom
fix-validate-config
Sep 23, 2025
Merged

Fix validate config#878
hatemhosny merged 2 commits intodevelopfrom
fix-validate-config

Conversation

@hatemhosny
Copy link
Copy Markdown
Collaborator

@hatemhosny hatemhosny commented Sep 23, 2025

Summary by CodeRabbit

  • New Features
    • Editor configurations are now more flexible: object-based inputs for markup, style, and script are consistently validated.
  • Bug Fixes
    • Partial or invalid script configurations now retain provided fields and automatically apply a default language (JavaScript) for more reliable behavior.
  • Tests
    • Updated test coverage and expectations to reflect the enhanced validation behavior.

@netlify
Copy link
Copy Markdown

netlify Bot commented Sep 23, 2025

Deploy Preview for livecodes ready!

Name Link
🔨 Latest commit 968e2a5
🔍 Latest deploy log https://app.netlify.com/projects/livecodes/deploys/68d300d860dc240008a4f0c3
😎 Deploy Preview https://deploy-preview-878--livecodes.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 23, 2025

Walkthrough

The config validator now treats any object assigned to markup/style/script as an editor object and validates it via validateEditorProps. Tests were updated to expect a default language on script objects during validation.

Changes

Cohort / File(s) Summary
Validation logic
src/livecodes/config/validate-config.ts
Removed isEditor predicate and replaced checks with is(..., 'object') for markup/style/script. All object values for these fields now flow through validateEditorProps, potentially applying defaults (e.g., language).
Tests
src/livecodes/config/__tests__/validate-config.spec.ts
Updated expectation for "editor: invalid - obj": now expects { script: { language: 'javascript' } } (with existing script fields preserved) instead of an empty object.

Sequence Diagram(s)

sequenceDiagram
  participant UserConfig as User Config
  participant Validator as validate-config.ts
  participant EditorProps as validateEditorProps

  UserConfig->>Validator: validate(config)
  alt field is object (markup/style/script)
    Validator->>EditorProps: validateEditorProps(fieldObject)
    EditorProps-->>Validator: normalized object (e.g., adds default language)
    Validator-->>UserConfig: config with validated field
  else field not object
    Validator-->>UserConfig: config unchanged for that field
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I thump my paws at changing breeze,
Defaults hop in with gentle ease;
Scripts now speak in Java’s tongue,
While tests keep rhythm, neatly sung.
In burrows deep, validators cheer—
All objects welcome, hoppy here! 🐇💻

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Fix validate config" concisely and accurately reflects the main change in the patch, which updates validate-config behavior and related tests; it is short, relevant, and clearly tied to the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-validate-config

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown
Contributor

Size Change: -159 B (-0.02%)

Total Size: 955 kB

ℹ️ View Unchanged
Filename Size Change
./build/404.html 1 kB 0 B
./build/app.html 250 B 0 B
./build/index.html 2.46 kB -6 B (-0.24%)
./build/livecodes/app.js 111 kB -89 B (-0.08%)
./build/livecodes/app.css 22.4 kB 0 B
./build/livecodes/assets.js 8.65 kB +32 B (+0.37%)
./build/livecodes/assets/noop.js 18 B 0 B
./build/livecodes/assets/templates/diagrams-starter.html 2.19 kB 0 B
./build/livecodes/backup.js 3.72 kB -1 B (-0.03%)
./build/livecodes/blockly.js 13.3 kB 0 B
./build/livecodes/broadcast.js 1.19 kB 0 B
./build/livecodes/bundle-types.js 4.37 kB 0 B
./build/livecodes/code-to-image.js 9.13 kB +1 B (+0.01%)
./build/livecodes/codejar.js 17.6 kB 0 B
./build/livecodes/codemirror.js 6.33 kB 0 B
./build/livecodes/compile.page.js 2.39 kB 0 B
./build/livecodes/compile.worker.js 14.3 kB 0 B
./build/livecodes/compiler-utils.js 3.16 kB 0 B
./build/livecodes/custom-editor-utils.js 198 B 0 B
./build/livecodes/deploy.js 6.89 kB -5 B (-0.07%)
./build/livecodes/editor-settings.js 17.7 kB -35 B (-0.2%)
./build/livecodes/embed-ui.js 5.55 kB +2 B (+0.04%)
./build/livecodes/embed.js 89.4 kB -57 B (-0.06%)
./build/livecodes/export.js 3.89 kB 0 B
./build/livecodes/firebase.js 22.7 kB 0 B
./build/livecodes/format.worker.js 13.4 kB 0 B
./build/livecodes/google-fonts.js 7.12 kB 0 B
./build/livecodes/headless.js 78.3 kB -19 B (-0.02%)
./build/livecodes/i18n-ar-language-info.json 5.23 kB 0 B
./build/livecodes/i18n-ar-translation.json 9.33 kB 0 B
./build/livecodes/i18n-de-language-info.json 5.25 kB 0 B
./build/livecodes/i18n-de-translation.json 9.44 kB 0 B
./build/livecodes/i18n-en-language-info.json 4.54 kB 0 B
./build/livecodes/i18n-en-translation.json 8.03 kB 0 B
./build/livecodes/i18n-es-language-info.json 5 kB 0 B
./build/livecodes/i18n-es-translation.json 9.17 kB 0 B
./build/livecodes/i18n-fa-language-info.json 5.35 kB 0 B
./build/livecodes/i18n-fa-translation.json 9.48 kB 0 B
./build/livecodes/i18n-fr-language-info.json 5.17 kB 0 B
./build/livecodes/i18n-fr-translation.json 9.42 kB 0 B
./build/livecodes/i18n-hi-language-info.json 5.78 kB 0 B
./build/livecodes/i18n-hi-translation.json 9.95 kB 0 B
./build/livecodes/i18n-it-language-info.json 5.04 kB 0 B
./build/livecodes/i18n-it-translation.json 9.26 kB 0 B
./build/livecodes/i18n-ja-language-info.json 5.57 kB 0 B
./build/livecodes/i18n-ja-translation.json 9.61 kB 0 B
./build/livecodes/i18n-pt-language-info.json 5.05 kB 0 B
./build/livecodes/i18n-pt-translation.json 9.35 kB 0 B
./build/livecodes/i18n-ru-language-info.json 5.56 kB 0 B
./build/livecodes/i18n-ru-translation.json 10.3 kB 0 B
./build/livecodes/i18n-ur-language-info.json 5.81 kB 0 B
./build/livecodes/i18n-ur-translation.json 9.78 kB 0 B
./build/livecodes/i18n-zh-CN-language-info.json 4.9 kB 0 B
./build/livecodes/i18n-zh-CN-translation.json 8.64 kB 0 B
./build/livecodes/i18n.js 20.2 kB -1 B (0%)
./build/livecodes/import-src.js 16 kB 0 B
./build/livecodes/import.js 14.5 kB +16 B (+0.11%)
./build/livecodes/index.js 5.34 kB +1 B (+0.02%)
./build/livecodes/lang-art-template-compiler.js 1.65 kB 0 B
./build/livecodes/lang-assemblyscript-compiler.js 290 B 0 B
./build/livecodes/lang-assemblyscript-script.js 386 B 0 B
./build/livecodes/lang-astro-compiler.js 2.34 kB 0 B
./build/livecodes/lang-clio-compiler.js 1.55 kB 0 B
./build/livecodes/lang-commonlisp-script.js 123 B 0 B
./build/livecodes/lang-cpp-script.js 1.75 kB 0 B
./build/livecodes/lang-cpp-wasm-script.js 2.84 kB 0 B
./build/livecodes/lang-csharp-wasm-script.js 2.18 kB 0 B
./build/livecodes/lang-diagrams-compiler-esm.js 5.08 kB 0 B
./build/livecodes/lang-dot-compiler.js 1.66 kB 0 B
./build/livecodes/lang-ejs-compiler.js 1.63 kB 0 B
./build/livecodes/lang-eta-compiler.js 1.65 kB 0 B
./build/livecodes/lang-fennel-compiler.js 1.61 kB 0 B
./build/livecodes/lang-gleam-compiler.js 3.09 kB 0 B
./build/livecodes/lang-go-wasm-script.js 3.26 kB 0 B
./build/livecodes/lang-haml-compiler.js 1.65 kB 0 B
./build/livecodes/lang-handlebars-compiler.js 1.92 kB 0 B
./build/livecodes/lang-imba-compiler.js 147 B 0 B
./build/livecodes/lang-java-script.js 4.05 kB 0 B
./build/livecodes/lang-jinja-compiler.js 1.65 kB 0 B
./build/livecodes/lang-julia-script.js 3.3 kB 0 B
./build/livecodes/lang-liquid-compiler.js 1.68 kB 0 B
./build/livecodes/lang-lua-wasm-script.js 205 B 0 B
./build/livecodes/lang-malina-compiler.js 2.94 kB 0 B
./build/livecodes/lang-mustache-compiler.js 1.65 kB 0 B
./build/livecodes/lang-nunjucks-compiler.js 1.93 kB 0 B
./build/livecodes/lang-perl-script.js 268 B 0 B
./build/livecodes/lang-php-wasm-script.js 347 B 0 B
./build/livecodes/lang-postgresql-compiler-esm.js 1.73 kB 0 B
./build/livecodes/lang-prolog-script.js 204 B 0 B
./build/livecodes/lang-pug-compiler.js 371 B 0 B
./build/livecodes/lang-python-wasm-script.js 1.92 kB 0 B
./build/livecodes/lang-r-script-esm.js 2.44 kB 0 B
./build/livecodes/lang-rescript-compiler-esm.js 2.16 kB 0 B
./build/livecodes/lang-rescript-formatter.js 1.52 kB 0 B
./build/livecodes/lang-riot-compiler.js 2.79 kB 0 B
./build/livecodes/lang-ruby-wasm-script.js 1.71 kB 0 B
./build/livecodes/lang-scss-compiler.js 1.71 kB 0 B
./build/livecodes/lang-solid-compiler.js 263 B 0 B
./build/livecodes/lang-sql-compiler.js 1.63 kB 0 B
./build/livecodes/lang-sql-script.js 1.96 kB 0 B
./build/livecodes/lang-svelte-compiler.js 4.67 kB 0 B
./build/livecodes/lang-tcl-script.js 1.82 kB 0 B
./build/livecodes/lang-teal-compiler.js 1.72 kB 0 B
./build/livecodes/lang-twig-compiler.js 1.64 kB 0 B
./build/livecodes/lang-vento-compiler.js 1.68 kB 0 B
./build/livecodes/lang-vue-compiler.js 6.06 kB 0 B
./build/livecodes/lang-vue2-compiler.js 3.45 kB 0 B
./build/livecodes/lang-wat-compiler.js 348 B 0 B
./build/livecodes/lang-wat-script.js 1.58 kB 0 B
./build/livecodes/language-info.js 7.71 kB 0 B
./build/livecodes/monaco-lang-astro.js 947 B 0 B
./build/livecodes/monaco-lang-clio.js 639 B 0 B
./build/livecodes/monaco-lang-imba.js 7.35 kB 0 B
./build/livecodes/monaco-lang-wat.js 2.46 kB 0 B
./build/livecodes/monaco.js 10.1 kB 0 B
./build/livecodes/open.js 6.21 kB +4 B (+0.06%)
./build/livecodes/processor-lightningcss-compiler.js 1.88 kB 0 B
./build/livecodes/processor-postcss-compiler.js 2.02 kB 0 B
./build/livecodes/processor-tailwindcss-compiler.js 5.06 kB 0 B
./build/livecodes/processor-unocss-compiler.js 355 B 0 B
./build/livecodes/processor-windicss-compiler.js 450 B 0 B
./build/livecodes/quill.css 697 B 0 B
./build/livecodes/quill.js 5.74 kB 0 B
./build/livecodes/resources.js 3.43 kB 0 B
./build/livecodes/result-utils.js 1.17 kB 0 B
./build/livecodes/share.js 3.81 kB -1 B (-0.03%)
./build/livecodes/snippets.js 6.04 kB 0 B
./build/livecodes/sync-ui.js 3.25 kB -1 B (-0.03%)
./build/livecodes/sync.js 3.55 kB 0 B
./build/livecodes/sync.worker.js 29.7 kB 0 B
./build/livecodes/templates.js 25.4 kB 0 B
./build/sdk/livecodes.js 3.96 kB 0 B
./build/sdk/livecodes.umd.js 4.02 kB 0 B
./build/sdk/package.json 293 B 0 B
./build/sdk/react.js 4.24 kB 0 B
./build/sdk/vue.js 4.35 kB 0 B

compressed-size-action

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/livecodes/config/validate-config.ts (1)

57-76: Guard language before calling getLanguageEditorId

With the broader object acceptance, x.language may be missing. Guard to avoid passing undefined into getLanguageEditorId.

-  const validateEditorProps = (x: Editor, editorId: EditorId): Editor => ({
-    language: fixSfcLanguage(
-      getLanguageEditorId(fixSfcLanguage(x.language, editorId)) === editorId
-        ? getLanguageByAlias(x.language) || defaultConfig[editorId].language
-        : defaultConfig[editorId].language,
-      editorId,
-    ),
+  const validateEditorProps = (x: Editor, editorId: EditorId): Editor => ({
+    language: (() => {
+      const base = is((x as any).language, 'string')
+        ? ((x as any).language as Language)
+        : defaultConfig[editorId].language;
+      const adjusted =
+        getLanguageEditorId(fixSfcLanguage(base, editorId)) === editorId
+          ? getLanguageByAlias(base) || defaultConfig[editorId].language
+          : defaultConfig[editorId].language;
+      return fixSfcLanguage(adjusted, editorId);
+    })(),
     ...(is(x.title, 'string') ? { title: x.title } : {}),
     ...(is(x.content, 'string') ? { content: x.content } : {}),
     ...(is(x.contentUrl, 'string') ? { contentUrl: x.contentUrl } : {}),
     ...(is(x.hideTitle, 'boolean') ? { hideTitle: x.hideTitle } : {}),
     ...(is(x.hiddenContent, 'string') ? { hiddenContent: x.hiddenContent } : {}),
src/livecodes/config/__tests__/validate-config.spec.ts (1)

160-160: Expectation update looks good; add array-case coverage

The new expectation aligns with broader object handling. Add a test to ensure arrays are rejected (after tightening the guard):

test('editor: invalid - array', () => {
  const testConfig = { script: [] } as any;
  const correctConfig = {};
  expect(validateConfig(testConfig)).toEqual(correctConfig);
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 341c5d5 and 968e2a5.

📒 Files selected for processing (2)
  • src/livecodes/config/__tests__/validate-config.spec.ts (1 hunks)
  • src/livecodes/config/validate-config.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/livecodes/config/validate-config.ts (1)
src/sdk/models.ts (1)
  • Editor (1093-1166)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Redirect rules - livecodes
  • GitHub Check: Header rules - livecodes
  • GitHub Check: build (18.x)
  • GitHub Check: tests (18.x, 4)
  • GitHub Check: tests (18.x, 5)
  • GitHub Check: tests (18.x, 3)
  • GitHub Check: tests (18.x, 1)
  • GitHub Check: tests (18.x, 2)
  • GitHub Check: Pages changed - livecodes
  • GitHub Check: build
  • GitHub Check: Cloudflare Pages

Comment on lines +141 to 149
...(is(config.markup, 'object')
? { markup: validateEditorProps(config.markup as Editor, 'markup') }
: {}),
...(isEditor(config.style)
...(is(config.style, 'object')
? { style: validateEditorProps(config.style as Editor, 'style') }
: {}),
...(isEditor(config.script)
...(is(config.script, 'object')
? { script: validateEditorProps(config.script as Editor, 'script') }
: {}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Don’t treat arrays as editors; gate with a plain-object check

is(x, 'object') returns true for arrays, so markup/style/script arrays will be passed to validateEditorProps, silently coercing bad inputs into defaulted editors. Tighten the guard to exclude arrays.

Apply this diff:

@@
   const zoomLevels: Array<Config['zoom']> = [1, 0.5, 0.25];
 
   const isFoldedLines = (x: any) => is(x, 'object') && (is(x.from, 'number') || is(x.to, 'number'));
 
+  const isPlainObject = (x: any): x is Record<string, unknown> =>
+    x != null && typeof x === 'object' && !Array.isArray(x);
+
@@
-    ...(is(config.markup, 'object')
+    ...(isPlainObject(config.markup)
       ? { markup: validateEditorProps(config.markup as Editor, 'markup') }
       : {}),
-    ...(is(config.style, 'object')
+    ...(isPlainObject(config.style)
       ? { style: validateEditorProps(config.style as Editor, 'style') }
       : {}),
-    ...(is(config.script, 'object')
+    ...(isPlainObject(config.script)
       ? { script: validateEditorProps(config.script as Editor, 'script') }
       : {}),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
...(is(config.markup, 'object')
? { markup: validateEditorProps(config.markup as Editor, 'markup') }
: {}),
...(isEditor(config.style)
...(is(config.style, 'object')
? { style: validateEditorProps(config.style as Editor, 'style') }
: {}),
...(isEditor(config.script)
...(is(config.script, 'object')
? { script: validateEditorProps(config.script as Editor, 'script') }
: {}),
...(isPlainObject(config.markup)
? { markup: validateEditorProps(config.markup as Editor, 'markup') }
: {}),
...(isPlainObject(config.style)
? { style: validateEditorProps(config.style as Editor, 'style') }
: {}),
...(isPlainObject(config.script)
? { script: validateEditorProps(config.script as Editor, 'script') }
: {}),
🤖 Prompt for AI Agents
In src/livecodes/config/validate-config.ts around lines 141 to 149, the current
guards use is(x, 'object') which returns true for arrays and allows arrays to be
passed into validateEditorProps; change the checks to ensure markup/style/script
are plain objects (exclude arrays and null) before calling validateEditorProps —
e.g., replace the is(...) checks with a plain-object test (like typeof ===
'object' && !Array.isArray(...) && value !== null or use a project helper such
as isPlainObject) so arrays are not treated as editors.

@hatemhosny hatemhosny merged commit b46f8ca into develop Sep 23, 2025
20 checks passed
@hatemhosny hatemhosny deleted the fix-validate-config branch September 24, 2025 11:45
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.

1 participant