create-outsystems-astro 0.2.0 → 0.4.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 (50) hide show
  1. package/README.md +100 -2
  2. package/bin/cli.js +189 -12
  3. package/package.json +7 -2
  4. package/template/.github/copilot-instructions.md +6 -0
  5. package/template/.github/workflows/test.yml +113 -0
  6. package/template/.gitignore +7 -0
  7. package/template/.prettierignore +11 -0
  8. package/template/.prettierrc +0 -0
  9. package/template/AGENTS.md +161 -0
  10. package/template/CLAUDE.md +7 -0
  11. package/template/GEMINI.md +13 -0
  12. package/template/astro.config.mjs +36 -15
  13. package/template/bun.lock +2984 -0
  14. package/template/deno.json +9 -0
  15. package/template/deno.lock +8391 -0
  16. package/template/eslint.config.mjs +171 -0
  17. package/template/output.ts +141 -103
  18. package/template/package-lock.json +15165 -3248
  19. package/template/package.json +96 -10
  20. package/template/patches/@analogjs+astro-angular+2.2.2.patch +13 -0
  21. package/template/patches/@angular+build+21.1.0.patch +55 -0
  22. package/template/playwright.config.ts +94 -0
  23. package/template/pnpm-lock.yaml +12106 -0
  24. package/template/src/framework/angular/Counter.component.ts +62 -0
  25. package/template/src/framework/react/Counter.tsx +43 -0
  26. package/template/src/{vue/components → framework/vue}/Counter.vue +14 -12
  27. package/template/src/lib/setCounterCount.ts +18 -0
  28. package/template/src/pages/angular/angular-counter.astro +15 -0
  29. package/template/src/pages/index.astro +3 -0
  30. package/template/src/pages/react/react-counter.astro +21 -0
  31. package/template/src/pages/vue/vue-counter.astro +21 -0
  32. package/template/src/styles/index.css +17 -16
  33. package/template/test/e2e/angular/angular-counter.spec.ts +25 -0
  34. package/template/test/e2e/react/react-counter.spec.ts +32 -0
  35. package/template/test/e2e/vue/vue-counter.spec.ts +32 -0
  36. package/template/test/integration/angular/Counter.component.spec.ts +50 -0
  37. package/template/test/integration/react/Counter.test.tsx +58 -0
  38. package/template/test/integration/vue/Counter.test.ts +93 -0
  39. package/template/test/setup-test-env-angular.ts +6 -0
  40. package/template/test/setup-test-env.ts +1 -0
  41. package/template/test/unit/lib/setCounterCount.test.ts +21 -0
  42. package/template/tsconfig.app.json +34 -0
  43. package/template/tsconfig.json +5 -9
  44. package/template/tsconfig.spec.json +12 -0
  45. package/template/types.d.ts +8 -0
  46. package/template/vitest.config.ts +56 -0
  47. package/template/yarn.lock +8037 -0
  48. package/template/src/pages/counter-react.astro +0 -14
  49. package/template/src/pages/counter-vue.astro +0 -14
  50. package/template/src/react/components/Counter.tsx +0 -35
