Compare commits

..

No commits in common. "main" and "0.0.10" have entirely different histories.
main ... 0.0.10

23 changed files with 3414 additions and 5671 deletions

2
.eslintignore Normal file
View file

@ -0,0 +1,2 @@
npm node_modules
build

1
.gitignore vendored
View file

@ -8,7 +8,6 @@ node_modules
# Don't include the compiled main.js file in the repo.
# They should be uploaded to GitHub releases instead.
main.js
styles.css
# Exclude sourcemaps
*.map

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 Roger Veciana i Rovira
Copyright (c) 2024 Roger Veciana i Rovira
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -16,16 +16,6 @@ This plugin allows you to edit and view recipes written in the Cooklang format.
- Multi language: The titles for the sections (i.e. *ingredients*, *cookware* and so on) will be translated into the recipe language or the one configured in the Obsidian settings
- Scale quantities: The slider in the ingredients part allows multiplying or dividing the amounts
## Searching
Obsidian won't search files that aren't of the extension *.md by default. Since cooklang has the .cook extension, any search will gnore the files, which is really impractical. Fortuntely, there's a workaround:
- Install the `omnisearch` plugin
- Open its settings
- Add the word `cook` at the section `Additional TEXT files to index`
The search has to be done from the sidebar search icon, but it works perfectly.
## Changelog

View file

@ -1,58 +0,0 @@
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import svelte from 'eslint-plugin-svelte';
import svelteParser from 'svelte-eslint-parser';
import type { Linter } from 'eslint';
import tsParser from '@typescript-eslint/parser';
const svelteRecommendedWithRules = svelte.configs.recommended.find(
(config) => 'rules' in config
);
const svelteRules = (svelteRecommendedWithRules?.rules ?? {}) as Linter.RulesRecord;
export default [
// ⛔ Ignore files/folders
{
ignores: ['node_modules', 'build', 'main.js', 'vite.config.mjs', 'version-bump.mjs'],
},
// Base JS rules
js.configs.recommended,
// TypeScript rules
...tseslint.configs.recommended,
// Svelte-specific configuration
{
files: ['**/*.svelte'],
plugins: {
svelte,
},
languageOptions: {
globals: { document: 'readonly',console: 'readonly',
window: 'readonly', },
parser: svelteParser,
parserOptions: {
parser: tsParser,
ecmaVersion: 2020,
sourceType: 'module',
extraFileExtensions: ['.svelte'],
},
},
rules: {
...svelteRules
},
},
// Global rules for all file
{
rules: {
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['error', { args: 'none' }],
'@typescript-eslint/ban-ts-comment': 'off',
'no-prototype-builtins': 'off',
'@typescript-eslint/no-empty-function': 'off',
},
},
];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

View file

