create-ec-app 0.0.1

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.
@@ -0,0 +1,505 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ import fs from "fs-extra";
4
+ import path from "path";
5
+ import { execSync } from "child_process";
6
+ import inquirer from "inquirer";
7
+ // Helper function to run commands and show a spinner
8
+ const runCommand = (command, spinnerMessage) => {
9
+ const spinner = ora(spinnerMessage).start();
10
+ try {
11
+ execSync(command, { stdio: "pipe" });
12
+ spinner.succeed();
13
+ }
14
+ catch (error) {
15
+ spinner.fail();
16
+ console.error(chalk.red(`Failed to execute command: ${command}`));
17
+ console.error(error);
18
+ process.exit(1);
19
+ }
20
+ };
21
+ export const createWebResourceApp = async (projectName) => {
22
+ // Prompt for Kendo theme
23
+ const kendoThemes = [
24
+ { name: "Default", value: "@progress/kendo-theme-default" },
25
+ { name: "Bootstrap (v5)", value: "@progress/kendo-theme-bootstrap" },
26
+ { name: "Material (v3)", value: "@progress/kendo-theme-material" },
27
+ { name: "Fluent", value: "@progress/kendo-theme-fluent" },
28
+ { name: "Classic", value: "@progress/kendo-theme-classic" },
29
+ ];
30
+ const { kendoThemePackage } = await inquirer.prompt([
31
+ {
32
+ type: "list",
33
+ name: "kendoThemePackage",
34
+ message: "Which Kendo UI theme would you like to install?",
35
+ choices: kendoThemes,
36
+ },
37
+ ]);
38
+ const projectDir = path.resolve(process.cwd(), projectName);
39
+ console.log(`\nScaffolding a new project in ${chalk.green(projectDir)}...\n`);
40
+ // Create React + Vite (TypeScript) project
41
+ runCommand(`npm create vite@latest ${projectName} -- --template react-ts`, "Creating Vite + React + TS project...");
42
+ process.chdir(projectDir);
43
+ // Update package.json with overrides for Vite 7 compatibility
44
+ const packageJsonPath = path.join(projectDir, "package.json");
45
+ const packageJson = fs.readJsonSync(packageJsonPath);
46
+ // Add custom build script
47
+ packageJson.scripts["build:dev"] = "tsc -b && vite build --mode development";
48
+ fs.writeJsonSync(packageJsonPath, packageJson, { spaces: 2 });
49
+ ora("Updated package.json with Vite 7 overrides and custom build script").succeed();
50
+ // Install dependencies with version constraints and overrides
51
+ const dependencies = [
52
+ "@progress/kendo-react-buttons",
53
+ "@progress/kendo-licensing",
54
+ "tailwindcss@^4",
55
+ "@tailwindcss/vite@^4",
56
+ "@tanstack/react-query",
57
+ "zustand",
58
+ "@types/xrm",
59
+ "@types/node",
60
+ kendoThemePackage,
61
+ ];
62
+ runCommand(`npm install ${dependencies.join(" ")}`, `Installing dependencies (Theme: ${kendoThemePackage.split("/")[1]})...`);
63
+ // Create kendo-tw-preset.js
64
+ const kendoPresetPath = path.join(projectDir, "kendo-tw-preset.js");
65
+ const kendoPresetContent = `module.exports = {
66
+ theme: {
67
+ extend: {
68
+ spacing: {
69
+ 1: "var( --kendo-spacing-1 )",
70
+ 1.5: "var( --kendo-spacing-1.5 )",
71
+ 2: "var( --kendo-spacing-2 )",
72
+ 2.5: "var( --kendo-spacing-2.5 )",
73
+ 3: "var( --kendo-spacing-3 )",
74
+ 3.5: "var( --kendo-spacing-3.5 )",
75
+ 4: "var( --kendo-spacing-4 )",
76
+ 4.5: "var( --kendo-spacing-4.5 )",
77
+ 5: "var( --kendo-spacing-5 )",
78
+ 5.5: "var( --kendo-spacing-5.5 )",
79
+ 6: "var( --kendo-spacing-6 )",
80
+ 6.5: "var( --kendo-spacing-6.5 )",
81
+ 7: "var( --kendo-spacing-7 )",
82
+ 7.5: "var( --kendo-spacing-7.5 )",
83
+ 8: "var( --kendo-spacing-8 )",
84
+ 9: "var( --kendo-spacing-9 )",
85
+ 10: "var( --kendo-spacing-10 )",
86
+ 11: "var( --kendo-spacing-11 )",
87
+ 12: "var( --kendo-spacing-12 )",
88
+ 13: "var( --kendo-spacing-13 )",
89
+ 14: "var( --kendo-spacing-14 )",
90
+ 15: "var( --kendo-spacing-15 )",
91
+ 16: "var( --kendo-spacing-16 )",
92
+ 17: "var( --kendo-spacing-17 )",
93
+ 18: "var( --kendo-spacing-18 )",
94
+ 19: "var( --kendo-spacing-19 )",
95
+ 20: "var( --kendo-spacing-20 )",
96
+ 21: "var( --kendo-spacing-21 )",
97
+ 22: "var( --kendo-spacing-22 )",
98
+ 23: "var( --kendo-spacing-23 )",
99
+ 24: "var( --kendo-spacing-24 )",
100
+ 25: "var( --kendo-spacing-25 )",
101
+ 26: "var( --kendo-spacing-26 )",
102
+ 27: "var( --kendo-spacing-27 )",
103
+ 28: "var( --kendo-spacing-28 )",
104
+ 29: "var( --kendo-spacing-29 )",
105
+ 30: "var( --kendo-spacing-30 )",
106
+ },
107
+ borderRadius: {
108
+ none: "var( --kendo-border-radius-none )",
109
+ sm: "var( --kendo-border-radius-sm )",
110
+ DEFAULT: "var( --kendo-border-radius-md )",
111
+ lg: "var( --kendo-border-radius-lg )",
112
+ xl: "var( --kendo-border-radius-xl )",
113
+ "2xl": "var( --kendo-border-radius-xxl )",
114
+ "3xl": "var( --kendo-border-radius-xxxl )",
115
+ full: "var( --kendo-border-radius-none )",
116
+ },
117
+ boxShadow: {
118
+ sm: "var( --kendo-elevation-2 )",
119
+ DEFAULT: "var( --kendo-elevation-4 )",
120
+ lg: "var( --kendo-elevation-6 )",
121
+ xl: "var( --kendo-elevation-8 )",
122
+ "2xl": "var( --keno-elevation-9 )",
123
+ },
124
+ colors: {
125
+ "app-surface": "var( --kendo-color-app-surface )",
126
+ "on-app-surface": "var( --kendo-color-on-app-surface )",
127
+ subtle: "var( --kendo-color-subtle )",
128
+ surface: "var( --kendo-color-surface )",
129
+ "surface-alt": "var( --kendo-color-surface-alt )",
130
+ border: "var( --kendo-color-border )",
131
+ "border-alt": "var( --kendo-color-border-alt )",
132
+ base: {
133
+ DEFAULT: "var( --kendo-color-base )",
134
+ hover: "var( --kendo-color-base-hover )",
135
+ active: "var( --kendo-color-base-active )",
136
+ emphasis: "var( --kendo-color-base-emphasis )",
137
+ subtle: "var( --kendo-color-base-subtle )",
138
+ "subtle-hover": "var( --kendo-color-base-subtle-hover )",
139
+ "subtle-active": "var( --kendo-color-base-subtle-active)",
140
+ "on-subtle": "var( --kendo-color-base-on-subtle )",
141
+ "on-surface": "var( --kendo-color-base-on-surface )",
142
+ },
143
+ "on-base": "var( --kendo-color-on-base )",
144
+ primary: {
145
+ DEFAULT: "var( --kendo-color-primary )",
146
+ hover: "var( --kendo-color-primary-hover )",
147
+ active: "var( --kendo-color-primary-active )",
148
+ emphasis: "var( --kendo-color-primary-emphasis )",
149
+ subtle: "var( --kendo-color-primary-subtle )",
150
+ "subtle-hover": "var( --kendo-color-primary-subtle-hover )",
151
+ "subtle-active": "var( --kendo-color-primary-subtle-active)",
152
+ "on-subtle": "var( --kendo-color-primary-on-subtle )",
153
+ "on-surface": "var( --kendo-color-primary-on-surface )",
154
+ },
155
+ "on-primary": "var( --kendo-color-on-primary )",
156
+ secondary: {
157
+ DEFAULT: "var( --kendo-color-secondary )",
158
+ hover: "var( --kendo-color-secondary-hover )",
159
+ active: "var( --kendo-color-secondary-active )",
160
+ emphasis: "var( --kendo-color-secondary-emphasis )",
161
+ subtle: "var( --kendo-color-secondary-subtle )",
162
+ "subtle-hover": "var( --kendo-color-secondary-subtle-hover )",
163
+ "subtle-active": "var( --kendo-color-secondary-subtle-active)",
164
+ "on-subtle": "var( --kendo-color-secondary-on-subtle )",
165
+ "on-surface": "var( --kendo-color-secondary-on-surface )",
166
+ },
167
+ "on-secondary": "var( --kendo-color-on-secondary )",
168
+ tertiary: {
169
+ DEFAULT: "var( --kendo-color-tertiary )",
170
+ hover: "var( --kendo-color-tertiary-hover )",
171
+ active: "var( --kendo-color-tertiary-active )",
172
+ emphasis: "var( --kendo-color-tertiary-emphasis )",
173
+ subtle: "var( --kendo-color-tertiary-subtle )",
174
+ "subtle-hover": "var( --kendo-color-tertiary-subtle-hover )",
175
+ "subtle-active": "var( --kendo-color-tertiary-subtle-active)",
176
+ "on-subtle": "var( --kendo-color-tertiary-on-subtle )",
177
+ "on-surface": "var( --kendo-color-tertiary-on-surface )",
178
+ },
179
+ "on-tertiary": "var( --kendo-color-on-tertiary )",
180
+ light: {
181
+ DEFAULT: "var( --kendo-color-light )",
182
+ hover: "var( --kendo-color-light-hover )",
183
+ active: "var( --kendo-color-light-active )",
184
+ emphasis: "var( --kendo-color-light-emphasis )",
185
+ subtle: "var( --kendo-color-light-subtle )",
186
+ "subtle-hover": "var( --kendo-color-light-subtle-hover )",
187
+ "subtle-active": "var( --kendo-color-light-subtle-active)",
188
+ "on-subtle": "var( --kendo-color-light-on-subtle )",
189
+ "on-surface": "var( --kendo-color-light-on-surface )",
190
+ },
191
+ "on-light": "var( --kendo-color-on-light )",
192
+ dark: {
193
+ DEFAULT: "var( --kendo-color-dark )",
194
+ hover: "var( --kendo-color-dark-hover )",
195
+ active: "var( --kendo-color-dark-active )",
196
+ emphasis: "var( --kendo-color-dark-emphasis )",
197
+ subtle: "var( --kendo-color-dark-subtle )",
198
+ "subtle-hover": "var( --kendo-color-dark-subtle-hover )",
199
+ "subtle-active": "var( --kendo-color-dark-subtle-active)",
200
+ "on-subtle": "var( --kendo-color-dark-on-subtle )",
201
+ "on-surface": "var( --kendo-color-dark-on-surface )",
202
+ },
203
+ "on-dark": "var( --kendo-color-on-dark )",
204
+ info: {
205
+ DEFAULT: "var( --kendo-color-info )",
206
+ hover: "var( --kendo-color-info-hover )",
207
+ active: "var( --kendo-color-info-active )",
208
+ emphasis: "var( --kendo-color-info-emphasis )",
209
+ subtle: "var( --kendo-color-info-subtle )",
210
+ "subtle-hover": "var( --kendo-color-info-subtle-hover )",
211
+ "subtle-active": "var( --kendo-color-info-subtle-active)",
212
+ "on-subtle": "var( --kendo-color-info-on-subtle )",
213
+ "on-surface": "var( --kendo-color-info-on-surface )",
214
+ },
215
+ "on-info": "var( --kendo-color-on-info )",
216
+ success: {
217
+ DEFAULT: "var( --kendo-color-success )",
218
+ hover: "var( --kendo-color-success-hover )",
219
+ active: "var( --kendo-color-success-active )",
220
+ emphasis: "var( --kendo-color-success-emphasis )",
221
+ subtle: "var( --kendo-color-success-subtle )",
222
+ "subtle-hover": "var( --kendo-color-success-subtle-hover )",
223
+ "subtle-active": "var( --kendo-color-success-subtle-active)",
224
+ "on-subtle": "var( --kendo-color-success-on-subtle )",
225
+ "on-surface": "var( --kendo-color-success-on-surface )",
226
+ },
227
+ "on-success": "var( --kendo-color-on-success )",
228
+ error: {
229
+ DEFAULT: "var( --kendo-color-error )",
230
+ hover: "var( --kendo-color-error-hover )",
231
+ active: "var( --kendo-color-error-active )",
232
+ emphasis: "var( --kendo-color-error-emphasis )",
233
+ subtle: "var( --kendo-color-error-subtle )",
234
+ "subtle-hover": "var( --kendo-color-error-subtle-hover )",
235
+ "subtle-active": "var( --kendo-color-error-subtle-active)",
236
+ "on-subtle": "var( --kendo-color-error-on-subtle )",
237
+ "on-surface": "var( --kendo-color-error-on-surface )",
238
+ },
239
+ "on-error": "var( --kendo-color-on-error )",
240
+ warning: {
241
+ DEFAULT: "var( --kendo-color-warning )",
242
+ hover: "var( --kendo-color-warning-hover )",
243
+ active: "var( --kendo-color-warning-active )",
244
+ emphasis: "var( --kendo-color-warning-emphasis )",
245
+ subtle: "var( --kendo-color-warning-subtle )",
246
+ "subtle-hover": "var( --kendo-color-warning-subtle-hover )",
247
+ "subtle-active": "var( --kendo-color-warning-subtle-active)",
248
+ "on-subtle": "var( --kendo-color-warning-on-subtle )",
249
+ "on-surface": "var( --kendo-color-warning-on-surface )",
250
+ },
251
+ "on-warning": "var( --kendo-color-on-warning )",
252
+ "series-a": {
253
+ DEFAULT: "var( --kendo-color-series-a )",
254
+ subtle: "var( --kendo-color-series-a-subtle )",
255
+ subtler: "var( --kendo-color-series-a-subtler )",
256
+ bold: "var( --kendo-color-series-a-bold )",
257
+ bolder: "var( --kendo-color-series-a-bolder )",
258
+ },
259
+ "series-b": {
260
+ DEFAULT: "var( --kendo-color-series-b )",
261
+ subtle: "var( --kendo-color-series-b-subtle )",
262
+ subtler: "var( --kendo-color-series-b-subtler )",
263
+ bold: "var( --kendo-color-series-b-bold )",
264
+ bolder: "var( --kendo-color-series-b-bolder )",
265
+ },
266
+ "series-c": {
267
+ DEFAULT: "var( --kendo-color-series-c )",
268
+ subtle: "var( --kendo-color-series-c-subtle )",
269
+ subtler: "var( --kendo-color-series-c-subtler )",
270
+ bold: "var( --kendo-color-series-c-bold )",
271
+ bolder: "var( --kendo-color-series-c-bolder )",
272
+ },
273
+ "series-d": {
274
+ DEFAULT: "var( --kendo-color-series-d )",
275
+ subtle: "var( --kendo-color-series-d-subtle )",
276
+ subtler: "var( --kendo-color-series-d-subtler )",
277
+ bold: "var( --kendo-color-series-d-bold )",
278
+ bolder: "var( --kendo-color-series-d-bolder )",
279
+ },
280
+ "series-e": {
281
+ DEFAULT: "var( --kendo-color-series-e )",
282
+ subtle: "var( --kendo-color-series-e-subtle )",
283
+ subtler: "var( --kendo-color-series-e-subtler )",
284
+ bold: "var( --kendo-color-series-e-bold )",
285
+ bolder: "var( --kendo-color-series-e-bolder )",
286
+ },
287
+ "series-f": {
288
+ DEFAULT: "var( --kendo-color-series-f )",
289
+ subtle: "var( --kendo-color-series-f-subtle )",
290
+ subtler: "var( --kendo-color-series-f-subtler )",
291
+ bold: "var( --kendo-color-series-f-bold )",
292
+ bolder: "var( --kendo-color-series-f-bolder )",
293
+ },
294
+ },
295
+ },
296
+ },
297
+ };`;
298
+ fs.writeFileSync(kendoPresetPath, kendoPresetContent, "utf8");
299
+ ora("Created kendo-tw-preset.js").succeed();
300
+ // Create tailwind.config.js with Kendo preset
301
+ const tailwindConfigPath = path.join(projectDir, "tailwind.config.js");
302
+ const tailwindConfigContent = `/** @type {import('tailwindcss').Config} */
303
+
304
+ import kendoTwPreset from "./kendo-tw-preset.js";
305
+
306
+ export default {
307
+ content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
308
+ presets: [kendoTwPreset],
309
+ theme: {
310
+ extend: {
311
+ colors: {},
312
+ },
313
+ },
314
+ plugins: [],
315
+ };`;
316
+ fs.writeFileSync(tailwindConfigPath, tailwindConfigContent, "utf8");
317
+ ora("Created tailwind.config.js with Kendo preset").succeed();
318
+ // Overwrite Vite config with advanced build options
319
+ const viteConfigPath = path.join(projectDir, "vite.config.ts");
320
+ const newViteConfigContent = `import path from "path";
321
+ import tailwindcss from "@tailwindcss/vite";
322
+ import { defineConfig } from "vite";
323
+ import react from "@vitejs/plugin-react";
324
+
325
+ export default defineConfig(({ command, mode }) => {
326
+ const isDev = mode === "development" || command === "serve";
327
+
328
+ return {
329
+ base: "./",
330
+ plugins: [react(), tailwindcss()],
331
+ resolve: {
332
+ alias: {
333
+ "@": path.resolve(__dirname, "./src"),
334
+ },
335
+ },
336
+ build: {
337
+ rollupOptions: {
338
+ external: ["../../token.json"],
339
+ output: {
340
+ manualChunks: undefined,
341
+ entryFileNames: "[name].js",
342
+ chunkFileNames: "[name].chunk.js",
343
+ assetFileNames: (assetInfo) => {
344
+ if (assetInfo.name?.endsWith(".css")) {
345
+ return "main.css";
346
+ }
347
+ return "[name].[ext]";
348
+ },
349
+ },
350
+ },
351
+ minify: !isDev,
352
+ mode: isDev ? "development" : "production",
353
+ assetsDir: "",
354
+ target: "es2015",
355
+ cssCodeSplit: false,
356
+ },
357
+ };
358
+ });
359
+ `;
360
+ fs.writeFileSync(viteConfigPath, newViteConfigContent, "utf8");
361
+ ora("Replaced vite.config.ts with custom build config").succeed();
362
+ // Update CSS entry point
363
+ const indexCssPath = path.join(projectDir, "src", "index.css");
364
+ fs.writeFileSync(indexCssPath, `@import "tailwindcss";`, "utf8");
365
+ ora("Updated CSS entry point").succeed();
366
+ // Clear App.css
367
+ const appCssPath = path.join(projectDir, "src", "App.css");
368
+ fs.writeFileSync(appCssPath, "", "utf8");
369
+ ora("Cleared App.css").succeed();
370
+ // Replace App.tsx with custom content
371
+ const appTsxPath = path.join(projectDir, "src", "App.tsx");
372
+ const newAppTsxContent = `import "./App.css";
373
+
374
+ function App() {
375
+ return (
376
+ <>
377
+ <div className="flex flex-col h-screen items-center justify-center">
378
+ Hello World!
379
+ </div>
380
+ </>
381
+ );
382
+ }
383
+
384
+ export default App;
385
+ `;
386
+ fs.writeFileSync(appTsxPath, newAppTsxContent, "utf8");
387
+ ora("Replaced App.tsx with custom template").succeed();
388
+ // Generate main.tsx from template
389
+ const mainTsxPath = path.join(projectDir, "src", "main.tsx");
390
+ const newMainTsxContent = `import { StrictMode } from "react";
391
+ import { createRoot } from "react-dom/client";
392
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
393
+ import "${kendoThemePackage}/dist/all.css";
394
+ import "./index.css";
395
+ import App from "./App.tsx";
396
+
397
+ const queryClient = new QueryClient({
398
+ defaultOptions: {
399
+ queries: {
400
+ refetchOnWindowFocus: false,
401
+ retry: 3,
402
+ staleTime: 5 * 60 * 1000, // 5 minutes
403
+ },
404
+ mutations: {
405
+ retry: 1,
406
+ },
407
+ },
408
+ });
409
+
410
+ const root = createRoot(document.getElementById("root")!);
411
+
412
+ root.render(
413
+ <StrictMode>
414
+ <QueryClientProvider client={queryClient}>
415
+ <App />
416
+ </QueryClientProvider>
417
+ </StrictMode>
418
+ );
419
+ `;
420
+ fs.writeFileSync(mainTsxPath, newMainTsxContent, "utf8");
421
+ ora("Generated custom main.tsx with providers").succeed();
422
+ // Modify index.html
423
+ const indexPath = path.join(projectDir, "index.html");
424
+ let indexContent = fs.readFileSync(indexPath, "utf8");
425
+ indexContent = indexContent
426
+ .replace("<title>Vite + React + TS</title>", "<title>EC | Vite + React + TS + Kendo UI + Tailwind</title>")
427
+ .replace("</head>", ` <script src="../../ClientGlobalContext.js.aspx" type="text/javascript"></script>\n </head>`);
428
+ fs.writeFileSync(indexPath, indexContent, "utf8");
429
+ ora("Added ClientGlobalContext script to index.html").succeed();
430
+ // Add .prettierrc in root directory
431
+ const prettierRcPath = path.join(projectDir, ".prettierrc");
432
+ const prettierRcContent = `{
433
+ "tabWidth": 4,
434
+ "useTabs": true,
435
+ "semi": true,
436
+ "singleQuote": false,
437
+ "trailingComma": "es5",
438
+ "bracketSpacing": true,
439
+ "jsxBracketSameLine": false,
440
+ "arrowParens": "always",
441
+ "printWidth": 120
442
+ }`;
443
+ fs.writeFileSync(prettierRcPath, prettierRcContent, "utf8");
444
+ ora("Added .prettierrc").succeed();
445
+ // Add token.json in root directory
446
+ const tokenJsonPath = path.join(projectDir, "token.json");
447
+ const tokenJsonContent = `{
448
+ "accessToken": "",
449
+ "expiresIn": "",
450
+ "expires_on": 0,
451
+ "subscription": "",
452
+ "tenant": "",
453
+ "tokenType": "Bearer"
454
+ }`;
455
+ fs.writeFileSync(tokenJsonPath, tokenJsonContent, "utf8");
456
+ ora("Added token.json").succeed();
457
+ // Create services directory and authService.ts
458
+ const servicesDir = path.join(projectDir, "src", "services");
459
+ fs.ensureDirSync(servicesDir);
460
+ const authServicePath = path.join(servicesDir, "authService.ts");
461
+ const authServiceContent = `const getAuthToken = async (): Promise<string> => {
462
+ const tokenModule = await import("../../token.json");
463
+ const token = tokenModule.default.accessToken;
464
+ return token;
465
+ };
466
+
467
+ export const getApiUrl = (): string => {
468
+ if (window.parent && window.parent.Xrm) {
469
+ const globalContext = window.Xrm.Utility.getGlobalContext();
470
+ const clientUrl = globalContext.getClientUrl();
471
+ return \`\${clientUrl}/api/data/v9.2\`;
472
+ }
473
+
474
+ return "https://DOMAIN.REGION.dynamics.com/api/data/v9.2";
475
+ };
476
+
477
+ export const getAuthHeaders = async (): Promise<HeadersInit> => {
478
+ if (window.parent && window.parent.Xrm) {
479
+ return {
480
+ "Content-Type": "application/json",
481
+ "OData-MaxVersion": "4.0",
482
+ "OData-Version": "4.0",
483
+ Prefer: 'odata.include-annotations="*"',
484
+ };
485
+ }
486
+
487
+ const token = await getAuthToken();
488
+ const headers: HeadersInit = {
489
+ Authorization: \`Bearer \${token}\`,
490
+ "Content-Type": "application/json",
491
+ "OData-MaxVersion": "4.0",
492
+ "OData-Version": "4.0",
493
+ Prefer: 'odata.include-annotations="*"',
494
+ };
495
+
496
+ return headers;
497
+ };`;
498
+ fs.writeFileSync(authServicePath, authServiceContent, "utf8");
499
+ ora("Created authService.ts in src/services").succeed();
500
+ // Initialize Git
501
+ runCommand("git init", "Initializing Git repository...");
502
+ runCommand("git add .", "Staging files for initial commit...");
503
+ runCommand(`git commit -m "Initial commit from create-ec-app"`, "Creating initial commit...");
504
+ };
505
+ //# sourceMappingURL=webresource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webresource.js","sourceRoot":"","sources":["../../src/creators/webresource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env node
2
+ import chalk from "chalk";
3
+ import inquirer from "inquirer";
4
+ import { createWebResourceApp } from "./creators/webresource.js";
5
+ import { createPortalApp } from "./creators/portal.js";
6
+ import { createPowerPagesApp } from "./creators/powerpages.js";
7
+ import { createMobileApp } from "./creators/mobile.js";
8
+ const main = async () => {
9
+ console.log(chalk.bold.hex("#F5AB00")("\nšŸš€ Welcome to EC App Creator!\n"));
10
+ console.log(chalk.gray("Create different types of applications for your EC ecosystem.\n"));
11
+ // Prompt for project name if not provided
12
+ let projectName = process.argv[2];
13
+ if (!projectName) {
14
+ const { newProjectName } = await inquirer.prompt([
15
+ {
16
+ type: "input",
17
+ name: "newProjectName",
18
+ message: "What is the name of your project?",
19
+ validate: (input) => /^([a-z0-9\-_])+$/.test(input) ||
20
+ "Project name may only include lowercase letters, numbers, underscores, and hyphens.",
21
+ },
22
+ ]);
23
+ projectName = newProjectName;
24
+ }
25
+ // Prompt for application type
26
+ const appTypes = [
27
+ {
28
+ name: "šŸ“± Webresource App",
29
+ value: "webresource",
30
+ description: "React app for Dynamics 365 webresources with Vite, Kendo UI, and Tailwind"
31
+ },
32
+ {
33
+ name: "🌐 Portal App",
34
+ value: "portal",
35
+ description: "Next.js app for customer portals with authentication and Dynamics integration"
36
+ },
37
+ {
38
+ name: "⚔ Power Pages App",
39
+ value: "powerpages",
40
+ description: "React SPA for Power Pages with specialized authentication and data services"
41
+ },
42
+ {
43
+ name: "šŸ“² Mobile App",
44
+ value: "mobile",
45
+ description: "React Native Expo app with NativeWind, TypeScript, and MSAL authentication"
46
+ }
47
+ ];
48
+ const { appType } = await inquirer.prompt([
49
+ {
50
+ type: "list",
51
+ name: "appType",
52
+ message: "What type of application would you like to create?",
53
+ choices: appTypes.map(type => ({
54
+ name: `${type.name}\n ${chalk.gray(type.description)}`,
55
+ value: type.value,
56
+ short: type.name.replace(/[šŸ“±šŸŒāš”šŸ“²]/g, '').trim()
57
+ })),
58
+ pageSize: 10
59
+ },
60
+ ]);
61
+ console.log(`\n${chalk.green("✨ Creating")} ${chalk.bold(appType)} app: ${chalk.cyan(projectName)}\n`);
62
+ // Route to the appropriate creator
63
+ switch (appType) {
64
+ case "webresource":
65
+ await createWebResourceApp(projectName);
66
+ break;
67
+ case "portal":
68
+ await createPortalApp(projectName);
69
+ break;
70
+ case "powerpages":
71
+ await createPowerPagesApp(projectName);
72
+ break;
73
+ case "mobile":
74
+ await createMobileApp(projectName);
75
+ break;
76
+ default:
77
+ console.error(chalk.red(`Unknown app type: ${appType}`));
78
+ process.exit(1);
79
+ }
80
+ // Final success message
81
+ console.log(chalk.green.bold("\nšŸŽ‰ Project created successfully!"));
82
+ console.log(`\n${chalk.cyan("Next steps:")}`);
83
+ console.log(` ${chalk.gray("›")} cd ${projectName}`);
84
+ if (appType === "webresource" || appType === "powerpages") {
85
+ console.log(` ${chalk.gray("›")} ${chalk.yellow("npx kendo-ui-license activate")} ${chalk.gray("(IMPORTANT: Activate your Kendo license)")}`);
86
+ }
87
+ console.log(` ${chalk.gray("›")} npm run dev`);
88
+ console.log(` ${chalk.gray("›")} npm run build\n`);
89
+ };
90
+ main().catch((error) => {
91
+ console.error(chalk.red("āŒ An error occurred:"), error);
92
+ process.exit(1);
93
+ });
94
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}