@khester/create-dynamics-app 1.0.8 → 1.1.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 (107) hide show
  1. package/bin/create-dynamics-app.js +1 -1
  2. package/dist/index.js +140 -15
  3. package/dist/index.js.map +1 -1
  4. package/dist/utils/consultingHelpers.d.ts +13 -0
  5. package/dist/utils/consultingHelpers.d.ts.map +1 -0
  6. package/dist/utils/consultingHelpers.js +569 -0
  7. package/dist/utils/consultingHelpers.js.map +1 -0
  8. package/dist/utils/copyTemplate.d.ts.map +1 -1
  9. package/dist/utils/copyTemplate.js.map +1 -1
  10. package/dist/utils/initGit.d.ts.map +1 -1
  11. package/dist/utils/initGit.js.map +1 -1
  12. package/dist/utils/installDependencies.d.ts.map +1 -1
  13. package/dist/utils/installDependencies.js +3 -2
  14. package/dist/utils/installDependencies.js.map +1 -1
  15. package/dist/utils/updatePackageJson.d.ts +1 -1
  16. package/dist/utils/updatePackageJson.d.ts.map +1 -1
  17. package/dist/utils/updatePackageJson.js +11 -1
  18. package/dist/utils/updatePackageJson.js.map +1 -1
  19. package/package.json +1 -1
  20. package/templates/dynamics-365-starter/INTEGRATION_TEST_RESULTS.md +302 -0
  21. package/templates/dynamics-365-starter/PHASE_4_COMPLETION_SUMMARY.md +305 -0
  22. package/templates/dynamics-365-starter/README.md +566 -137
  23. package/templates/dynamics-365-starter/deployment/QUICKSTART-MAC.md +507 -0
  24. package/templates/dynamics-365-starter/deployment/QUICKSTART-WINDOWS.md +372 -0
  25. package/templates/dynamics-365-starter/deployment/README.md +484 -0
  26. package/templates/dynamics-365-starter/deployment/pipelines/README.md +375 -0
  27. package/templates/dynamics-365-starter/deployment/pipelines/azure-pipelines.yml +330 -0
  28. package/templates/dynamics-365-starter/deployment/pipelines/github-actions.yml +422 -0
  29. package/templates/dynamics-365-starter/deployment/pipelines/jenkins.groovy +636 -0
  30. package/templates/dynamics-365-starter/deployment/scripts/deploy.ps1 +417 -0
  31. package/templates/dynamics-365-starter/deployment/scripts/deploy.sh +582 -0
  32. package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.ps1 +486 -0
  33. package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.sh +567 -0
  34. package/templates/dynamics-365-starter/deployment/scripts/validate-setup.ps1 +703 -0
  35. package/templates/dynamics-365-starter/deployment/scripts/validate-setup.sh +671 -0
  36. package/templates/dynamics-365-starter/docs/ARCHITECTURE_OVERVIEW.md +506 -0
  37. package/templates/dynamics-365-starter/docs/BEST_PRACTICES.md +723 -0
  38. package/templates/dynamics-365-starter/docs/MIGRATION_GUIDE.md +447 -0
  39. package/templates/dynamics-365-starter/docs/team-standards/README.md +273 -0
  40. package/templates/dynamics-365-starter/docs/team-standards/client-onboarding.md +577 -0
  41. package/templates/dynamics-365-starter/docs/team-standards/code-review-checklist.md +359 -0
  42. package/templates/dynamics-365-starter/docs/team-standards/coding-standards.md +700 -0
  43. package/templates/dynamics-365-starter/docs/team-standards/cross-platform-team-guide.md +736 -0
  44. package/templates/dynamics-365-starter/docs/team-standards/development-workflows.md +727 -0
  45. package/templates/dynamics-365-starter/docs/troubleshooting/common-errors.md +758 -0
  46. package/templates/dynamics-365-starter/docs/troubleshooting/platform-specific-issues.md +878 -0
  47. package/templates/dynamics-365-starter/package.json +22 -1
  48. package/templates/dynamics-365-starter/public/index.html +8 -11
  49. package/templates/dynamics-365-starter/scripts/custom-build.js +255 -0
  50. package/templates/dynamics-365-starter/src/client-project-template/README.md +234 -0
  51. package/templates/dynamics-365-starter/src/client-project-template/config/client.template.json +114 -0
  52. package/templates/dynamics-365-starter/src/client-project-template/config/environments/template.json +186 -0
  53. package/templates/dynamics-365-starter/src/client-project-template/scripts/client-setup.js +667 -0
  54. package/templates/dynamics-365-starter/src/components/AccountForm.css +71 -0
  55. package/templates/dynamics-365-starter/src/components/AccountForm.tsx +541 -0
  56. package/templates/dynamics-365-starter/src/components/AccountManagement.css +86 -0
  57. package/templates/dynamics-365-starter/src/components/AccountManagement.tsx +370 -0
  58. package/templates/dynamics-365-starter/src/components/ContactForm.tsx +149 -63
  59. package/templates/dynamics-365-starter/src/components/ContactManagement.tsx +153 -63
  60. package/templates/dynamics-365-starter/src/components/Logging/LogDialog.tsx +291 -0
  61. package/templates/dynamics-365-starter/src/components/Logging/LoggingContext.tsx +166 -0
  62. package/templates/dynamics-365-starter/src/components/Logging/LoggingDebugPanel.css +192 -0
  63. package/templates/dynamics-365-starter/src/components/Logging/LoggingDebugPanel.tsx +177 -0
  64. package/templates/dynamics-365-starter/src/components/Logging/LoggingProvider.tsx +3 -0
  65. package/templates/dynamics-365-starter/src/components/Logging/logger.ts +193 -0
  66. package/templates/dynamics-365-starter/src/constants/account.ts +410 -0
  67. package/templates/dynamics-365-starter/src/constants/contact.ts +362 -0
  68. package/templates/dynamics-365-starter/src/examples/README.md +52 -0
  69. package/templates/dynamics-365-starter/src/examples/component-examples/opportunity-management.tsx +625 -0
  70. package/templates/dynamics-365-starter/src/examples/entity-examples/opportunity-model.ts +545 -0
  71. package/templates/dynamics-365-starter/src/examples/integration-examples/custom-pcf-wrapper.tsx +722 -0
  72. package/templates/dynamics-365-starter/src/examples/workflow-examples/sales-workflow.ts +662 -0
  73. package/templates/dynamics-365-starter/src/index.tsx +107 -19
  74. package/templates/dynamics-365-starter/src/models/Account.ts +480 -0
  75. package/templates/dynamics-365-starter/src/models/BaseEntity.ts +204 -0
  76. package/templates/dynamics-365-starter/src/models/Contact.ts +580 -0
  77. package/templates/dynamics-365-starter/src/page-templates/EntityDashboard.tsx +519 -0
  78. package/templates/dynamics-365-starter/src/page-templates/EntityDetailPage.tsx +456 -0
  79. package/templates/dynamics-365-starter/src/page-templates/EntityListPage.tsx +406 -0
  80. package/templates/dynamics-365-starter/src/page-templates/RelatedEntitiesPage.tsx +578 -0
  81. package/templates/dynamics-365-starter/src/page-templates/SearchPage.tsx +629 -0
  82. package/templates/dynamics-365-starter/src/pcf/ContactControlWrapper.tsx +75 -22
  83. package/templates/dynamics-365-starter/src/pcf/MultiEntityControlWrapper.tsx +205 -0
  84. package/templates/dynamics-365-starter/src/providers/DynamicsProvider.tsx +297 -80
  85. package/templates/dynamics-365-starter/src/services/MockApiService.ts +260 -0
  86. package/templates/dynamics-365-starter/src/services/ServiceFactory.ts +65 -0
  87. package/templates/dynamics-365-starter/src/services/XrmApiService.ts +213 -0
  88. package/templates/dynamics-365-starter/src/styles/index.css +74 -7
  89. package/templates/dynamics-365-starter/tools/entity-generator/index.js +168 -0
  90. package/templates/dynamics-365-starter/tools/entity-generator/templates/constants.template.ts +124 -0
  91. package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.css +283 -0
  92. package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.tsx +275 -0
  93. package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.css +204 -0
  94. package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.tsx +413 -0
  95. package/templates/dynamics-365-starter/tools/entity-generator/templates/model.template.ts +250 -0
  96. package/templates/dynamics-365-starter/tools/metadata-sync/d365-client.js +410 -0
  97. package/templates/dynamics-365-starter/tools/metadata-sync/index.js +512 -0
  98. package/templates/dynamics-365-starter/tools/metadata-sync/type-generator.js +675 -0
  99. package/templates/dynamics-365-starter/tsconfig.json +11 -8
  100. package/templates/dynamics-365-starter/webpack.config.js +8 -9
  101. package/templates/power-pages-starter/README.md +7 -1
  102. package/templates/power-pages-starter/public/index.html +8 -11
  103. package/templates/power-pages-starter/src/components/ContactForm.tsx +60 -41
  104. package/templates/power-pages-starter/src/index.tsx +3 -3
  105. package/templates/power-pages-starter/src/providers/PowerPagesProvider.tsx +46 -23
  106. package/templates/power-pages-starter/tsconfig.json +3 -9
  107. package/templates/power-pages-starter/webpack.config.js +8 -3
