unictive-angular 1.0.3 → 1.0.4

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 (54) hide show
  1. package/bin/index.js +42 -113
  2. package/bin/utils/createProject.js +88 -0
  3. package/bin/utils/setupAssets.js +103 -0
  4. package/bin/utils/showStatus.js +44 -0
  5. package/bin/utils/updatePackageJson.js +26 -0
  6. package/package.json +6 -4
  7. package/test/.editorconfig +17 -0
  8. package/test/.vscode/extensions.json +4 -0
  9. package/test/.vscode/launch.json +20 -0
  10. package/test/.vscode/tasks.json +42 -0
  11. package/test/README.md +59 -0
  12. package/test/angular.json +92 -0
  13. package/test/package-lock.json +9930 -0
  14. package/test/package.json +40 -0
  15. package/test/package.json.backup +35 -0
  16. package/test/public/favicon.ico +0 -0
  17. package/test/src/app/app.config.ts +12 -0
  18. package/test/src/app/app.html +336 -0
  19. package/test/src/app/app.routes.ts +3 -0
  20. package/test/src/app/app.scss +0 -0
  21. package/test/src/app/app.spec.ts +25 -0
  22. package/test/src/app/app.ts +12 -0
  23. package/test/src/app/core/README.md +10 -0
  24. package/test/src/app/core/config/README.md +10 -0
  25. package/test/src/app/core/guards/README.md +10 -0
  26. package/test/src/app/core/interceptors/README.md +10 -0
  27. package/test/src/app/core/models/README.md +10 -0
  28. package/test/src/app/core/services/README.md +10 -0
  29. package/test/src/app/features/dashboard/application/README.md +10 -0
  30. package/test/src/app/features/dashboard/domain/README.md +10 -0
  31. package/test/src/app/features/dashboard/infrastructure/README.md +10 -0
  32. package/test/src/app/features/dashboard/presentation/README.md +10 -0
  33. package/test/src/app/features/profile/application/README.md +10 -0
  34. package/test/src/app/features/profile/domain/README.md +10 -0
  35. package/test/src/app/features/profile/infrastructure/README.md +10 -0
  36. package/test/src/app/features/profile/presentation/README.md +10 -0
  37. package/test/src/app/features/settings/application/README.md +10 -0
  38. package/test/src/app/features/settings/domain/README.md +10 -0
  39. package/test/src/app/features/settings/infrastructure/README.md +10 -0
  40. package/test/src/app/features/settings/presentation/README.md +10 -0
  41. package/test/src/app/shared/README.md +10 -0
  42. package/test/src/app/shared/directives/README.md +10 -0
  43. package/test/src/app/shared/pipes/README.md +10 -0
  44. package/test/src/app/shared/ui/README.md +10 -0
  45. package/test/src/app/shared/utils/README.md +10 -0
  46. package/test/src/environments/environment.prod.ts +5 -0
  47. package/test/src/environments/environment.staging.ts +5 -0
  48. package/test/src/environments/environment.ts +5 -0
  49. package/test/src/index.html +13 -0
  50. package/test/src/main.ts +6 -0
  51. package/test/src/styles.scss +1 -0
  52. package/test/tsconfig.app.json +15 -0
  53. package/test/tsconfig.json +34 -0
  54. package/test/tsconfig.spec.json +14 -0
package/bin/index.js CHANGED
@@ -7,61 +7,33 @@
7
7
  * 👤 by - EkaHersada
8
8
  */
9
9
 
10
- const { execSync, spawn } = require("child_process");
10
+ const { execSync, spawn} = require("child_process");
11
11
  const fs = require("fs");
12
12
  const os = require("os");
13
13
  const path = require("path");
14
- const readline = require("readline");
14
+ const { show_status, run_with_spinner } = require('./utils/showStatus');
15
+ const { setupAssets } = require('./utils/setupAssets');
16
+ const { create_project } = require('./utils/createProject');
17
+ const { update_package_json } = require('./utils/updatePackageJson');
18
+ const updateNotifier = require("update-notifier")
19
+
15
20
 
16
21
  // Baca versi dari package.json
17
22
  const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.json"), "utf8"));
18
23
 
