create-outsystems-astro 0.8.2 → 0.10.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 (56) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +62 -1
  3. package/integrations/.prettierignore +15 -0
  4. package/integrations/.yarn/releases/yarn-4.15.0.cjs +940 -0
  5. package/integrations/.yarnrc.yml +6 -0
  6. package/integrations/bun.lock +1225 -0
  7. package/integrations/bunfig.toml +3 -0
  8. package/integrations/deno.json +4 -0
  9. package/integrations/deno.lock +3896 -0
  10. package/integrations/eslint.config.mjs +61 -0
  11. package/integrations/html/client.ts +30 -0
  12. package/integrations/html/index.ts +57 -0
  13. package/integrations/html/server.ts +54 -0
  14. package/integrations/package-lock.json +8898 -0
  15. package/integrations/package.json +39 -0
  16. package/integrations/pnpm-lock.yaml +5499 -0
  17. package/integrations/pnpm-workspace.yaml +4 -0
  18. package/integrations/tsconfig.json +15 -0
  19. package/integrations/yarn.lock +6305 -0
  20. package/package.json +3 -1
  21. package/template/.github/workflows/bun-test.yml +127 -0
  22. package/template/.github/workflows/deno-test.yml +127 -0
  23. package/template/.github/workflows/{test.yml → npm-test.yml} +7 -7
  24. package/template/.github/workflows/pnpm-test.yml +158 -0
  25. package/template/.github/workflows/yarn-test.yml +158 -0
  26. package/template/.gitignore +4 -0
  27. package/template/.prettierignore +1 -0
  28. package/template/.yarn/releases/yarn-4.15.0.cjs +940 -0
  29. package/template/.yarnrc.yml +8 -0
  30. package/template/AGENTS.md +46 -1
  31. package/template/README.md +15 -0
  32. package/template/astro.config.mjs +8 -3
  33. package/template/bun.lock +580 -966
  34. package/template/bunfig.toml +3 -0
  35. package/template/deno.json +3 -19
  36. package/template/deno.lock +1416 -1548
  37. package/template/eslint.config.mjs +1 -0
  38. package/template/package-lock.json +7332 -9398
  39. package/template/package.json +69 -93
  40. package/template/patches/@analogjs+astro-angular+2.5.2.patch +26 -0
  41. package/template/pnpm-lock.yaml +2638 -2683
  42. package/template/pnpm-workspace.yaml +11 -6
  43. package/template/src/framework/html/Demo.ts +105 -0
  44. package/template/src/framework/html/Store.ts +47 -0
  45. package/template/src/images/html.png +0 -0
  46. package/template/src/pages/html/html-demo.astro +61 -0
  47. package/template/src/pages/multi/store.astro +3 -1
  48. package/template/src/stores/framework.ts +1 -0
  49. package/template/test/e2e/html/html-demo.spec.ts +36 -0
  50. package/template/test/integration/html/Demo.test.ts +83 -0
  51. package/template/tsconfig.json +1 -1
  52. package/template/vitest.config.ts +9 -0
  53. package/template/yarn.lock +14730 -10574
  54. package/template/patches/@analogjs+astro-angular+2.3.1.patch +0 -13
  55. package/template/patches-deno/playwright+1.58.2.patch +0 -26
  56. /package/template/patches/{@angular+build+21.2.5.patch → @angular+build+21.2.12.patch} +0 -0