@@ -0,0 +1,703 @@
1
+ # Developer Environment Validation Script (PowerShell)
2
+ # Cross-platform validation for Dynamics 365 development setup
3
+
4
+ param(
5
+ [switch]$Quiet,
6
+ [switch]$Verbose,
7
+ [switch]$Help
8
+ )
9
+
10
+ # Set error action preference
11
+ $ErrorActionPreference = "Continue"
12
+
13
+ # Script configuration
14
+ $ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
15
+ $ProjectRoot = Split-Path -Parent (Split-Path -Parent $ScriptRoot)
16
+
17
+ # Validation results
18
+ $ValidationPassed = $true
19
+ $Errors = @()
20
+ $Warnings = @()
21
+
22
+ function Show-Banner {
23
+ Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
24
+ Write-Host "║ Developer Environment Validation Tool ║" -ForegroundColor Cyan
25
+ Write-Host "║ Cross-Platform Compatibility Check ║" -ForegroundColor Cyan
26
+ Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
27
+ Write-Host ""
28
+ }
29
+
30
+ function Write-Info {
31
+ param([string]$Message)
32
+ if (-not $Quiet) {
33
+ Write-Host "ℹ️ $Message" -ForegroundColor Blue
34
+ }
35
+ }
36
+
37
+ function Write-Success {
38
+ param([string]$Message)
39
+ Write-Host "✅ $Message" -ForegroundColor Green
40
+ }
41
+
42
+ function Write-Warning {
43
+ param([string]$Message)
44
+ Write-Host "⚠️ $Message" -ForegroundColor Yellow
45
+ $script:Warnings += $Message
46
+ }
47
+
48
+ function Write-Error {
49
+ param([string]$Message)
50
+ Write-Host "❌ $Message" -ForegroundColor Red
51
+ $script:Errors += $Message
52
+ $script:ValidationPassed = $false
53
+ }
54
+
55
+ function Get-PlatformInfo {
56
+ return @{
57
+ Platform = "Windows"
58
+ Architecture = $env:PROCESSOR_ARCHITECTURE
59
+ Version = [System.Environment]::OSVersion.Version.ToString()
60
+ PowerShellVersion = $PSVersionTable.PSVersion.ToString()
61
+ }
62
+ }
63
+
64
+ function Test-Command {
65
+ param(
66
+ [string]$Command,
67
+ [bool]$Required,
68
+ [string]$MinVersion = ""
69
+ )
70
+
71
+ try {
72
+ $version = & $Command --version 2>$null | Select-Object -First 1
73
+ Write-Success "$Command is installed - $version"
74
+
75
+ # Version checking for critical tools
76
+ if ($Command -eq "node" -and $MinVersion) {
77
+ $currentVersion = (& node --version) -replace 'v', ''
78
+ if ([Version]$currentVersion -lt [Version]$MinVersion) {
79
+ Write-Warning "$Command version $currentVersion is below recommended $MinVersion"
80
+ }
81
+ }
82
+
83
+ return $true
84
+ }
85
+ catch {
86
+ if ($Required) {
87
+ Write-Error "$Command is required but not installed"
88
+ }
89
+ else {
90
+ Write-Warning "$Command is not installed (optional)"
91
+ }
92
+ return $false
93
+ }
94
+ }
95
+
96
+ function Test-Prerequisites {
97
+ Write-Info "Checking prerequisites for Windows platform..."
98
+ Write-Host ""
99
+
100
+ # Core development tools
101
+ Test-Command -Command "node" -Required $true -MinVersion "18.0.0"
102
+ Test-Command -Command "npm" -Required $true
103
+ Test-Command -Command "git" -Required $true
104
+
105
+ # Windows-specific tools
106
+ Test-Command -Command "jq" -Required $false
107
+ Test-Command -Command "curl" -Required $false
108
+
109
+ # PowerShell modules
110
+ $requiredModules = @(
111
+ "Microsoft.PowerApps.Administration.PowerShell",
112
+ "Microsoft.PowerApps.PowerShell"
113
+ )
114
+
115
+ foreach ($module in $requiredModules) {
116
+ if (Get-Module -Name $module -ListAvailable -ErrorAction SilentlyContinue) {
117
+ Write-Success "$module is installed"
118
+ }
119
+ else {
120
+ Write-Warning "$module is not installed (run as Administrator: Install-Module -Name $module)"
121
+ }
122
+ }
123
+
124
+ # PowerShell version check
125
+ if ($PSVersionTable.PSVersion.Major -ge 7) {
126
+ Write-Success "PowerShell Core 7+ detected (recommended)"
127
+ }
128
+ elseif ($PSVersionTable.PSVersion.Major -ge 5) {
129
+ Write-Success "Windows PowerShell 5+ detected (compatible)"
130
+ }
131
+ else {
132
+ Write-Warning "PowerShell version may be too old (recommended: 5.1+ or 7+)"
133
+ }
134
+
135
+ # Optional development tools
136
+ Test-Command -Command "code" -Required $false
137
+ Test-Command -Command "docker" -Required $false
138
+
139
+ Write-Host ""
140
+ }
141
+
142
+ function Test-ProjectStructure {
143
+ Write-Info "Validating project structure..."
144
+ Write-Host ""
145
+
146
+ # Core project files
147
+ $requiredFiles = @(
148
+ "package.json",
149
+ "tsconfig.json",
150
+ "src\index.tsx",
151
+ "deployment\README.md"
152
+ )
153
+
154
+ foreach ($file in $requiredFiles) {
155
+ $filePath = Join-Path $ProjectRoot $file
156
+ if (Test-Path $filePath) {
157
+ Write-Success "Found required file: $file"
158
+ }
159
+ else {
160
+ Write-Error "Missing required file: $file"
161
+ }
162
+ }
163
+
164
+ # Deployment scripts
165
+ $scriptTypes = @("ps1", "sh")
166
+ foreach ($scriptType in $scriptTypes) {
167
+ $scriptPath = Join-Path $ProjectRoot "deployment\scripts"
168
+ $scriptCount = (Get-ChildItem -Path $scriptPath -Filter "*.$scriptType" -ErrorAction SilentlyContinue).Count
169
+
170
+ if ($scriptCount -gt 0) {
171
+ Write-Success "Found $scriptCount .$scriptType deployment scripts"
172
+ }
173
+ else {
174
+ Write-Warning "No .$scriptType deployment scripts found"
175
+ }
176
+ }
177
+
178
+ # Configuration directories
179
+ $configDirs = @(
180
+ "config\environments",
181
+ "deployment\scripts",
182
+ "src\models",
183
+ "src\services"
184
+ )
185
+
186
+ foreach ($dir in $configDirs) {
187
+ $dirPath = Join-Path $ProjectRoot $dir
188
+ if (Test-Path $dirPath -PathType Container) {
189
+ Write-Success "Found directory: $dir"
190
+ }
191
+ else {
192
+ Write-Error "Missing directory: $dir"
193
+ }
194
+ }
195
+
196
+ Write-Host ""
197
+ }
198
+
199
+ function Test-Dependencies {
200
+ Write-Info "Validating npm dependencies..."
201
+ Write-Host ""
202
+
203
+ $packageJsonPath = Join-Path $ProjectRoot "package.json"
204
+ if (-not (Test-Path $packageJsonPath)) {
205
+ Write-Error "package.json not found"
206
+ return
207
+ }
208
+
209
+ # Check if node_modules exists
210
+ $nodeModulesPath = Join-Path $ProjectRoot "node_modules"
211
+ if (Test-Path $nodeModulesPath -PathType Container) {
212
+ Write-Success "node_modules directory exists"
213
+
214
+ # Check package-lock.json
215
+ $packageLockPath = Join-Path $ProjectRoot "package-lock.json"
216
+ if (Test-Path $packageLockPath) {
217
+ Write-Success "package-lock.json exists (good for reproducible builds)"
218
+ }
219
+ else {
220
+ Write-Warning "package-lock.json missing (consider running 'npm install')"
221
+ }
222
+
223
+ # Validate key dependencies
224
+ $keyDeps = @("react", "typescript", "@types\react")
225
+ foreach ($dep in $keyDeps) {
226
+ $depPath = Join-Path $nodeModulesPath $dep
227
+ if (Test-Path $depPath -PathType Container) {
228
+ Write-Success "Dependency installed: $dep"
229
+ }
230
+ else {
231
+ Write-Warning "Dependency missing: $dep"
232
+ }
233
+ }
234
+ }
235
+ else {
236
+ Write-Error "node_modules directory missing - run 'npm install'"
237
+ }
238
+
239
+ # Check for outdated packages
240
+ try {
241
+ $outdatedOutput = npm outdated --silent 2>$null
242
+ if ($outdatedOutput) {
243
+ Write-Warning "Some packages are outdated - consider running 'npm update'"
244
+ }
245
+ else {
246
+ Write-Success "All packages are up to date"
247
+ }
248
+ }
249
+ catch {
250
+ # Ignore errors from npm outdated
251
+ }
252
+
253
+ Write-Host ""
254
+ }
255
+
256
+ function Test-Configuration {
257
+ Write-Info "Validating environment configuration..."
258
+ Write-Host ""
259
+
260
+ $configDir = Join-Path $ProjectRoot "config\environments"
261
+
262
+ if (-not (Test-Path $configDir -PathType Container)) {
263
+ Write-Error "Configuration directory missing: config\environments"
264
+ return
265
+ }
266
+
267
+ # Check for template file
268
+ $templatePath = Join-Path $configDir "template.json"
269
+ if (Test-Path $templatePath) {
270
+ Write-Success "Template configuration file exists"
271
+ }
272
+ else {
273
+ Write-Warning "Template configuration file missing"
274
+ }
275
+
276
+ # Check for environment-specific files
277
+ $envFiles = Get-ChildItem -Path $configDir -Filter "*.json" | Where-Object { $_.Name -ne "template.json" }
278
+ if ($envFiles.Count -gt 0) {
279
+ Write-Success "Found $($envFiles.Count) environment configuration files"
280
+
281
+ # List environment files
282
+ foreach ($envFile in $envFiles) {
283
+ $envName = $envFile.BaseName
284
+ Write-Info " Environment: $envName"
285
+ }
286
+ }
287
+ else {
288
+ Write-Warning "No environment-specific configuration files found"
289
+ Write-Info "Create environment configs from template.json"
290
+ }
291
+
292
+ # Check .env files
293
+ $envLocalPath = Join-Path $ProjectRoot ".env.local"
294
+ if (Test-Path $envLocalPath) {
295
+ Write-Success "Local environment file (.env.local) exists"
296
+ }
297
+ else {
298
+ Write-Warning "Local environment file (.env.local) missing"
299
+ Write-Info "Create .env.local for personal configuration"
300
+ }
301
+
302
+ $envPath = Join-Path $ProjectRoot ".env"
303
+ if (Test-Path $envPath) {
304
+ Write-Warning "Found .env file - ensure it doesn't contain secrets"
305
+ }
306
+
307
+ Write-Host ""
308
+ }
309
+
310
+ function Test-BuildSystem {
311
+ Write-Info "Validating build system..."
312
+ Write-Host ""
313
+
314
+ # Check TypeScript configuration
315
+ $tsconfigPath = Join-Path $ProjectRoot "tsconfig.json"
316
+ if (Test-Path $tsconfigPath) {
317
+ Write-Success "TypeScript configuration exists"
318
+
319
+ # Validate TypeScript can compile
320
+ try {
321
+ $null = npx tsc --noEmit --skipLibCheck 2>$null
322
+ Write-Success "TypeScript compilation check passed"
323
+ }
324
+ catch {
325
+ Write-Warning "TypeScript compilation issues detected"
326
+ }
327
+ }
328
+ else {
329
+ Write-Error "TypeScript configuration missing (tsconfig.json)"
330
+ }
331
+
332
+ # Check package.json scripts
333
+ $packageJsonPath = Join-Path $ProjectRoot "package.json"
334
+ if (Test-Path $packageJsonPath) {
335
+ $packageJson = Get-Content $packageJsonPath | ConvertFrom-Json
336
+ $requiredScripts = @("build", "build:prod", "lint", "typecheck")
337
+
338
+ foreach ($script in $requiredScripts) {
339
+ if ($packageJson.scripts.$script) {
340
+ Write-Success "npm script exists: $script"
341
+ }
342
+ else {
343
+ Write-Warning "npm script missing: $script"
344
+ }
345
+ }
346
+ }
347
+
348
+ # Check if project builds
349
+ Write-Info "Testing build process..."
350
+ Push-Location $ProjectRoot
351
+ try {
352
+ $null = npm run build:dev 2>$null
353
+ Write-Success "Development build successful"
354
+ }
355
+ catch {
356
+ Write-Warning "Development build failed - check 'npm run build:dev'"
357
+ }
358
+ finally {
359
+ Pop-Location
360
+ }
361
+
362
+ Write-Host ""
363
+ }
364
+
365
+ function Test-DeploymentSetup {
366
+ Write-Info "Validating deployment setup..."
367
+ Write-Host ""
368
+
369
+ $deploymentDir = Join-Path $ProjectRoot "deployment"
370
+
371
+ if (-not (Test-Path $deploymentDir -PathType Container)) {
372
+ Write-Error "Deployment directory missing"
373
+ return
374
+ }
375
+
376
+ # Check deployment scripts
377
+ $scriptDir = Join-Path $deploymentDir "scripts"
378
+ if (Test-Path $scriptDir -PathType Container) {
379
+ Write-Success "Deployment scripts directory exists"
380
+
381
+ # Check for required scripts
382
+ $requiredScripts = @("deploy", "health-check", "team-onboarding")
383
+ foreach ($script in $requiredScripts) {
384
+ $psScript = Join-Path $scriptDir "$script.ps1"
385
+ $bashScript = Join-Path $scriptDir "$script.sh"
386
+
387
+ if ((Test-Path $psScript) -or (Test-Path $bashScript)) {
388
+ Write-Success "Required script exists: $script"
389
+ }
390
+ else {
391
+ Write-Warning "Required script missing: $script"
392
+ }
393
+ }
394
+ }
395
+ else {
396
+ Write-Error "Deployment scripts directory missing"
397
+ }
398
+
399
+ # Check deployment configuration
400
+ $readmePath = Join-Path $deploymentDir "README.md"
401
+ if (Test-Path $readmePath) {
402
+ Write-Success "Deployment documentation exists"
403
+ }
404
+ else {
405
+ Write-Warning "Deployment documentation missing"
406
+ }
407
+
408
+ Write-Host ""
409
+ }
410
+
411
+ function Test-DevelopmentTools {
412
+ Write-Info "Validating development tools and IDE setup..."
413
+ Write-Host ""
414
+
415
+ # Check VS Code extensions (if VS Code is available)
416
+ if (Get-Command code -ErrorAction SilentlyContinue) {
417
+ Write-Success "VS Code is available"
418
+
419
+ # Check for workspace configuration
420
+ $vscodeSettingsPath = Join-Path $ProjectRoot ".vscode\settings.json"
421
+ if (Test-Path $vscodeSettingsPath) {
422
+ Write-Success "VS Code workspace settings exist"
423
+ }
424
+ else {
425
+ Write-Warning "VS Code workspace settings missing"
426
+ }
427
+
428
+ $vscodeExtensionsPath = Join-Path $ProjectRoot ".vscode\extensions.json"
429
+ if (Test-Path $vscodeExtensionsPath) {
430
+ Write-Success "VS Code extension recommendations exist"
431
+ }
432
+ else {
433
+ Write-Warning "VS Code extension recommendations missing"
434
+ }
435
+ }
436
+
437
+ # Check Git configuration
438
+ if (Get-Command git -ErrorAction SilentlyContinue) {
439
+ try {
440
+ $userName = git config --get user.name 2>$null
441
+ $userEmail = git config --get user.email 2>$null
442
+
443
+ if ($userName -and $userEmail) {
444
+ Write-Success "Git user configuration exists"
445
+ }
446
+ else {
447
+ Write-Warning "Git user configuration incomplete"
448
+ }
449
+ }
450
+ catch {
451
+ Write-Warning "Could not check Git configuration"
452
+ }
453
+
454
+ # Check for Git hooks
455
+ $hooksDir = Join-Path $ProjectRoot ".git\hooks"
456
+ if (Test-Path $hooksDir -PathType Container) {
457
+ $hookFiles = Get-ChildItem -Path $hooksDir -File | Where-Object { -not $_.Name.EndsWith(".sample") }
458
+ if ($hookFiles.Count -gt 0) {
459
+ Write-Success "Git hooks are configured"
460
+ }
461
+ else {
462
+ Write-Info "No custom Git hooks found"
463
+ }
464
+ }
465
+ }
466
+
467
+ Write-Host ""
468
+ }
469
+
470
+ function Test-TeamCompatibility {
471
+ Write-Info "Validating cross-platform team compatibility..."
472
+ Write-Host ""
473
+
474
+ # Check for platform-specific quick start guides
475
+ $guidesDir = Join-Path $ProjectRoot "deployment"
476
+ $windowsGuide = Join-Path $guidesDir "QUICKSTART-WINDOWS.md"
477
+ $macGuide = Join-Path $guidesDir "QUICKSTART-MAC.md"
478
+
479
+ if (Test-Path $windowsGuide) {
480
+ Write-Success "Windows quick start guide exists"
481
+ }
482
+ else {
483
+ Write-Warning "Windows quick start guide missing"
484
+ }
485
+
486
+ if (Test-Path $macGuide) {
487
+ Write-Success "Mac quick start guide exists"
488
+ }
489
+ else {
490
+ Write-Warning "Mac quick start guide missing"
491
+ }
492
+
493
+ # Check for dual-platform scripts
494
+ $scriptsDir = Join-Path $ProjectRoot "deployment\scripts"
495
+ $scriptPairs = @(
496
+ @("deploy.sh", "deploy.ps1"),
497
+ @("health-check.sh", "health-check.ps1"),
498
+ @("team-onboarding.sh", "team-onboarding.ps1")
499
+ )
500
+
501
+ foreach ($pair in $scriptPairs) {
502
+ $bashScript = Join-Path $scriptsDir $pair[0]
503
+ $psScript = Join-Path $scriptsDir $pair[1]
504
+
505
+ $hasBash = Test-Path $bashScript
506
+ $hasPs = Test-Path $psScript
507
+
508
+ if ($hasBash -and $hasPs) {
509
+ Write-Success "Cross-platform scripts available: $($pair[0] -replace '\.sh$', '')"
510
+ }
511
+ elseif ($hasBash -or $hasPs) {
512
+ Write-Warning "Only one platform script available: $($pair[0] -replace '\.sh$', '')"
513
+ }
514
+ else {
515
+ Write-Warning "No platform scripts found: $($pair[0] -replace '\.sh$', '')"
516
+ }
517
+ }
518
+
519
+ # Check for shared configuration compatibility
520
+ $configFiles = Get-ChildItem -Path (Join-Path $ProjectRoot "config") -Filter "*.json" -Recurse -ErrorAction SilentlyContinue
521
+ if ($configFiles.Count -gt 0) {
522
+ Write-Success "JSON configuration files are cross-platform compatible"
523
+ }
524
+ else {
525
+ Write-Warning "No JSON configuration files found"
526
+ }
527
+
528
+ Write-Host ""
529
+ }
530
+
531
+ function Test-QualityChecks {
532
+ Write-Info "Running code quality checks..."
533
+ Write-Host ""
534
+
535
+ $packageJsonPath = Join-Path $ProjectRoot "package.json"
536
+ if (-not (Test-Path $packageJsonPath)) {
537
+ Write-Warning "package.json not found - skipping quality checks"
538
+ return
539
+ }
540
+
541
+ Push-Location $ProjectRoot
542
+ try {
543
+ # Run linting
544
+ try {
545
+ $null = npm run lint 2>$null
546
+ Write-Success "Linting passed"
547
+ }
548
+ catch {
549
+ Write-Warning "Linting issues detected - run 'npm run lint' to see details"
550
+ }
551
+
552
+ # Run type checking
553
+ try {
554
+ $null = npm run typecheck 2>$null
555
+ Write-Success "Type checking passed"
556
+ }
557
+ catch {
558
+ Write-Warning "Type checking issues detected - run 'npm run typecheck' to see details"
559
+ }
560
+
561
+ # Run tests if available
562
+ $packageJson = Get-Content $packageJsonPath | ConvertFrom-Json
563
+ if ($packageJson.scripts.test) {
564
+ try {
565
+ $null = npm test 2>$null
566
+ Write-Success "Tests passed"
567
+ }
568
+ catch {
569
+ Write-Warning "Tests failed - run 'npm test' to see details"
570
+ }
571
+ }
572
+ else {
573
+ Write-Info "No test script configured"
574
+ }
575
+ }
576
+ finally {
577
+ Pop-Location
578
+ }
579
+
580
+ Write-Host ""
581
+ }
582
+
583
+ function Show-Report {
584
+ Write-Host ""
585
+ Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
586
+ Write-Host "║ VALIDATION REPORT ║" -ForegroundColor Cyan
587
+ Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
588
+ Write-Host ""
589
+
590
+ # Summary
591
+ if ($ValidationPassed) {
592
+ Write-Host "🎉 VALIDATION PASSED" -ForegroundColor Green
593
+ Write-Host "Your development environment is properly configured!"
594
+ }
595
+ else {
596
+ Write-Host "❌ VALIDATION FAILED" -ForegroundColor Red
597
+ Write-Host "Please address the errors below before proceeding."
598
+ }
599
+
600
+ Write-Host ""
601
+
602
+ # Error summary
603
+ if ($Errors.Count -gt 0) {
604
+ Write-Host "🚨 ERRORS ($($Errors.Count)):" -ForegroundColor Red
605
+ foreach ($error in $Errors) {
606
+ Write-Host " • $error"
607
+ }
608
+ Write-Host ""
609
+ }
610
+
611
+ # Warning summary
612
+ if ($Warnings.Count -gt 0) {
613
+ Write-Host "⚠️ WARNINGS ($($Warnings.Count)):" -ForegroundColor Yellow
614
+ foreach ($warning in $Warnings) {
615
+ Write-Host " • $warning"
616
+ }
617
+ Write-Host ""
618
+ }
619
+
620
+ # Platform information
621
+ $platformInfo = Get-PlatformInfo
622
+ Write-Host "📋 PLATFORM INFORMATION:" -ForegroundColor Blue
623
+ Write-Host " Platform: $($platformInfo.Platform)"
624
+ Write-Host " Architecture: $($platformInfo.Architecture)"
625
+ Write-Host " PowerShell: $($platformInfo.PowerShellVersion)"
626
+ Write-Host " Scripts: PowerShell (.ps1)"
627
+ Write-Host ""
628
+
629
+ # Next steps
630
+ Write-Host "🚀 NEXT STEPS:" -ForegroundColor Cyan
631
+ if ($ValidationPassed) {
632
+ Write-Host " 1. Run team onboarding script for your platform"
633
+ Write-Host " 2. Configure your first environment"
634
+ Write-Host " 3. Test deployment to development environment"
635
+ Write-Host " 4. Generate your first entity"
636
+ }
637
+ else {
638
+ Write-Host " 1. Fix all errors listed above"
639
+ Write-Host " 2. Address any warnings that apply to your workflow"
640
+ Write-Host " 3. Re-run this validation script"
641
+ Write-Host " 4. Proceed with team onboarding when validation passes"
642
+ }
643
+
644
+ Write-Host ""
645
+ Write-Host "📚 HELPFUL COMMANDS:" -ForegroundColor Magenta
646
+ Write-Host " Team Onboarding: .\deployment\scripts\team-onboarding.ps1"
647
+ Write-Host " Quick Start: start deployment\QUICKSTART-WINDOWS.md"
648
+ Write-Host " Deploy Dev: .\deployment\scripts\deploy.ps1 -Environment dev"
649
+ Write-Host ""
650
+ }
651
+
652
+ function Show-Help {
653
+ Write-Host "Developer Environment Validation Tool (PowerShell)"
654
+ Write-Host "Usage: .\validate-setup.ps1 [options]"
655
+ Write-Host ""
656
+ Write-Host "Options:"
657
+ Write-Host " -Help Show this help message"
658
+ Write-Host " -Quiet Suppress informational output"
659
+ Write-Host " -Verbose Enable verbose output"
660
+ Write-Host ""
661
+ Write-Host "This script validates your development environment setup"
662
+ Write-Host "for cross-platform Dynamics 365 development."
663
+ }
664
+
665
+ # Main execution
666
+ function Main {
667
+ if ($Help) {
668
+ Show-Help
669
+ return
670
+ }
671
+
672
+ Show-Banner
673
+
674
+ $platformInfo = Get-PlatformInfo
675
+ Write-Host "Platform: $($platformInfo.Platform) ($($platformInfo.Architecture))" -ForegroundColor Blue
676
+ Write-Host "Project: $(Split-Path -Leaf $ProjectRoot)" -ForegroundColor Blue
677
+ Write-Host ""
678
+
679
+ # Run all validation checks
680
+ Test-Prerequisites
681
+ Test-ProjectStructure
682
+ Test-Dependencies
683
+ Test-Configuration
684
+ Test-BuildSystem
685
+ Test-DeploymentSetup
686
+ Test-DevelopmentTools
687
+ Test-TeamCompatibility
688
+ Test-QualityChecks
689
+
690
+ # Generate final report
691
+ Show-Report
692
+
693
+ # Exit with appropriate code
694
+ if ($ValidationPassed) {
695
+ exit 0
696
+ }
697
+ else {
698
+ exit 1
699
+ }
700
+ }
701
+
702
+ # Run main function
703
+ Main