diff --git a/.changeset/chatty-taxis-chew.md b/.changeset/chatty-taxis-chew.md
new file mode 100644
index 00000000..99bd8910
--- /dev/null
+++ b/.changeset/chatty-taxis-chew.md
@@ -0,0 +1,5 @@
+---
+"jsrepo": patch
+---
+
+`*.(sass|scss)` support 🎉
diff --git a/.changeset/giant-pianos-sin.md b/.changeset/giant-pianos-sin.md
new file mode 100644
index 00000000..b4295444
--- /dev/null
+++ b/.changeset/giant-pianos-sin.md
@@ -0,0 +1,5 @@
+---
+"jsrepo": patch
+---
+
+`*.html` support 🎉
diff --git a/examples/registry/blocks/angular/button/button.html b/examples/registry/blocks/angular/button/button.html
new file mode 100644
index 00000000..2c087e06
--- /dev/null
+++ b/examples/registry/blocks/angular/button/button.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Button
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/registry/blocks/scripts/test.js b/examples/registry/blocks/scripts/test.js
new file mode 100644
index 00000000..57d2a94f
--- /dev/null
+++ b/examples/registry/blocks/scripts/test.js
@@ -0,0 +1 @@
+console.log('hello')
\ No newline at end of file
diff --git a/examples/registry/blocks/styles/test.scss b/examples/registry/blocks/styles/test.scss
new file mode 100644
index 00000000..2eabf488
--- /dev/null
+++ b/examples/registry/blocks/styles/test.scss
@@ -0,0 +1,3 @@
+* {
+ box-sizing: border-box;
+}
\ No newline at end of file
diff --git a/examples/registry/jsrepo-manifest.json b/examples/registry/jsrepo-manifest.json
index 75bb5e2d..10d0e4e2 100644
--- a/examples/registry/jsrepo-manifest.json
+++ b/examples/registry/jsrepo-manifest.json
@@ -135,6 +135,32 @@
}
]
},
+ {
+ "name": "angular",
+ "blocks": [
+ {
+ "name": "button",
+ "directory": "blocks/angular/button",
+ "category": "angular",
+ "tests": false,
+ "subdirectory": true,
+ "list": true,
+ "files": [
+ "button.html"
+ ],
+ "localDependencies": [
+ "styles/test",
+ "scripts/test"
+ ],
+ "dependencies": [],
+ "devDependencies": [],
+ "_imports_": {
+ "../../styles/test.scss": "{{styles/test}}.scss",
+ "../../scripts/test.js": "{{scripts/test}}.js"
+ }
+ }
+ ]
+ },
{
"name": "logging",
"blocks": [
@@ -154,5 +180,45 @@
"devDependencies": []
}
]
+ },
+ {
+ "name": "scripts",
+ "blocks": [
+ {
+ "name": "test",
+ "directory": "blocks/scripts",
+ "category": "scripts",
+ "tests": false,
+ "subdirectory": false,
+ "list": true,
+ "files": [
+ "test.js"
+ ],
+ "localDependencies": [],
+ "_imports_": {},
+ "dependencies": [],
+ "devDependencies": []
+ }
+ ]
+ },
+ {
+ "name": "styles",
+ "blocks": [
+ {
+ "name": "test",
+ "directory": "blocks/styles",
+ "category": "styles",
+ "tests": false,
+ "subdirectory": false,
+ "list": true,
+ "files": [
+ "test.scss"
+ ],
+ "localDependencies": [],
+ "_imports_": {},
+ "dependencies": [],
+ "devDependencies": []
+ }
+ ]
}
]
\ No newline at end of file
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 76373832..22c66b00 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -15,24 +15,12 @@
"bugs": {
"url": "https://github.com/ieedan/jsrepo/issues"
},
- "keywords": [
- "repo",
- "cli",
- "svelte",
- "vue",
- "typescript",
- "javascript",
- "shadcn",
- "registry"
- ],
+ "keywords": ["repo", "cli", "svelte", "vue", "typescript", "javascript", "shadcn", "registry"],
"type": "module",
"exports": "./dist/index.js",
"bin": "./dist/index.js",
"main": "./dist/index.js",
- "files": [
- "./schemas/**/*",
- "dist"
- ],
+ "files": ["./schemas/**/*", "dist"],
"scripts": {
"start": "tsup --silent && node ./dist/index.js",
"build": "tsup",
@@ -68,6 +56,7 @@
"node-fetch": "^3.3.2",
"octokit": "^4.0.2",
"package-manager-detector": "^0.2.7",
+ "parse5": "^7.2.1",
"pathe": "^1.1.2",
"prettier": "^3.4.2",
"svelte": "^5.14.4",
diff --git a/packages/cli/src/utils/build/check.ts b/packages/cli/src/utils/build/check.ts
index cd785f32..88ec6b4c 100644
--- a/packages/cli/src/utils/build/check.ts
+++ b/packages/cli/src/utils/build/check.ts
@@ -172,6 +172,11 @@ const rules = {
'astro',
'solid-js',
'@angular/core',
+ '@angular/common',
+ '@angular/forms',
+ '@angular/platform-browser',
+ '@angular/platform-browser-dynamic',
+ '@angular/router',
]);
const frameworkDeps = [...block.devDependencies, ...block.dependencies]
diff --git a/packages/cli/src/utils/language-support.ts b/packages/cli/src/utils/language-support.ts
index eb191a76..ca4abc41 100644
--- a/packages/cli/src/utils/language-support.ts
+++ b/packages/cli/src/utils/language-support.ts
@@ -6,6 +6,7 @@ import * as v from '@vue/compiler-sfc';
import color from 'chalk';
import { type Node, walk } from 'estree-walker';
import { type TsConfigResult, createPathsMatcher, getTsconfig } from 'get-tsconfig';
+import * as parse5 from 'parse5';
import path from 'pathe';
import * as prettier from 'prettier';
import * as sv from 'svelte/compiler';
@@ -77,6 +78,87 @@ const css: Lang = {
},
};
+/** Language support for `*.html` files. */
+const html: Lang = {
+ matches: (fileName) => fileName.endsWith('.html'),
+ resolveDependencies: ({ filePath, isSubDir, excludeDeps, dirs, cwd }) => {
+ const sourceCode = fs.readFileSync(filePath).toString();
+
+ const ast = parse5.parse(sourceCode);
+
+ const imports: string[] = [];
+
+ // @ts-ignore yeah I know
+ const walk = (node, enter: (node) => void) => {
+ if (!node) return;
+
+ enter(node);
+
+ if (node.childNodes && node.childNodes.length > 0) {
+ for (const n of node.childNodes) {
+ walk(n, enter);
+ }
+ }
+ };
+
+ for (const node of ast.childNodes) {
+ walk(node, (n) => {
+ if (n.tagName === 'script') {
+ for (const attr of n.attrs) {
+ if (attr.name === 'src') {
+ imports.push(attr.value);
+ }
+ }
+ }
+
+ if (
+ n.tagName === 'link' &&
+ // @ts-ignore yeah I know
+ n.attrs.find((attr) => attr.name === 'rel' && attr.value === 'stylesheet')
+ ) {
+ for (const attr of n.attrs) {
+ if (attr.name === 'href' && !attr.value.startsWith('http')) {
+ imports.push(attr.value);
+ }
+ }
+ }
+ });
+ }
+
+ const resolveResult = resolveImports({
+ moduleSpecifiers: imports,
+ filePath,
+ isSubDir,
+ dirs,
+ cwd,
+ doNotInstall: ['svelte', '@sveltejs/kit', ...excludeDeps],
+ });
+
+ if (resolveResult.isErr()) {
+ return Err(
+ resolveResult
+ .unwrapErr()
+ .map((err) => formatError(err))
+ .join('\n')
+ );
+ }
+
+ return Ok(resolveResult.unwrap());
+ },
+ comment: (content) => ``,
+ format: async (code, { formatter, prettierOptions }) => {
+ if (!formatter) return code;
+
+ if (formatter === 'prettier') {
+ return await prettier.format(code, { parser: 'html', ...prettierOptions });
+ }
+
+ // biome is in progress for formatting html
+
+ return code;
+ },
+};
+
/** Language support for `*.(json)` files. */
const json: Lang = {
matches: (fileName) => fileName.endsWith('.json'),
@@ -131,6 +213,23 @@ const jsonc: Lang = {
},
};
+/** Language support for `*.(sass|scss)` files. */
+const sass: Lang = {
+ matches: (fileName) => fileName.endsWith('.sass') || fileName.endsWith('.scss'),
+ resolveDependencies: () =>
+ Ok({ dependencies: [], local: [], devDependencies: [], imports: {} }),
+ comment: (content) => `/*\n${lines.join(lines.get(content), { prefix: () => '\t' })}\n*/`,
+ format: async (code, { formatter, prettierOptions }) => {
+ if (!formatter) return code;
+
+ if (formatter === 'prettier') {
+ return await prettier.format(code, { parser: 'scss', ...prettierOptions });
+ }
+
+ return code;
+ },
+};
+
/** Language support for `*.svelte` files. */
const svelte: Lang = {
matches: (fileName) => fileName.endsWith('.svelte'),
@@ -719,6 +818,6 @@ const resolveRemoteDeps = (
};
};
-const languages: Lang[] = [css, json, jsonc, svelte, svg, typescript, vue, yaml];
+const languages: Lang[] = [css, html, json, jsonc, sass, svelte, svg, typescript, vue, yaml];
-export { css, json, jsonc, svelte, svg, typescript, vue, yaml, languages };
+export { css, html, json, jsonc, sass, svelte, svg, typescript, vue, yaml, languages };
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9fcc09d9..a5163fb6 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -65,6 +65,9 @@ importers:
package-manager-detector:
specifier: ^0.2.7
version: 0.2.7
+ parse5:
+ specifier: ^7.2.1
+ version: 7.2.1
pathe:
specifier: ^1.1.2
version: 1.1.2
@@ -2291,6 +2294,9 @@ packages:
resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
engines: {node: '>=18'}
+ parse5@7.2.1:
+ resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==}
+
path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
@@ -5268,6 +5274,10 @@ snapshots:
parse-ms@4.0.0: {}
+ parse5@7.2.1:
+ dependencies:
+ entities: 4.5.0
+
path-browserify@1.0.1: {}
path-exists@4.0.0: {}
diff --git a/sites/docs/src/lib/components/icons/html.svelte b/sites/docs/src/lib/components/icons/html.svelte
new file mode 100644
index 00000000..6a05c538
--- /dev/null
+++ b/sites/docs/src/lib/components/icons/html.svelte
@@ -0,0 +1,21 @@
+
+
+
diff --git a/sites/docs/src/lib/components/icons/index.ts b/sites/docs/src/lib/components/icons/index.ts
index a4868a49..6f1426f2 100644
--- a/sites/docs/src/lib/components/icons/index.ts
+++ b/sites/docs/src/lib/components/icons/index.ts
@@ -11,6 +11,8 @@ import GitLab from './gitlab.svelte';
import BitBucket from './bitbucket.svelte';
import Yaml from './yaml.svelte';
import Svg from './svg.svelte';
+import HTML from './html.svelte';
+import SASS from './sass.svelte';
export interface Props extends HTMLAttributes {
class?: string;
@@ -20,6 +22,7 @@ export interface Props extends HTMLAttributes {
export {
CSS,
+ HTML,
GitHub,
TypeScript,
Svelte,
@@ -30,5 +33,6 @@ export {
GitLab,
BitBucket,
Yaml,
+ SASS,
Svg
};
diff --git a/sites/docs/src/lib/components/icons/sass.svelte b/sites/docs/src/lib/components/icons/sass.svelte
new file mode 100644
index 00000000..a7bd0441
--- /dev/null
+++ b/sites/docs/src/lib/components/icons/sass.svelte
@@ -0,0 +1,19 @@
+
+
+
diff --git a/sites/docs/src/routes/docs/language-support/+page.svelte b/sites/docs/src/routes/docs/language-support/+page.svelte
index d4222c47..9ef8ebe4 100644
--- a/sites/docs/src/routes/docs/language-support/+page.svelte
+++ b/sites/docs/src/routes/docs/language-support/+page.svelte
@@ -92,6 +92,20 @@
dependencyResolutionStatus: '🚫',
formattingStatus: '🚫',
watermarkStatus: '✅'
+ },
+ {
+ logo: sass,
+ name: '*.(sass|scss)',
+ dependencyResolutionStatus: '🚫',
+ formattingStatus: '⚠️',
+ watermarkStatus: '✅'
+ },
+ {
+ logo: html,
+ name: '*.(html)',
+ dependencyResolutionStatus: '⚠️',
+ formattingStatus: '⚠️',
+ watermarkStatus: '✅'
}
];
@@ -138,6 +152,14 @@
{/snippet}
+{#snippet sass({ size }: { size: number })}
+
+{/snippet}
+
+{#snippet html({ size }: { size: number })}
+
+{/snippet}
+