@@ -1,6 +1,11 @@
1
- onlyBuiltDependencies:
2
- - '@parcel/watcher'
3
- - esbuild
4
- - lmdb
5
- - msgpackr-extract
6
- - sharp
1
+ allowBuilds:
2
+ '@parcel/watcher': true
3
+ esbuild: true
4
+ lmdb: true
5
+ msgpackr-extract: true
6
+ sharp: true
7
+ minimumReleaseAge: 10080
8
+ minimumReleaseAgeExclude:
9
+ - tmp@0.2.6
10
+ overrides:
11
+ tmp: ^0.2.6
@@ -0,0 +1,105 @@
1
+ import AstroLogo from "../../images/astro.png?url";
2
+ import OutSystemsLogo from "../../images/outsystems.png?url";
3
+
4
+ interface DemoProps {
5
+ children?: string;
6
+ header?: string;
7
+ initialCount?: number;
8
+ showMessage?: string;
9
+ }
10
+
11
+ export default function Demo({
12
+ initialCount = 0,
13
+ showMessage = "",
14
+ }: DemoProps): string {
15
+ return `
16
+ <div class="counter-title" slot="header">HTML Demo Component</div>
17
+ <div class="html-demo">
18
+ <div class="card-grid">
19
+ <div class="card">
20
+ <strong>HTML counter component</strong>
21
+ <div class="card-content">
22
+ Internal counter controls. It keeps state within the component.
23
+ <div class="counter-controls">
24
+ <button class="subtract">-</button>
25
+ <pre class="count">${initialCount}</pre>
26
+ <button class="add">+</button>
27
+ </div>
28
+ </div>
29
+ The button sends the current count value to a function in the parent
30
+ component.
31
+ <div class="card-content">
32
+ <div>
33
+ <button class="card-btn send">Send value</button>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ <div class="card">
38
+ <strong>Nano Stores</strong>
39
+ <div class="card-content">
40
+ <div>
41
+ <strong>Value:</strong>
42
+ <div class="nanostore-value"></div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ <div class="card unused">
47
+ <strong>Slot content (not supported)</strong>
48
+ <div class="card-content"></div>
49
+ </div>
50
+ </div>
51
+ <div class="counter-logos">
52
+ <img alt="OutSystems logo" src="${OutSystemsLogo}" />
53
+ <img alt="Astro logo" src="${AstroLogo}" />
54
+ </div>
55
+ <script>
56
+ (function () {
57
+ const container = (document.currentScript && document.currentScript.parentElement) || document.querySelector('.html-demo');
58
+ let count = ${initialCount};
59
+ const countEl = container.querySelector('.count');
60
+ const addBtn = container.querySelector('.add');
61
+ const subtractBtn = container.querySelector('.subtract');
62
+ const sendBtn = container.querySelector('.send');
63
+ const nanostoreEl = container.querySelector('.nanostore-value');
64
+
65
+ addBtn.addEventListener('click', function () {
66
+ count += 1;
67
+ countEl.textContent = count;
68
+ });
69
+
70
+ subtractBtn.addEventListener('click', function () {
71
+ count -= 1;
72
+ countEl.textContent = count;
73
+ });
74
+
75
+ sendBtn.addEventListener('click', function () {
76
+ if ('${showMessage}' && window['${showMessage}']) {
77
+ window['${showMessage}'](count);
78
+ }
79
+ });
80
+
81
+ if (!window.Stores) window.Stores = {};
82
+ if (!window.Stores['htmlStore']) {
83
+ let _value = 'Test Value';
84
+ const _subs = [];
85
+ window.Stores['htmlStore'] = {
86
+ get: function () { return _value; },
87
+ set: function (v) { _value = v; _subs.forEach(function (fn) { fn(v); }); },
88
+ subscribe: function (fn) {
89
+ fn(_value);
90
+ _subs.push(fn);
91
+ return function () { _subs.splice(_subs.indexOf(fn), 1); };
92
+ },
93
+ };
94
+ }
95
+
96
+ const store = window.Stores['htmlStore'];
97
+ nanostoreEl.textContent = store.get();
98
+ store.subscribe(function (value) {
99
+ nanostoreEl.textContent = value;
100
+ });
101
+ })();
102
+ </script>
103
+ </div>
104
+ `;
105
+ }
@@ -0,0 +1,47 @@
1
+ import HTMLLogo from "../../images/html.png?url";
2
+ import { framework } from "../../stores/framework";
3
+
4
+ if (typeof window !== "undefined") {
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ if (!(window as any).Stores) (window as any).Stores = {};
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ (window as any).Stores["framework"] = framework;
9
+ }
10
+
11
+ export default function Store(): string {
12
+ return `
13
+ <div class="card">
14
+ <strong>HTML Store</strong>
15
+ <div class="card-content">
16
+ <img alt="HTML logo" height="150" src="${HTMLLogo}" />
17
+ <div>
18
+ <strong>Value:</strong>
19
+ <div class="framework-value"></div>
20
+ </div>
21
+ <div>
22
+ <button class="card-btn select-btn">Select HTML</button>
23
+ </div>
24
+ </div>
25
+ <script>
26
+ (function () {
27
+ const container = (document.currentScript && document.currentScript.parentElement)
28
+ || document.querySelector('.html-store');
29
+ const valueEl = container.querySelector('.framework-value');
30
+ const btn = container.querySelector('.select-btn');
31
+
32
+ const store = window.Stores && window.Stores['framework'];
33
+
34
+ if (store) {
35
+ store.subscribe(function (value) {
36
+ valueEl.textContent = value;
37
+ });
38
+ }
39
+
40
+ btn.addEventListener('click', function () {
41
+ if (store) store.set('HTML');
42
+ });
43
+ })();
44
+ </script>
45
+ </div>
46
+ `;
47
+ }
Binary file
@@ -0,0 +1,61 @@
1
+ ---
2
+ import DemoComponent from "../../framework/html/Demo";
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 { setupStore } from "../../stores/demo";
12
+ setupStore("htmlStore");
13
+ window["showMessage"] = (count) => {
14
+ document.getElementById("counter").textContent = count;
15
+ };
16
+ document.addEventListener("DOMContentLoaded", function () {
17
+ const input = document.getElementById("store");
18
+ input.value = window.Stores["htmlStore"].get();
19
+ });
20
+ </script>
21
+ </head>
22
+ <body>
23
+ <div class="counter-title">Astro Page</div>
24
+ <div class="card-grid">
25
+ <div class="card">
26
+ <strong>Counter component</strong>
27
+ <div class="card-content">
28
+ <div style="text-align: center; margin-top: 30px;">
29
+ Counter value:
30
+ <div>
31
+ <span id="counter"></span>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ <div class="card">
37
+ <strong>Nano Stores</strong>
38
+ <div class="card-content">
39
+ <div style="text-align: center; margin-top: 30px;">
40
+ <input
41
+ id="store"
42
+ placeholder="Type something..."
43
+ type="text"
44
+ /><button
45
+ class="card-btn"
46
+ onclick="window.Stores['htmlStore'].set(document.getElementById('store').value)"
47
+ >Update Store</button
48
+ >
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ <hr />
54
+ <DemoComponent
55
+ client:load
56
+ initialCount={initialCount}
57
+ showMessage={showMessage}
58
+ >
59
+ </DemoComponent>
60
+ </body>
61
+ </html>
@@ -1,5 +1,6 @@
1
1
  ---