@ -1,7 +1,7 @@
{
"id": "cooklang-viewer-and-editor",
"name": "Cooklang",
"version": "0.1.0",
"version": "0.0.10",
"minAppVersion": "0.12.0",
"description": "Display and edit recipes written in the Cooklang format.",
"author": "Roger Veciana i Rovira",

7272
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,13 @@
{
"name": "cooklang-viewer-and-editor",
"version": "0.1.0",
"name": "obsidian-svelte-starter",
"version": "0.0.10",
"description": "A plugin development template for devs who want to use svelte in Obsidian.",
"main": "main.js",
"type": "module",
"scripts": {
"lint": "eslint . --ext .ts",
"dev": "npm run lint && vite build --watch",
"test": "vitest",
"build": "npx svelte-check && vite build",
"bumpversion": "node version-bump.mjs && git add manifest.json versions.json && git commit -m 'bump version'",
"bumpversion": "node version-bump.mjs && git add manifest.json versions.json",
"postversion": "npm run bumpversion",
"prepare": "husky",
"set-date": "year=`date +%Y` && cat LICENSE|sed \"3s/.*/Copyright (c) $year Roger Veciana i Rovira/\">LICENSE.tmp && mv LICENSE.tmp LICENSE"
@ -20,32 +18,25 @@
],
"author": "Roger Veciana i Rovira",
"devDependencies": {
"@cooklang/cooklang-ts": "^1.2.7",
"@svelte-plugins/tooltips": "^3.0.3",
"@sveltejs/vite-plugin-svelte": "^5.1.0",
"@tsconfig/svelte": "^5.0.4",
"@types/node": "^22.15.29",
"@typescript-eslint/parser": "^8.33.1",
"builtin-modules": "^5.0.0",
"esbuild-svelte": "^0.9.3",
"eslint": "^9.28.0",
"eslint-plugin-svelte": "^3.9.0",
"@cooklang/cooklang-ts": "^1.2.5",
"@svelte-plugins/tooltips": "^3.0.0",
"@sveltejs/vite-plugin-svelte": "^1.0.1",
"@tsconfig/svelte": "^3.0.0",
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "6.19.0",
"@typescript-eslint/parser": "6.19.0",
"builtin-modules": "3.3.0",
"eslint": "^8.56.0",
"eslint-plugin-svelte": "^2.35.1",
"franc": "^6.2.0",
"husky": "^9.1.7",
"jiti": "^2.4.2",
"obsidian": "^1.8.7",
"svelte": "^5.33.14",
"svelte-check": "^4.1.6",
"husky": "^9.0.11",
"obsidian": "0.15.9",
"svelte": "^3.49.0",
"svelte-check": "^2.8.0",
"svelte-i18next": "^2.2.2",
"svelte-preprocess": "^6.0.3",
"tslib": "^2.8.1",
"typescript": "~5.8.3",
"typescript-eslint": "^8.33.0",
"vite": "^6.3.5",
"vite-plugin-static-copy": "^3.0.0",
"vitest": "^3.2.1"
},
"dependencies": {
"svelte-range-slider-pips": "^4.0.0"
"svelte-preprocess": "^5.1.3",
"tslib": "2.4.0",
"typescript": "5.3.3",
"vite": "^3.0.0"
}
}

View file

@ -1,5 +1,5 @@
import i18next from "i18next";
import { createI18nStore } from "svelte-i18next/i18n.js";
import { createI18nStore } from "svelte-i18next";
export const i18n = createI18nStore(i18next);

View file

@ -8,7 +8,6 @@ export const resources = {
"step": "Step",
"some": "Some",
"source": "Source",
"servings": "Servings",
}
},
es: {
@ -20,7 +19,6 @@ export const resources = {
"step": "Paso",
"some": "Algunos",
"source": "Fuente",
"servings": "Porciones",
}
},
ca: {
@ -32,7 +30,6 @@ export const resources = {
"step": "Pas",
"some": "Alguns",
"source": "Font",
"servings": "Racions",
}
},
de: {
@ -44,7 +41,6 @@ export const resources = {
"step": "Schritt",
"some": "Einige",
"source": "Quelle",
"servings": "Portionen",
}
},
fr: {
@ -56,7 +52,6 @@ export const resources = {
"step": "Étape",
"some": "Certains",
"source": "Source",
"servings": "Portions",
}
},
pt: {
@ -68,7 +63,6 @@ export const resources = {
"step": "Passo",
"some": "Alguns",
"source": "Fonte",
"servings": "Porções",
}
},
it: {
@ -80,7 +74,6 @@ export const resources = {
"step": "Passo",
"some": "Alcuni",
"source": "Fonte",
"servings": "Porzioni",
}
},
nl: {
@ -92,7 +85,6 @@ export const resources = {
"step": "Stap",
"some": "Sommige",
"source": "Bron",
"servings": "Porties",
}
},
tr: {
@ -104,7 +96,6 @@ export const resources = {
"step": "Adım",
"some": "Bazı",
"source": "Kaynak",
"servings": "Porsiyonlar",
}
},
el: {
@ -116,7 +107,6 @@ export const resources = {
"step": "Βήμα",
"some": "Κάποια",
"source": "Πηγή",
"servings": "Μερίδες",
}
}
}

View file