package/README.md CHANGED
@@ -12,16 +12,43 @@ Generates [Astro Islands](https://docs.astro.build/en/concepts/islands/) for use
12
12
  - Loading performance of component must be instant. The Astro Island will load after the page/screen has loaded since the initializer and tag will be loaded after.
13
13
 
14
14
  ## Current supported frameworks
15
+ - [Angular](https://analogjs.org/docs/packages/astro-angular/overview)
15
16
  - [React](https://docs.astro.build/en/guides/integrations-guide/react/)
16
17
  - [Vue](https://docs.astro.build/en/guides/integrations-guide/vue/)
17
18
 
18
19
  ## Getting started
19
20
  Run the Create OutSystems Astro generator:
21
+
22
+ ### npm
20
23
  ```bash
21
24
  npx create-outsystems-astro
22
25
  ```
26
+
27
+ ### Yarn
28
+ ```bash
29
+ yarn create outsystems-astro
30
+ ```
31
+
32
+ ### pnpm
33
+ ```bash
34
+ pnpm dlx create-outsystems-astro
35
+ ```
36
+
37
+ ### Bun
38
+ ```bash
39
+ bunx create-outsystems-astro
40
+ ```
41
+
42
+ ### Deno
43
+ The Deno DX command is available in [Deno 2.6](https://deno.com/blog/v2.6).
44
+ ```bash
45
+ dx create-outsystems-astro
46
+ ```
47
+
23
48
  This will create the generated files as well as an example component.
24
49
 
50
+ [View the full documentation](https://hs2323.github.io/create-outsystems-astro/guides/getting-started/).
51
+
25
52
  ## 🚀 Project Structure
26
53
 
27
54
  ```text
@@ -55,6 +82,8 @@ Stylesheets that may apply to the component.
55
82
 
56
83
  All commands are run from the root of the project, from a terminal:
57
84
 
85
+ ### npm
86
+
58
87
  | Command | Action |
59
88
  | :------------------------ | :----------------------------------------------- |
60
89
  | `npm install` | Installs dependencies |
@@ -65,15 +94,84 @@ All commands are run from the root of the project, from a terminal:
65
94
  | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
66
95
  | `npm run astro -- --help` | Get help using the Astro CLI |
67
96
 
97
+ ### Yarn
98
+
99
+ | Command | Action |
100
+ | :------------------------ | :----------------------------------------------- |
101
+ | `yarn install` | Installs dependencies |
102
+ | `yarn run dev` | Starts local dev server at `localhost:4321` |
103
+ | `yarn run build` | Build distribution to `./dist/` |
104
+ | `yarn run output` | Build OutSystems production site to `./output/` |
105
+ | `yarn run preview` | Preview build locally, before creating output |
106
+ | `yarn run astro ...` | Run CLI commands like `astro add`, `astro check` |
107
+ | `yarn run astro -- --help` | Get help using the Astro CLI |
108
+
109
+ ### pnpm
110
+
111
+ | Command | Action |
112
+ | :------------------------ | :----------------------------------------------- |
113
+ | `pnpm install` | Installs dependencies |
114
+ | `pnpm run dev` | Starts local dev server at `localhost:4321` |
115
+ | `pnpm run build` | Build distribution to `./dist/` |
116
+ | `pnpm run output` | Build OutSystems production site to `./output/` |
117
+ | `pnpm run preview` | Preview build locally, before creating output |
118
+ | `pnpm run astro ...` | Run CLI commands like `astro add`, `astro check` |
119
+ | `pnpm run astro -- --help` | Get help using the Astro CLI |
120
+
121
+ ### Bun
122
+
123
+ | Command | Action |
124
+ | :------------------------ | :----------------------------------------------- |
125
+ | `bun install` | Installs dependencies |
126
+ | `bun run dev` | Starts local dev server at `localhost:4321` |
127
+ | `bun run build` | Build distribution to `./dist/` |
128
+ | `bun run output:bun` | Build OutSystems production site to `./output/` |
129
+ | `bun run preview` | Preview build locally, before creating output |
130
+ | `bun run astro ...` | Run CLI commands like `astro add`, `astro check` |
131
+ | `bun run astro -- --help` | Get help using the Astro CLI |
132
+
133
+ ### Deno
134
+
135
+ | Command | Action |
136
+ | :------------------------ | :----------------------------------------------- |
137
+ | `deno install && deno run postinstall` | Installs dependencies |
138
+ | `deno run dev` | Starts local dev server at `localhost:4321` |
139
+ | `deno run build` | Build distribution to `./dist/` |
140
+ | `deno run output:deno` | Build OutSystems production site to `./output/` |
141
+ | `deno run preview` | Preview build locally, before creating output |
142
+ | `deno run astro ...` | Run CLI commands like `astro add`, `astro check` |
143
+ | `deno run astro -- --help` | Get help using the Astro CLI |
68
144
 
69
145
  ## Getting Started
70
- Delete the demo application under the ```src``` flder and choose your framework(s) to build the components in.
146
+ Delete the demo application under the ```src``` folder and being to build your own application.
71
147
 
72
148
  ## Converting to OutSystems
73
149
 
74
- Once development is complete, run:
150
+ Once development is complete, run the output generation command:
151
+
152
+ ### npm
75
153
  ```bash
76
154
  npm run output
77
155
  ```
78
156
 
157
+ ### Yarn
158
+ ```bash
159
+ yarn run output
160
+ ```
161
+
162
+ ### pnpm
163
+ ```bash
164
+ pnpm run output
165
+ ```
166
+
167
+ ### Bun
168
+ ```bash
169
+ bun run output:bun
170
+ ```
171
+
172
+ ### Deno
173
+ ```bash
174
+ deno run output:deno
175
+ ```
176
+
79
177
  This will create a set of files that will then need to be coverted to OutSystems components.
package/bin/cli.js CHANGED
@@ -1,13 +1,33 @@
1
1
  #!/usr/bin/env node
2
- import fs from "fs";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
5
  import prompts from "prompts";
6
- import { execSync } from "child_process";
6
+ import yargs from "yargs";
7
+ import { hideBin } from 'yargs/helpers';
8
+ import { execSync } from "node:child_process";
9
+
10
+ prompts.override(
11
+ yargs(hideBin(process.argv)).parse()
12
+ );
7
13
 
8
14
  const __filename = fileURLToPath(import.meta.url);
9
15
  const __dirname = path.dirname(__filename);
10
16
 
17
+ const FRAMEWORKS = [
18
+ { title: "Angular", value: "angular" },
19
+ { title: "React", value: "react" },
20
+ { title: "Vue", value: "vue" }
21
+ ];
22
+
23
+ const LOCKFILES = {
24
+ npm: ["package-lock.json"],
25
+ yarn: ["yarn.lock"],
26
+ pnpm: ["pnpm-lock.yaml"],
27
+ bun: ["bun.lock"],
28
+ deno: ["deno.lock", "deno.json"]
29
+ };
30
+
11
31
  async function main() {
12
32
  console.log("🚀 Welcome to create-outsystems-astro!");
13
33
 
@@ -26,6 +46,28 @@ async function main() {
26
46
  console.log("📦 Copying template...");
27
47
  copyDir(templateDir, targetDir);
28
48
 
49
+ const packageManager = packageInstall(targetDir);
50
+
51
+ let selectedFrameworks = [];
52
+
53
+ while (selectedFrameworks.length === 0) {
54
+ const frameworkResponse = await prompts({
55
+ type: "multiselect",
56
+ name: "frameworks",
57
+ message: "Which frameworks do you want to include?",
58
+ choices: FRAMEWORKS,
59
+ hint: "- Space to select. Enter to confirm",
60
+ validate: value =>
61
+ value.length > 0 ? true : "Please select at least one framework."
62
+ });
63
+
64
+ selectedFrameworks = frameworkResponse.frameworks || [];
65
+ }
66
+
67
+ deleteUnselectedFrameworkFolders(targetDir, selectedFrameworks);
68
+
69
+ updateAstroConfig(targetDir, selectedFrameworks);
70
+
29
71
  const readmeSrc = path.resolve(__dirname, "../README.md");
30
72
  const readmeDest = path.join(targetDir, "README.md");
31
73
 
@@ -33,20 +75,14 @@ async function main() {
33
75
  fs.copyFileSync(readmeSrc, readmeDest);
34
76
  }
35
77
 
36
- // Install dependencies
37
- console.log("📦 Installing dependencies...");
38
- try {
39
- execSync("npm install", { cwd: targetDir, stdio: "inherit" });
40
- } catch {
41
- console.warn("⚠️ Failed to automatically install dependencies.");
42
- }
78
+
43
79
 
44
80
  console.log(`
45
81
  ✅ All done!
46
82
 
47
83
  Next steps:
48
84
  cd ${response.projectName}
49
- npm run dev
85
+ ${packageManager} run dev
50
86
  `);
51
87
  }
52
88
 
@@ -65,6 +101,147 @@ function copyDir(src, dest) {
65
101
  }
66
102
  }
67
103
 
104
+ function deleteUnselectedFrameworkFolders(projectDir, selectedFrameworks) {
105
+ const allFrameworks = FRAMEWORKS.map(f => f.value);
106
+
107
+ const frameworksToDelete = allFrameworks.filter(
108
+ f => !selectedFrameworks.includes(f)
109
+ );
110
+
111
+ for (const framework of frameworksToDelete) {
112
+ const pageDir = path.join(projectDir, "src", "pages", framework);
113
+ const componentDir = path.join(projectDir, "src", "framework", framework);
114
+ const testDir = path.join(projectDir, "test", "integration", framework);
115
+ const testE2EDir = path.join(projectDir, "test", "e2e", framework);
116
+
117
+ if (fs.existsSync(pageDir)) {
118
+ console.log(`🗑️ Removing ${path.relative(projectDir, pageDir)}`);
119
+ fs.rmSync(pageDir, { recursive: true, force: true });
120
+ }
121
+
122
+ if (fs.existsSync(componentDir)) {
123
+ console.log(`🗑️ Removing ${path.relative(projectDir, componentDir)}`);
124
+ fs.rmSync(componentDir, { recursive: true, force: true });
125
+ }
126
+
127
+ if (fs.existsSync(testDir)) {
128
+ console.log(`🗑️ Removing ${path.relative(projectDir, testDir)}`);
129
+ fs.rmSync(testDir, { recursive: true, force: true });
130
+ }
131
+
132
+ if (fs.existsSync(testE2EDir)) {
133
+ console.log(`🗑️ Removing ${path.relative(projectDir, testE2EDir)}`);
134
+ fs.rmSync(testE2EDir, { recursive: true, force: true });
135
+ }
136
+
137
+ }
138
+ }
139
+
140
+ function updateAstroConfig(projectDir, selectedFrameworks) {
141
+ const configPath = path.join(projectDir, "astro.config.mjs");
142
+
143
+ if (!fs.existsSync(configPath)) {
144
+ console.warn("⚠️ astro.config.mjs not found, skipping integration cleanup.");
145
+ return;
146
+ }
147
+
148
+ let content = fs.readFileSync(configPath, "utf-8");
149
+
150
+ const allFrameworks = {
151
+ angular: {
152
+ import: /import\s+angular\s+from\s+['"]@analogjs\/astro-angular['"];\s*\n?/,
153
+ integration: /angular\s*\(\s*\{[\s\S]*?\}\s*\)\s*,?\s*/
154
+ },
155
+ react: {
156
+ import: /import\s+react\s+from\s+['"]@astrojs\/react['"];\s*\n?/,
157
+ integration: /react\(\)\s*,?\s*/
158
+ },
159
+ vue: {
160
+ import: /import\s+vue\s+from\s+['"]@astrojs\/vue['"];\s*\n?/,
161
+ integration: /vue\(\)\s*,?\s*/
162
+ }
163
+ };
164
+
165
+ for (const [framework, patterns] of Object.entries(allFrameworks)) {
166
+ if (!selectedFrameworks.includes(framework)) {
167
+ content = content.replace(patterns.import, "");
168
+ content = content.replace(patterns.integration, "");
169
+ }
170
+ }
171
+
172
+ // Clean up trailing commas inside integrations array
173
+ content = content.replace(
174
+ /integrations:\s*\[\s*,/g,
175
+ "integrations: ["
176
+ );
177
+ content = content.replace(
178
+ /,\s*\]/g,
179
+ "]"
180
+ );
181
+
182
+ fs.writeFileSync(configPath, content, "utf-8");
183
+ console.log("🛠️ Updated astro.config.mjs integrations");
184
+ }
185
+
186
+ function detectPackageManager() {
187
+ if (typeof Deno !== "undefined") return "deno";
188
+
189
+ const ua = process.env.npm_config_user_agent || "";
190
+
191
+ if (ua.startsWith("npm/")) return "npm";
192
+ if (ua.startsWith("yarn/")) return "yarn";
193
+ if (ua.startsWith("pnpm/")) return "pnpm";
194
+ if (ua.startsWith("bun/")) return "bun";
195
+
196
+ return "unknown";
197
+ }
198
+
199
+ function cleanupLockfiles(projectDir, activePackageManager) {
200
+ for (const [packageManager, files] of Object.entries(LOCKFILES)) {
201
+ if (packageManager === activePackageManager) continue;
202
+
203
+ for (const file of files) {
204
+ const filePath = path.join(projectDir, file);
205
+ if (fs.existsSync(filePath)) {
206
+ fs.rmSync(filePath, { force: true });
207
+ console.log(`🗑️ Removed ${file}`);
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ function packageInstall(targetDir) {
214
+ try {
215
+ const packageManager = detectPackageManager();
216
+ console.log(`🧰 Detected package manager: ${packageManager}`);
217
+
218
+ if (packageManager === "unknown") {
219
+ console.warn("⚠️ Could not detect package manager — keeping all lockfiles.");
220
+ } else {
221
+ cleanupLockfiles(targetDir, packageManager);
222
+ }
223
+
224
+ const installCmd = {
225
+ npm: "npm install",
226
+ yarn: "yarn",
227
+ pnpm: "pnpm install",
228
+ bun: "bun install",
229
+ deno: "deno install && deno run postinsall",
230
+ unknown: "npm install"
231
+ }[packageManager];
232
+
233
+ console.log(`📦 Installing dependencies using ${packageManager}...`);
234
+ execSync(installCmd, {
235
+ cwd: targetDir,
236
+ stdio: "inherit"
237
+ });
238
+
239
+ return packageManager
240
+ } catch {
241
+ console.warn("⚠️ Failed to automatically install dependencies.");
242
+ }
243
+ }
244
+
68
245
  main().catch(err => {
69
246
  console.error(err);
70
247
  process.exit(1);
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "create-outsystems-astro",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.4.0",
5
5
  "description": "Create an OutSystems Astro Island project to import as a component into your OutSystems application",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/hs2323/create-outsystems-astro.git"
9
+ },
6
10
  "bin": {
7
11
  "create-outsystems-astro": "bin/cli.js"
8
12
  },
@@ -23,6 +27,7 @@
23
27
  ],
24
28
  "license": "MIT",
25
29
  "dependencies": {
26
- "prompts": "^2.4.2"
30
+ "prompts": "^2.4.2",
31
+ "yargs": "^18.0.0"
27
32
  }
28
33
  }
@@ -0,0 +1,6 @@
1
+ # Copilot instructions
2
+
3
+ This file is the authoritative Copilot instruction file for this repository.
4
+ If any content in AGENTS.md conflicts with the instructions below, always follow the instructions in this file.
5
+
6
+ Reference (for additional details): [AGENTS.md](../AGENTS.md)
@@ -0,0 +1,113 @@
1
+ name: Test
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [ main ]
7
+
8
+ env:
9
+ NODE_VERSION: '24.13.0'
10
+
11
+ jobs:
12
+
13
+ format:
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v6.0.1
19
+
20
+ - name: Use Node.js
21
+ uses: actions/setup-node@v6.2.0
22
+ with:
23
+ node-version: ${{ env.NODE_VERSION }}
24
+
25
+ - name: Run format
26
+ run: npm run format
27
+
28
+ lint:
29
+ runs-on: ubuntu-latest
30
+
31
+ steps:
32
+ - name: Checkout code
33
+ uses: actions/checkout@v6.0.1
34
+
35
+ - name: Use Node.js
36
+ uses: actions/setup-node@v6.2.0
37
+ with:
38
+ node-version: ${{ env.NODE_VERSION }}
39
+
40
+ - name: Run lint
41
+ run: npm run lint
42
+
43
+ security:
44
+ runs-on: ubuntu-latest
45
+
46
+ steps:
47
+ - name: Checkout code
48
+ uses: actions/checkout@v6.0.1
49
+
50
+ - name: Use Node.js
51
+ uses: actions/setup-node@v6.2.0
52
+ with:
53
+ node-version: ${{ env.NODE_VERSION }}
54
+
55
+ - name: Run security check
56
+ run: npm audit
57
+
58
+ test:
59
+ runs-on: ubuntu-latest
60
+
61
+ steps:
62
+ - name: Checkout code
63
+ uses: actions/checkout@v6.0.1
64
+
65
+ - name: Use Node.js
66
+ uses: actions/setup-node@v6.2.0
67
+ with:
68
+ node-version: ${{ env.NODE_VERSION }}
69
+
70
+ - name: Install dependencies
71
+ run: npm ci
72
+
73
+ - name: Run tests
74
+ run: npm run test
75
+
76
+ teste2e:
77
+ runs-on: ubuntu-latest
78
+
79
+ steps:
80
+ - name: Checkout code
81
+ uses: actions/checkout@v6.0.1
82
+
83
+ - name: Use Node.js
84
+ uses: actions/setup-node@v6.2.0
85
+ with:
86
+ node-version: ${{ env.NODE_VERSION }}
87
+
88
+ - name: Install dependencies
89
+ run: npm ci
90
+
91
+ - name: Install Playwright
92
+ run: npm run test:e2e:install
93
+
94
+ - name: Run tests
95
+ run: npm run test:e2e
96
+
97
+ typecheck:
98
+ runs-on: ubuntu-latest
99
+
100
+ steps:
101
+ - name: Checkout code
102
+ uses: actions/checkout@v6.0.1
103
+
104
+ - name: Use Node.js
105
+ uses: actions/setup-node@v6.2.0
106
+ with:
107
+ node-version: ${{ env.NODE_VERSION }}
108
+
109
+ - name: Install dependencies
110
+ run: npm ci
111
+
112
+ - name: Run type check
113
+ run: npm run typecheck
@@ -25,3 +25,10 @@ pnpm-debug.log*
25
25
 
26
26
  # output folder
27
27
  output/
28
+
29
+ # Playwright
30
+ /test-results/
31
+ /playwright-report/
32
+ /blob-report/
33
+ /playwright/.cache/
34
+ /playwright/.auth/
@@ -0,0 +1,11 @@
1
+ .github/
2
+ bun.lock
3
+ deno.lock
4
+ dist/
5
+ node_modules/
6
+ output/
7
+ package-lock.json
8
+ package.json
9
+ patches/
10
+ pnpm-lock.yaml
11
+ yarn.lock
File without changes