diff --git a/.husky/pre-commit b/.husky/pre-commit index dff836d..a52db04 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1 +1 @@ -pnpm exec lint-staged \ No newline at end of file +pnpm test && pnpm exec lint-staged diff --git a/package.json b/package.json index 5d6e2cc..4f80131 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "build": "turbo run build", "lint": "turbo run lint", "type-check": "turbo run type-check", - "prepare": "husky" + "prepare": "husky", + "test": "turbo run test" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.50.0", @@ -18,7 +19,8 @@ "lint-staged": "^16.2.7", "prettier": "^3.7.4", "turbo": "^2.0.0", - "typescript": "^5.3.0" + "typescript": "^5.3.0", + "vitest": "^4.0.16" }, "packageManager": "pnpm@9.0.0", "engines": { diff --git a/packages/core/CONTRIBUTING.md b/packages/core/CONTRIBUTING.md index fe14ef3..dc126aa 100644 --- a/packages/core/CONTRIBUTING.md +++ b/packages/core/CONTRIBUTING.md @@ -72,20 +72,13 @@ To add support for a new app (e.g., Twitter/X, TikTok), follow these steps in `p 2. **Export the Handler:** Add your new handler to `packages/core/src/platforms/index.ts`. - -3. **Register the Handler:** - Import and add your handler to the `handlers` array in `packages/core/src/index.ts`. + Add your new handler to the `handlers` array in `packages/core/src/platforms/index.ts`. ```typescript - // packages/core/src/index.ts - import { - instagramHandler, - linkedinHandler, - youtubeHandler, - twitterHandler, // Import your new handler - } from './platforms'; + // packages/core/src/platforms/index.ts + import { twitterHandler } from './twitter'; - const handlers = [ + export const handlers = [ youtubeHandler, linkedinHandler, instagramHandler, @@ -93,6 +86,26 @@ To add support for a new app (e.g., Twitter/X, TikTok), follow these steps in `p ]; ``` +3. **Add Tests:** + Add tests for your new handler in `packages/core/src/tests/index.test.ts`. + ```typescript + // packages/core/src/tests/index.test.ts + const testCases: SocialLinks = { + // ...other cases + twitter: [ + { + name: 'twitter profile', + url: 'https://twitter.com/elonmusk', + webUrl: 'https://twitter.com/elonmusk', + ios: 'twitter://user?screen_name=elonmusk', + android: + 'intent://user?screen_name=elonmusk#Intent;scheme=twitter;package=com.twitter.android;end', + }, + ], + // ...other cases + }; + ``` + ## Testing on Mobile To verify that your deep link works correctly: diff --git a/packages/core/package.json b/packages/core/package.json index 095328b..3e654cc 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -20,6 +20,7 @@ "scripts": { "build": "tsup", "dev": "tsup --watch", + "test": "vitest run", "prepublishOnly": "pnpm build", "type-check": "tsc --noEmit" }, @@ -43,6 +44,7 @@ }, "devDependencies": { "tsup": "^8.0.0", - "typescript": "^5.3.0" + "typescript": "^5.3.0", + "vitest": "^4.0.16" } } diff --git a/packages/core/src/tests/index.test.ts b/packages/core/src/tests/index.test.ts new file mode 100644 index 0000000..91b0aa1 --- /dev/null +++ b/packages/core/src/tests/index.test.ts @@ -0,0 +1,204 @@ +import { describe, it, expect } from 'vitest'; +import { generateDeepLink } from '../index'; +import type { PlatformLink, SocialLinks } from './types'; + +function generateDeepLinkTest(platform: string, links: PlatformLink[]) { + describe(platform, () => { + for (const link of links) { + it(link.name, () => { + const deepLink = generateDeepLink(link.url); + expect(deepLink).toBeDefined(); + expect(deepLink.platform).toBe(platform); + expect(deepLink.webUrl).toBe(link.webUrl); + expect(deepLink.ios).toBe(link.ios); + expect(deepLink.android).toBe(link.android); + }); + } + }); +} + +const testCases: SocialLinks = { + discord: [ + { + name: 'discord channel', + url: 'https://discord.com/channels/1451197679739863177/1451197680259829793', + webUrl: 'https://discord.com/channels/1451197679739863177/1451197680259829793', + ios: 'discord://channels/1451197679739863177/1451197680259829793', + android: + 'intent://discord.com/channels/1451197679739863177/1451197680259829793#Intent;scheme=discord;package=com.discord;end', + }, + { + name: 'discord invite', + url: 'https://discord.gg/MWwnUKaq', + webUrl: 'https://discord.gg/MWwnUKaq', + ios: 'discord://invite/MWwnUKaq', + android: 'intent://discord.gg/MWwnUKaq#Intent;scheme=discord;package=com.discord;end', + }, + ], + facebook: [ + { + name: 'facebook profile', + url: 'https://www.facebook.com/Google/', + webUrl: 'https://facebook.com/Google', + ios: 'fb://facewebmodal/f?href=facebook.com/Google', + android: 'intent://facebook.com/Google#Intent;scheme=https;package=com.facebook.katana;end', + }, + ], + github: [ + { + name: 'github profile', + url: 'https://github.com/kishandev2509', + webUrl: 'https://github.com/kishandev2509', + ios: 'github://user/kishandev2509', + android: + 'intent://github.com/kishandev2509#Intent;scheme=https;package=com.github.android;end', + }, + ], + instagram: [ + { + name: 'instagram profile', + url: 'https://www.instagram.com/kishand.ev/', + webUrl: 'https://instagram.com/kishand.ev', + ios: 'instagram://user?username=kishand.ev', + android: + 'intent://user?username=kishand.ev#Intent;scheme=instagram;package=com.instagram.android;end', + }, + ], + linkedin: [ + { + name: 'linkedin profile', + url: 'https://www.linkedin.com/in/kishandev2509/', + webUrl: 'https://linkedin.com/in/kishandev2509', + ios: 'linkedin://in/kishandev2509', + android: + 'intent://linkedin.com/in/kishandev2509#Intent;scheme=https;package=com.linkedin.android;S.browser_fallback_url=https://linkedin.com/in/kishandev2509;end', + }, + ], + pinterest: [ + { + name: 'pinterest pin', + url: 'https://www.pinterest.com/pin/paisajes-in-2023--55098795435856717/', + webUrl: 'https://pinterest.com/pin/paisajes-in-2023--55098795435856717', + ios: 'pinterest://board/pin/paisajes-in-2023--55098795435856717', + android: + 'intent://pinterest.com/pin/paisajes-in-2023--55098795435856717#Intent;scheme=https;package=com.pinterest;S.browser_fallback_url=https%3A%2F%2Fpinterest.com%2Fpin%2Fpaisajes-in-2023--55098795435856717;end', + }, + ], + reddit: [ + { + name: 'reddit post', + url: 'https://www.reddit.com/r/IndiaTech/comments/1q6dk9y/vlc_and_where_is_my_train/#lightbox', + webUrl: 'https://reddit.com/r/IndiaTech/comments/1q6dk9y/vlc_and_where_is_my_train#lightbox', + ios: 'reddit://r/IndiaTech', + android: 'intent://r/IndiaTech#Intent;scheme=reddit;package=com.reddit.android;end', + }, + ], + snapchat: [ + { + name: 'snapchat add profile', + url: 'https://www.snapchat.com/add/random', + webUrl: 'https://snapchat.com/add/random', + ios: 'snapchat://add/random', + android: + 'intent://add/random#Intent;scheme=snapchat;package=com.snapchat.android;S.browser_fallback_url=https%3A%2F%2Fsnapchat.com%2Fadd%2Frandom;end', + }, + ], + spotify: [ + { + name: 'spotify artist', + url: 'https://open.spotify.com/artist/4YRxDV8wJFPHPTeXepOstw', + webUrl: 'https://open.spotify.com/artist/4YRxDV8wJFPHPTeXepOstw', + ios: 'spotify:artist:4YRxDV8wJFPHPTeXepOstw', + android: + 'intent://artist/4YRxDV8wJFPHPTeXepOstw#Intent;scheme=spotify;package=com.spotify.music;end', + }, + ], + substack: [ + { + name: 'substack profile', + url: 'https://example.substack.com', + webUrl: 'https://example.substack.com/', + ios: 'https://example.substack.com/', + android: 'https://example.substack.com/', + }, + ], + telegram: [ + { + name: 'telegram profile', + url: 'https://t.me/kishandev2509', + webUrl: 'https://t.me/kishandev2509', + ios: 'tg://resolve?domain=kishandev2509', + android: 'intent://resolve?domain=kishandev2509#Intent;scheme=tg;end', + }, + ], + threads: [ + { + name: 'threads profile', + url: 'https://www.threads.net/@iamsaban', + webUrl: 'https://threads.net/@iamsaban', + ios: 'barcelona://user?username=iamsaban', + android: + 'intent://threads.net/@iamsaban#Intent;scheme=https;package=com.instagram.barcelona;end', + }, + ], + twitch: [ + { + name: 'twitch profile', + url: 'https://www.twitch.tv/directory/tags/80427d95-bb46-42d3-bf4d-408e9bdca49a', + webUrl: 'https://twitch.tv/directory/tags/80427d95-bb46-42d3-bf4d-408e9bdca49a', + ios: 'twitch://directory/tags/80427d95-bb46-42d3-bf4d-408e9bdca49a', + android: + 'intent://twitch.tv/directory/tags/80427d95-bb46-42d3-bf4d-408e9bdca49a#Intent;scheme=https;package=tv.twitch.android.app;S.browser_fallback_url=https%3A%2F%2Ftwitch.tv%2Fdirectory%2Ftags%2F80427d95-bb46-42d3-bf4d-408e9bdca49a;end', + }, + ], + whatsapp: [ + { + name: 'whatsapp', + url: 'https://wa.me/919876543210', + webUrl: 'https://web.whatsapp.com/send?phone=+919876543210', + ios: 'whatsapp://send?phone=+919876543210', + android: 'intent://send?phone=+919876543210#Intent;scheme=whatsapp;package=com.whatsapp;end', + }, + ], + youtube: [ + { + name: 'youtube with video id', + url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', + webUrl: 'https://youtube.com/watch?v=dQw4w9WgXcQ', + ios: 'vnd.youtube://watch?v=dQw4w9WgXcQ', + android: + 'intent://watch?v=dQw4w9WgXcQ#Intent;scheme=vnd.youtube;package=com.google.android.youtube;end', + }, + { + name: 'youtube with video id and time', + url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=10s', + webUrl: 'https://youtube.com/watch?v=dQw4w9WgXcQ&t=10s', + ios: 'vnd.youtube://watch?v=dQw4w9WgXcQ&t=10s', + android: + 'intent://watch?v=dQw4w9WgXcQ&t=10s#Intent;scheme=vnd.youtube;package=com.google.android.youtube;end', + }, + ], + zoom: [ + { + name: 'zoom meeting', + url: 'https://zoom.us/j/1234567890', + webUrl: 'https://zoom.us/j/1234567890', + ios: 'zoomus://zoom.us/join?confno=1234567890', + android: + 'intent://zoom.us/join?confno=1234567890#Intent;scheme=zoomus;package=us.zoom.videomeetings;end', + }, + ], + unknown: [ + { + name: 'unknown', + url: 'https://www.google.com', + webUrl: 'https://google.com/', + ios: null, + android: null, + }, + ], +}; + +Object.entries(testCases).forEach(([platform, links]) => { + generateDeepLinkTest(platform, links); +}); diff --git a/packages/core/src/tests/types.ts b/packages/core/src/tests/types.ts new file mode 100644 index 0000000..5b24aa8 --- /dev/null +++ b/packages/core/src/tests/types.ts @@ -0,0 +1,11 @@ +import { Platform } from '../types'; + +export type PlatformLink = { + name: string; + url: string; + webUrl: string; + ios: string | null; + android: string | null; +}; + +export type SocialLinks = Record; diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 5d262e7..c3ac464 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -9,5 +9,5 @@ "lib": ["ES2020", "DOM"] }, "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "exclude": ["node_modules", "dist", "src/tests/**/*", "**/*.test.ts"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 861e910..6d2dfb1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: typescript: specifier: ^5.3.0 version: 5.9.3 + vitest: + specifier: ^4.0.16 + version: 4.0.16(yaml@2.8.2) apps/demo: dependencies: @@ -57,6 +60,9 @@ importers: typescript: specifier: ^5.3.0 version: 5.9.3 + vitest: + specifier: ^4.0.16 + version: 4.0.16(yaml@2.8.2) packages: @@ -531,6 +537,15 @@ packages: cpu: [x64] os: [win32] + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -596,6 +611,35 @@ packages: resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vitest/expect@4.0.16': + resolution: {integrity: sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==} + + '@vitest/mocker@4.0.16': + resolution: {integrity: sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.16': + resolution: {integrity: sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==} + + '@vitest/runner@4.0.16': + resolution: {integrity: sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==} + + '@vitest/snapshot@4.0.16': + resolution: {integrity: sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==} + + '@vitest/spy@4.0.16': + resolution: {integrity: sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==} + + '@vitest/utils@4.0.16': + resolution: {integrity: sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -631,6 +675,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -658,6 +706,10 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -725,6 +777,9 @@ packages: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -783,6 +838,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -790,6 +848,10 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -989,6 +1051,9 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + onetime@7.0.0: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} @@ -1115,6 +1180,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -1131,6 +1199,12 @@ packages: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -1167,13 +1241,24 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1290,11 +1375,90 @@ packages: terser: optional: true + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.0.16: + resolution: {integrity: sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.16 + '@vitest/browser-preview': 4.0.16 + '@vitest/browser-webdriverio': 4.0.16 + '@vitest/ui': 4.0.16 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -1598,6 +1762,15 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.53.5': optional: true + '@standard-schema/spec@1.1.0': {} + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + '@types/estree@1.0.8': {} '@types/json-schema@7.0.15': {} @@ -1693,6 +1866,45 @@ snapshots: '@typescript-eslint/types': 8.50.0 eslint-visitor-keys: 4.2.1 + '@vitest/expect@4.0.16': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.16 + '@vitest/utils': 4.0.16 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.16(vite@7.3.1(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.0.16 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(yaml@2.8.2) + + '@vitest/pretty-format@4.0.16': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.16': + dependencies: + '@vitest/utils': 4.0.16 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.16': + dependencies: + '@vitest/pretty-format': 4.0.16 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.16': {} + + '@vitest/utils@4.0.16': + dependencies: + '@vitest/pretty-format': 4.0.16 + tinyrainbow: 3.0.3 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -1722,6 +1934,8 @@ snapshots: argparse@2.0.1: {} + assertion-error@2.0.1: {} + balanced-match@1.0.2: {} brace-expansion@1.1.12: @@ -1746,6 +1960,8 @@ snapshots: callsites@3.1.0: {} + chai@6.2.2: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -1798,6 +2014,8 @@ snapshots: environment@1.1.0: {} + es-module-lexer@1.7.0: {} + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -1923,10 +2141,16 @@ snapshots: estraverse@5.3.0: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + esutils@2.0.3: {} eventemitter3@5.0.1: {} + expect-type@1.3.0: {} + fast-deep-equal@3.1.3: {} fast-json-stable-stringify@2.1.0: {} @@ -2105,6 +2329,8 @@ snapshots: object-assign@4.1.1: {} + obug@2.1.1: {} + onetime@7.0.0: dependencies: mimic-function: 5.0.1 @@ -2220,6 +2446,8 @@ snapshots: shebang-regex@3.0.0: {} + siginfo@2.0.0: {} + signal-exit@4.1.0: {} slice-ansi@7.1.2: @@ -2231,6 +2459,10 @@ snapshots: source-map@0.7.6: {} + stackback@0.0.2: {} + + std-env@3.10.0: {} + string-argv@0.3.2: {} string-width@7.2.0: @@ -2272,13 +2504,19 @@ snapshots: dependencies: any-promise: 1.3.0 + tinybench@2.9.0: {} + tinyexec@0.3.2: {} + tinyexec@1.0.2: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@3.0.3: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -2366,10 +2604,62 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + vite@7.3.1(yaml@2.8.2): + dependencies: + esbuild: 0.27.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.5 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + yaml: 2.8.2 + + vitest@4.0.16(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.16 + '@vitest/mocker': 4.0.16(vite@7.3.1(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.16 + '@vitest/runner': 4.0.16 + '@vitest/snapshot': 4.0.16 + '@vitest/spy': 4.0.16 + '@vitest/utils': 4.0.16 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(yaml@2.8.2) + why-is-node-running: 2.3.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + which@2.0.2: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wrap-ansi@9.0.2: diff --git a/tsconfig.json b/tsconfig.json index 72d043e..3acfad2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,5 +12,5 @@ "isolatedModules": true, "noEmit": true }, - "exclude": ["node_modules", "dist"] + "exclude": ["node_modules", "dist", "src/tests/**/*", "**/*.test.ts"] } diff --git a/turbo.json b/turbo.json index 145b635..d8fb284 100644 --- a/turbo.json +++ b/turbo.json @@ -12,6 +12,9 @@ "lint": { "dependsOn": ["^build"] }, - "type-check": {} + "type-check": {}, + "test": { + "outputs": [] + } } }