create-outsystems-astro 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +5 -0
  2. package/bin/cli.js +6 -1
  3. package/package.json +1 -1
  4. package/template/.prettierignore +4 -1
  5. package/template/.prettierrc +4 -0
  6. package/template/AGENTS.md +104 -15
  7. package/template/astro.config.mjs +2 -0
  8. package/template/bun.lock +621 -656
  9. package/template/deno.json +1 -5
  10. package/template/deno.lock +1303 -977
  11. package/template/eslint.config.mjs +19 -0
  12. package/template/output.ts +14 -2
  13. package/template/package-lock.json +3949 -4042
  14. package/template/package.json +62 -58
  15. package/template/pnpm-lock.yaml +2431 -1927
  16. package/template/pnpm-workspace.yaml +6 -0
  17. package/template/src/framework/angular/Counter.component.ts +25 -13
  18. package/template/src/framework/react/Counter.tsx +41 -9
  19. package/template/src/framework/svelte/Counter.svelte +77 -0
  20. package/template/src/framework/vue/Counter.vue +49 -14
  21. package/template/src/pages/angular/angular-counter.astro +30 -10
  22. package/template/src/pages/react/react-counter.astro +58 -16
  23. package/template/src/pages/svelte/svelte-counter.astro +63 -0
  24. package/template/src/pages/vue/vue-counter.astro +61 -15
  25. package/template/src/stores/.gitkeep +0 -0
  26. package/template/src/styles/index.css +65 -0
  27. package/template/svelte.config.js +5 -0
  28. package/template/test/e2e/react/react-counter.spec.ts +12 -2
  29. package/template/test/e2e/svelte/svelte-counter.spec.ts +42 -0
  30. package/template/test/e2e/vue/vue-counter.spec.ts +12 -2
  31. package/template/test/integration/angular/Counter.component.spec.ts +1 -1
  32. package/template/test/integration/react/Counter.test.tsx +35 -10
  33. package/template/test/integration/svelte/Counter.test.ts +81 -0
  34. package/template/test/integration/svelte/SlotCounter.wrapper.svelte +27 -0
  35. package/template/test/integration/vue/Counter.test.ts +42 -4
  36. package/template/vitest.config.ts +17 -2
  37. package/template/yarn.lock +3656 -2059
  38. /package/template/patches/{@analogjs+astro-angular+2.2.2.patch → @analogjs+astro-angular+2.3.0.patch} +0 -0
  39. /package/template/patches/{@angular+build+21.1.0.patch → @angular+build+21.2.0.patch} +0 -0
@@ -0,0 +1,6 @@
1
+ onlyBuiltDependencies:
2
+ - '@parcel/watcher'
3
+ - esbuild
4
+ - lmdb
5
+ - msgpackr-extract
6
+ - sharp
@@ -11,17 +11,29 @@ import { Operation, setCounterCount } from "../../lib/setCounterCount";
11
11
  standalone: true,