2
- import AngularStore from "../../framework/angular/Store.component"
2
+ import AngularStore from "../../framework/angular/Store.component";
3
+ import HTMLStore from "../../framework/html/Store";
3
4
  import PreactStore from "../../framework/preact/Store";
4
5
  import ReactStore from "../../framework/react/Store";
5
6
  import SolidStore from "../../framework/solid/Store";
@@ -14,6 +15,7 @@ import styles from "../../styles/index.css?url";
14
15
  <body>
15
16
  <div class="card-grid">
16
17
  <AngularStore client:load />
18
+ <HTMLStore client:load />
17
19
  <PreactStore client:only="preact" />
18
20
  <ReactStore client:only="react" />
19
21
  <SolidStore client:only="solid-js" />
@@ -2,6 +2,7 @@ import { atom } from "nanostores";
2
2
 
3
3
  export type CurrentSelectedFramework =
4
4
  | ""
5
+ | "HTML"
5
6
  | "Preact"
6
7
  | "React"
7
8
  | "Solid"
@@ -0,0 +1,36 @@
1
+ import { expect, test } from "@playwright/test";
2
+
3
+ test.beforeEach(async ({ page }) => {
4
+ await page.goto("/html/html-demo");
5
+ });
6
+
7
+ test.describe("Has values", () => {
8
+ test("Should have header", async ({ page }) => {
9
+ await expect(page.getByText("HTML Demo Component")).toBeVisible();
10
+ });
11
+ });
12
+
13
+ test.describe("Change counter", () => {
14
+ test("Should increment counter when clicking + button", async ({ page }) => {
15
+ await page.getByRole("button", { name: "+" }).click();
16
+ await expect(page.locator("pre")).toContainText("6");
17
+ });
18
+
19
+ test("Should decrement counter when clicking - button", async ({ page }) => {
20
+ await page.getByRole("button", { name: "-" }).click();
21
+ await expect(page.locator("pre")).toContainText("4");
22
+ });
23
+
24
+ test("Should show message on Send value", async ({ page }) => {
25
+ await page.getByRole("button", { name: "Send value" }).click();
26
+ await expect(page.locator("span#counter")).toContainText("5");
27
+ });
28
+ });
29
+
30
+ test.describe("Update Nano Store", () => {
31
+ test("Should update Nano Store", async ({ page }) => {
32
+ await page.locator("#store").fill("Updated Value");
33
+ await page.getByRole("button", { name: "Update Store" }).click();
34
+ await expect(page.locator(".nanostore-value")).toHaveText("Updated Value");
35
+ });
36
+ });
@@ -0,0 +1,83 @@
1
+ import { fireEvent, screen } from "@testing-library/dom";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+
4
+ import Demo from "../../../src/framework/html/Demo";
5
+
6
+ function renderDemo(props: Parameters<typeof Demo>[0] = {}) {
7
+ document.body.innerHTML = Demo(props);
8
+ document.body.querySelectorAll("script").forEach((script) => {
9
+ new Function(script.textContent ?? "")();
10
+ });
11
+ }
12
+
13
+ describe("Demo", () => {
14
+ let capturedListener: ((val: string) => void) | undefined;
15
+ let storeValue = "Mocked Nano Value";
16
+
17
+ beforeEach(() => {
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ (window as any).mockFunction = vi.fn();
20
+
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ (window as any).Stores = {
23
+ htmlStore: {
24
+ get: vi.fn(() => storeValue),
25
+ set: vi.fn((v: string) => {
26
+ storeValue = v;
27
+ capturedListener?.(v);
28
+ }),
29
+ subscribe: vi.fn((fn: (val: string) => void) => {
30
+ capturedListener = fn;
31
+ fn(storeValue);
32
+ return () => {};
33
+ }),
34
+ },
35
+ };
36
+ });
37
+
38
+ afterEach(() => {
39
+ vi.clearAllMocks();
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ delete (window as any).mockFunction;
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ delete (window as any).Stores;
44
+ capturedListener = undefined;
45
+ storeValue = "Mocked Nano Value";
46
+ });
47
+
48
+ it("renders the initial count", () => {
49
+ renderDemo({ initialCount: 5 });
50
+ expect(screen.getByText("5")).toBeInTheDocument();
51
+ });
52
+
53
+ it("increments count when add button is clicked", () => {
54
+ renderDemo({ initialCount: 5 });
55
+ fireEvent.click(screen.getByRole("button", { name: "+" }));
56
+ expect(screen.getByText("6")).toBeInTheDocument();
57
+ });
58
+
59
+ it("decrements count when subtract button is clicked", () => {
60
+ renderDemo({ initialCount: 5 });
61
+ fireEvent.click(screen.getByRole("button", { name: "-" }));
62
+ expect(screen.getByText("4")).toBeInTheDocument();
63
+ });
64
+
65
+ it("calls the show message function with the current count", () => {
66
+ renderDemo({ initialCount: 5, showMessage: "mockFunction" });
67
+ fireEvent.click(screen.getByRole("button", { name: "Send value" }));
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ expect((window as any).mockFunction).toHaveBeenCalledWith(5);
70
+ });
71
+
72
+ it("displays the initial nanostore value", () => {
73
+ renderDemo({});
74
+ expect(screen.getByText("Mocked Nano Value")).toBeInTheDocument();
75
+ });
76
+
77
+ it("updates the display when the nanostore value changes", () => {
78
+ renderDemo({});
79
+ expect(screen.getByText("Mocked Nano Value")).toBeInTheDocument();
80
+ capturedListener?.("Updated Value");
81
+ expect(screen.getByText("Updated Value")).toBeInTheDocument();
82
+ });
83
+ });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "extends": "astro/tsconfigs/strict",
3
3
  "include": [".astro/types.d.ts", "**/*"],
4
- "exclude": ["dist"],
4
+ "exclude": [".integrations", "dist", "output"],
5
5
  "compilerOptions": {
6
6
  "jsx": "preserve",
7
7
  "types": ["node", "vitest/globals"]
@@ -22,6 +22,15 @@ export default defineConfig(({ mode }) => ({
22
22
  setupFiles: ["test/setup-test-env-angular.ts"],
23
23
  },
24
24
  },
25
+ {
26
+ test: {
27
+ environment: "happy-dom",
28
+ globals: true,
29
+ include: ["test/integration/html/**/*.test.ts"],
30
+ name: "html",
31
+ setupFiles: ["test/setup-test-env.ts"],
32
+ },
33
+ },
25
34
  {
26
35
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
36
  plugins: [preact() as any],