diff --git a/README.md b/README.md
index 136b066f..752f4094 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ For a preview of extensions running these technologies, see documentation about
| | | | | | | | | |
| :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: |
-| ESNext
✅ | TypeScript
✅ | WASM
✅ | React
✅ | Vue
✅ | Angular
👋 | Svelte
👋 | Solid
👋 | Preact
✅ |
+| ESNext
✅ | TypeScript
✅ | WASM
✅ | React
✅ | Vue
✅ | Angular
👋 | Svelte
✅ | Solid
👋 | Preact
✅ |
👋 = PR Welcome!
diff --git a/examples/data.ts b/examples/data.ts
index 6cb58584..1efa82fa 100644
--- a/examples/data.ts
+++ b/examples/data.ts
@@ -355,6 +355,15 @@ const FRAMEWORK_TEMPLATES: Template[] = [
hasBackground: false,
hasEnv: false,
configFiles: ['postcss.config.js', 'tailwind.config.js', 'tsconfig.json']
+ },
+ {
+ name: 'new-svelte',
+ uiContext: ['newTab'],
+ uiFramework: 'svelte',
+ css: 'css',
+ hasBackground: false,
+ hasEnv: false,
+ configFiles: ['tsconfig.json']
}
]
diff --git a/examples/new-svelte/.gitignore b/examples/new-svelte/.gitignore
new file mode 100644
index 00000000..5e8c65b7
--- /dev/null
+++ b/examples/new-svelte/.gitignore
@@ -0,0 +1,31 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+node_modules
+
+# testing
+coverage
+
+# production
+dist
+
+# misc
+.DS_Store
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# lock files
+yarn.lock
+package-lock.json
+
+# debug files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# extension.js
+extension-env.d.ts
diff --git a/examples/new-svelte/images/extension_48.png b/examples/new-svelte/images/extension_48.png
new file mode 100644
index 00000000..f60575b3
Binary files /dev/null and b/examples/new-svelte/images/extension_48.png differ
diff --git a/examples/new-svelte/manifest.json b/examples/new-svelte/manifest.json
new file mode 100644
index 00000000..d01b9833
--- /dev/null
+++ b/examples/new-svelte/manifest.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://json.schemastore.org/chrome-manifest.json",
+ "manifest_version": 3,
+ "version": "0.0.1",
+ "name": "New Tab Svelte",
+ "description": "An Extension.js example.",
+ "icons": {
+ "48": "images/extension_48.png"
+ },
+ "chrome_url_overrides": {
+ "newtab": "newtab/index.html"
+ }
+}
diff --git a/examples/new-svelte/newtab/NewTabApp.svelte b/examples/new-svelte/newtab/NewTabApp.svelte
new file mode 100644
index 00000000..abdb8d17
--- /dev/null
+++ b/examples/new-svelte/newtab/NewTabApp.svelte
@@ -0,0 +1,18 @@
+
+
+
diff --git a/examples/new-svelte/newtab/index.html b/examples/new-svelte/newtab/index.html
new file mode 100644
index 00000000..3b5b215a
--- /dev/null
+++ b/examples/new-svelte/newtab/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ Svelte Template
+
+
+
+
+
+
+
diff --git a/examples/new-svelte/newtab/script.ts b/examples/new-svelte/newtab/script.ts
new file mode 100644
index 00000000..91038953
--- /dev/null
+++ b/examples/new-svelte/newtab/script.ts
@@ -0,0 +1,8 @@
+import 'sakura.css'
+import './styles.css'
+import App from './NewTabApp.svelte'
+
+const app = new App({
+ target: document.getElementById('app')!
+})
+export default app
diff --git a/examples/new-svelte/newtab/styles.css b/examples/new-svelte/newtab/styles.css
new file mode 100644
index 00000000..27482048
--- /dev/null
+++ b/examples/new-svelte/newtab/styles.css
@@ -0,0 +1,85 @@
+html {
+ font-size: 62.5%;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
+ 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
+}
+
+body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: calc(100vh - 4rem);
+ min-width: 300px;
+ padding: 2rem;
+ font-size: 1.8rem;
+ line-height: 1.618;
+ max-width: 38em;
+ margin: auto;
+ color: #c9c9c9;
+ background-color: #0a0c10;
+}
+
+@media (max-width: 684px) {
+ body {
+ font-size: 1.53rem;
+ }
+}
+
+@media (max-width: 382px) {
+ body {
+ font-size: 1.35rem;
+ }
+}
+
+h1 {
+ line-height: 1.1;
+ font-weight: 700;
+ margin-bottom: 1.5rem;
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ word-break: break-word;
+ font-size: 4.7em;
+}
+
+@media (max-width: 684px) {
+ h1 {
+ font-size: 2.7em;
+ }
+}
+
+p {
+ margin-top: 0px;
+ margin-bottom: 2.5rem;
+}
+
+a {
+ text-decoration: none;
+ border-bottom: 2px solid #c9c9c9;
+ color: #e5e7eb;
+}
+
+img {
+ height: auto;
+ max-width: 100%;
+ margin-top: 0px;
+ margin-bottom: 2.5rem;
+}
+
+@media (max-width: 684px) {
+ img {
+ margin-top: 2rem;
+ margin-bottom: 1rem;
+ }
+}
+
+body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: calc(100vh - 4rem);
+}
+
+header > div {
+ display: flex;
+ align-items: center;
+}
diff --git a/examples/new-svelte/package.json b/examples/new-svelte/package.json
new file mode 100644
index 00000000..a7df7d0e
--- /dev/null
+++ b/examples/new-svelte/package.json
@@ -0,0 +1,20 @@
+{
+ "private": true,
+ "name": "new-tab",
+ "description": "An Extension.js example.",
+ "version": "0.0.1",
+ "author": {
+ "name": "Cezar Augusto",
+ "email": "boss@cezaraugusto.net",
+ "url": "https://cezaraugusto.com"
+ },
+ "license": "MIT",
+ "dependencies": {
+ "svelte": "4.2.19",
+ "sakura.css": "^1.5.0"
+ },
+ "devDependencies": {
+ "typescript": "5.3.3",
+ "@tsconfig/svelte": "5.0.4"
+ }
+}
diff --git a/examples/new-svelte/public/logo.png b/examples/new-svelte/public/logo.png
new file mode 100644
index 00000000..a520d188
Binary files /dev/null and b/examples/new-svelte/public/logo.png differ
diff --git a/examples/new-svelte/template.spec.ts b/examples/new-svelte/template.spec.ts
new file mode 100644
index 00000000..81b9f32c
--- /dev/null
+++ b/examples/new-svelte/template.spec.ts
@@ -0,0 +1,33 @@
+import path from 'path'
+import {execSync} from 'child_process'
+import {extensionFixtures} from '../extension-fixtures'
+
+const exampleDir = 'examples/new-svelte'
+const pathToExtension = path.join(__dirname, `dist/chrome`)
+const test = extensionFixtures(pathToExtension, true)
+
+test.beforeAll(async () => {
+ execSync(`pnpm extension build ${exampleDir}`, {
+ cwd: path.join(__dirname, '..')
+ })
+})
+
+test('should exist an element with the welcome message text', async ({
+ page
+}) => {
+ await page.goto('chrome://newtab/')
+ const h1 = page.locator('h1')
+ await test.expect(h1).toContainText('Welcome to your')
+})
+
+test('should exist a default color value', async ({page}) => {
+ await page.goto('chrome://newtab/')
+ const h1 = page.locator('h1')
+ const color = await page.evaluate(
+ (locator) => {
+ return window.getComputedStyle(locator!).getPropertyValue('color')
+ },
+ await h1.elementHandle()
+ )
+ await test.expect(color).toEqual('rgb(201, 201, 201)')
+})
diff --git a/examples/new-svelte/tsconfig.json b/examples/new-svelte/tsconfig.json
new file mode 100644
index 00000000..0921d6f7
--- /dev/null
+++ b/examples/new-svelte/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "extends": "@tsconfig/svelte/tsconfig.json",
+ "compilerOptions": {
+ "allowJs": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "moduleResolution": "node",
+ "module": "esnext",
+ "noEmit": true,
+ "resolveJsonModule": true,
+ "strict": true,
+ "target": "esnext",
+ "verbatimModuleSyntax": true,
+ "useDefineForClassFields": true,
+ "skipLibCheck": true
+ },
+ "include": ["./"],
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/examples/types.ts b/examples/types.ts
index fce17454..93da3b24 100644
--- a/examples/types.ts
+++ b/examples/types.ts
@@ -12,7 +12,7 @@ export type ConfigFiles =
export interface Template {
name: string
uiContext: UIContext[] | undefined
- uiFramework: 'react' | 'preact' | 'vue' | undefined
+ uiFramework: 'react' | 'preact' | 'vue' | 'svelte' | undefined
css: 'css' | 'sass' | 'less' | 'stylus'
hasBackground: boolean
hasEnv: boolean
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b5ebed06..fbe70a04 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -445,6 +445,22 @@ importers:
specifier: ^1.77.8
version: 1.79.2
+ examples/new-svelte:
+ dependencies:
+ sakura.css:
+ specifier: ^1.5.0
+ version: 1.5.0
+ svelte:
+ specifier: 4.2.19
+ version: 4.2.19
+ devDependencies:
+ '@tsconfig/svelte':
+ specifier: 5.0.4
+ version: 5.0.4
+ typescript:
+ specifier: 5.3.3
+ version: 5.3.3
+
examples/new-tailwind:
dependencies:
react:
@@ -485,6 +501,43 @@ importers:
examples/sidebar: {}
+ examples/sidebar-shadcn:
+ dependencies:
+ react:
+ specifier: ^18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
+ devDependencies:
+ '@tailwindcss/typography':
+ specifier: ^0.5.15
+ version: 0.5.15(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.5.5)(typescript@5.3.3)))
+ '@types/react':
+ specifier: ^18.2.64
+ version: 18.3.8
+ '@types/react-dom':
+ specifier: ^18.2.21
+ version: 18.3.0
+ autoprefixer:
+ specifier: ^10.4.20
+ version: 10.4.20(postcss@8.4.47)
+ daisyui:
+ specifier: ^4.12.10
+ version: 4.12.10(postcss@8.4.47)
+ extension:
+ specifier: latest
+ version: 2.0.0-beta.1(@babel/core@7.25.2)(@prefresh/babel-plugin@0.5.1)(@types/webpack@4.41.39)(browserslist@4.23.3)(esbuild@0.23.1)(less@4.2.0)(preact@10.24.0)(sass@1.79.2)(type-fest@4.26.1)(typescript@5.3.3)
+ postcss:
+ specifier: ^8.4.47
+ version: 8.4.47
+ tailwindcss:
+ specifier: ^3.4.13
+ version: 3.4.13(ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.5.5)(typescript@5.3.3))
+ typescript:
+ specifier: 5.3.3
+ version: 5.3.3
+
examples/special-folders-pages: {}
examples/special-folders-scripts: {}
@@ -775,6 +828,12 @@ importers:
sass-loader:
specifier: ^16.0.0
version: 16.0.2(sass@1.79.2)(webpack@5.92.1(@swc/core@1.7.26)(esbuild@0.23.1))
+ svelte-loader:
+ specifier: ^3.2.3
+ version: 3.2.3(svelte@4.2.19)
+ svelte-preprocess:
+ specifier: ^2.6.4
+ version: 2.16.0(svelte@4.2.19)
vue-loader:
specifier: ^17.4.2
version: 17.4.2(webpack@5.92.1(@swc/core@1.7.26)(esbuild@0.23.1))
@@ -2448,6 +2507,11 @@ packages:
'@swc/types@0.1.12':
resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==}
+ '@tailwindcss/typography@0.5.15':
+ resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20'
+
'@trysound/sax@0.2.0':
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@@ -2464,6 +2528,9 @@ packages:
'@tsconfig/node16@1.0.4':
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
+ '@tsconfig/svelte@5.0.4':
+ resolution: {integrity: sha512-BV9NplVgLmSi4mwKzD8BD/NQ8erOY/nUE/GpgWe2ckx+wIQF5RyRirn/QsSSCPeulVpc3RA/iJt6DpfTIZps0Q==}
+
'@types/adm-zip@0.5.5':
resolution: {integrity: sha512-YCGstVMjc4LTY5uK9/obvxBya93axZOVOyf2GSUulADzmLhYE45u2nAssCs/fWBs1Ifq5Vat75JTPwd5XZoPJw==}
@@ -2974,6 +3041,10 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ aria-query@5.3.2:
+ resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
+ engines: {node: '>= 0.4'}
+
array-flatten@1.1.1:
resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
@@ -3015,6 +3086,10 @@ packages:
axios@1.7.7:
resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==}
+ axobject-query@4.1.0:
+ resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
+ engines: {node: '>= 0.4'}
+
babel-jest@29.7.0:
resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -3193,6 +3268,18 @@ packages:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
engines: {node: '>= 0.4'}
+ caller-callsite@2.0.0:
+ resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==}
+ engines: {node: '>=4'}
+
+ caller-path@2.0.0:
+ resolution: {integrity: sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==}
+ engines: {node: '>=4'}
+
+ callsites@2.0.0:
+ resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==}
+ engines: {node: '>=4'}
+
callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
@@ -3269,6 +3356,9 @@ packages:
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
+ code-red@1.0.4:
+ resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==}
+
collect-v8-coverage@1.0.2:
resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==}
@@ -3383,6 +3473,10 @@ packages:
core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+ cosmiconfig@5.2.1:
+ resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==}
+ engines: {node: '>=4'}
+
cosmiconfig@8.3.6:
resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
engines: {node: '>=14'}
@@ -3830,6 +3924,9 @@ packages:
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+ 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'}
@@ -4289,10 +4386,22 @@ packages:
immutable@4.3.7:
resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
+ import-cwd@2.1.0:
+ resolution: {integrity: sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==}
+ engines: {node: '>=4'}
+
+ import-fresh@2.0.0:
+ resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==}
+ engines: {node: '>=4'}
+
import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
+ import-from@2.1.0:
+ resolution: {integrity: sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==}
+ engines: {node: '>=4'}
+
import-local@3.2.0:
resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==}
engines: {node: '>=8'}
@@ -4350,6 +4459,10 @@ packages:
resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
engines: {node: '>= 0.4'}
+ is-directory@0.3.1:
+ resolution: {integrity: sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==}
+ engines: {node: '>=0.10.0'}
+
is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -4408,6 +4521,9 @@ packages:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
+ is-reference@3.0.2:
+ resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==}
+
is-relative@0.1.3:
resolution: {integrity: sha512-wBOr+rNM4gkAZqoLRJI4myw5WzzIdQosFAAbnvfXP5z1LyzgAI3ivOKehC5KfqlQJZoihVhirgtCBj378Eg8GA==}
engines: {node: '>=0.10.0'}
@@ -4651,6 +4767,9 @@ packages:
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+ json-parse-better-errors@1.0.2:
+ resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
+
json-parse-even-better-errors@2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
@@ -4752,6 +4871,9 @@ packages:
resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==}
engines: {node: '>= 12.13.0'}
+ locate-character@3.0.0:
+ resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
+
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
@@ -4764,9 +4886,15 @@ packages:
resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ lodash.castarray@4.4.0:
+ resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
+
lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
+ lodash.isplainobject@4.0.6:
+ resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
+
lodash.memoize@4.1.2:
resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
@@ -5137,6 +5265,10 @@ packages:
resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==}
engines: {node: '>= 0.10'}
+ parse-json@4.0.0:
+ resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
+ engines: {node: '>=4'}
+
parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
@@ -5198,6 +5330,9 @@ packages:
resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==}
engines: {node: '>=0.12'}
+ periscopic@3.1.0:
+ resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
+
picocolors@1.1.0:
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
@@ -5362,6 +5497,10 @@ packages:
peerDependencies:
postcss: ^8.4
+ postcss-load-config@2.1.2:
+ resolution: {integrity: sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==}
+ engines: {node: '>= 4'}
+
postcss-load-config@4.0.2:
resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
engines: {node: '>= 14'}
@@ -5518,6 +5657,10 @@ packages:
peerDependencies:
postcss: ^8.4
+ postcss-selector-parser@6.0.10:
+ resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
+ engines: {node: '>=4'}
+
postcss-selector-parser@6.1.2:
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
engines: {node: '>=4'}
@@ -5730,6 +5873,10 @@ packages:
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
engines: {node: '>=8'}
+ resolve-from@3.0.0:
+ resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==}
+ engines: {node: '>=4'}
+
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@@ -5785,6 +5932,9 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ sakura.css@1.5.0:
+ resolution: {integrity: sha512-AcAZa9F4SCs2xaKLWcXQxJxKfeod2PN3sR31+R22MKuyoJxNChH1wBG4mQaY9gVpJ3VpNA1XHPOrOM9hFo9cSw==}
+
sanitize.css@13.0.0:
resolution: {integrity: sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==}
@@ -6035,6 +6185,10 @@ packages:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
+ strip-indent@2.0.0:
+ resolution: {integrity: sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==}
+ engines: {node: '>=4'}
+
strip-json-comments@2.0.1:
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
engines: {node: '>=0.10.0'}
@@ -6117,6 +6271,29 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ svelte-dev-helper@1.1.9:
+ resolution: {integrity: sha512-oU+Xv7Dl4kRU2kdFjsoPLfJfnt5hUhsFUZtuzI3Ku/f2iAFZqBoEuXOqK3N9ngD4dxQOmN4OKWPHVi3NeAeAfQ==}
+
+ svelte-hmr@0.14.12:
+ resolution: {integrity: sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==}
+ engines: {node: ^12.20 || ^14.13.1 || >= 16}
+ peerDependencies:
+ svelte: '>=3.19.0'
+
+ svelte-loader@3.2.3:
+ resolution: {integrity: sha512-ntitVuO0EneIlw5Zsn/GNnxu8+KkqbfrsjEGvk7qrd67IA24OBVqY9p0NjUGlpewPxGL3iD4z/8VA+hM9AsZxA==}
+ peerDependencies:
+ svelte: ^3.0.0 || ^4.0.0-next.0 || ^5.0.0-next.1
+
+ svelte-preprocess@2.16.0:
+ resolution: {integrity: sha512-RVN/q/SOVCy4QxZeCEUXczYP/OxOT7LN6wo8RKL0rn9BUYe5/oGSn8p8eRiOGgcE3vWZRPQkHwpDC+AKSzlWyA==}
+ peerDependencies:
+ svelte: ^1.44.0 || ^2.0.0 || ^3.0.0
+
+ svelte@4.2.19:
+ resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==}
+ engines: {node: '>=16'}
+
svg-parser@2.0.4:
resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
@@ -6143,6 +6320,11 @@ packages:
engines: {node: '>=14.0.0'}
hasBin: true
+ tailwindcss@3.4.13:
+ resolution: {integrity: sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
@@ -8637,6 +8819,14 @@ snapshots:
dependencies:
'@swc/counter': 0.1.3
+ '@tailwindcss/typography@0.5.15(tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.5.5)(typescript@5.3.3)))':
+ dependencies:
+ lodash.castarray: 4.4.0
+ lodash.isplainobject: 4.0.6
+ lodash.merge: 4.6.2
+ postcss-selector-parser: 6.0.10
+ tailwindcss: 3.4.13(ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.5.5)(typescript@5.3.3))
+
'@trysound/sax@0.2.0': {}
'@tsconfig/node10@1.0.11': {}
@@ -8647,6 +8837,8 @@ snapshots:
'@tsconfig/node16@1.0.4': {}
+ '@tsconfig/svelte@5.0.4': {}
+
'@types/adm-zip@0.5.5':
dependencies:
'@types/node': 22.5.5
@@ -9304,6 +9496,8 @@ snapshots:
argparse@2.0.1: {}
+ aria-query@5.3.2: {}
+
array-flatten@1.1.1: {}
array-union@2.1.0: {}
@@ -9339,7 +9533,6 @@ snapshots:
picocolors: 1.1.0
postcss: 8.4.47
postcss-value-parser: 4.2.0
- optional: true
available-typed-arrays@1.0.7:
dependencies:
@@ -9353,6 +9546,8 @@ snapshots:
transitivePeerDependencies:
- debug
+ axobject-query@4.1.0: {}
+
babel-jest@29.7.0(@babel/core@7.25.2):
dependencies:
'@babel/core': 7.25.2
@@ -9608,6 +9803,19 @@ snapshots:
get-intrinsic: 1.2.4
set-function-length: 1.2.2
+ caller-callsite@2.0.0:
+ dependencies:
+ callsites: 2.0.0
+ optional: true
+
+ caller-path@2.0.0:
+ dependencies:
+ caller-callsite: 2.0.0
+ optional: true
+
+ callsites@2.0.0:
+ optional: true
+
callsites@3.1.0: {}
camelcase-css@2.0.1: {}
@@ -9681,6 +9889,14 @@ snapshots:
co@4.6.0: {}
+ code-red@1.0.4:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@types/estree': 1.0.6
+ acorn: 8.12.1
+ estree-walker: 3.0.3
+ periscopic: 3.1.0
+
collect-v8-coverage@1.0.2: {}
color-convert@1.9.3:
@@ -9780,6 +9996,14 @@ snapshots:
core-util-is@1.0.3: {}
+ cosmiconfig@5.2.1:
+ dependencies:
+ import-fresh: 2.0.0
+ is-directory: 0.3.1
+ js-yaml: 3.14.1
+ parse-json: 4.0.0
+ optional: true
+
cosmiconfig@8.3.6(typescript@5.3.3):
dependencies:
import-fresh: 3.3.0
@@ -10283,6 +10507,10 @@ snapshots:
estree-walker@2.0.2: {}
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.6
+
esutils@2.0.3: {}
etag@1.8.1: {}
@@ -10634,8 +10862,7 @@ snapshots:
forwarded@0.2.0: {}
- fraction.js@4.3.7:
- optional: true
+ fraction.js@4.3.7: {}
fresh@0.5.2: {}
@@ -10918,11 +11145,27 @@ snapshots:
immutable@4.3.7: {}
+ import-cwd@2.1.0:
+ dependencies:
+ import-from: 2.1.0
+ optional: true
+
+ import-fresh@2.0.0:
+ dependencies:
+ caller-path: 2.0.0
+ resolve-from: 3.0.0
+ optional: true
+
import-fresh@3.3.0:
dependencies:
parent-module: 1.0.1
resolve-from: 4.0.0
+ import-from@2.1.0:
+ dependencies:
+ resolve-from: 3.0.0
+ optional: true
+
import-local@3.2.0:
dependencies:
pkg-dir: 4.2.0
@@ -10968,6 +11211,9 @@ snapshots:
dependencies:
hasown: 2.0.2
+ is-directory@0.3.1:
+ optional: true
+
is-docker@3.0.0: {}
is-extglob@2.1.1: {}
@@ -11007,6 +11253,10 @@ snapshots:
is-plain-object@5.0.0: {}
+ is-reference@3.0.2:
+ dependencies:
+ '@types/estree': 1.0.6
+
is-relative@0.1.3: {}
is-stream@2.0.1: {}
@@ -11491,6 +11741,9 @@ snapshots:
json-buffer@3.0.1: {}
+ json-parse-better-errors@1.0.2:
+ optional: true
+
json-parse-even-better-errors@2.3.1: {}
json-schema-traverse@0.4.1: {}
@@ -11584,6 +11837,8 @@ snapshots:
loader-utils@3.3.1: {}
+ locate-character@3.0.0: {}
+
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
@@ -11596,8 +11851,12 @@ snapshots:
dependencies:
p-locate: 6.0.0
+ lodash.castarray@4.4.0: {}
+
lodash.debounce@4.0.8: {}
+ lodash.isplainobject@4.0.6: {}
+
lodash.memoize@4.1.2: {}
lodash.merge@4.6.2: {}
@@ -11810,8 +12069,7 @@ snapshots:
normalize-path@3.0.0: {}
- normalize-range@0.1.2:
- optional: true
+ normalize-range@0.1.2: {}
npm-run-path@4.0.1:
dependencies:
@@ -11952,6 +12210,12 @@ snapshots:
pbkdf2: 3.1.2
safe-buffer: 5.2.1
+ parse-json@4.0.0:
+ dependencies:
+ error-ex: 1.3.2
+ json-parse-better-errors: 1.0.2
+ optional: true
+
parse-json@5.2.0:
dependencies:
'@babel/code-frame': 7.24.7
@@ -12006,6 +12270,12 @@ snapshots:
safe-buffer: 5.2.1
sha.js: 2.4.11
+ periscopic@3.1.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ estree-walker: 3.0.3
+ is-reference: 3.0.2
+
picocolors@1.1.0: {}
picomatch@2.3.1: {}
@@ -12176,6 +12446,12 @@ snapshots:
postcss: 8.4.47
optional: true
+ postcss-load-config@2.1.2:
+ dependencies:
+ cosmiconfig: 5.2.1
+ import-cwd: 2.1.0
+ optional: true
+
postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.5.5)(typescript@5.3.3)):
dependencies:
lilconfig: 3.1.2
@@ -12370,6 +12646,11 @@ snapshots:
postcss-selector-parser: 6.1.2
optional: true
+ postcss-selector-parser@6.0.10:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
postcss-selector-parser@6.1.2:
dependencies:
cssesc: 3.0.0
@@ -12609,6 +12890,9 @@ snapshots:
dependencies:
resolve-from: 5.0.0
+ resolve-from@3.0.0:
+ optional: true
+
resolve-from@4.0.0: {}
resolve-from@5.0.0: {}
@@ -12675,6 +12959,8 @@ snapshots:
safer-buffer@2.1.2: {}
+ sakura.css@1.5.0: {}
+
sanitize.css@13.0.0:
optional: true
@@ -12957,6 +13243,9 @@ snapshots:
strip-final-newline@2.0.0: {}
+ strip-indent@2.0.0:
+ optional: true
+
strip-json-comments@2.0.1: {}
strip-json-comments@3.1.1: {}
@@ -13076,6 +13365,47 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
+ svelte-dev-helper@1.1.9:
+ optional: true
+
+ svelte-hmr@0.14.12(svelte@4.2.19):
+ dependencies:
+ svelte: 4.2.19
+ optional: true
+
+ svelte-loader@3.2.3(svelte@4.2.19):
+ dependencies:
+ loader-utils: 2.0.4
+ svelte: 4.2.19
+ svelte-dev-helper: 1.1.9
+ svelte-hmr: 0.14.12(svelte@4.2.19)
+ optional: true
+
+ svelte-preprocess@2.16.0(svelte@4.2.19):
+ dependencies:
+ detect-indent: 6.1.0
+ postcss-load-config: 2.1.2
+ strip-indent: 2.0.0
+ svelte: 4.2.19
+ optional: true
+
+ svelte@4.2.19:
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
+ '@types/estree': 1.0.6
+ acorn: 8.12.1
+ aria-query: 5.3.2
+ axobject-query: 4.1.0
+ code-red: 1.0.4
+ css-tree: 2.3.1
+ estree-walker: 3.0.3
+ is-reference: 3.0.2
+ locate-character: 3.0.0
+ magic-string: 0.30.11
+ periscopic: 3.1.0
+
svg-parser@2.0.4: {}
svg-tags@1.0.0: {}
@@ -13131,6 +13461,33 @@ snapshots:
transitivePeerDependencies:
- ts-node
+ tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.5.5)(typescript@5.3.3)):
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.6
+ lilconfig: 2.1.0
+ micromatch: 4.0.8
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.1.0
+ postcss: 8.4.47
+ postcss-import: 15.1.0(postcss@8.4.47)
+ postcss-js: 4.0.1(postcss@8.4.47)
+ postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.7.26)(@types/node@22.5.5)(typescript@5.3.3))
+ postcss-nested: 6.2.0(postcss@8.4.47)
+ postcss-selector-parser: 6.1.2
+ resolve: 1.22.8
+ sucrase: 3.35.0
+ transitivePeerDependencies:
+ - ts-node
+
tapable@2.2.1: {}
term-size@2.2.1: {}
diff --git a/programs/cli/README.md b/programs/cli/README.md
index b76b7691..e45d551d 100644
--- a/programs/cli/README.md
+++ b/programs/cli/README.md
@@ -56,7 +56,7 @@ For a preview of extensions running these technologies, see documentation about
| | | | | | | | | |
| :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: |
-| ESNext
✅ | TypeScript
✅ | WASM
✅ | React
✅ | Vue
✅ | Angular
👋 | Svelte
👋 | Solid
👋 | Preact
✅ |
+| ESNext
✅ | TypeScript
✅ | WASM
✅ | React
✅ | Vue
✅ | Angular
👋 | Svelte
✅ | Solid
👋 | Preact
✅ |
👋 = PR Welcome!
diff --git a/programs/cli/types/index.d.ts b/programs/cli/types/index.d.ts
index 7c88eece..8ce07c21 100644
--- a/programs/cli/types/index.d.ts
+++ b/programs/cli/types/index.d.ts
@@ -5,6 +5,7 @@
///
///
///
+///
declare namespace NodeJS {
interface ProcessEnv {
diff --git a/programs/develop/package.json b/programs/develop/package.json
index 1f5c70a0..3b198458 100644
--- a/programs/develop/package.json
+++ b/programs/develop/package.json
@@ -105,6 +105,8 @@
"react-refresh-typescript": "^2.0.9",
"resolve-url-loader": "^5.0.0",
"sass-loader": "^16.0.0",
+ "svelte-loader": "^3.2.3",
+ "svelte-preprocess": "^2.6.4",
"vue-loader": "^17.4.2",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.7.16"
diff --git a/programs/develop/webpack/plugin-extension/index.ts b/programs/develop/webpack/plugin-extension/index.ts
index 20fe86d8..6e7e8b10 100644
--- a/programs/develop/webpack/plugin-extension/index.ts
+++ b/programs/develop/webpack/plugin-extension/index.ts
@@ -28,6 +28,7 @@ import {isUsingReact} from '../plugin-js-frameworks/js-tools/react'
import {isUsingPreact} from '../plugin-js-frameworks/js-tools/preact'
import {isUsingTypeScript} from '../plugin-js-frameworks/js-tools/typescript'
import {isUsingVue} from '../plugin-js-frameworks/js-tools/vue'
+import {isUsingSvelte} from '../plugin-js-frameworks/js-tools/svelte'
export class ExtensionPlugin {
public static readonly name: string = 'plugin-extension'
@@ -64,7 +65,8 @@ export class ExtensionPlugin {
jsx:
isUsingReact(path.dirname(this.manifestPath)) ||
isUsingPreact(path.dirname(this.manifestPath)) ||
- isUsingVue(path.dirname(this.manifestPath)),
+ isUsingVue(path.dirname(this.manifestPath)) ||
+ isUsingSvelte(path.dirname(this.manifestPath)),
typescript: isUsingTypeScript(path.dirname(this.manifestPath)),
minify: compiler.options.mode === 'production'
}
diff --git a/programs/develop/webpack/plugin-js-frameworks/index.ts b/programs/develop/webpack/plugin-js-frameworks/index.ts
index a79ac747..0465180a 100644
--- a/programs/develop/webpack/plugin-js-frameworks/index.ts
+++ b/programs/develop/webpack/plugin-js-frameworks/index.ts
@@ -6,8 +6,8 @@ import {isUsingPreact, maybeUsePreact} from './js-tools/preact'
import {isUsingReact, maybeUseReact} from './js-tools/react'
import {maybeUseVue} from './js-tools/vue'
import {isUsingTypeScript} from './js-tools/typescript'
+import {maybeUseSvelte} from './js-tools/svelte'
// import {maybeUseAngular} from './js-tools/angular'
-// import {maybeUseSvelte} from './js-tools/svelte'
// import {maybeUseSolid} from './js-tools/solid'
export class JsFrameworksPlugin {
@@ -27,12 +27,14 @@ export class JsFrameworksPlugin {
const maybeInstallReact = await maybeUseReact(projectPath)
const maybeInstallPreact = await maybeUsePreact(projectPath)
const maybeInstallVue = await maybeUseVue(projectPath)
+ const maybeInstallSvelte = await maybeUseSvelte(projectPath)
compiler.options.resolve.alias = {
...(maybeInstallBabel?.alias || {}),
...(maybeInstallReact?.alias || {}),
...(maybeInstallPreact?.alias || {}),
...(maybeInstallVue?.alias || {}),
+ ...(maybeInstallSvelte?.alias || {}),
...compiler.options.resolve.alias
}
@@ -80,12 +82,14 @@ export class JsFrameworksPlugin {
...(maybeInstallReact?.loaders || []),
...(maybeInstallPreact?.loaders || []),
...(maybeInstallVue?.loaders || []),
+ ...(maybeInstallSvelte?.loaders || []),
...compiler.options.module.rules
].filter(Boolean)
maybeInstallReact?.plugins?.forEach((plugin) => plugin.apply(compiler))
maybeInstallPreact?.plugins?.forEach((plugin) => plugin.apply(compiler))
maybeInstallVue?.plugins?.forEach((plugin) => plugin.apply(compiler))
+ maybeInstallSvelte?.plugins?.forEach((plugin) => plugin.apply(compiler))
}
public async apply(compiler: Compiler) {
diff --git a/programs/develop/webpack/plugin-js-frameworks/js-tools/svelte.ts b/programs/develop/webpack/plugin-js-frameworks/js-tools/svelte.ts
new file mode 100644
index 00000000..12a344a3
--- /dev/null
+++ b/programs/develop/webpack/plugin-js-frameworks/js-tools/svelte.ts
@@ -0,0 +1,88 @@
+// ██████╗ ███████╗██╗ ██╗███████╗██╗ ██████╗ ██████╗
+// ██╔══██╗██╔════╝██║ ██║██╔════╝██║ ██╔═══██╗██╔══██╗
+// ██║ ██║█████╗ ██║ ██║█████╗ ██║ ██║ ██║██████╔╝
+// ██║ ██║██╔══╝ ╚██╗ ██╔╝██╔══╝ ██║ ██║ ██║██╔═══╝
+// ██████╔╝███████╗ ╚████╔╝ ███████╗███████╗╚██████╔╝██║
+// ╚═════╝ ╚══════╝ ╚═══╝ ╚══════╝╚══════╝ ╚═════╝ ╚═╝
+
+import path from 'path'
+import fs from 'fs'
+import * as messages from '../../lib/messages'
+import {installOptionalDependencies} from '../../lib/utils'
+import {JsFramework} from '../../webpack-types'
+
+let userMessageDelivered = false
+
+export function isUsingSvelte(projectPath: string) {
+ const packageJsonPath = path.join(projectPath, 'package.json')
+
+ if (!fs.existsSync(packageJsonPath)) {
+ return false
+ }
+
+ const packageJson = require(packageJsonPath)
+
+ const svelteAsDevDep =
+ packageJson.devDependencies && packageJson.devDependencies?.svelte
+ const svelteAsDep =
+ packageJson.dependencies && packageJson.dependencies.svelte
+
+ if (svelteAsDevDep || svelteAsDep) {
+ if (!userMessageDelivered) {
+ if (process.env.EXTENSION_ENV === 'development') {
+ console.log(messages.isUsingIntegration('Svelte'))
+ }
+
+ userMessageDelivered = true
+ }
+ }
+
+ return !!svelteAsDevDep || !!svelteAsDep
+}
+
+export async function maybeUseSvelte(
+ projectPath: string
+): Promise {
+ if (!isUsingSvelte(projectPath)) return undefined
+
+ const isDev = process.env.NODE_ENV !== 'production'
+
+ try {
+ require.resolve('svelte-loader')
+ } catch (e) {
+ const typeScriptDependencies = ['typescript']
+
+ await installOptionalDependencies('TypeScript', typeScriptDependencies)
+
+ const svelteDependencies = ['svelte-loader', 'svelte-preprocess']
+
+ await installOptionalDependencies('Svelte', svelteDependencies)
+
+ // The compiler will exit after installing the dependencies
+ // as it can't read the new dependencies without a restart.
+ console.log(messages.youAreAllSet('Svelte'))
+ process.exit(0)
+ }
+
+ const svelteLoaders: JsFramework['loaders'] = [
+ {
+ test: /\.svelte$/,
+ loader: require.resolve('svelte-loader'),
+ include: projectPath,
+ exclude: /node_modules/,
+ options: {
+ compilerOptions: {
+ dev: isDev
+ },
+ hotReload: isDev,
+ preprocess: require('svelte-preprocess')()
+ }
+ }
+ ]
+
+ return {
+ plugins: undefined,
+ loaders: svelteLoaders,
+ alias: undefined
+ }
+}