Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/chatty-taxis-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"jsrepo": patch
---

`*.(sass|scss)` support 🎉
5 changes: 5 additions & 0 deletions .changeset/giant-pianos-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"jsrepo": patch
---

`*.html` support 🎉
15 changes: 15 additions & 0 deletions examples/registry/blocks/angular/button/button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Button</title>
<link rel="stylesheet" href="../../styles/test.scss">
</head>
<body>
<button id="hey">
Hey there
</button>
</body>
<script src="../../scripts/test.js"></script>
</html>
1 change: 1 addition & 0 deletions examples/registry/blocks/scripts/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('hello')
3 changes: 3 additions & 0 deletions examples/registry/blocks/styles/test.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* {
box-sizing: border-box;
}
66 changes: 66 additions & 0 deletions examples/registry/jsrepo-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand All @@ -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": []
}
]
}
]
17 changes: 3 additions & 14 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions packages/cli/src/utils/build/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
103 changes: 101 additions & 2 deletions packages/cli/src/utils/language-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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) => `<!--\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: 'html', ...prettierOptions });
}

// biome is in progress for formatting html

return code;
},
};

/** Language support for `*.(json)` files. */
const json: Lang = {
matches: (fileName) => fileName.endsWith('.json'),
Expand Down Expand Up @@ -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'),
Expand Down Expand Up @@ -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 };
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions sites/docs/src/lib/components/icons/html.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts">
import type { Props } from '.';
import { cn } from '$lib/utils';

let { class: className, ...rest }: Props = $props();
</script>

<svg
class={cn('size-4', className)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 452 520"
{...rest}
>
<path fill="#e34f26" d="M41 460L0 0h451l-41 460-185 52" />
<path fill="#ef652a" d="M226 472l149-41 35-394H226" />
<path
fill="#ecedee"
d="M226 208h-75l-5-58h80V94H84l15 171h127zm0 147l-64-17-4-45h-56l7 89 117 32z"
/>
<path fill="#fff" d="M226 265h69l-7 73-62 17v59l115-32 16-174H226zm0-171v56h136l5-56z" />
</svg>
4 changes: 4 additions & 0 deletions sites/docs/src/lib/components/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<SVGElement> {
class?: string;
Expand All @@ -20,6 +22,7 @@ export interface Props extends HTMLAttributes<SVGElement> {

export {
CSS,
HTML,
GitHub,
TypeScript,
Svelte,
Expand All @@ -30,5 +33,6 @@ export {
GitLab,
BitBucket,
Yaml,
SASS,
Svg
};
19 changes: 19 additions & 0 deletions sites/docs/src/lib/components/icons/sass.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script lang="ts">
import type { Props } from '.';
import { cn } from '$lib/utils';

let { class: className, ...rest }: Props = $props();
</script>

<svg
class={cn('size-4', className)}
viewBox="0 0 512 384"
xmlns="http://www.w3.org/2000/svg"
width="512"
height="384"
{...rest}
><path
fill="#CF649A"
d="M441 221c-18 0-34 4-47 10-5-9-9-17-10-24s-2-11-1-20 6-21 6-22c0 0-1-5-11-5-11 0-20 2-21 5l-4 15c-2 9-20 43-31 60-4-7-7-13-7-17-1-8-2-12-1-21s6-20 6-21-1-6-11-6c-11 0-20 2-21 5l-4 15-34 76-8 18c-2 4 0 0 0 1l-3 5-4 5s-1-7 1-16c3-19 12-49 12-51 0 0 2-5-6-8-7-3-9 2-10 2l-1 1s8-34-16-34c-14 0-35 17-45 31l-34 19-17 9-1-1c-29-31-82-52-79-93 0-15 6-54 101-102 79-39 141-28 152-4 16 34-33 97-115 106-31 3-47-9-51-13-4-5-5-5-7-4s-1 5 0 8c3 6 13 17 30 23 15 5 51 8 95-9 49-19 88-72 77-117-12-45-87-60-157-35-43 15-88 39-121 70-39 36-45 68-43 81 10 47 74 78 100 100l-3 2c-13 7-63 33-75 60-14 31 2 53 13 56 33 10 68-7 86-34 18-28 16-64 8-80l-1-1 11-6 18-10c-3 9-5 19-6 34-2 17 6 40 15 49 4 4 9 4 12 4 11 0 16-9 22-20l13-28s-8 41 13 41c7 0 15-9 18-14l1-1 1-2 20-37 25-57 5 20c2 8 7 16 10 24l-4 7-8 10c-10 12-23 26-24 30-2 5-2 8 2 11 3 2 8 2 13 2l18-4 17-9c10-7 16-18 15-32 0-7-3-15-6-22l3-4c16-23 28-49 28-49l5 21 9 20a89 89 0 0 0-27 36c-6 17-2 24 7 26 4 1 10-1 14-3 5-1 11-4 17-8 10-8 20-18 19-32 0-6-2-13-4-19 12-5 29-8 49-5 45 5 54 33 52 44-2 12-11 18-14 20l-4 4c1 2 2 2 5 2 3-1 23-10 24-31 1-28-25-58-71-57zM97 336c-14 16-35 23-44 17-9-5-6-29 13-46 11-10 25-20 34-26l9-5 1-1 3-1c6 24 0 45-16 62zm108-73c-5 13-16 45-22 43-6-1-9-26-2-50 4-12 13-26 18-32 8-9 17-12 19-8 3 5-10 39-13 47zm89 43-5 1v-2l16-17 9-11v1c0 14-14 24-20 28zm68-16c-2-1-1-5 4-16 2-5 7-13 15-20l2 9c0 18-13 24-21 27z"
/></svg
>
Loading
Loading