12
12
  template: `
13
13
  <div class="counter-title" slot="header">Counter</div>
14
-
15
- <div class="counter-controls">
16
- <button (click)="subtract()">-</button>
17
- <pre>{{ count() }}</pre>
18
- <button (click)="add()">+</button>
19
- </div>
20
-
21
- <div class="counter-message">
22
- <button (click)="showParentMessage()">Send value</button>
14
+ <div class="card-grid">
15
+ <div class="card">
16
+ Internal counter controls. It keeps state within the component.
17
+ <div class="card-content">
18
+ <div class="counter-controls">
19
+ <button (click)="subtract()">-</button>
20
+ <pre>{{ count() }}</pre>
21
+ <button (click)="add()">+</button>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div class="card">
26
+ The button sends the current count value to a function in the parent
27
+ component.
28
+ <div class="card-content">
29
+ <div>
30
+ <button class="card-btn" (click)="showParentMessage()">
31
+ Send value
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </div>
23
36
  </div>
24
-
25
37
  <div class="counter-logos">
26
38
  <img [src]="outSystemsLogo" alt="OutSystems logo" />
27
39
  <img [src]="astroLogo" alt="Astro logo" />
@@ -48,11 +60,11 @@ export default class CounterComponent implements OnInit {
48
60
  showParentMessage() {
49
61
  const fnName = this.messageFunctionName();
50
62
 
51
- // Safety check to ensure the function exists on window/document
63
+ // Safety check to ensure the function exists on window.
52
64
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
- if (typeof (document as any)[fnName] === "function") {
65
+ if (typeof (window as any)[fnName] === "function") {
54
66
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
- (document as any)[fnName](this.count());
67
+ (window as any)[fnName](this.count());
56
68
  }
57
69
  }
58
70
 
@@ -1,3 +1,4 @@
1
+ import { useStore } from "@nanostores/react";
1
2
  import { useState } from "react";
2
3
 
3
4
  import AstroLogo from "../../images/astro.png?url";
@@ -20,19 +21,50 @@ export default function Counter({
20
21
  const subtract = () =>
21
22
  setCount((i) => setCounterCount(i, Operation.Subtract));
22
23
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
- const showParentMessage = () => (document as any)[showMessage](count);
24
+ const showParentMessage = () => (window as any)[showMessage](count);
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ const nanoStoreValue = useStore((window as any).Stores["reactStore"]);
24
27
 
25
28
  return (
26
29
  <>
27
30
  {header}
28
- <div className="counter-controls">
29
- <button onClick={subtract}>-</button>
30
- <pre>{count}</pre>
31
- <button onClick={add}>+</button>
32
- </div>
33
- <div>{children}</div>
34
- <div className="counter-message">
35
- <button onClick={showParentMessage}>Send value</button>
31
+ <div className="card-grid">
32
+ <div className="card">
33
+ Internal counter controls. It keeps state within the component.
34
+ <div className="card-content">
35
+ <div className="counter-controls">
36
+ <button onClick={subtract}>-</button>
37
+ <pre>{count}</pre>
38
+ <button onClick={add}>+</button>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ <div className="card">
43
+ The button sends the current count value to a function in the parent
44
+ component.
45
+ <div className="card-content">
46
+ <div>
47
+ <button className="card-btn" onClick={showParentMessage}>
48
+ Send value
49
+ </button>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ <div className="card">
54
+ Slot content coming in to the component
55
+ <div className="card-content">
56
+ <div>{children}</div>
57
+ </div>
58
+ </div>
59
+ <div className="card">
60
+ Nano Store content
61
+ <div className="card-content">
62
+ <div>
63
+ <strong>Nano Store value:</strong>
64
+ <div id="nanostore">{nanoStoreValue}</div>
65
+ </div>
66
+ </div>
67
+ </div>
36
68
  </div>
37
69
  <div className="counter-logos">
38
70
  <img alt="OutSystems logo" src={OutSystemsLogo} />
@@ -0,0 +1,77 @@
1
+ <script lang="ts">
2
+ import AstroLogo from "../../images/astro.png?url";
3
+ import OutSystemsLogo from "../../images/outsystems.png?url";
4
+ import { Operation, setCounterCount } from "../../lib/setCounterCount";
5
+
6
+ export let initialCount: number;
7
+ export let showMessage: string;
8
+
9
+ let count = initialCount;
10
+
11
+ const add = () => {
12
+ count = setCounterCount(count, Operation.Add);
13
+ };
14
+
15
+ const subtract = () => {
16
+ count = setCounterCount(count, Operation.Subtract);
17
+ };
18
+
19
+ const showParentMessage = () => {
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ (window as any)[showMessage](count);
22
+ };
23
+
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ const nanoStoreValue = (window as any).Stores["svelteStore"];
26
+ </script>
27
+
28
+ <slot name="header" />
29
+
30
+ <div class="card-grid">
31
+ <div class="card">
32
+ Internal counter controls. It keeps state within the component.
33
+ <div class="card-content">
34
+ <div class="counter-controls">
35
+ <button on:click={subtract}>-</button>
36
+ <pre>{count}</pre>
37
+ <button on:click={add}>+</button>
38
+ </div>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="card">
43
+ The button sends the current count value to a function in the parent
44
+ component.
45
+ <div class="card-content">
46
+ <div>
47
+ <button class="card-btn" on:click={showParentMessage}>
48
+ Send value
49
+ </button>
50
+ </div>
51
+ </div>
52
+ </div>
53
+
54
+ <div class="card">
55
+ Slot content coming in to the component
56
+ <div class="card-content">
57
+ <div>
58
+ <slot />
59
+ </div>
60
+ </div>
61
+ </div>
62
+
63
+ <div class="card">
64
+ Nano Store content
65
+ <div class="card-content">
66
+ <div>
67
+ <strong>Nano Store value:</strong>
68
+ <div id="nanostore">{$nanoStoreValue}</div>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+
74
+ <div class="counter-logos">
75
+ <img alt="OutSystems logo" src={OutSystemsLogo} />
76
+ <img alt="Astro logo" src={AstroLogo} />
77
+ </div>
@@ -1,8 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import { ref } from "vue";
3
+ import { useStore } from "@nanostores/vue";
3
4
 
4
- import OutSystemsLogo from "../../images/outsystems.png?url";
5
5
  import AstroLogo from "../../images/astro.png?url";
6
+ import OutSystemsLogo from "../../images/outsystems.png?url";
6
7
  import { Operation, setCounterCount } from "../../lib/setCounterCount";
7
8
 
8
9
  const props = defineProps<{
@@ -21,29 +22,63 @@ const subtract = () => {
21
22
  };
22
23
 
23
24
  const showParentMessage = () => {
24
- (document as Document)[props.showMessage]?.(count.value);
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ (window as any)[props.showMessage](count.value);
25
27
  };
28
+
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ const nanoStoreValue = useStore((window as any).Stores["vueStore"]);
26
31
  </script>
27
32
 
28
33
  <template>
29
- <div>
30
- <slot name="header" />
34
+ <slot name="header" />
31
35
 
32
- <div class="counter-controls">
33
- <button @click="subtract">-</button>
34
- <pre>{{ count }}</pre>
35
- <button @click="add">+</button>
36
+ <div class="card-grid">
37
+ <div class="card">
38
+ Internal counter controls. It keeps state within the component.
39
+ <div class="card-content">
40
+ <div class="counter-controls">
41
+ <button @click="subtract">-</button>
42
+ <pre>{{ count }}</pre>
43
+ <button @click="add">+</button>
44
+ </div>
45
+ </div>
36
46
  </div>
37
47
 
38
- <slot />
48
+ <div class="card">
49
+ The button sends the current count value to a function in the parent
50
+ component.
51
+ <div class="card-content">
52
+ <div>
53
+ <button class="card-btn" @click="showParentMessage">
54
+ Send value
55
+ </button>
56
+ </div>
57
+ </div>
58
+ </div>
39
59
 
40
- <div class="counter-message">
41
- <button @click="showParentMessage">Send value</button>
60
+ <div class="card">
61
+ Slot content coming in to the component
62
+ <div class="card-content">
63
+ <div>
64
+ <slot />
65
+ </div>
66
+ </div>
42
67
  </div>
43
68
 
44
- <div class="counter-logos">
45
- <img :src="OutSystemsLogo" alt="OutSystems logo" />
46
- <img :src="AstroLogo" alt="Astro logo" />
69
+ <div class="card">
70
+ Nano Store content
71
+ <div class="card-content">
72
+ <div>
73
+ <strong>Nano Store value:</strong>
74
+ <div id="nanostore">{{ nanoStoreValue }}</div>
75
+ </div>
76
+ </div>
47
77
  </div>
48
78
  </div>
79
+
80
+ <div class="counter-logos">
81
+ <img alt="OutSystems logo" :src="OutSystemsLogo" />
82
+ <img alt="Astro logo" :src="AstroLogo" />
83
+ </div>
49
84
  </template>
@@ -1,15 +1,35 @@
1
1
  ---
2
- import CounterComponent from '../../framework/angular/Counter.component';
2
+ import CounterComponent from "../../framework/angular/Counter.component";
3
3
  import styles from "../../styles/index.css?url";
4
4
  const initialCount = 5;
5
5
  const showMessage = "showMessage";
6
6
  ---
7
- <link href={styles} rel="stylesheet" />
8
- <script is:inline>
9
- document.showMessage = (count) => {
10
- document.getElementById("counter").textContent = count;
11
- };
12
- </script>
13
- <CounterComponent client:visible initialCount={initialCount} showMessage={showMessage}>
14
- </CounterComponent>
15
- <div style="text-align: center; margin-top: 20px;">Counter value: <span id="counter"></span></div>
7
+ <html lang="en">
8
+ <head>
9
+ <link href={styles} rel="stylesheet" />
10
+ <script>
11
+ window.showMessage = (count) => {
12
+ document.getElementById("counter").textContent = count;
13
+ };
14
+ </script>
15
+ </head>
16
+ <body>
17
+ <div class="counter-title">HTML Content</div>
18
+ <div class="card-grid">
19
+ <div class="card">
20
+ Value sent back from component.
21
+ <div class="card-content">
22
+ <div style="text-align: center; margin-top: 30px;">
23
+ Counter value sent back: <br /><span id="counter"></span>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ <hr />
29
+ <CounterComponent
30
+ client:visible
31
+ initialCount={initialCount}
32
+ showMessage={showMessage}
33
+ />
34
+ </body>
35
+ </html>
@@ -1,21 +1,63 @@
1
1
  ---
2
- import CounterComponent from '../../framework/react/Counter';
2
+ import CounterComponent from "../../framework/react/Counter";
3
3
  import styles from "../../styles/index.css?url";
4
4
  const initialCount = 5;
5
5
  const showMessage = "showMessage";
6
6
  ---
7
- <link href={styles} rel="stylesheet" />
8
- <script is:inline>
9
- document.showMessage = (count) => {
10
- document.getElementById("counter").textContent = count;
11
- };
12
- </script>
13
- <CounterComponent client:only="react" initialCount={initialCount} showMessage={showMessage}>
14
- <div class="counter-title" slot="header">
15
- Counter
16
- </div>
17
- <div style="text-align: center;">
18
- <p>Slot content!</p>
19
- </div>
20
- </CounterComponent>
21
- <div style="text-align: center; margin-top: 20px;">Counter value: <span id="counter"></span></div>
7
+ <html lang="en">
8
+ <head>
9
+ <link href={styles} rel="stylesheet" />
10
+ <script>
11
+ import { atom } from "nanostores";
12
+ window["showMessage"] = (count) => {
13
+ document.getElementById("counter").textContent = count;
14
+ };
15
+ window.Stores = [];
16
+ window.Stores["reactStore"] = atom("Test Value");
17
+ document.addEventListener("DOMContentLoaded", function () {
18
+ const input = document.getElementById("store");
19
+ input.value = window.Stores["reactStore"].get();
20
+ });
21
+ </script>
22
+ </head>
23
+ <body>
24
+ <div class="counter-title">HTML Content</div>
25
+ <div class="card-grid">
26
+ <div class="card">
27
+ Value sent back from component.
28
+ <div class="card-content">
29
+ <div style="text-align: center; margin-top: 30px;">
30
+ Counter value sent back: <br /><span id="counter"></span>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div class="card">
35
+ Update Nano Store value
36
+ <div class="card-content">
37
+ <div style="text-align: center; margin-top: 30px;">
38
+ <input
39
+ id="store"
40
+ placeholder="Type something..."
41
+ type="text"
42
+ /><button
43
+ class="card-btn"
44
+ onclick="window.Stores['reactStore'].set(document.getElementById('store').value)"
45
+ >Update Store</button
46
+ >
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <hr />
52
+ <CounterComponent
53
+ client:only="react"
54
+ initialCount={initialCount}
55
+ showMessage={showMessage}
56
+ >
57
+ <div class="counter-title" slot="header">Counter Component</div>
58
+ <div style="text-align: center;">
59
+ <p><strong>This is content passed into the component.</strong></p>
60
+ </div>
61
+ </CounterComponent>
62
+ </body>
63
+ </html>
@@ -0,0 +1,63 @@
1
+ ---
2
+ import CounterComponent from "../../framework/svelte/Counter.svelte";
3
+ import styles from "../../styles/index.css?url";
4
+ const initialCount = 5;
5
+ const showMessage = "showMessage";
6
+ ---
7
+ <html lang="en">
8
+ <head>
9
+ <link href={styles} rel="stylesheet" />
10
+ <script>
11
+ import { atom } from "nanostores";
12
+ window["showMessage"] = (count) => {
13
+ document.getElementById("counter").textContent = count;
14
+ };
15
+ window.Stores = [];
16
+ window.Stores["svelteStore"] = atom("Test Value");
17
+ document.addEventListener("DOMContentLoaded", function () {
18
+ const input = document.getElementById("store");
19
+ input.value = window.Stores["svelteStore"].get();
20
+ });
21
+ </script>
22
+ </head>
23
+ <body>
24
+ <div class="counter-title">HTML Content</div>
25
+ <div class="card-grid">
26
+ <div class="card">
27
+ Value sent back from component.
28
+ <div class="card-content">
29
+ <div style="text-align: center; margin-top: 30px;">
30
+ Counter value sent back: <br /><span id="counter"></span>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div class="card">
35
+ Update Nano Store value
36
+ <div class="card-content">
37
+ <div style="text-align: center; margin-top: 30px;">
38
+ <input
39
+ id="store"
40
+ placeholder="Type something..."
41
+ type="text"
42
+ /><button
43
+ class="card-btn"
44
+ onclick="window.Stores['svelteStore'].set(document.getElementById('store').value)"
45
+ >Update Store</button
46
+ >
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <hr />
52
+ <CounterComponent
53
+ client:only="svelte"
54
+ initialCount={initialCount}
55
+ showMessage={showMessage}
56
+ >
57
+ <div class="counter-title" slot="header">Counter Component</div>
58
+ <div style="text-align: center;">
59
+ <p><strong>This is content passed into the component.</strong></p>
60
+ </div>
61
+ </CounterComponent>
62
+ </body>
63
+ </html>
@@ -4,18 +4,64 @@ import styles from "../../styles/index.css?url";
4
4
  const initialCount = 5;
5
5
  const showMessage = "showMessage";
6
6
  ---
7
- <link href={styles} rel="stylesheet" />
8
- <script is:inline>
9
- document.showMessage = (count) => {
10
- document.getElementById("counter").textContent = count;
11
- };
12
- </script>
13
- <CounterComponent client:only="vue" initialCount={initialCount} showMessage={showMessage}>
14
- <div class="counter-title" slot="header">
15
- Counter
16
- </div>
17
- <div style="text-align: center;">
18
- <p>Slot content!</p>
19
- </div>
20
- </CounterComponent>
21
- <div style="text-align: center; margin-top: 20px;">Counter value: <span id="counter"></span></div>
7
+ <html lang="en">
8
+ <head>
9
+ <link href={styles} rel="stylesheet" />
10
+ <script>
11
+ import { atom } from "nanostores";
12
+ window["showMessage"] = (count) => {
13
+ document.getElementById("counter").textContent = count;
14
+ };
15
+ window.Stores = [];
16
+ window.Stores["vueStore"] = atom("Test Value");
17
+ document.addEventListener("DOMContentLoaded", function () {
18
+ const input = document.getElementById("store");
19
+ input.value = window.Stores["vueStore"].get();
20
+ });
21
+ </script>
22
+ </head>
23
+ <body>
24
+ <div class="counter-title">HTML Content</div>
25
+ <div class="card-grid">
26
+ <div class="card">
27
+ Value sent back from component.
28
+ <div class="card-content">
29
+ <div style="text-align: center; margin-top: 30px;">
30
+ Counter value sent back: <br /><span id="counter"></span>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <div class="card">
35
+ Update Nano Store value
36
+ <div class="card-content">
37
+ <div style="text-align: center; margin-top: 30px;">
38
+ <input
39
+ id="store"
40
+ placeholder="Type something..."
41
+ type="text"
42
+ /><button
43
+ class="card-btn"
44
+ onclick="window.Stores['vueStore'].set(document.getElementById('store').value)"
45
+ >Update Store</button
46
+ >
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <hr />
52
+ <link href={styles} rel="stylesheet" />
53
+ <script is:inline>
54
+ window.showMessage = (count) => {
55
+ document.getElementById("counter").textContent = count;
56
+ };
57
+ </script>
58
+ <CounterComponent client:only="vue" initialCount={initialCount} showMessage={showMessage}>
59
+ <div class="counter-title" slot="header">
60
+ Counter Component
61
+ </div>
62
+ <div style="text-align: center;">
63
+ <p>This is content passed into the component.</p>
64
+ </div>
65
+ </CounterComponent>
66
+ </body>
67
+ </html>
File without changes
@@ -11,10 +11,12 @@
11
11
  grid-template-columns: repeat(3, minmax(0, 1fr));
12
12
  margin-top: 0.5em;
13
13
  place-items: center;
14
+ border: 1;
14
15
  }
15
16
 
16
17
  .counter-message,
17
18
  .logos {
19
+ font-size: 1.2em;
18
20
  text-align: center;
19
21
  }
20
22
 
@@ -28,3 +30,66 @@
28
30
  .counter-logos img {
29
31
  width: 150px;
30
32
  }
33
+
34
+ .card {
35
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); /* Add shadows to create the "card" effect */
36
+ transition: 0.3s; /* Smooth transition for hover effects */
37
+ border-radius: 5px; /* Rounded corners */
38
+ overflow: hidden; /* Ensures content stays within the rounded corners */
39
+ background-color: #fff;
40
+ padding: 10px;
41
+ }
42
+
43
+ /* On mouse-over, add a deeper shadow */
44
+ .card:hover {
45
+ box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
46
+ }
47
+
48
+ .card-image {
49
+ width: 100%; /* Image takes full width of the card */
50
+ height: 200px; /* Fixed height for consistency */
51
+ object-fit: cover; /* Ensures image covers the area without distortion */
52
+ }
53
+
54
+ .card-content {
55
+ padding: 16px; /* Add some padding inside the card container */
56
+ }
57
+
58
+ .card-title {
59
+ margin-top: 0;
60
+ font-size: 1.25rem;
61
+ }
62
+
63
+ .card-description {
64
+ color: #555;
65
+ }
66
+
67
+ .card-link {
68
+ display: inline-block;
69
+ margin-top: 10px;
70
+ color: dodgerblue;
71
+ text-decoration: none;
72
+ }
73
+
74
+ .card-grid {
75
+ display: grid;
76
+ /* Automatically fill columns with a minimum width of 250px and maximum of 1fr */
77
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
78
+ gap: 24px; /* Space between cards */
79
+ padding: 24px;
80
+ }
81
+
82
+ .card-btn {
83
+ margin-top: 20px;
84
+ padding: 10px 15px;
85
+ background-color: #007bff;
86
+ color: white;
87
+ border: none;
88
+ border-radius: 5px;
89
+ cursor: pointer;
90
+ align-self: flex-start; /* Button size */
91
+ }
92
+
93
+ .card-btn:hover {
94
+ background-color: #0056b3;
95
+ }
@@ -0,0 +1,5 @@
1
+ import { vitePreprocess } from "@astrojs/svelte";
2
+
3
+ export default {
4
+ preprocess: vitePreprocess(),
5
+ };