24
+ // ===================== Cek argumen versi =====================
19
25
  if (process.argv.includes("-v") || process.argv.includes("--version")) {
20
- console.log(pkg.version);
26
+ console.log(`${pkg.name} v${pkg.version}`);
21
27
  process.exit(0);
22
28
  }
23
29
 
30
+ // ===================== Notifikasi Update =====================
31
+ updateNotifier({ pkg, updateCheckInterval: 1000 * 60 * 60 * 24 }).notify();
32
+
24
33
  // ===================== Utility =====================
25
34
  const sleep = (ms) => new Promise((res) => setTimeout(res, ms));
26
35
  const clear = () => process.stdout.write("\x1Bc");
27
36
 
28
- function show_status(message, status = "info") {
29
- const icons = {
30
- info: "â„šī¸ ",
31
- success: "✅",
32
- warning: "âš ī¸ ",
33
- error: "❌",
34
- loading: "âŗ",
35
- };
36
- console.log(`${icons[status] || ""} ${message}`);
37
- }
38
-
39
- async function run_with_spinner(cmd, msg, successMsg, errorMsg) {
40
- let spinnerFrames = ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "█", "▉", "▊", "▋", "▌", "▍", "▎"];
41
- let i = 0;
42
- let active = true;
43
-
44
- const spinner = setInterval(() => {
45
- process.stdout.write(`\r${spinnerFrames[i++ % spinnerFrames.length]} ${msg}`);
46
- }, 100);
47
-
48
- return new Promise((resolve, reject) => {
49
- const child = spawn(cmd, { shell: true, stdio: "ignore" });
50
-
51
- child.on("exit", (code) => {
52
- clearInterval(spinner);
53
- process.stdout.write("\r\x1b[K"); // clear line
54
- if (code === 0) {
55
- show_status(successMsg, "success");
56
- resolve(true);
57
- } else {
58
- show_status(errorMsg, "error");
59
- reject(new Error(errorMsg));
60
- }
61
- });
62
- });
63
- }
64
-
65
37
  // ===================== Header =====================
