diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8a0dc04 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,27 @@ +name: Test + +on: + push: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "22" + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 9 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run Vitest + run: pnpm run test diff --git a/package.json b/package.json index 4f2aba1..a54b417 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,13 @@ "private": true, "type": "module", "version": "0.0.1", + "engines": { + "node": "20.16.0" + }, "scripts": { "dev": "astro dev", "start": "astro dev", + "test": "vitest", "build": "astro check && astro build", "preview": "astro preview", "astro": "astro", @@ -20,7 +24,8 @@ "hono": "^4.5.4", "mime": "^4.0.4", "tailwindcss": "^3.4.7", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "vite-tsconfig-paths": "^5.0.1" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240729.0", diff --git a/packages/remark-obsidian/embed/embed.test.ts b/packages/remark-obsidian/embed/embed.test.ts index dd26e3f..e8ca632 100644 --- a/packages/remark-obsidian/embed/embed.test.ts +++ b/packages/remark-obsidian/embed/embed.test.ts @@ -12,10 +12,7 @@ test("![[Internal Link]]", () => { htmlExtensions: [html()], }); - assert.equal( - serialized, - '
' - ); + assert.equal(serialized, ''); }); test("![[Internal Link.pdf]]", () => { @@ -26,7 +23,7 @@ test("![[Internal Link.pdf]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -38,7 +35,7 @@ test("![[Internal Link.pdf#width=100&height=200]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -50,7 +47,7 @@ test("![[Internal Link.pdf#page=5]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -62,7 +59,7 @@ test("![[Internal Link.pdf#page=5&zoom=2]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -74,7 +71,7 @@ test("![[Internal Link.jpg]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -86,7 +83,7 @@ test("![[Internal Link.mp3]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -98,7 +95,7 @@ test("![[Internal Link.mp4]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -110,7 +107,7 @@ test("![[Internal Link#Section]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -122,6 +119,6 @@ test("![[Internal Link#^block-id]]", () => { assert.equal( serialized, - '' + '' ); }); diff --git a/packages/remark-obsidian/embed/html.ts b/packages/remark-obsidian/embed/html.ts index a7c6e3a..0a13c0a 100644 --- a/packages/remark-obsidian/embed/html.ts +++ b/packages/remark-obsidian/embed/html.ts @@ -3,7 +3,7 @@ import type { CompileData, Handle, HtmlExtension } from "micromark-util-types"; import mime from "mime"; import { safeTpl } from "../parser-utils"; -import { slugify } from "../internal-link/utils"; +import { slugify } from "~/utils"; export function html(): HtmlExtension { const enterEmbed: Handle = function () { @@ -71,36 +71,33 @@ export function html(): HtmlExtension { ? `#${embed.headings.at(-1)}` : ""; - this.tag(``); + this.tag( + `` + ); return; } - console.log("extension?", embed.extension); - if (embed.extension) { - embed.value = `/assets/${slugify(embed.value)}`; - } - if (embed.extension === "pdf") { const params = embed.pdfParams && Object.entries(embed.pdfParams) .map(([key, value]: [string, unknown]) => `${key}="${value}"`) - .join(" ") + " "; + .join(" "); this.tag( - `` + `` ); return; } - const width = safeTpl`width="${embed.dimensions?.[0]}" `; + const width = safeTpl` width="${embed.dimensions?.[0]}" `; const height = safeTpl`height="${embed.dimensions?.[1]}" `; this.tag( - `` + )}"${width}${height}>` ); }; diff --git a/packages/remark-obsidian/internal-link/internal-link.test.ts b/packages/remark-obsidian/internal-link/internal-link.test.ts index 931ca8d..b398daf 100644 --- a/packages/remark-obsidian/internal-link/internal-link.test.ts +++ b/packages/remark-obsidian/internal-link/internal-link.test.ts @@ -83,7 +83,7 @@ test("[[Internal Link#^Abc123]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -93,7 +93,7 @@ test("[[Internal Link#^Abc123|Alias]]", () => { htmlExtensions: [html()], }); - assert.equal(serialized, ''); + assert.equal(serialized, ''); }); test("[[#Main Section]]", () => { @@ -102,7 +102,7 @@ test("[[#Main Section]]", () => { htmlExtensions: [html()], }); - assert.equal(serialized, ''); + assert.equal(serialized, ''); }); test("[[#Main Section|Alias]]", () => { @@ -111,7 +111,7 @@ test("[[#Main Section|Alias]]", () => { htmlExtensions: [html()], }); - assert.equal(serialized, ''); + assert.equal(serialized, ''); }); test("[[#Main Section#Sub Section]]", () => { @@ -122,7 +122,7 @@ test("[[#Main Section#Sub Section]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -134,7 +134,7 @@ test("[[#Main Section#Sub Section|Alias]]", () => { assert.equal( serialized, - '' + '' ); }); @@ -144,7 +144,7 @@ test("[[#^Abc123]]", () => { htmlExtensions: [html()], }); - assert.equal(serialized, ''); + assert.equal(serialized, ''); }); test("[[#^Abc123|Alias]]", () => { @@ -153,5 +153,5 @@ test("[[#^Abc123|Alias]]", () => { htmlExtensions: [html()], }); - assert.equal(serialized, ''); + assert.equal(serialized, ''); }); diff --git a/packages/remark-obsidian/internal-link/utils.ts b/packages/remark-obsidian/internal-link/utils.ts index 430221b..697724d 100644 --- a/packages/remark-obsidian/internal-link/utils.ts +++ b/packages/remark-obsidian/internal-link/utils.ts @@ -1,6 +1,7 @@ +import { slugify } from "~/utils"; import type { InternalLinkNode } from "../types"; -export const slugify = (s: string) => s.toLowerCase().replace(/\s+/g, "-"); +export { slugify } from "~/utils"; export const displayName = (internalLink: InternalLinkNode) => { let displayName = internalLink.alias ?? internalLink.value ?? ""; @@ -29,6 +30,6 @@ export const href = ( return slugify( internalLink.value ? `/${internalLink.value}${blockOrHeadings}` - : `/${blockOrHeadings}` + : `${blockOrHeadings}` ); }; diff --git a/packages/remark-obsidian/remark-obsidian.test.ts b/packages/remark-obsidian/remark-obsidian.test.ts index 8b82c12..91c22da 100644 --- a/packages/remark-obsidian/remark-obsidian.test.ts +++ b/packages/remark-obsidian/remark-obsidian.test.ts @@ -49,40 +49,40 @@ test("[[Internal Links#Main Section#Sub Section|Alias]]", async () => { test("[[Internal Links#^Abc-123]]", async () => { const { code } = await md.render("[[Internal Links#^Abc-123]]"); expect(code).toContain( - 'Internal Links > ^Abc-123' + 'Internal Links > ^Abc-123' ); }); test("[[Internal Links#^Abc-123|Alias]]", async () => { const { code } = await md.render("[[Internal Links#^Abc-123|Alias]]"); - expect(code).toContain('Alias'); + expect(code).toContain('Alias'); }); test("[[#Main Section]]", async () => { const { code } = await md.render("[[#Main Section]]"); - expect(code).toContain('Main Section'); + expect(code).toContain('Main Section'); }); test("[[#Main Section|Alias]]", async () => { const { code } = await md.render("[[#Main Section|Alias]]"); - expect(code).toContain('Alias'); + expect(code).toContain('Alias'); }); test("[[#Main Section#Sub Section]]", async () => { const { code } = await md.render("[[#Main Section#Sub Section]]"); expect(code).toContain( - 'Main Section > Sub Section' + 'Main Section > Sub Section' ); }); test("[[#^Abc-123]]", async () => { const { code } = await md.render("[[#^Abc-123]]"); - expect(code).toContain('^Abc-123'); + expect(code).toContain('^Abc-123'); }); test("[[#^Abc-123|Alias]]", async () => { const { code } = await md.render("[[#^Abc-123|Alias]]"); - expect(code).toContain('Alias'); + expect(code).toContain('Alias'); }); // New embed tests @@ -219,13 +219,13 @@ test("![[Internal Link#Section|Alias]]", async () => { test("![[Internal Link#^block-id]]", async () => { const { code } = await md.render("![[Internal Link#^block-id]]"); expect(code).toContain( - '' + '' ); }); test("![[Internal Link#^block-id|Alias]]", async () => { const { code } = await md.render("![[Internal Link#^block-id|Alias]]"); expect(code).toContain( - '' + '' ); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae799b6..174c62c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,9 @@ importers: typescript: specifier: ^5.5.4 version: 5.5.4 + vite-tsconfig-paths: + specifier: ^5.0.1 + version: 5.0.1(typescript@5.5.4)(vite@5.3.5(@types/node@22.1.0)) devDependencies: '@cloudflare/workers-types': specifier: ^4.20240729.0 @@ -2836,6 +2839,14 @@ packages: vite-plugin-full-reload@1.2.0: resolution: {integrity: sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==} + vite-tsconfig-paths@5.0.1: + resolution: {integrity: sha512-yqwv+LstU7NwPeNqajZzLEBVpUFU6Dugtb2P84FXuvaoYA+/70l9MHE+GYfYAycVyPSDYZ7mjOFuYBRqlEpTig==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + vite@5.3.5: resolution: {integrity: sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -6090,6 +6101,17 @@ snapshots: picocolors: 1.0.1 picomatch: 2.3.1 + vite-tsconfig-paths@5.0.1(typescript@5.5.4)(vite@5.3.5(@types/node@22.1.0)): + dependencies: + debug: 4.3.6 + globrex: 0.1.2 + tsconfck: 3.1.1(typescript@5.5.4) + optionalDependencies: + vite: 5.3.5(@types/node@22.1.0) + transitivePeerDependencies: + - supports-color + - typescript + vite@5.3.5(@types/node@22.1.0): dependencies: esbuild: 0.21.5 diff --git a/src/utils.ts b/src/utils.ts index 730fd13..8fcf2dd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,8 @@ -export const slugify = (s: string) => s.toLowerCase().replace(/\s+/g, "-"); +export const slugify = (s: string) => + s + .toLowerCase() + .replace(/\s+/g, "-") + .replace(/[^a-z0-9-#\/\.]/g, ""); export const isValidSha256 = (hashString: string) => /^[a-fA-F0-9]{64}$/.test(hashString); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..2cb2f69 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig({ + plugins: [tsconfigPaths()], + test: { + // Add any additional test configurations here if needed + }, +});