chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

chore(vue,types): Add initial support for SFC files to improve runtime prop checking - #4902

Merged
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props
Jan 16, 2025
Merged

chore(vue,types): Add initial support for SFC files to improve runtime prop checking#4902
wobsoriano merged 18 commits into
mainfrom
rob/fix-vue-components-runtime-props

Conversation

@wobsoriano

@wobsorianowobsoriano commented Jan 15, 2025

Copy link
Copy Markdown
Member

Description

This PR adds initial support for Vue Single-File Components starting with the <SignIn /> component.

Right now we're using render functions to build out our Clerk components and this Esbuild plugin to generate prop types (e.g. SignInProps) to runtime props. This way, we can have the Vue SDK component prop in sync with prop types imported from @clerk/types.

The problem above is that it generates props but without runtime type validation (only type validation in IDE). Example output:

Screenshot 2025-01-15 at 12 24 13 PM

With this PR, it also generate runtime type props:

Screenshot 2025-01-15 at 11 59 07 AM

Everything should still function the same. I'll do a follow up PR for the rest of the components 🫡

Additional context

We're also doing this to unblock the release of the new sign-in-or-up feature which is not properly working with the current setup. If you have something like this:

<SignIn withSignUp />
<SignIn with-sign-up />
<SignIn :with-sign-up="true" />

The 3rd one above will only work as we're forcefully setting the value. The first 2 ones are expected to output true as the value but instead outputs an empty string:

Screenshot 2025-01-15 at 12 59 31 PM

This results in a falsy value and depending on the logic, might have some unexpected results. It happens because it does not have a proper runtime type.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@vercel

vercelBot commented Jan 15, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

NameStatusPreviewCommentsUpdated (UTC)
clerk-js-sandbox✅ Ready (Inspect)Visit Preview💬 Add feedbackJan 16, 2025 4:24pm

@changeset-bot

changeset-botBot commented Jan 15, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 03ab2e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
NameType
@clerk/typesPatch
@clerk/vuePatch
@clerk/astroPatch
@clerk/backendPatch
@clerk/clerk-jsPatch
@clerk/elementsPatch
@clerk/expo-passkeysPatch
@clerk/clerk-expoPatch
@clerk/expressPatch
@clerk/fastifyPatch
@clerk/localizationsPatch
@clerk/nextjsPatch
@clerk/nuxtPatch
@clerk/react-routerPatch
@clerk/clerk-reactPatch
@clerk/remixPatch
@clerk/sharedPatch
@clerk/tanstack-startPatch
@clerk/testingPatch
@clerk/themesPatch
@clerk/uiPatch
@clerk/chrome-extensionPatch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wobsoriano
wobsorianoforce-pushed the rob/fix-vue-components-runtime-props branch from 9260c12 to fa6e4a4CompareJanuary 15, 2025 20:06
@wobsoriano
wobsoriano marked this pull request as ready for review January 15, 2025 20:28
Comment on lines +17 to +20
dts: false,
esbuildPlugins: [
// Adds .vue files support
vuePlugin() as EsbuildPlugin,

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This vuePlugin transforms .vue files to JavaScript. We also turned off dts generation of tsup so that the vue-tsc module will generate it instead

@wobsorianowobsoriano changed the title chore(vue,types): Add initial support for SFC files to improve runtime prop checkingchore(vue): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
Comment on lines +61 to +63
"unplugin-vue": "^5.2.1",
"vue": "3.5.12",
"vue-tsc": "^2.0.24"

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

unplugin-vue - esbuild plugin to tranform .vue files to JS
vue-tsc - dts emit with .vue file support

AfterSignOutUrl;

interface TransferableOption {
export interface TransferableOption {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'm getting a transitive type dependency error because the SignInProps is exported but not the TransferableOption interface that it depends on

@wobsorianowobsoriano changed the title chore(vue): Add initial support for SFC files to improve runtime prop checkingchore(vue,types): Add initial support for SFC files to improve runtime prop checkingJan 15, 2025
@clerkclerk deleted a comment from clerk-cookieJan 15, 2025
globals: true,
environment: 'jsdom',
},
plugins: [vue()],

@wobsorianowobsorianoJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Required when testing .vue SFC files

@clerkclerk deleted a comment from clerk-cookieJan 15, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignIn /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This is the <SignInButton /> component and functions the same as before only that we moved it into a single-file component (SFC) and that the Esbuild Vue plugin (check tsup config) can convert the typescript type props to runtime type props

Comment threadpackages/vue/package.json Outdated
"scripts": {
"build": "tsup",
"build": "tsup --onSuccess \"pnpm build:dts\"",
"build:dts": "vue-tsc --declaration --emitDeclarationOnly && rm -rf dist/components/__tests__",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you tell vue-tsc to ignore the test files so that we don't have to run rm -rf?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Updated! Got the idea here

<script setup lang="ts">
import { Portal } from '../uiComponents';
import { useClerk } from '../../composables';
import { SignInProps } from '@clerk/types';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Add type on the import

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

added!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@wobsoriano@octoper@LekoArts@clerk-cookie