66
38
  function clear_and_header(version) {
67
39
  clear();
@@ -115,50 +87,10 @@ async function check_dependencies() {
115
87
  console.log("");
116
88
  }
117
89
 
118
- // ===================== Input Project Name =====================
119
- async function get_project_name() {
120
- const rl = readline.createInterface({
121
- input: process.stdin,
122
- output: process.stdout,
123
- });
124
-
125
- function ask(q) {
126
- return new Promise((resolve) => rl.question(q, resolve));
127
- }
128
90
 
129
- let name;
130
- while (true) {
131
- name = await ask("Masukan nama project: ");
132
- name = name.trim().toLowerCase().replace(/[^a-z0-9\-_]/g, "").replace(/^-+|-+$/g, "");
133
- if (!name) {
134
- show_status("Nama project tidak boleh kosong!", "error");
135
- continue;
136
- }
137
- if (name.length > 50) {
138
- show_status("Nama project terlalu panjang!", "error");
139
- continue;
140
- }
141
- break;
142
- }
143
91
 
144
- rl.close();
145
- return name;
146
- }
147
92
 
148
- // ===================== Create Project =====================
149
- async function create_project() {
150
- const projectName = await get_project_name();
151
- if (fs.existsSync(projectName)) {
152
- show_status(`Direktori '${projectName}' sudah ada!`, "error");
153
- process.exit(1);
154
- }
155
93
 
156
- show_status(`Membuat project Angular: ${projectName}`, "info");
157
- execSync(`ng new ${projectName}`, { stdio: "inherit" });
158
- process.chdir(projectName);
159
- show_status("Project berhasil dibuat!", "success");
160
- return projectName;
161
- }
162
94
 
163
95
  // ===================== Structure =====================
164
96
  function create_structure() {
@@ -225,20 +157,8 @@ folders.forEach((folder) => {
225
157
 
226
158
  }
227
159
 
228
- // ===================== Update package.json =====================
229
- function update_package_json() {
230
- show_status("Memperbarui package.json...", "info");
231
- const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
232
- fs.copyFileSync("package.json", "package.json.backup");
233
160
 
234
- pkg.scripts["start:dev"] = "ng serve --port 4200 --open";
235
- pkg.scripts["build:dev"] = "ng build";
236
- pkg.scripts["lint"] = "ng lint";
237
- pkg.scripts["test"] = "ng test --watch=false";
238
161
 
239
- fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2));
240
- show_status("package.json berhasil diperbarui!", "success");
241
- }
242
162
 
243
163
  // ===================== Show Completion =====================
244
164
  function show_completion(projectName, OS) {
@@ -248,25 +168,11 @@ function show_completion(projectName, OS) {
248
168
  console.log(`đŸ“Ļ Nama Project: ${projectName}`);
249
169
  console.log(`đŸ–Ĩ Sistem: ${OS}`);
250
170
  console.log("🚀 Jalankan dengan:");
251
- console.log(` cd ${projectName} && npm start`);
171
+ console.log(` cd ${projectName} && ng serve`);
252
172
  console.log("✅ Semua proses selesai. Selamat berkoding!");
253
173
  }
254
174
 
255
- // ===================== Main =====================
256
- async function main() {
257
-
258
- const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.json"), "utf8"));
259
-
260
- clear_and_header(pkg.version);
261
- const OS = check_os();
262
- await check_dependencies();
263
- const projectName = await create_project();
264
- create_structure();
265
- update_package_json();
266
175
 
267
- await run_with_spinner("npm install", "Menginstall dependencies...", "Dependencies berhasil diinstall!", "Gagal install dependencies");
268
- show_completion(projectName, OS);
269
- }
270
176
 
271
177
  function copyRecursiveSync(src, dest) {
272
178
  if (!fs.existsSync(src)) return;
@@ -289,14 +195,37 @@ function copyRecursiveSync(src, dest) {
289
195
  }
290
196
 
291
197
  async function copy_template() {
292
- await run_with_spinner(
293
- `cp -r "${path.join(__dirname, "templates", "app")}" "${path.join(process.cwd(), "src", "app")}"`,
294
- "Menyalin folder app dari template ke src/app...",
295
- "Folder src/app berhasil disalin!",
296
- "Gagal menyalin folder src/app!"
297
- );
198
+ show_status("Menyalin folder app dari template ke src/app...", "info");
199
+
200
+ const srcFolder = path.join(__dirname, "templates", "app");
201
+ const destFolder = path.join(process.cwd(), "src", "app");
202
+
203
+ copyRecursiveSync(srcFolder, destFolder);
204
+
205
+ show_status("Folder src/app berhasil disalin!", "success");
206
+ }
207
+
208
+
209
+ // ===================== MARK:Main =====================
210
+ async function main() {
211
+
212
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.json"), "utf8"));
213
+ clear_and_header(pkg.version);
214
+
215
+ const OS = check_os();
216
+ await check_dependencies();
217
+ const projectName = await create_project();
218
+ create_structure();
219
+ await sleep(1000);
220
+ setupAssets();
221
+ await sleep(1000);
222
+ update_package_json();
223
+ await run_with_spinner("npm install", "Menginstall dependencies...", "Dependencies berhasil diinstall!", "Gagal install dependencies");
224
+ await sleep(1000);
225
+ show_completion(projectName, OS);
298
226
  }
299
227
 
228
+
300
229
 
301
230
 
302
231
  main().catch((err) => {
@@ -0,0 +1,88 @@
1
+ const fs = require('fs');
2
+ const { show_status} = require('./showStatus');
3
+ const { execSync, spawn} = require("child_process");
4
+ const readline = require("readline");
5
+ const path = require('path');
6
+
7
+
8
+
9
+ // ===================== Input Project Name =====================
10
+ async function get_project_name() {
11
+ const rl = readline.createInterface({
12
+ input: process.stdin,
13
+ output: process.stdout,
14
+ });
15
+
16
+ function ask(q) {
17
+ return new Promise((resolve) => rl.question(q, resolve));
18
+ }
19
+
20
+ let name;
21
+ while (true) {
22
+ name = await ask("Masukan nama project: ");
23
+ name = name.trim().toLowerCase().replace(/[^a-z0-9\-_]/g, "").replace(/^-+|-+$/g, "");
24
+ if (!name) {
25
+ show_status("Nama project tidak boleh kosong!", "error");
26
+ continue;
27
+ }
28
+ if (name.length > 50) {
29
+ show_status("Nama project terlalu panjang!", "error");
30
+ continue;
31
+ }
32
+ break;
33
+ }
34
+
35
+ rl.close();
36
+ return name;
37
+ }
38
+
39
+ // ===================== Create Project =====================
40
+ // async function create_project() {
41
+ // const projectName = await get_project_name();
42
+ // if (fs.existsSync(projectName)) {
43
+ // show_status(`Direktori '${projectName}' sudah ada!`, "error");
44
+ // process.exit(1);
45
+ // }
46
+
47
+ // show_status(`Membuat project Angular (zoneless, no-SSR): ${projectName}`, "info");
48
+
49
+ // const command = process.platform === "win32" ? "npx.cmd" : "npx";
50
+ // const args = [
51
+ // "ng", "new", projectName,
52
+ // "--zone-less", // aktifkan Zoneless
53
+ // "--ssr=false", // nonaktifkan SSR
54
+ // "--skip-git", // tidak membuat repo git
55
+ // // "--defaults" // pakai default pilihan
56
+ // "--style=scss"
57
+ // ];
58
+
59
+ // await new Promise((resolve, reject) => {
60
+ // const child = spawn(command, args, { stdio: "inherit" });
61
+
62
+ // child.on("error", reject);
63
+ // child.on("close", (code) => {
64
+ // if (code === 0) resolve();
65
+ // else reject(new Error(`ng new exited with code ${code}`));
66
+ // });
67
+ // });
68
+
69
+ // process.chdir(projectName);
70
+ // show_status("Project berhasil dibuat!", "success");
71
+ // return projectName;
72
+ // }
73
+
74
+ async function create_project() {
75
+ const projectName = await get_project_name();
76
+ if (fs.existsSync(projectName)) {
77
+ show_status(`Direktori '${projectName}' sudah ada!`, "error");
78
+ process.exit(1);
79
+ }
80
+
81
+ show_status(`Membuat project Angular: ${projectName}`, "info");
82
+ execSync(`ng new ${projectName} --zoneless --ssr=false --skip-git --style=scss`, { stdio: "inherit" });
83
+ process.chdir(projectName);
84
+ show_status("Project berhasil dibuat!", "success");
85
+ return projectName;
86
+ }
87
+
88
+ module.exports = { get_project_name, create_project };
@@ -0,0 +1,103 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { show_status } = require('./showStatus');
4
+
5
+ function setupAssets() {
6
+ show_status("Generate environment files...", "info");
7
+ const angularJsonPath = path.join(process.cwd(), 'angular.json');
8
+ const assetsPath = path.join(process.cwd(), 'src', 'assets');
9
+ const envPath = path.join(process.cwd(), 'src', 'environments');
10
+
11
+ // Pastikan file angular.json ada
12
+ if (!fs.existsSync(angularJsonPath)) {
13
+ console.error('✖ angular.json not found! Run this script in the Angular project root.');
14
+ process.exit(1);
15
+ }
16
+
17
+ // 1. Update angular.json untuk menambahkan src/assets
18
+ const angularJson = JSON.parse(fs.readFileSync(angularJsonPath, 'utf8'));
19
+ const projectName = Object.keys(angularJson.projects)[0];
20
+ const buildOptions = angularJson.projects[projectName].architect.build.options;
21
+
22
+ if (!buildOptions.assets.includes('src/assets')) {
23
+ buildOptions.assets.push('src/assets');
24
+ fs.writeFileSync(angularJsonPath, JSON.stringify(angularJson, null, 2));
25
+ console.log('✔ Added "src/assets" to angular.json');
26
+ } else {
27
+ console.log('ℹ "src/assets" already exists in angular.json');
28
+ }
29
+
30
+ // 2. Buat folder assets jika belum ada
31
+ if (!fs.existsSync(assetsPath)) {
32
+ fs.mkdirSync(assetsPath, { recursive: true });
33
+ console.log('✔ Created src/assets folder');
34
+ } else {
35
+ console.log('ℹ src/assets folder already exists');
36
+ }
37
+
38
+
39
+ // 3. Generate folder environments di root src
40
+ if (!fs.existsSync(envPath)) {
41
+ fs.mkdirSync(envPath, { recursive: true });
42
+ console.log('✔ Created src/environments folder');
43
+ }
44
+
45
+ const envFiles = [
46
+ {
47
+ name: 'environment.ts',
48
+ content: `export const environment = {
49
+ production: false,
50
+ apiUrl: 'http://localhost:3000/api',
51
+ envName: 'dev'
52
+ };`,
53
+ json: {
54
+ production: false,
55
+ apiUrl: 'http://localhost:3000/api',
56
+ envName: 'dev'
57
+ }
58
+ },
59
+ {
60
+ name: 'environment.staging.ts',
61
+ content: `export const environment = {
62
+ production: false,
63
+ apiUrl: 'https://staging.example.com/api',
64
+ envName: 'staging'
65
+ };`,
66
+ json: {
67
+ production: false,
68
+ apiUrl: 'https://staging.example.com/api',
69
+ envName: 'staging'
70
+ }
71
+ },
72
+ {
73
+ name: 'environment.prod.ts',
74
+ content: `export const environment = {
75
+ production: true,
76
+ apiUrl: 'https://api.example.com',
77
+ envName: 'prod'
78
+ };`,
79
+ json: {
80
+ production: true,
81
+ apiUrl: 'https://api.example.com',
82
+ envName: 'prod'
83
+ }
84
+ }
85
+ ];
86
+
87
+ // 5. Generate environment JSON di src/assets/environments
88
+ envFiles.forEach(file => {
89
+ const jsonFileName = file.name;
90
+ const jsonPath = path.join(envPath, jsonFileName);
91
+ if (!fs.existsSync(jsonPath)) {
92
+ fs.writeFileSync(jsonPath, file.content);
93
+
94
+ console.log(`✔ Created ${jsonFileName} in src/environments`);
95
+ } else {
96
+ console.log(`ℹ ${jsonFileName} already exists in src/environments`);
97
+ }
98
+ });
99
+
100
+ console.log('🎉 environments setup complete!');
101
+ }
102
+
103
+ module.exports = { setupAssets };
@@ -0,0 +1,44 @@
1
+
2
+ const { execSync, spawn} = require("child_process");
3
+
4
+
5
+ function show_status(message, status = "info") {
6
+ const icons = {
7
+ info: "â„šī¸ ",
8
+ success: "✅",
9
+ warning: "âš ī¸ ",
10
+ error: "❌",
11
+ loading: "âŗ",
12
+ };
13
+ console.log(`${icons[status] || ""} ${message}`);
14
+ }
15
+
16
+
17
+
18
+ async function run_with_spinner(cmd, msg, successMsg, errorMsg) {
19
+ let spinnerFrames = ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "█", "▉", "▊", "▋", "▌", "▍", "▎"];
20
+ let i = 0;
21
+ let active = true;
22
+
23
+ const spinner = setInterval(() => {
24
+ process.stdout.write(`\r${spinnerFrames[i++ % spinnerFrames.length]} ${msg}`);
25
+ }, 100);
26
+
27
+ return new Promise((resolve, reject) => {
28
+ const child = spawn(cmd, { shell: true, stdio: "ignore" });
29
+
30
+ child.on("exit", (code) => {
31
+ clearInterval(spinner);
32
+ process.stdout.write("\r\x1b[K"); // clear line
33
+ if (code === 0) {
34
+ show_status(successMsg, "success");
35
+ resolve(true);
36
+ } else {
37
+ show_status(errorMsg, "error");
38
+ reject(new Error(errorMsg));
39
+ }
40
+ });
41
+ });
42
+ }
43
+
44
+ module.exports = { show_status, run_with_spinner };
@@ -0,0 +1,26 @@
1
+ const fs = require('fs');
2
+ const { show_status } = require('./showStatus');
3
+
4
+
5
+ // ===================== Update package.json =====================
6
+ function update_package_json() {
7
+ show_status("Memperbarui package.json...", "info");
8
+
9
+ const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
10
+ fs.copyFileSync("package.json", "package.json.backup");
11
+
12
+ // Tambahkan/Update scripts
13
+ pkg.scripts["start:dev"] = "ng serve --port 4200 --open";
14
+ pkg.scripts["build:dev"] = "cp src/env/config.dev.json src/assets/config.json && ng build";
15
+ pkg.scripts["build:staging"] = "cp src/env/config.staging.json src/assets/config.json && ng build";
16
+ pkg.scripts["build:prod"] = "cp src/env/config.prod.json src/assets/config.json && ng build --configuration production";
17
+ pkg.scripts["lint"] = "ng lint";
18
+ pkg.scripts["test"] = "ng test --watch=false";
19
+
20
+ fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2));
21
+
22
+ show_status("package.json berhasil diperbarui dengan script build multi-env!", "success");
23
+ }
24
+
25
+
26
+ module.exports = {update_package_json };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "unictive-angular",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "CLI untuk membuat project Angular dengan struktur kustom (Modules, Core, API, Shared).",
5
- "scripts": {
5
+ "scripts": {
6
6
  "build": "npm publish --access public"
7
- },
7
+ },
8
8
  "bin": {
9
9
  "unictive-angular": "./bin/index.js"
10
10
  },
@@ -16,5 +16,7 @@
16
16
  ],
17
17
  "author": "EkaHersada",
18
18
  "license": "MIT",
19
- "dependencies": {}
19
+ "dependencies": {
20
+ "update-notifier": "^7.3.1"
21
+ }
20
22
  }