@ -2,21 +2,17 @@ import {
Plugin,
TFile,
TextFileView,
type WorkspaceLeaf,
WorkspaceLeaf,
setIcon
} from "obsidian";
import i18next from "i18next";
import { resources } from "./lang/resources.js";
import { resources } from "./lang/resources";
import Edit from "./ui/Edit.svelte";
import View from "./ui/View.svelte";
import { DEFAULT_SETTINGS, Settings, type CookLangSettings } from "./ui/Settings.js";
import { getI18n, isTFile } from "./ui/utils.js";
import { mount, unmount } from "svelte";
import { Parser, type ParseResult } from "@cooklang/cooklang-ts";
import { DEFAULT_SETTINGS, Settings, type CookLangSettings } from "./ui/Settings";
import { getI18n, isTFile } from "./ui/utils";
const VIEW_TYPE = "svelte-cooklang";
@ -35,19 +31,16 @@ i18next.init({
const DEFAULT_DATA = "";
class CooklangSvelteView extends TextFileView {
view!: View | Edit;
view: View | Edit;
mode: "source" | "preview" = "preview";
changeModeButton!: HTMLElement;
changeModeButton: HTMLElement;
data: string = DEFAULT_DATA;
images: Record<string, string> = {};
settings: CookLangSettings;
props = $state({data:DEFAULT_DATA, images:{}, settings: DEFAULT_SETTINGS});
constructor(leaf: WorkspaceLeaf, settings: CookLangSettings) {
super(leaf);
this.settings = settings;
}
getViewType(): string {
@ -69,33 +62,32 @@ class CooklangSvelteView extends TextFileView {
this.changeModeButton = this.addAction(
"pencil",
"Preview (Ctrl+Click to open in new pane)",
(e) => { this.switchMode(e.metaKey || e.ctrlKey);}
(e) => { this.switchMode(e.metaKey || e.ctrlKey);},
17
);
}
renderPreview(newTab=false){
const container = this.contentEl.createEl("div");
const newElement = this.mode === "preview"?
mount(View , {target: container, props: this.props})
:
mount(Edit, {target: container,
props: {data: this.props.data,
onChange: (newData:string) => {
this.props.data = newData;
this.data = newData;
}}
})
if(newTab && this.file){
const newElement = this.mode === "preview"
? new View({
target: container,
props: { data: this.data, images: this.images, settings: this.settings },
})
: new Edit({
target: container,
props: {
data: this.data,
onChange: (newData:string) => (this.data = newData),
},
});
if(newTab){
const newTab = this.app.workspace.getLeaf(true);
newTab.openFile(this.file);
} else {
if (this.view) {
unmount(this.view);
this.view.$destroy();
}
this.view = newElement;
}
@ -105,14 +97,13 @@ class CooklangSvelteView extends TextFileView {
getViewData(): string {
return this.data;
}
setViewData(data: string): void {
const images = (
this.file?.parent?.children.filter(isTFile).filter(
(f) => (f.basename === this.file?.basename ||
f.basename.startsWith(this.file?.basename + ".")) &&
f.name != this.file?.name &&
this.file.parent.children.filter(isTFile).filter(
(f) => (f.basename === this.file.basename ||
f.basename.startsWith(this.file.basename + ".")) &&
f.name != this.file.name &&
["png", "jpg", "jpeg", "gif","webp"].includes(f.extension)
) as TFile[]
).reduce((acc, f) => {
@ -126,22 +117,15 @@ class CooklangSvelteView extends TextFileView {
return acc;
}, {} as Record<string, string>);
this.images = images;
const recipe: ParseResult = new Parser().parse(data);
if(recipe.metadata.locale){
const lang = recipe.metadata.locale.split("_")[0]
i18next.changeLanguage(lang);
} else if(this.settings.autoLanguage){
const lang = getI18n(data);
if(this.settings.autoLanguage){
const lang = getI18n(data);
i18next.changeLanguage(lang);
}
this.data = data;
this.props.data = data;
this.props.images = images;
this.renderPreview(false)
this.view.$set({ data, images });
}
clear(): void {
@ -160,7 +144,8 @@ class CooklangSvelteView extends TextFileView {
}
export default class CooklangPlugin extends Plugin {
settings: CookLangSettings = DEFAULT_SETTINGS;
private view: CooklangSvelteView;
settings: CookLangSettings;
async onload() {
@ -169,7 +154,7 @@ export default class CooklangPlugin extends Plugin {
this.registerView(
VIEW_TYPE,
(leaf: WorkspaceLeaf) =>
(new CooklangSvelteView(leaf, this.settings))
(this.view = new CooklangSvelteView(leaf, this.settings))
);
this.app.workspace.onLayoutReady(this.onLayoutReady.bind(this));
@ -225,7 +210,7 @@ export default class CooklangPlugin extends Plugin {
if (this.app.workspace.getLeavesOfType(VIEW_TYPE).length) {
return;
}
this.app.workspace.getRightLeaf(false)?.setViewState({
this.app.workspace.getRightLeaf(false).setViewState({
type: VIEW_TYPE,
});
}

View file

@ -1,22 +1,15 @@
<script lang="ts">
let { data, onChange }: { data: string; onChange: (newData: string) => void } = $props();
$effect(() => {
if (data !== undefined) {
onChange(data);
}
});
export let data: string;
export let onChange: (newData: string) => void;
$: onChange(data);
</script>
<div>
<div
class="content"
contenteditable="true"
role="textbox"
tabindex="0"
aria-multiline="true"
bind:textContent={data}
onkeydown={(e) => {
on:keydown={(e) => {
if (e.key === 'Enter') {
document.execCommand('insertLineBreak');
e.preventDefault();

View file

@ -1,5 +1,5 @@
import { type App, PluginSettingTab, Setting } from "obsidian";
import type CooklangPlugin from "src/starterIndex.svelte";
import { App, PluginSettingTab, Setting } from "obsidian";
import type CooklangPlugin from "src/starterIndex";
export class Settings extends PluginSettingTab {
plugin: CooklangPlugin;

View file

@ -1,27 +1,22 @@
<script lang="ts">
import { Parser, type ParseResult } from '@cooklang/cooklang-ts';
import { tooltip } from '@svelte-plugins/tooltips';
import i18n from '../lang/i18n.js';
import { DEFAULT_SETTINGS, type CookLangSettings } from './Settings.js';
import { formatNumber } from './utils.js';
import RangeSlider from 'svelte-range-slider-pips';
import i18n from '../lang/i18n';
import { DEFAULT_SETTINGS, type CookLangSettings } from './Settings';
import { formatNumber } from './utils';
let {
data,
images = {},
settings = DEFAULT_SETTINGS
}: { data: string; images: Record<string, string>; settings: CookLangSettings } = $props();
export let data: string;
export let images: Record<string, string> = {};
export let settings: CookLangSettings = DEFAULT_SETTINGS;
const scales = [0.25, 0.5, 1, 1.5, 2, 3, 4];
let scaleIdx = $state(2);
let scale = $derived(scales[scaleIdx]);
const translateIngredientsQuantity = (quantity: string | number, scale: number = 1) =>
const translateIngredientsQuantity = (quantity: string | number) =>
quantity === 'some'
? $i18n.t('some')
: formatNumber(quantity, settings.showFractionsInQuantities, scale);
: formatNumber(quantity, settings.showFractionsInQuantities);
const recipe: ParseResult = new Parser().parse(data);
let recipe: ParseResult;
$: recipe = new Parser().parse(data);
</script>
<div>
@ -35,22 +30,18 @@
<section class="section">
<h3 class="section-title">{$i18n.t('ingredients')}</h3>
{#if recipe.metadata.servings}
<p class="servings">
{$i18n.t('servings')}: {scale * parseInt(recipe.metadata.servings)}
</p>
<p class="servings">Servings: {recipe.metadata.servings}</p>
{/if}
<ul class="ingredients">
{#each recipe.ingredients as ingredient}
<li>
{translateIngredientsQuantity(ingredient.quantity, scale)}
{translateIngredientsQuantity(ingredient.quantity)}
{ingredient.units}
{ingredient.name}
</li>
{/each}
</ul>
<RangeSlider bind:value={scaleIdx} min={0} max={6} />
</section>
{/if}
{#if settings.showCookwareList && recipe.cookwares.length > 0}
@ -109,7 +100,7 @@
<style>
.image-main {
max-width: 300px;
width: 100%;
}
section {
border: 1px solid #ccc;

View file

@ -1,36 +0,0 @@
import { describe, it, expect, vi } from 'vitest';
import { formatNumber } from './utils.js';
describe('formatNumber', () => {
it('Should parse a simple string with a number only', () => {
expect(formatNumber(2)).toBe("2");
});
it('Should parse a simple string with a string only', () => {
expect(formatNumber("hello")).toBe("hello");
});
it('Should parse a string with a number and a string', () => {
expect(formatNumber("2 kilos")).toBe("2 kilos");
expect(formatNumber("about 2 kilos")).toBe("about 2 kilos");
});
it('Should parse a string with a scaled number and a string', () => {
expect(formatNumber("2 kilos", true, 2)).toBe("4 kilos");
expect(formatNumber("2 kilos", true, 0.5)).toBe("1 kilos");
});
it('Should parse a string with a scaled number with decimals', () => {
expect(formatNumber("2.5 kilos", true, 2)).toBe("5 kilos");
});
it('Should parse a string with a scaled number with decimals, rounding to une decimal', () => {
expect(formatNumber("2.55 kilos")).toBe("2.5 kilos");
expect(formatNumber("1 kilos", false, 0.3333333)).toBe("0.3 kilos");
});
it('Should convert to fractions', () => {
expect(formatNumber(0.33333, true)).toBe("1/3");
expect(formatNumber(0.5, true)).toBe("1/2");
expect(formatNumber(0.2, true)).toBe("1/5");
});
});

View file

@ -1,7 +1,7 @@
import type { Ingredient, Cookware, Timer, Text } from "@cooklang/cooklang-ts";
import { franc } from "franc";
import { iso6393To1 } from "./langCodes.js";
import { type TAbstractFile, TFile } from "obsidian";
import { iso6393To1 } from "./langCodes";
import { TAbstractFile, TFile } from "obsidian";
export const isText = (
step: Ingredient | Cookware | Timer | Text
@ -39,37 +39,29 @@ export const getI18n = (data:string) => {
}
const formatFraction = (num:number, useFraction:boolean=false) =>{
if(!useFraction) return +num.toFixed( 1 );
export const formatNumber = (num: number|string, useFraction:boolean=false): string => {
if(typeof num === 'string') return num;
const epsilon = 0.0001;
if (Math.abs(num - 1 / 2) < epsilon) return "1/2";
else if (Math.abs(num - 1 / 3) < epsilon) return "1/3";
else if (Math.abs(num - 2 / 3) < epsilon) return "2/3";
else if (Math.abs(num - 1 / 4) < epsilon) return "1/4";
else if (Math.abs(num - 3 / 4) < epsilon) return "3/4";
else if (Math.abs(num - 1 / 5) < epsilon) return "1/5";
else if (Math.abs(num - 2 / 5) < epsilon) return "2/5";
else if (Math.abs(num - 3 / 5) < epsilon) return "3/5";
else if (Math.abs(num - 4 / 5) < epsilon) return "4/5";
else if (Math.abs(num - 1 / 6) < epsilon) return "1/6";
else if (Math.abs(num - 5 / 6) < epsilon) return "5/6";
else if (Math.abs(num - 1 / 7) < epsilon) return "1/7";
else if (Math.abs(num - 1 / 8) < epsilon) return "1/8";
else if (Math.abs(num - 3 / 8) < epsilon) return "3/8";
else if (Math.abs(num - 5 / 8) < epsilon) return "5/8";
else if (Math.abs(num - 7 / 8) < epsilon) return "7/8";
else if (Math.abs(num - 1 / 9) < epsilon) return "1/9";
else if (Math.abs(num - 1 / 10) < epsilon) return "1/10";
else if (Math.abs(num - 1 / 12) < epsilon) return "1/12";
else if (Math.abs(num - 1 / 16) < epsilon) return "1/16";
else if (Math.abs(num - 1 / 32) < epsilon)return "1/32";
// If no fraction matches, just return
return +num.toFixed( 1 );
}
export const formatNumber = (num: number|string, useFraction:boolean=false, scale=1): string => {
const str = String(num);
const parts = str.match(/\d+(\.\d+)?|[a-zA-Z']+/g);
if (!parts) return str;
return parts.map(part => /^\d+(\.\d+)?$/.test(part) ? formatFraction(Number(part)*scale, useFraction) : part).join(" ");
if(Math.abs(num - 1/2) < epsilon) return useFraction?"1/2":"0.5";
else if(Math.abs(num - 1/3) < epsilon) return useFraction?"1/3":"0.33";
else if(Math.abs(num - 2/3) < epsilon) return useFraction?"2/3":"0.66";
else if(Math.abs(num - 1/4) < epsilon) return useFraction?"1/4":"0.25";
else if(Math.abs(num - 3/4) < epsilon) return useFraction?"3/4":"0.75";
else if(Math.abs(num - 1/5) < epsilon) return useFraction?"1/5":"0.2";
else if(Math.abs(num - 2/5) < epsilon) return useFraction?"2/5":"0.4";
else if(Math.abs(num - 3/5) < epsilon) return useFraction?"3/5":"0.6";
else if(Math.abs(num - 4/5) < epsilon) return useFraction?"4/5":"0.8";
else if(Math.abs(num - 1/6) < epsilon) return useFraction?"1/6":"0.16";
else if(Math.abs(num - 5/6) < epsilon) return useFraction?"5/6":"0.83";
else if(Math.abs(num - 1/7) < epsilon) return useFraction?"1/7":"0.14";
else if(Math.abs(num - 1/8) < epsilon) return useFraction?"1/8":"0.125";
else if(Math.abs(num - 3/8) < epsilon) return useFraction?"3/8":"0.375";
else if(Math.abs(num - 5/8) < epsilon) return useFraction?"5/8":"0.625";
else if(Math.abs(num - 7/8) < epsilon) return useFraction?"7/8":"0.875";
else if(Math.abs(num - 1/9) < epsilon) return useFraction?"1/9":"0.11";
else if(Math.abs(num - 1/10) < epsilon) return useFraction?"1/10":"0.1";
else if(Math.abs(num - 1/12) < epsilon) return useFraction?"1/12":"0.08";
else if(Math.abs(num - 1/16) < epsilon) return useFraction?"1/16":"0.06";
else if(Math.abs(num - 1/32) < epsilon) return useFraction?"1/32":"0.03";
else return num.toString();
};

1337
styles.css

File diff suppressed because it is too large Load diff

View file

@ -1,7 +0,0 @@
// test/__mocks__/obsidian.ts
export class TFile {
path: string = "";
name: string = "";
}
export type TAbstractFile = TFile;

View file

@ -1,28 +1,21 @@
{
"compilerOptions": {
"verbatimModuleSyntax": true,
"types": ["svelte"],
"skipLibCheck": true,
"baseUrl": ".",
"inlineSources": true,
"allowJs": true,
"noImplicitAny": true,
"moduleResolution": "node16",
"module": "node16",
"target": "ES2022",
"esModuleInterop": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"importHelpers": true,
"isolatedModules": true,
"strictNullChecks": true,
"lib": [
"DOM",
"ES5",
"ES6",
"ES7"
],
"baseUrl": ".",
"inlineSources": true,
"module": "ESNext",
"target": "ES6",
"allowJs": true,
"noImplicitAny": true,
"moduleResolution": "node",
"importHelpers": true,
"isolatedModules": true,
"strictNullChecks": true,
"lib": [
"DOM",
"ES5",
"ES6",
"ES7"
]
},
"extends": "@tsconfig/svelte/tsconfig.json",
"include": [

View file

@ -8,8 +8,5 @@
"0.0.7": "0.12.0",
"0.0.8": "0.12.0",
"0.0.9": "0.12.0",
"0.0.10": "0.12.0",
"0.0.11": "0.12.0",
"0.0.12": "0.12.0",
"0.1.0": "0.12.0"
"0.0.10": "0.12.0"
}

View file

@ -1,38 +1,17 @@
import path from 'path';
import { defineConfig } from 'vite';
import esbuildSvelte from 'esbuild-svelte';
import sveltePreprocess from 'svelte-preprocess';
import builtins from 'builtin-modules';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import autoPreprocess from 'svelte-preprocess';
import builtins from 'builtin-modules';
const prod = (process.argv[2] === 'production');
export default defineConfig(() => {
return {
plugins: [
svelte({
preprocess: sveltePreprocess({ typescript: true,
}),
}),
esbuildSvelte({
compilerOptions: { css: 'injected' },
}),
viteStaticCopy({
targets: [
{
src: 'build/main.js',
dest: '..',
},
{
src: 'build/styles.css',
dest: '..',
}
],
watch: false,
}),
svelte({
preprocess: autoPreprocess()
})
],
watch: !prod,
build: {
@ -43,7 +22,7 @@ export default defineConfig(() => {
ignoreTryCatch: false,
},
lib: {
entry: path.resolve(__dirname, './src/starterIndex.svelte.ts'),
entry: path.resolve(__dirname, './src/starterIndex.ts'),
formats: ['cjs'],
},
css: {},
@ -53,7 +32,6 @@ export default defineConfig(() => {
entryFileNames: 'main.js',
assetFileNames: 'styles.css',
},
external: ['obsidian',
'electron',
"codemirror",
@ -85,8 +63,8 @@ export default defineConfig(() => {
],
},
// Use root as the output dir
outDir: './build',
emptyOutDir: false,
emptyOutDir: false,
outDir: '.',
},
}
});

View file

@ -1,14 +0,0 @@
import { defineConfig } from 'vitest/config';
import path from 'path';
export default defineConfig({
test: {
environment: 'node',
globals: true,
},
resolve: {
alias: {
obsidian: path.resolve(__dirname, 'test/__mocks__/obsidian.ts'),
},
},
});