create-ec-app 1.8.0 → 1.9.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.
- package/README.md +72 -17
- package/dist/cssScope.js +3 -5
- package/dist/cssScope.js.map +1 -1
- package/dist/index.d.ts +46 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +129 -53
- package/dist/index.js.map +1 -1
- package/dist/libFunctions.d.ts +13 -6
- package/dist/libFunctions.d.ts.map +1 -1
- package/dist/libFunctions.js +24 -9
- package/dist/libFunctions.js.map +1 -1
- package/dist/pcf.d.ts.map +1 -1
- package/dist/pcf.js +4 -1
- package/dist/pcf.js.map +1 -1
- package/dist/portalContainers.js +7 -5
- package/dist/portalContainers.js.map +1 -1
- package/package.json +18 -11
- package/scripts/build-generated.mjs +59 -0
- package/scripts/refresh-shadcn-template.ts +406 -0
- package/scripts/smoke-scaffold.mjs +245 -0
- package/templates/base/eslint.config.js +1 -1
- package/templates/base/package-lock.json +380 -476
- package/templates/base/package.json +14 -19
- package/templates/pcf/base/package-lock.json +35 -53
- package/templates/targets/code-apps/AGENTS.md +1 -1
- package/templates/targets/code-apps/CLAUDE.md +1 -0
- package/templates/targets/code-apps/package.patch.json +1 -1
- package/templates/targets/power-pages/AGENTS.md +1 -1
- package/templates/targets/power-pages/CLAUDE.md +1 -0
- package/templates/targets/power-pages/README.md +22 -2
- package/templates/targets/power-pages/src/App.patch.tsx +3 -1
- package/templates/targets/power-pages/src/components/shared/AuthError.tsx +18 -0
- package/templates/targets/power-pages/src/context/AuthContext.tsx +0 -4
- package/templates/targets/swa/CLAUDE.md +1 -0
- package/templates/targets/webresource/AGENTS.md +5 -4
- package/templates/targets/webresource/CLAUDE.md +1 -0
- package/templates/targets/webresource/README.md +5 -5
- package/templates/ui/kendo/package.patch.json +2 -2
- package/templates/ui/shadcn-ui/SHADCN_TEMPLATE.md +20 -0
- package/templates/ui/shadcn-ui/package.patch.json +18 -9
- package/templates/ui/shadcn-ui/src/components/ui/accordion.tsx +79 -0
- package/templates/ui/shadcn-ui/src/components/ui/alert-dialog.tsx +199 -0
- package/templates/ui/shadcn-ui/src/components/ui/alert.tsx +76 -0
- package/templates/ui/shadcn-ui/src/components/ui/aspect-ratio.tsx +11 -0
- package/templates/ui/shadcn-ui/src/components/ui/attachment.tsx +206 -0
- package/templates/ui/shadcn-ui/src/components/ui/avatar.tsx +110 -0
- package/templates/ui/shadcn-ui/src/components/ui/badge.tsx +49 -0
- package/templates/ui/shadcn-ui/src/components/ui/breadcrumb.tsx +122 -0
- package/templates/ui/shadcn-ui/src/components/ui/bubble.tsx +125 -0
- package/templates/ui/shadcn-ui/src/components/ui/button-group.tsx +83 -0
- package/templates/ui/shadcn-ui/src/components/ui/button.tsx +67 -0
- package/templates/ui/shadcn-ui/src/components/ui/calendar.tsx +222 -0
- package/templates/ui/shadcn-ui/src/components/ui/card.tsx +103 -0
- package/templates/ui/shadcn-ui/src/components/ui/carousel.tsx +240 -0
- package/templates/ui/shadcn-ui/src/components/ui/chart.tsx +373 -0
- package/templates/ui/shadcn-ui/src/components/ui/checkbox.tsx +31 -0
- package/templates/ui/shadcn-ui/src/components/ui/collapsible.tsx +33 -0
- package/templates/ui/shadcn-ui/src/components/ui/combobox.tsx +299 -0
- package/templates/ui/shadcn-ui/src/components/ui/command.tsx +195 -0
- package/templates/ui/shadcn-ui/src/components/ui/context-menu.tsx +264 -0
- package/templates/ui/shadcn-ui/src/components/ui/dialog.tsx +170 -0
- package/templates/ui/shadcn-ui/src/components/ui/direction.tsx +22 -0
- package/templates/ui/shadcn-ui/src/components/ui/drawer.tsx +134 -0
- package/templates/ui/shadcn-ui/src/components/ui/dropdown-menu.tsx +272 -0
- package/templates/ui/shadcn-ui/src/components/ui/empty.tsx +104 -0
- package/templates/ui/shadcn-ui/src/components/ui/field.tsx +236 -0
- package/templates/ui/shadcn-ui/src/components/ui/hover-card.tsx +44 -0
- package/templates/ui/shadcn-ui/src/components/ui/input-group.tsx +156 -0
- package/templates/ui/shadcn-ui/src/components/ui/input-otp.tsx +87 -0
- package/templates/ui/shadcn-ui/src/components/ui/input.tsx +19 -0
- package/templates/ui/shadcn-ui/src/components/ui/item.tsx +196 -0
- package/templates/ui/shadcn-ui/src/components/ui/kbd.tsx +26 -0
- package/templates/ui/shadcn-ui/src/components/ui/label.tsx +22 -0
- package/templates/ui/shadcn-ui/src/components/ui/marker.tsx +69 -0
- package/templates/ui/shadcn-ui/src/components/ui/menubar.tsx +282 -0
- package/templates/ui/shadcn-ui/src/components/ui/message-scroller.tsx +129 -0
- package/templates/ui/shadcn-ui/src/components/ui/message.tsx +92 -0
- package/templates/ui/shadcn-ui/src/components/ui/native-select.tsx +61 -0
- package/templates/ui/shadcn-ui/src/components/ui/navigation-menu.tsx +164 -0
- package/templates/ui/shadcn-ui/src/components/ui/pagination.tsx +129 -0
- package/templates/ui/shadcn-ui/src/components/ui/popover.tsx +89 -0
- package/templates/ui/shadcn-ui/src/components/ui/progress.tsx +31 -0
- package/templates/ui/shadcn-ui/src/components/ui/radio-group.tsx +42 -0
- package/templates/ui/shadcn-ui/src/components/ui/resizable.tsx +50 -0
- package/templates/ui/shadcn-ui/src/components/ui/scroll-area.tsx +53 -0
- package/templates/ui/shadcn-ui/src/components/ui/select.tsx +194 -0
- package/templates/ui/shadcn-ui/src/components/ui/separator.tsx +26 -0
- package/templates/ui/shadcn-ui/src/components/ui/sheet.tsx +149 -0
- package/templates/ui/shadcn-ui/src/components/ui/sidebar.tsx +702 -0
- package/templates/ui/shadcn-ui/src/components/ui/skeleton.tsx +13 -0
- package/templates/ui/shadcn-ui/src/components/ui/slider.tsx +59 -0
- package/templates/ui/shadcn-ui/src/components/ui/sonner.tsx +47 -0
- package/templates/ui/shadcn-ui/src/components/ui/spinner.tsx +10 -0
- package/templates/ui/shadcn-ui/src/components/ui/switch.tsx +33 -0
- package/templates/ui/shadcn-ui/src/components/ui/table.tsx +114 -0
- package/templates/ui/shadcn-ui/src/components/ui/tabs.tsx +90 -0
- package/templates/ui/shadcn-ui/src/components/ui/textarea.tsx +18 -0
- package/templates/ui/shadcn-ui/src/components/ui/toggle-group.tsx +87 -0
- package/templates/ui/shadcn-ui/src/components/ui/toggle.tsx +45 -0
- package/templates/ui/shadcn-ui/src/components/ui/tooltip.tsx +59 -0
- package/templates/ui/shadcn-ui/src/index.patch.css +0 -118
- package/templates/ui/shadcn-ui/src/runtime/PortalContainer.ts +8 -0
- package/templates/base/biome.json +0 -54
|
@@ -8,36 +8,31 @@
|
|
|
8
8
|
"build": "tsc -b && vite build",
|
|
9
9
|
"build:dev": "tsc -b && vite build --mode development",
|
|
10
10
|
"lint": "eslint .",
|
|
11
|
-
"preview": "vite preview"
|
|
12
|
-
"format": "biome format --write .",
|
|
13
|
-
"lint:biome": "biome lint .",
|
|
14
|
-
"check": "biome check --write --no-errors-on-unmatched .",
|
|
15
|
-
"format:check": "biome format --check .",
|
|
16
|
-
"lint:fix": "biome lint --apply ."
|
|
11
|
+
"preview": "vite preview"
|
|
17
12
|
},
|
|
18
13
|
"dependencies": {
|
|
19
|
-
"@tailwindcss/vite": "^4.3.
|
|
20
|
-
"
|
|
21
|
-
"@tanstack/react-query": "^5.100.14",
|
|
14
|
+
"@tailwindcss/vite": "^4.3.1",
|
|
15
|
+
"@tanstack/react-query": "^5.101.2",
|
|
22
16
|
"@types/xrm": "^9.0.94",
|
|
23
17
|
"react": "^19.2.7",
|
|
24
18
|
"react-dom": "^19.2.7",
|
|
19
|
+
"tailwindcss": "^4.3.1",
|
|
25
20
|
"zod": "^4.4.3",
|
|
26
21
|
"zustand": "^5.0.14"
|
|
27
22
|
},
|
|
28
23
|
"devDependencies": {
|
|
29
24
|
"@eslint/js": "^10.0.1",
|
|
30
|
-
"@tanstack/eslint-plugin-query": "^5.
|
|
31
|
-
"@types/node": "^
|
|
32
|
-
"@types/react": "^19.2.
|
|
25
|
+
"@tanstack/eslint-plugin-query": "^5.101.2",
|
|
26
|
+
"@types/node": "^22.20.0",
|
|
27
|
+
"@types/react": "^19.2.17",
|
|
33
28
|
"@types/react-dom": "^19.2.3",
|
|
34
|
-
"@vitejs/plugin-react": "^6.0.
|
|
35
|
-
"eslint": "^10.
|
|
29
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
30
|
+
"eslint": "^10.6.0",
|
|
36
31
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
37
|
-
"eslint-plugin-react-refresh": "^0.5.
|
|
38
|
-
"globals": "^17.
|
|
39
|
-
"typescript": "
|
|
40
|
-
"typescript-eslint": "^8.
|
|
41
|
-
"vite": "^8.0
|
|
32
|
+
"eslint-plugin-react-refresh": "^0.5.3",
|
|
33
|
+
"globals": "^17.7.0",
|
|
34
|
+
"typescript": "^6.0.3",
|
|
35
|
+
"typescript-eslint": "^8.62.0",
|
|
36
|
+
"vite": "^8.1.0"
|
|
42
37
|
}
|
|
43
38
|
}
|
|
@@ -124,9 +124,9 @@
|
|
|
124
124
|
}
|
|
125
125
|
},
|
|
126
126
|
"node_modules/@azure/opentelemetry-instrumentation-azure-sdk/node_modules/@opentelemetry/core": {
|
|
127
|
-
"version": "2.
|
|
128
|
-
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.
|
|
129
|
-
"integrity": "sha512-
|
|
127
|
+
"version": "2.8.0",
|
|
128
|
+
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.8.0.tgz",
|
|
129
|
+
"integrity": "sha512-hd1Lfh8p545nNz+jq1Ejfz+Mn1hyLuxYn1YzTfFNrxr8urEWMNQLPf1Th8kjOH+HxwawCrtgBp8JpBUR4ZSgww==",
|
|
130
130
|
"dev": true,
|
|
131
131
|
"license": "Apache-2.0",
|
|
132
132
|
"dependencies": {
|
|
@@ -2277,14 +2277,14 @@
|
|
|
2277
2277
|
}
|
|
2278
2278
|
},
|
|
2279
2279
|
"node_modules/@opentelemetry/sdk-trace-web": {
|
|
2280
|
-
"version": "2.
|
|
2281
|
-
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-2.
|
|
2282
|
-
"integrity": "sha512-
|
|
2280
|
+
"version": "2.8.0",
|
|
2281
|
+
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-2.8.0.tgz",
|
|
2282
|
+
"integrity": "sha512-P3ZM8BGJ5mwjtyfAxRyxsCyWHvaj+xahdhLoS3YiPsEyTHcWTVzx2691C8SrGkpvro3tNFCsWuNNrvM+spKODg==",
|
|
2283
2283
|
"dev": true,
|
|
2284
2284
|
"license": "Apache-2.0",
|
|
2285
2285
|
"dependencies": {
|
|
2286
|
-
"@opentelemetry/core": "2.
|
|
2287
|
-
"@opentelemetry/sdk-trace-base": "2.
|
|
2286
|
+
"@opentelemetry/core": "2.8.0",
|
|
2287
|
+
"@opentelemetry/sdk-trace-base": "2.8.0"
|
|
2288
2288
|
},
|
|
2289
2289
|
"engines": {
|
|
2290
2290
|
"node": "^18.19.0 || >=20.6.0"
|
|
@@ -2294,9 +2294,9 @@
|
|
|
2294
2294
|
}
|
|
2295
2295
|
},
|
|
2296
2296
|
"node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/core": {
|
|
2297
|
-
"version": "2.
|
|
2298
|
-
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.
|
|
2299
|
-
"integrity": "sha512-
|
|
2297
|
+
"version": "2.8.0",
|
|
2298
|
+
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.8.0.tgz",
|
|
2299
|
+
"integrity": "sha512-hd1Lfh8p545nNz+jq1Ejfz+Mn1hyLuxYn1YzTfFNrxr8urEWMNQLPf1Th8kjOH+HxwawCrtgBp8JpBUR4ZSgww==",
|
|
2300
2300
|
"dev": true,
|
|
2301
2301
|
"license": "Apache-2.0",
|
|
2302
2302
|
"dependencies": {
|
|
@@ -2310,13 +2310,13 @@
|
|
|
2310
2310
|
}
|
|
2311
2311
|
},
|
|
2312
2312
|
"node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/resources": {
|
|
2313
|
-
"version": "2.
|
|
2314
|
-
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.
|
|
2315
|
-
"integrity": "sha512-
|
|
2313
|
+
"version": "2.8.0",
|
|
2314
|
+
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.8.0.tgz",
|
|
2315
|
+
"integrity": "sha512-qmXQ27ilDbUK/vGMqwL8D4/rhn76C+sherM4wTbjlfknR8Nvfc/hCxjRJPhkzZzUsPiNg16SA31NxMabwttRjg==",
|
|
2316
2316
|
"dev": true,
|
|
2317
2317
|
"license": "Apache-2.0",
|
|
2318
2318
|
"dependencies": {
|
|
2319
|
-
"@opentelemetry/core": "2.
|
|
2319
|
+
"@opentelemetry/core": "2.8.0",
|
|
2320
2320
|
"@opentelemetry/semantic-conventions": "^1.29.0"
|
|
2321
2321
|
},
|
|
2322
2322
|
"engines": {
|
|
@@ -2327,14 +2327,14 @@
|
|
|
2327
2327
|
}
|
|
2328
2328
|
},
|
|
2329
2329
|
"node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/sdk-trace-base": {
|
|
2330
|
-
"version": "2.
|
|
2331
|
-
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.
|
|
2332
|
-
"integrity": "sha512-
|
|
2330
|
+
"version": "2.8.0",
|
|
2331
|
+
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.8.0.tgz",
|
|
2332
|
+
"integrity": "sha512-mhU4jp+vW0mGbFRd+GeXHvmfA4aDqWjBjLC3pE5XMpLs0IE2ryYb019Ts2AQrOq67gaTF25D91+fgvEHDZEnuQ==",
|
|
2333
2333
|
"dev": true,
|
|
2334
2334
|
"license": "Apache-2.0",
|
|
2335
2335
|
"dependencies": {
|
|
2336
|
-
"@opentelemetry/core": "2.
|
|
2337
|
-
"@opentelemetry/resources": "2.
|
|
2336
|
+
"@opentelemetry/core": "2.8.0",
|
|
2337
|
+
"@opentelemetry/resources": "2.8.0",
|
|
2338
2338
|
"@opentelemetry/semantic-conventions": "^1.29.0"
|
|
2339
2339
|
},
|
|
2340
2340
|
"engines": {
|
|
@@ -2483,9 +2483,6 @@
|
|
|
2483
2483
|
"arm"
|
|
2484
2484
|
],
|
|
2485
2485
|
"dev": true,
|
|
2486
|
-
"libc": [
|
|
2487
|
-
"glibc"
|
|
2488
|
-
],
|
|
2489
2486
|
"license": "MIT",
|
|
2490
2487
|
"optional": true,
|
|
2491
2488
|
"os": [
|
|
@@ -2507,9 +2504,6 @@
|
|
|
2507
2504
|
"arm"
|
|
2508
2505
|
],
|
|
2509
2506
|
"dev": true,
|
|
2510
|
-
"libc": [
|
|
2511
|
-
"musl"
|
|
2512
|
-
],
|
|
2513
2507
|
"license": "MIT",
|
|
2514
2508
|
"optional": true,
|
|
2515
2509
|
"os": [
|
|
@@ -2531,9 +2525,6 @@
|
|
|
2531
2525
|
"arm64"
|
|
2532
2526
|
],
|
|
2533
2527
|
"dev": true,
|
|
2534
|
-
"libc": [
|
|
2535
|
-
"glibc"
|
|
2536
|
-
],
|
|
2537
2528
|
"license": "MIT",
|
|
2538
2529
|
"optional": true,
|
|
2539
2530
|
"os": [
|
|
@@ -2555,9 +2546,6 @@
|
|
|
2555
2546
|
"arm64"
|
|
2556
2547
|
],
|
|
2557
2548
|
"dev": true,
|
|
2558
|
-
"libc": [
|
|
2559
|
-
"musl"
|
|
2560
|
-
],
|
|
2561
2549
|
"license": "MIT",
|
|
2562
2550
|
"optional": true,
|
|
2563
2551
|
"os": [
|
|
@@ -2579,9 +2567,6 @@
|
|
|
2579
2567
|
"x64"
|
|
2580
2568
|
],
|
|
2581
2569
|
"dev": true,
|
|
2582
|
-
"libc": [
|
|
2583
|
-
"glibc"
|
|
2584
|
-
],
|
|
2585
2570
|
"license": "MIT",
|
|
2586
2571
|
"optional": true,
|
|
2587
2572
|
"os": [
|
|
@@ -2603,9 +2588,6 @@
|
|
|
2603
2588
|
"x64"
|
|
2604
2589
|
],
|
|
2605
2590
|
"dev": true,
|
|
2606
|
-
"libc": [
|
|
2607
|
-
"musl"
|
|
2608
|
-
],
|
|
2609
2591
|
"license": "MIT",
|
|
2610
2592
|
"optional": true,
|
|
2611
2593
|
"os": [
|
|
@@ -4094,9 +4076,9 @@
|
|
|
4094
4076
|
}
|
|
4095
4077
|
},
|
|
4096
4078
|
"node_modules/engine.io": {
|
|
4097
|
-
"version": "6.6.
|
|
4098
|
-
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.
|
|
4099
|
-
"integrity": "sha512-
|
|
4079
|
+
"version": "6.6.9",
|
|
4080
|
+
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.9.tgz",
|
|
4081
|
+
"integrity": "sha512-clKkw4C7nJ22mGgoVcCg6V/W/TxdNyIOTr89k2ONZu81qqkddPFDF0LXcbAwhzPD8DjkiRCjzuiO6Y+fkpD4vg==",
|
|
4100
4082
|
"dev": true,
|
|
4101
4083
|
"license": "MIT",
|
|
4102
4084
|
"dependencies": {
|
|
@@ -4109,23 +4091,23 @@
|
|
|
4109
4091
|
"cors": "~2.8.5",
|
|
4110
4092
|
"debug": "~4.4.1",
|
|
4111
4093
|
"engine.io-parser": "~5.2.1",
|
|
4112
|
-
"ws": "~8.
|
|
4094
|
+
"ws": "~8.21.0"
|
|
4113
4095
|
},
|
|
4114
4096
|
"engines": {
|
|
4115
4097
|
"node": ">=10.2.0"
|
|
4116
4098
|
}
|
|
4117
4099
|
},
|
|
4118
4100
|
"node_modules/engine.io-client": {
|
|
4119
|
-
"version": "6.6.
|
|
4120
|
-
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.
|
|
4121
|
-
"integrity": "sha512-
|
|
4101
|
+
"version": "6.6.6",
|
|
4102
|
+
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.6.tgz",
|
|
4103
|
+
"integrity": "sha512-iY6QdftLQ9pyiPoX082bpf/u1UewnOaJrtJIF9T0++QB34lZrj0uP+Q/bj8AlUsAxqhnkTV2BS8SBZSxOmoV5Q==",
|
|
4122
4104
|
"dev": true,
|
|
4123
4105
|
"license": "MIT",
|
|
4124
4106
|
"dependencies": {
|
|
4125
4107
|
"@socket.io/component-emitter": "~3.1.0",
|
|
4126
4108
|
"debug": "~4.4.1",
|
|
4127
4109
|
"engine.io-parser": "~5.2.1",
|
|
4128
|
-
"ws": "~8.
|
|
4110
|
+
"ws": "~8.21.0",
|
|
4129
4111
|
"xmlhttprequest-ssl": "~2.1.1"
|
|
4130
4112
|
}
|
|
4131
4113
|
},
|
|
@@ -6439,14 +6421,14 @@
|
|
|
6439
6421
|
}
|
|
6440
6422
|
},
|
|
6441
6423
|
"node_modules/socket.io-adapter": {
|
|
6442
|
-
"version": "2.5.
|
|
6443
|
-
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.
|
|
6444
|
-
"integrity": "sha512-
|
|
6424
|
+
"version": "2.5.8",
|
|
6425
|
+
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.8.tgz",
|
|
6426
|
+
"integrity": "sha512-6Oy52pbg+kvdCVvjcN+FnY7BvxZ7cIHNScbvztT/It5d0vbwoJoVZmF2gjJmnV0/4WlXRfG15zc45ySk9Ah8bw==",
|
|
6445
6427
|
"dev": true,
|
|
6446
6428
|
"license": "MIT",
|
|
6447
6429
|
"dependencies": {
|
|
6448
6430
|
"debug": "~4.4.1",
|
|
6449
|
-
"ws": "~8.
|
|
6431
|
+
"ws": "~8.21.0"
|
|
6450
6432
|
}
|
|
6451
6433
|
},
|
|
6452
6434
|
"node_modules/socket.io-client": {
|
|
@@ -7173,9 +7155,9 @@
|
|
|
7173
7155
|
}
|
|
7174
7156
|
},
|
|
7175
7157
|
"node_modules/ws": {
|
|
7176
|
-
"version": "8.
|
|
7177
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.
|
|
7178
|
-
"integrity": "sha512-
|
|
7158
|
+
"version": "8.21.0",
|
|
7159
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
|
|
7160
|
+
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
|
|
7179
7161
|
"dev": true,
|
|
7180
7162
|
"license": "MIT",
|
|
7181
7163
|
"engines": {
|
|
@@ -36,7 +36,7 @@ The app supports two modes.
|
|
|
36
36
|
- Run `npx power-apps init` before real push/data-source work.
|
|
37
37
|
- Treat `power.config.example.json` as documentation only; do not rename it to bypass initialization.
|
|
38
38
|
|
|
39
|
-
Do not mix this with webresource `
|
|
39
|
+
Do not mix this with webresource `AuthService.ts`, `token.json`, or Power Pages `AuthContext`.
|
|
40
40
|
|
|
41
41
|
## Critical Files
|
|
42
42
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -37,7 +37,7 @@ The app supports two modes.
|
|
|
37
37
|
- Use the existing `AuthContext` flow only where this template already requires it.
|
|
38
38
|
- Never commit client secrets, tenant-specific secrets, or real token values.
|
|
39
39
|
|
|
40
|
-
Do not mix Power Pages auth with webresource `
|
|
40
|
+
Do not mix Power Pages auth with webresource `AuthService.ts` or `token.json`.
|
|
41
41
|
|
|
42
42
|
## Critical Files
|
|
43
43
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -14,7 +14,7 @@ This is a Power Pages Single Page Application (SPA) built with React, Vite, and
|
|
|
14
14
|
|
|
15
15
|
## Auth and API Access
|
|
16
16
|
|
|
17
|
-
This SPA uses ADAL (Azure Active Directory Authentication Library) for authentication.
|
|
17
|
+
This SPA uses ADAL (Azure Active Directory Authentication Library) for authentication. ADAL is deprecated by Microsoft and should not be treated as a long-term ideal path, but this template keeps the existing ADAL implementation for Power Pages scenarios until a validated MSAL v2 migration is introduced.
|
|
18
18
|
|
|
19
19
|
### Authentication Setup
|
|
20
20
|
|
|
@@ -37,6 +37,26 @@ The `AuthContext` requires the following environment variables:
|
|
|
37
37
|
- After successful authentication, users are redirected back with tokens
|
|
38
38
|
- Tokens are automatically cached and reused for subsequent requests
|
|
39
39
|
- Call `logout()` to clear tokens and sign out the user
|
|
40
|
+
- Auth errors are exposed as `error` on `useAuth()` and can be cleared with `clearError()`
|
|
41
|
+
|
|
42
|
+
### Authentication Errors
|
|
43
|
+
|
|
44
|
+
The generated app includes `src/components/shared/AuthError.tsx` and renders it near the app root. Keep that pattern if you replace the root layout:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { AuthError } from "@/components/shared/AuthError";
|
|
48
|
+
|
|
49
|
+
function App() {
|
|
50
|
+
return (
|
|
51
|
+
<main>
|
|
52
|
+
<AuthError />
|
|
53
|
+
{/* app routes or page content */}
|
|
54
|
+
</main>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`AuthContext` does not throw automatically when authentication fails, so the app can display a local error and let the user dismiss it.
|
|
40
60
|
|
|
41
61
|
## Example Data Fetch Using TanStack Query and AuthContext
|
|
42
62
|
|
|
@@ -156,7 +176,7 @@ export const AuthButton = () => {
|
|
|
156
176
|
<Button>Click me</Button>;
|
|
157
177
|
```
|
|
158
178
|
|
|
159
|
-
- Shadcn/ui: Components are
|
|
179
|
+
- Shadcn/ui: Components are copied from the committed template snapshot and available under the `@/components` alias. Example:
|
|
160
180
|
|
|
161
181
|
```tsx
|
|
162
182
|
import { Button } from "@/components/ui/button";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useAuth } from "./context/AuthContext";
|
|
2
|
+
import { AuthError } from "./components/shared/AuthError";
|
|
2
3
|
|
|
3
4
|
function App() {
|
|
4
|
-
const { isAuthenticated
|
|
5
|
+
const { isAuthenticated } = useAuth();
|
|
5
6
|
|
|
6
7
|
return (
|
|
7
8
|
<div className="flex h-screen flex-col items-center justify-center gap-4">
|
|
9
|
+
<AuthError />
|
|
8
10
|
{isAuthenticated ? (
|
|
9
11
|
<div>You are logged in</div>
|
|
10
12
|
) : (
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useAuth } from "@/context/AuthContext";
|
|
2
|
+
|
|
3
|
+
export function AuthError() {
|
|
4
|
+
const { error, clearError } = useAuth();
|
|
5
|
+
|
|
6
|
+
if (!error) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<div role="alert" className="rounded border p-3">
|
|
12
|
+
<p>Authentication error: {error}</p>
|
|
13
|
+
<button type="button" onClick={clearError}>
|
|
14
|
+
Dismiss
|
|
15
|
+
</button>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -263,10 +263,6 @@ const AuthProviderContent = ({ children }: { children: ReactNode }) => {
|
|
|
263
263
|
getIdToken,
|
|
264
264
|
};
|
|
265
265
|
|
|
266
|
-
if (error) {
|
|
267
|
-
throw new Error(`Authentication error: ${error}`);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
266
|
return (
|
|
271
267
|
<AuthContext.Provider value={value}>{children}</AuthContext.Provider>
|
|
272
268
|
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -34,13 +34,13 @@ The app supports two modes.
|
|
|
34
34
|
- Never commit real token values.
|
|
35
35
|
- Never bundle `token.json` into deployment output.
|
|
36
36
|
|
|
37
|
-
Do not mix the two modes. Do not duplicate runtime detection. Reuse `
|
|
37
|
+
Do not mix the two modes. Do not duplicate runtime detection. Reuse `AuthService.ts`.
|
|
38
38
|
|
|
39
39
|
## Critical Files
|
|
40
40
|
|
|
41
41
|
| File | Rule |
|
|
42
42
|
|---|---|
|
|
43
|
-
| `src/services/
|
|
43
|
+
| `src/services/AuthService.ts` | Single source of truth for runtime detection, base URL, and auth headers. |
|
|
44
44
|
| `src/main.tsx` | Preserve bootstrap, providers, and global theme/style imports. |
|
|
45
45
|
| `vite.config.ts` | Preserve Dynamics-friendly output: `base: "./"`, predictable filenames, and `main.css`. |
|
|
46
46
|
| `index.html` | Treat as the Dynamics integration boundary. Preserve `ClientGlobalContext.js.aspx` where present. |
|
|
@@ -183,7 +183,7 @@ Do not run broad expensive checks unless the change touches shared infrastructur
|
|
|
183
183
|
```ts
|
|
184
184
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
185
185
|
|
|
186
|
-
import { getApiUrl, getAuthHeaders } from "@/services/
|
|
186
|
+
import { getApiUrl, getAuthHeaders } from "@/services/AuthService";
|
|
187
187
|
|
|
188
188
|
export interface Account {
|
|
189
189
|
accountid: string;
|
|
@@ -234,9 +234,10 @@ export const useUpdateAccount = () => {
|
|
|
234
234
|
});
|
|
235
235
|
};
|
|
236
236
|
```
|
|
237
|
+
|
|
237
238
|
## Figma MCP
|
|
238
239
|
When using the Figma MCP server, ensure that you are not just blindly copying the designs. Take note and always place a focus on the following:
|
|
239
240
|
|
|
240
241
|
- Ensure responsiveness on all screen sizes
|
|
241
242
|
- If there are icons as part of the design, use those, don't blindly look for Lucide-React equivalents.
|
|
242
|
-
- Use the exact colours in the design. Don't make up your own.
|
|
243
|
+
- Use the exact colours in the design. Don't make up your own.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -30,7 +30,7 @@ React + TypeScript template for Dynamics 365/Dataverse web resources. Generated
|
|
|
30
30
|
## Key Files
|
|
31
31
|
|
|
32
32
|
- `src/main.tsx`: Sets up React, Tailwind, and TanStack Query. If Kendo UI was selected, imports the chosen theme CSS (`<theme>/dist/all.css`).
|
|
33
|
-
- `src/services/
|
|
33
|
+
- `src/services/AuthService.ts`: Utilities to build API URLs and headers based on environment (inside Dynamics vs. local dev).
|
|
34
34
|
- `token.json`: Local development token store. Build is configured to treat this as external and not bundle it.
|
|
35
35
|
- `index.html`: Injects `ClientGlobalContext.js.aspx` for Dynamics runtime.
|
|
36
36
|
- `vite.config.ts`: Uses base `./`, disables code splitting, emits `main.css`, and places assets at the top of `dist`.
|
|
@@ -40,7 +40,7 @@ React + TypeScript template for Dynamics 365/Dataverse web resources. Generated
|
|
|
40
40
|
The app auto-detects whether it runs inside Dynamics 365 (uses `window.Xrm` and does not add an Authorization header) or locally (reads a bearer token from `token.json`).
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
// src/services/
|
|
43
|
+
// src/services/AuthService.ts
|
|
44
44
|
export const getApiUrl = (): string => {
|
|
45
45
|
if (window.parent && window.parent.Xrm) {
|
|
46
46
|
const clientUrl = window.Xrm.Utility.getGlobalContext().getClientUrl();
|
|
@@ -72,7 +72,7 @@ export const getAuthHeaders = async (): Promise<HeadersInit> => {
|
|
|
72
72
|
Example usage:
|
|
73
73
|
|
|
74
74
|
```ts
|
|
75
|
-
import { getApiUrl, getAuthHeaders } from "@/services/
|
|
75
|
+
import { getApiUrl, getAuthHeaders } from "@/services/AuthService";
|
|
76
76
|
|
|
77
77
|
const res = await fetch(`${getApiUrl()}/accounts?$top=10`, {
|
|
78
78
|
headers: await getAuthHeaders(),
|
|
@@ -139,7 +139,7 @@ The following example shows a minimal data service and hooks to fetch and update
|
|
|
139
139
|
Create `src/services/accounts.ts`:
|
|
140
140
|
|
|
141
141
|
```ts
|
|
142
|
-
import { getApiUrl, getAuthHeaders } from "@/services/
|
|
142
|
+
import { getApiUrl, getAuthHeaders } from "@/services/AuthService";
|
|
143
143
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
144
144
|
|
|
145
145
|
export interface Account {
|
|
@@ -232,7 +232,7 @@ export function AccountsList() {
|
|
|
232
232
|
<Button>Click me</Button>;
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
-
- Shadcn/ui: Components are
|
|
235
|
+
- Shadcn/ui: Components are copied from the committed template snapshot and available under the `@/components` alias. Example:
|
|
236
236
|
|
|
237
237
|
```tsx
|
|
238
238
|
import { Button } from "@/components/ui/button";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# shadcn Template Snapshot
|
|
2
|
+
|
|
3
|
+
This template contains committed shadcn component source.
|
|
4
|
+
|
|
5
|
+
Generated with:
|
|
6
|
+
|
|
7
|
+
- shadcn CLI: 4.12.0
|
|
8
|
+
- style: radix-nova
|
|
9
|
+
- base color: neutral
|
|
10
|
+
- Tailwind: v4
|
|
11
|
+
- generated by: `npm run refresh:shadcn-template`
|
|
12
|
+
|
|
13
|
+
Normal `create-ec-app` scaffolding does not run `npx shadcn`.
|
|
14
|
+
To refresh this snapshot, run:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm run refresh:shadcn-template
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
After refreshing, generate a test app and run a build before committing.
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dependencies": {
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
3
|
+
"@base-ui/react": "1.6.0",
|
|
4
|
+
"@shadcn/react": "0.1.0",
|
|
5
|
+
"class-variance-authority": "0.7.1",
|
|
6
|
+
"clsx": "2.1.1",
|
|
7
|
+
"cmdk": "1.1.1",
|
|
8
|
+
"date-fns": "4.4.0",
|
|
9
|
+
"embla-carousel-react": "8.6.0",
|
|
10
|
+
"input-otp": "1.4.2",
|
|
11
|
+
"lucide-react": "1.21.0",
|
|
12
|
+
"next-themes": "0.4.6",
|
|
13
|
+
"radix-ui": "1.6.0",
|
|
14
|
+
"react-day-picker": "10.0.1",
|
|
15
|
+
"react-resizable-panels": "4.12.0",
|
|
16
|
+
"recharts": "3.8.0",
|
|
17
|
+
"shadcn": "4.12.0",
|
|
18
|
+
"sonner": "2.0.7",
|
|
19
|
+
"tailwind-merge": "3.6.0",
|
|
20
|
+
"vaul": "1.1.2"
|
|
12
21
|
}
|
|
13
22
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Accordion as AccordionPrimitive } from "radix-ui"
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"
|
|
6
|
+
|
|
7
|
+
function Accordion({
|
|
8
|
+
className,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Root>) {
|
|
11
|
+
return (
|
|
12
|
+
<AccordionPrimitive.Root
|
|
13
|
+
data-slot="accordion"
|
|
14
|
+
className={cn("flex w-full flex-col", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function AccordionItem({
|
|
21
|
+
className,
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Item>) {
|
|
24
|
+
return (
|
|
25
|
+
<AccordionPrimitive.Item
|
|
26
|
+
data-slot="accordion-item"
|
|
27
|
+
className={cn("not-last:border-b", className)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function AccordionTrigger({
|
|
34
|
+
className,
|
|
35
|
+
children,
|
|
36
|
+
...props
|
|
37
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
|
|
38
|
+
return (
|
|
39
|
+
<AccordionPrimitive.Header className="flex">
|
|
40
|
+
<AccordionPrimitive.Trigger
|
|
41
|
+
data-slot="accordion-trigger"
|
|
42
|
+
className={cn(
|
|
43
|
+
"group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
|
|
44
|
+
className
|
|
45
|
+
)}
|
|
46
|
+
{...props}
|
|
47
|
+
>
|
|
48
|
+
{children}
|
|
49
|
+
<ChevronDownIcon data-slot="accordion-trigger-icon" className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden" />
|
|
50
|
+
<ChevronUpIcon data-slot="accordion-trigger-icon" className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline" />
|
|
51
|
+
</AccordionPrimitive.Trigger>
|
|
52
|
+
</AccordionPrimitive.Header>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function AccordionContent({
|
|
57
|
+
className,
|
|
58
|
+
children,
|
|
59
|
+
...props
|
|
60
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Content>) {
|
|
61
|
+
return (
|
|
62
|
+
<AccordionPrimitive.Content
|
|
63
|
+
data-slot="accordion-content"
|
|
64
|
+
className="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
|
|
65
|
+
{...props}
|
|
66
|
+
>
|
|
67
|
+
<div
|
|
68
|
+
className={cn(
|
|
69
|
+
"h-(--radix-accordion-content-height) pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
|
|
70
|
+
className
|
|
71
|
+
)}
|
|
72
|
+
>
|
|
73
|
+
{children}
|
|
74
|
+
</div>
|
|
75
|
+
</AccordionPrimitive.Content>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
|