@@ -0,0 +1,17 @@
1
+ # Editor configuration, see https://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ indent_style = space
7
+ indent_size = 2
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.ts]
12
+ quote_type = single
13
+ ij_typescript_use_double_quotes = false
14
+
15
+ [*.md]
16
+ max_line_length = off
17
+ trim_trailing_whitespace = false
@@ -0,0 +1,4 @@
1
+ {
2
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3
+ "recommendations": ["angular.ng-template"]
4
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3
+ "version": "0.2.0",
4
+ "configurations": [
5
+ {
6
+ "name": "ng serve",
7
+ "type": "chrome",
8
+ "request": "launch",
9
+ "preLaunchTask": "npm: start",
10
+ "url": "http://localhost:4200/"
11
+ },
12
+ {
13
+ "name": "ng test",
14
+ "type": "chrome",
15
+ "request": "launch",
16
+ "preLaunchTask": "npm: test",
17
+ "url": "http://localhost:9876/debug.html"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
3
+ "version": "2.0.0",
4
+ "tasks": [
5
+ {
6
+ "type": "npm",
7
+ "script": "start",
8
+ "isBackground": true,
9
+ "problemMatcher": {
10
+ "owner": "typescript",
11
+ "pattern": "$tsc",
12
+ "background": {
13
+ "activeOnStart": true,
14
+ "beginsPattern": {
15
+ "regexp": "(.*?)"
16
+ },
17
+ "endsPattern": {
18
+ "regexp": "bundle generation complete"
19
+ }
20
+ }
21
+ }
22
+ },
23
+ {
24
+ "type": "npm",
25
+ "script": "test",
26
+ "isBackground": true,
27
+ "problemMatcher": {
28
+ "owner": "typescript",
29
+ "pattern": "$tsc",
30
+ "background": {
31
+ "activeOnStart": true,
32
+ "beginsPattern": {
33
+ "regexp": "(.*?)"
34
+ },
35
+ "endsPattern": {
36
+ "regexp": "bundle generation complete"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ]
42
+ }
package/test/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Test
2
+
3
+ This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.0.3.
4
+
5
+ ## Development server
6
+
7
+ To start a local development server, run:
8
+
9
+ ```bash
10
+ ng serve
11
+ ```
12
+
13
+ Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
14
+
15
+ ## Code scaffolding
16
+
17
+ Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
18
+
19
+ ```bash
20
+ ng generate component component-name
21
+ ```
22
+
23
+ For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
24
+
25
+ ```bash
26
+ ng generate --help
27
+ ```
28
+
29
+ ## Building
30
+
31
+ To build the project run:
32
+
33
+ ```bash
34
+ ng build
35
+ ```
36
+
37
+ This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
38
+
39
+ ## Running unit tests
40
+
41
+ To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
42
+
43
+ ```bash
44
+ ng test
45
+ ```
46
+
47
+ ## Running end-to-end tests
48
+
49
+ For end-to-end (e2e) testing, run:
50
+
51
+ ```bash
52
+ ng e2e
53
+ ```
54
+
55
+ Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
56
+
57
+ ## Additional Resources
58
+
59
+ For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.