@khester/create-dynamics-app 1.1.0 → 2.0.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 +46 -0
- package/dist/artifacts/registry.d.ts +18 -0
- package/dist/artifacts/registry.d.ts.map +1 -0
- package/dist/artifacts/registry.js +316 -0
- package/dist/artifacts/registry.js.map +1 -0
- package/dist/artifacts/types.d.ts +113 -0
- package/dist/artifacts/types.d.ts.map +1 -0
- package/dist/artifacts/types.js +7 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/artifacts/validators.d.ts +16 -0
- package/dist/artifacts/validators.d.ts.map +1 -0
- package/dist/artifacts/validators.js +45 -0
- package/dist/artifacts/validators.js.map +1 -0
- package/dist/fromDesign.d.ts +5 -0
- package/dist/fromDesign.d.ts.map +1 -0
- package/dist/fromDesign.js +98 -0
- package/dist/fromDesign.js.map +1 -0
- package/dist/index.js +113 -177
- package/dist/index.js.map +1 -1
- package/dist/injectDevTools.d.ts +28 -0
- package/dist/injectDevTools.d.ts.map +1 -0
- package/dist/injectDevTools.js +148 -0
- package/dist/injectDevTools.js.map +1 -0
- package/dist/scaffold.d.ts +27 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +156 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/templatePlan.d.ts +3 -0
- package/dist/templatePlan.d.ts.map +1 -0
- package/dist/templatePlan.js +43 -0
- package/dist/templatePlan.js.map +1 -0
- package/dist/utils/copyTemplate.d.ts +13 -1
- package/dist/utils/copyTemplate.d.ts.map +1 -1
- package/dist/utils/copyTemplate.js +98 -4
- package/dist/utils/copyTemplate.js.map +1 -1
- package/dist/utils/updatePackageJson.d.ts +11 -1
- package/dist/utils/updatePackageJson.d.ts.map +1 -1
- package/dist/utils/updatePackageJson.js +12 -10
- package/dist/utils/updatePackageJson.js.map +1 -1
- package/package.json +10 -7
- package/templates/_shared/dev-tools/auth/get-token.js +72 -0
- package/templates/_shared/dev-tools/dev/mock-xrm.js +42 -0
- package/templates/_shared/dev-tools/metadata-sync/index.js +152 -0
- package/templates/_shared/dev-tools/smoke/test-retrieve.js +44 -0
- package/templates/dialog-form/README.md +27 -0
- package/templates/dialog-form/_variants/App.v8.tsx +39 -0
- package/templates/dialog-form/_variants/App.v9.tsx +41 -0
- package/templates/dialog-form/gitignore +5 -0
- package/templates/dialog-form/package.json +27 -0
- package/templates/dialog-form/public/index.html +11 -0
- package/templates/dialog-form/src/index.tsx +10 -0
- package/templates/dialog-form/src/services/dataverse.ts +30 -0
- package/templates/dialog-form/tsconfig.json +15 -0
- package/templates/dialog-form/webpack.config.js +17 -0
- package/templates/grid-customizer/README.md +28 -0
- package/templates/grid-customizer/gitignore +4 -0
- package/templates/grid-customizer/package.json +25 -0
- package/templates/grid-customizer/src/GridCustomizer.ts +28 -0
- package/templates/grid-customizer/src/cell-renderers.tsx +35 -0
- package/templates/grid-customizer/src/index.ts +4 -0
- package/templates/grid-customizer/src/types/grid-types.ts +30 -0
- package/templates/grid-customizer/src/utils/color-utils.ts +24 -0
- package/templates/grid-customizer/tsconfig.json +15 -0
- package/templates/grid-customizer/webpack.config.js +17 -0
- package/templates/pcf-dataset/ControlManifest.Input.xml +16 -0
- package/templates/pcf-dataset/README.md +21 -0
- package/templates/pcf-dataset/gitignore +5 -0
- package/templates/pcf-dataset/index.ts +39 -0
- package/templates/pcf-dataset/package.json +30 -0
- package/templates/pcf-dataset/strings/{{componentName}}.1033.resx +47 -0
- package/templates/pcf-dataset/tsconfig.json +8 -0
- package/templates/pcf-dataset/{{componentName}}Component.tsx +39 -0
- package/templates/pcf-field/ControlManifest.Input.xml +17 -0
- package/templates/pcf-field/README.md +95 -0
- package/templates/pcf-field/_variants/ValueInput.boolean.tsx +24 -0
- package/templates/pcf-field/_variants/ValueInput.date.tsx +27 -0
- package/templates/pcf-field/_variants/ValueInput.number.tsx +35 -0
- package/templates/pcf-field/_variants/ValueInput.text.tsx +27 -0
- package/templates/pcf-field/gitignore +5 -0
- package/templates/pcf-field/index.ts +61 -0
- package/templates/pcf-field/package.json +30 -0
- package/templates/pcf-field/strings/{{componentName}}.1033.resx +47 -0
- package/templates/pcf-field/tsconfig.json +8 -0
- package/templates/pcf-field/{{componentName}}Component.tsx +35 -0
- package/templates/power-pages-starter/gitignore +5 -0
- package/templates/react-custom-page/gitignore +5 -0
- package/templates/{dynamics-365-starter → react-custom-page}/package.json +3 -3
- package/templates/react-custom-page/tools/metadata-sync/index.js +152 -0
- package/templates/static-web-app/README.md +36 -0
- package/templates/static-web-app/_variants/App.v8.tsx +32 -0
- package/templates/static-web-app/_variants/App.v9.tsx +31 -0
- package/templates/static-web-app/api/host.json +12 -0
- package/templates/static-web-app/api/package.json +19 -0
- package/templates/static-web-app/api/src/functions/hello.ts +16 -0
- package/templates/static-web-app/api/tsconfig.json +14 -0
- package/templates/static-web-app/frontend/index.html +12 -0
- package/templates/static-web-app/frontend/package.json +23 -0
- package/templates/static-web-app/frontend/src/index.tsx +8 -0
- package/templates/static-web-app/frontend/tsconfig.json +16 -0
- package/templates/static-web-app/frontend/vite.config.ts +13 -0
- package/templates/static-web-app/gitignore +8 -0
- package/templates/static-web-app/package.json +15 -0
- package/templates/static-web-app/staticwebapp.config.json +7 -0
- package/templates/teams-app/README.md +27 -0
- package/templates/teams-app/_variants/graph.off.ts +7 -0
- package/templates/teams-app/_variants/graph.on.ts +22 -0
- package/templates/teams-app/appPackage/manifest.json +26 -0
- package/templates/teams-app/gitignore +5 -0
- package/templates/teams-app/index.html +12 -0
- package/templates/teams-app/package.json +26 -0
- package/templates/teams-app/src/App.tsx +25 -0
- package/templates/teams-app/src/index.tsx +8 -0
- package/templates/teams-app/tsconfig.json +16 -0
- package/templates/teams-app/vite.config.ts +9 -0
- package/templates/web-resource/README.md +39 -0
- package/templates/web-resource/_variants/App.v8.tsx +29 -0
- package/templates/web-resource/_variants/App.v9.tsx +28 -0
- package/templates/web-resource/gitignore +5 -0
- package/templates/web-resource/package.json +27 -0
- package/templates/web-resource/public/index.html +11 -0
- package/templates/web-resource/src/index.tsx +10 -0
- package/templates/web-resource/src/services/dataverse.ts +30 -0
- package/templates/web-resource/tsconfig.json +15 -0
- package/templates/web-resource/webpack.config.js +17 -0
- package/dist/utils/consultingHelpers.d.ts +0 -13
- package/dist/utils/consultingHelpers.d.ts.map +0 -1
- package/dist/utils/consultingHelpers.js +0 -569
- package/dist/utils/consultingHelpers.js.map +0 -1
- package/templates/dynamics-365-starter/INTEGRATION_TEST_RESULTS.md +0 -302
- package/templates/dynamics-365-starter/PHASE_4_COMPLETION_SUMMARY.md +0 -305
- package/templates/dynamics-365-starter/deployment/QUICKSTART-MAC.md +0 -507
- package/templates/dynamics-365-starter/deployment/QUICKSTART-WINDOWS.md +0 -372
- package/templates/dynamics-365-starter/deployment/pipelines/README.md +0 -375
- package/templates/dynamics-365-starter/deployment/pipelines/azure-pipelines.yml +0 -330
- package/templates/dynamics-365-starter/deployment/pipelines/github-actions.yml +0 -422
- package/templates/dynamics-365-starter/deployment/pipelines/jenkins.groovy +0 -636
- package/templates/dynamics-365-starter/deployment/scripts/deploy.ps1 +0 -417
- package/templates/dynamics-365-starter/deployment/scripts/deploy.sh +0 -582
- package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.ps1 +0 -486
- package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.sh +0 -567
- package/templates/dynamics-365-starter/deployment/scripts/validate-setup.ps1 +0 -703
- package/templates/dynamics-365-starter/deployment/scripts/validate-setup.sh +0 -671
- package/templates/dynamics-365-starter/docs/team-standards/README.md +0 -273
- package/templates/dynamics-365-starter/docs/team-standards/client-onboarding.md +0 -577
- package/templates/dynamics-365-starter/docs/team-standards/code-review-checklist.md +0 -359
- package/templates/dynamics-365-starter/docs/team-standards/coding-standards.md +0 -700
- package/templates/dynamics-365-starter/docs/team-standards/cross-platform-team-guide.md +0 -736
- package/templates/dynamics-365-starter/docs/team-standards/development-workflows.md +0 -727
- package/templates/dynamics-365-starter/docs/troubleshooting/common-errors.md +0 -758
- package/templates/dynamics-365-starter/docs/troubleshooting/platform-specific-issues.md +0 -878
- package/templates/dynamics-365-starter/src/client-project-template/README.md +0 -234
- package/templates/dynamics-365-starter/src/client-project-template/config/client.template.json +0 -114
- package/templates/dynamics-365-starter/src/client-project-template/config/environments/template.json +0 -186
- package/templates/dynamics-365-starter/src/client-project-template/scripts/client-setup.js +0 -667
- package/templates/dynamics-365-starter/src/examples/README.md +0 -52
- package/templates/dynamics-365-starter/src/examples/component-examples/opportunity-management.tsx +0 -625
- package/templates/dynamics-365-starter/src/examples/entity-examples/opportunity-model.ts +0 -545
- package/templates/dynamics-365-starter/src/examples/integration-examples/custom-pcf-wrapper.tsx +0 -722
- package/templates/dynamics-365-starter/src/examples/workflow-examples/sales-workflow.ts +0 -662
- package/templates/dynamics-365-starter/src/page-templates/EntityDashboard.tsx +0 -519
- package/templates/dynamics-365-starter/src/page-templates/EntityDetailPage.tsx +0 -456
- package/templates/dynamics-365-starter/src/page-templates/EntityListPage.tsx +0 -406
- package/templates/dynamics-365-starter/src/page-templates/RelatedEntitiesPage.tsx +0 -578
- package/templates/dynamics-365-starter/src/page-templates/SearchPage.tsx +0 -629
- package/templates/dynamics-365-starter/tools/entity-generator/index.js +0 -168
- package/templates/dynamics-365-starter/tools/entity-generator/templates/constants.template.ts +0 -124
- package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.css +0 -283
- package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.tsx +0 -275
- package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.css +0 -204
- package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.tsx +0 -413
- package/templates/dynamics-365-starter/tools/entity-generator/templates/model.template.ts +0 -250
- package/templates/dynamics-365-starter/tools/metadata-sync/d365-client.js +0 -410
- package/templates/dynamics-365-starter/tools/metadata-sync/index.js +0 -512
- package/templates/dynamics-365-starter/tools/metadata-sync/type-generator.js +0 -675
- /package/templates/{dynamics-365-starter → react-custom-page}/README.md +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/deployment/README.md +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/docs/ARCHITECTURE_OVERVIEW.md +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/docs/BEST_PRACTICES.md +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/docs/MIGRATION_GUIDE.md +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/public/index.html +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/scripts/custom-build.js +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountForm.css +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountForm.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountManagement.css +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountManagement.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactForm.css +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactForm.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactManagement.css +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactManagement.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LogDialog.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingContext.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingDebugPanel.css +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingDebugPanel.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingProvider.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/logger.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/constants/account.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/constants/contact.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/index.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/models/Account.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/models/BaseEntity.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/models/Contact.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/pcf/ContactControlWrapper.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/pcf/MultiEntityControlWrapper.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/providers/DynamicsProvider.tsx +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/services/MockApiService.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/services/ServiceFactory.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/services/XrmApiService.ts +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/src/styles/index.css +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/tsconfig.json +0 -0
- /package/templates/{dynamics-365-starter → react-custom-page}/webpack.config.js +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# create-dynamics-app
|
|
2
|
+
|
|
3
|
+
Unified CLI to scaffold Dynamics 365 / Power Platform artifacts — one tool, per-artifact templates, a Fluent **v8/v9** choice, integrated dev-tools, and an optional **from-design** mode.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
create-dynamics-app <project-name> --artifact <id> [--v8|--v9]
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Artifacts (`--artifact`)
|
|
10
|
+
|
|
11
|
+
| id | What it scaffolds | Fluent |
|
|
12
|
+
|----|-------------------|--------|
|
|
13
|
+
| `react-custom-page` | React SPA for a model-driven custom page | v8 |
|
|
14
|
+
| `power-pages` | Power Pages portal starter | v8 |
|
|
15
|
+
| `pcf-field` | PCF field control (property-type aware: text/number/boolean/date) | v8 |
|
|
16
|
+
| `pcf-dataset` | PCF dataset/grid control (DetailsList) | v8 |
|
|
17
|
+
| `grid-customizer` | Editable-grid cell-renderer customizer | v9 |
|
|
18
|
+
| `web-resource` | React web resource (webpack bundle) | **v8 or v9** |
|
|
19
|
+
| `dialog-form` | Single React form host (opened as a dialog) | **v8 or v9** |
|
|
20
|
+
| `static-web-app` | Azure SWA — React frontend + Functions `api/` | **v8 or v9** |
|
|
21
|
+
| `teams-app` | Teams tab (React + teams-js), optional Graph (`--graph`) | v9 |
|
|
22
|
+
|
|
23
|
+
Run with no flags for an interactive picker.
|
|
24
|
+
|
|
25
|
+
## Flags
|
|
26
|
+
|
|
27
|
+
- `-a, --artifact <id>` — artifact to scaffold (see table).
|
|
28
|
+
- `--v8` / `--v9` (or `-l, --library fluent-v8|fluent-v9`) — Fluent version for artifacts that support a choice. Only the chosen library is installed.
|
|
29
|
+
- `-n, --namespace`, `--component-name`, `--property-type` — PCF options.
|
|
30
|
+
- `--graph` — include Microsoft Graph (teams-app).
|
|
31
|
+
- `--from-design <file>` — generate from a form-builder export (a `FormBuilderProject` JSON, e.g. from `/generate-form`). Wraps `@dataverse-kit/export-engine` to produce a deployable project (host + form code + a design-derived data layer). Supported targets: `web-resource`, `pcf`, `static-web-app`. From-design output is generated by the export engine and is structurally different from a blank starter (it ships its own token tooling); `package.json.dynamicsKit.artifact` records which.
|
|
32
|
+
- `--skip-git`, `--skip-install`.
|
|
33
|
+
|
|
34
|
+
## Dev-tools (in generated projects)
|
|
35
|
+
|
|
36
|
+
Blank starters get `package.json` scripts for: `auth:token` (Azure CLI → `.env`), `metadata:pull` (typed entities via dvgen), `smoke:live` (live-org retrieve), plus a mock-Xrm helper for local serve.
|
|
37
|
+
|
|
38
|
+
## Breaking changes in 2.0.0
|
|
39
|
+
|
|
40
|
+
See `CHANGELOG.md`. In short: removed the consulting flags (`-c/-e/-p/-d/--generate-sample`); `--template dynamics-365|pcf-control` are removed (use `--artifact react-custom-page` / `--artifact pcf-field`); `--template power-pages` still works as a deprecated alias.
|
|
41
|
+
|
|
42
|
+
## Testing & coverage boundaries
|
|
43
|
+
|
|
44
|
+
- Unit + smoke tests (`npm test`) run the scaffold pipeline for all 9 artifacts (zero-residual-token + variant/prune checks) but do **not** `npm install` or build the generated projects.
|
|
45
|
+
- React artifacts are verified to `tsc --noEmit` clean for v8 and v9 via manual installs; **PCF** type-correctness (against generated `ManifestTypes` from `pcf-scripts refreshTypes`) is verified manually, not in CI.
|
|
46
|
+
- The `--from-design` generated-project build is verified manually.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ArtifactDescriptor, TemplateFlagMigration } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The artifact registry. Phase 0 wires the three templates that exist today
|
|
4
|
+
* (`react-custom-page`, `power-pages`, `pcf-field`); the remaining artifacts
|
|
5
|
+
* are declared with `available: false` and their templates land in Phase A.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ARTIFACTS: ArtifactDescriptor[];
|
|
8
|
+
export declare function getArtifact(id: string): ArtifactDescriptor | undefined;
|
|
9
|
+
export declare function availableArtifacts(): ArtifactDescriptor[];
|
|
10
|
+
/**
|
|
11
|
+
* Legacy `--template <flag>` migration. `power-pages` is an honest passthrough
|
|
12
|
+
* (template unchanged). `dynamics-365` / `pcf-control` hard-deprecate: the old
|
|
13
|
+
* flows generated entity/page/deploy code (now removed) and PCF output changed,
|
|
14
|
+
* so silently remapping would break the published-CLI contract — we error out
|
|
15
|
+
* with migration guidance instead.
|
|
16
|
+
*/
|
|
17
|
+
export declare const TEMPLATE_FLAG_MIGRATIONS: Record<string, TemplateFlagMigration>;
|
|
18
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/artifacts/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAGlB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAiFpB;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,kBAAkB,EAkOzC,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEtE;AAED,wBAAgB,kBAAkB,IAAI,kBAAkB,EAAE,CAEzD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAI1E,CAAC"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { validateComponentName, validateNamespace, toIdentifier } from './validators.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fluent library dependency, added per the chosen componentLibrary so the
|
|
4
|
+
* generated project ships ONLY the version it uses (the v8/v9 choice is real,
|
|
5
|
+
* not cosmetic). The template base package.json carries neither Fluent package.
|
|
6
|
+
* `packagePath` targets the package.json that consumes Fluent (root, or an
|
|
7
|
+
* SWA's `frontend`).
|
|
8
|
+
*/
|
|
9
|
+
function fluentLibraryDeps(packagePath) {
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
when: (vars) => vars.componentLibrary === 'fluent-v8',
|
|
13
|
+
dependencies: { '@fluentui/react': '^8.110.10' },
|
|
14
|
+
packagePath,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
when: (vars) => vars.componentLibrary === 'fluent-v9',
|
|
18
|
+
dependencies: { '@fluentui/react-components': '^9.46.2' },
|
|
19
|
+
packagePath,
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* PCF bound-property type → generated TypeScript value type, input-renderer variant,
|
|
25
|
+
* and the type-appropriate default used when reading `context.parameters.value.raw`.
|
|
26
|
+
*/
|
|
27
|
+
const PCF_TYPE_MAP = {
|
|
28
|
+
'SingleLine.Text': { tsType: 'string', renderKind: 'text', valueDefault: '""' },
|
|
29
|
+
'Whole.None': { tsType: 'number | null', renderKind: 'number', valueDefault: 'null' },
|
|
30
|
+
Decimal: { tsType: 'number | null', renderKind: 'number', valueDefault: 'null' },
|
|
31
|
+
OptionSet: { tsType: 'number | null', renderKind: 'number', valueDefault: 'null' },
|
|
32
|
+
TwoOptions: { tsType: 'boolean', renderKind: 'boolean', valueDefault: 'false' },
|
|
33
|
+
'DateAndTime.DateOnly': { tsType: 'Date | null', renderKind: 'date', valueDefault: 'null' },
|
|
34
|
+
};
|
|
35
|
+
/** Derive the common PCF naming vars (namespace / componentName / prefix). */
|
|
36
|
+
function derivePcfNaming(answers, { projectName }) {
|
|
37
|
+
const namespace = answers.namespace || 'DynamicsUIKit';
|
|
38
|
+
const componentName = answers.componentName || toIdentifier(projectName);
|
|
39
|
+
return { namespace, componentName, prefix: namespace.toLowerCase() };
|
|
40
|
+
}
|
|
41
|
+
/** PCF field control: naming + property-type family (tsType/renderKind/valueDefault). */
|
|
42
|
+
function derivePcfVars(answers, ctx) {
|
|
43
|
+
const propertyType = answers.propertyType || 'SingleLine.Text';
|
|
44
|
+
const family = PCF_TYPE_MAP[propertyType] ?? PCF_TYPE_MAP['SingleLine.Text'];
|
|
45
|
+
return {
|
|
46
|
+
...derivePcfNaming(answers, ctx),
|
|
47
|
+
propertyType,
|
|
48
|
+
tsType: family.tsType,
|
|
49
|
+
renderKind: family.renderKind,
|
|
50
|
+
valueDefault: family.valueDefault,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Shared namespace/componentName prompts for PCF-family artifacts. */
|
|
54
|
+
const PCF_NAMING_PROMPTS = [
|
|
55
|
+
{
|
|
56
|
+
name: 'namespace',
|
|
57
|
+
message: 'Namespace for the PCF control:',
|
|
58
|
+
type: 'input',
|
|
59
|
+
default: 'DynamicsUIKit',
|
|
60
|
+
validate: validateNamespace,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'componentName',
|
|
64
|
+
message: 'Component name:',
|
|
65
|
+
type: 'input',
|
|
66
|
+
validate: validateComponentName,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
/**
|
|
70
|
+
* The artifact registry. Phase 0 wires the three templates that exist today
|
|
71
|
+
* (`react-custom-page`, `power-pages`, `pcf-field`); the remaining artifacts
|
|
72
|
+
* are declared with `available: false` and their templates land in Phase A.
|
|
73
|
+
*/
|
|
74
|
+
export const ARTIFACTS = [
|
|
75
|
+
{
|
|
76
|
+
id: 'react-custom-page',
|
|
77
|
+
label: '⚡ React Custom Page — full React app mounted as a Dynamics 365 custom page',
|
|
78
|
+
description: 'Slim React SPA (models/services/components + dvgen dev-tools) for a model-driven app custom page.',
|
|
79
|
+
templateDir: 'react-custom-page',
|
|
80
|
+
supportsLibraryChoice: false,
|
|
81
|
+
// codegen is shipped in-template (tools/metadata-sync + metadata:* scripts), so only inject token.
|
|
82
|
+
devTools: ['token'],
|
|
83
|
+
prompts: [],
|
|
84
|
+
exportTarget: 'static-web-app',
|
|
85
|
+
templateVersion: '2.0.0',
|
|
86
|
+
available: true,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'power-pages',
|
|
90
|
+
label: '🌐 Power Pages — Power Pages portal starter',
|
|
91
|
+
description: 'Power Pages portal scaffold (ContactForm, providers, webpack).',
|
|
92
|
+
templateDir: 'power-pages-starter',
|
|
93
|
+
supportsLibraryChoice: false,
|
|
94
|
+
devTools: [],
|
|
95
|
+
prompts: [],
|
|
96
|
+
templateVersion: '2.0.0',
|
|
97
|
+
available: true,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'pcf-field',
|
|
101
|
+
label: '🎛️ PCF Field Control — PowerApps Component Framework field control',
|
|
102
|
+
description: 'PCF field control (React + Fluent UI), built with pcf-scripts.',
|
|
103
|
+
templateDir: 'pcf-field',
|
|
104
|
+
supportsLibraryChoice: false,
|
|
105
|
+
devTools: [],
|
|
106
|
+
prompts: [
|
|
107
|
+
{
|
|
108
|
+
name: 'namespace',
|
|
109
|
+
message: 'Namespace for the PCF control:',
|
|
110
|
+
type: 'input',
|
|
111
|
+
default: 'DynamicsUIKit',
|
|
112
|
+
validate: validateNamespace,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
// Default (= project name) is filled by the driver.
|
|
116
|
+
name: 'componentName',
|
|
117
|
+
message: 'Component name:',
|
|
118
|
+
type: 'input',
|
|
119
|
+
validate: validateComponentName,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'propertyType',
|
|
123
|
+
message: 'Bound property type:',
|
|
124
|
+
type: 'list',
|
|
125
|
+
default: 'SingleLine.Text',
|
|
126
|
+
choices: [
|
|
127
|
+
{ name: 'Text (SingleLine.Text)', value: 'SingleLine.Text' },
|
|
128
|
+
{ name: 'Whole number (Whole.None)', value: 'Whole.None' },
|
|
129
|
+
{ name: 'Decimal (Decimal)', value: 'Decimal' },
|
|
130
|
+
{ name: 'Yes/No (TwoOptions)', value: 'TwoOptions' },
|
|
131
|
+
{ name: 'Option set (OptionSet)', value: 'OptionSet' },
|
|
132
|
+
{ name: 'Date (DateAndTime.DateOnly)', value: 'DateAndTime.DateOnly' },
|
|
133
|
+
],
|
|
134
|
+
validate: (v) => v in PCF_TYPE_MAP
|
|
135
|
+
? true
|
|
136
|
+
: `Unknown property type ${JSON.stringify(v)}. One of: ${Object.keys(PCF_TYPE_MAP).join(', ')}.`,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
derive: derivePcfVars,
|
|
140
|
+
// Pick the input renderer matching the property type, then drop the variant set.
|
|
141
|
+
variants: [
|
|
142
|
+
{
|
|
143
|
+
choose: 'renderKind',
|
|
144
|
+
cases: {
|
|
145
|
+
text: '_variants/ValueInput.text.tsx',
|
|
146
|
+
number: '_variants/ValueInput.number.tsx',
|
|
147
|
+
boolean: '_variants/ValueInput.boolean.tsx',
|
|
148
|
+
date: '_variants/ValueInput.date.tsx',
|
|
149
|
+
},
|
|
150
|
+
to: 'ValueInput.tsx',
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
prune: ['_variants'],
|
|
154
|
+
exportTarget: 'pcf',
|
|
155
|
+
templateVersion: '2.0.0',
|
|
156
|
+
available: true,
|
|
157
|
+
},
|
|
158
|
+
// ----- Declared now, templates land in Phase A (not yet offered) -----
|
|
159
|
+
{
|
|
160
|
+
id: 'web-resource',
|
|
161
|
+
label: '📄 Web Resource — React (Fluent v8/v9) web resource',
|
|
162
|
+
description: 'Dynamics web resource: React + Fluent UI bundled to a single JS web resource.',
|
|
163
|
+
templateDir: 'web-resource',
|
|
164
|
+
supportsLibraryChoice: true,
|
|
165
|
+
defaultLibrary: 'fluent-v8',
|
|
166
|
+
devTools: ['token', 'serve', 'codegen'],
|
|
167
|
+
prompts: [],
|
|
168
|
+
// Select the Fluent v8 or v9 App shell based on the chosen component library.
|
|
169
|
+
variants: [
|
|
170
|
+
{
|
|
171
|
+
choose: 'componentLibrary',
|
|
172
|
+
cases: {
|
|
173
|
+
'fluent-v8': '_variants/App.v8.tsx',
|
|
174
|
+
'fluent-v9': '_variants/App.v9.tsx',
|
|
175
|
+
},
|
|
176
|
+
to: 'src/App.tsx',
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
prune: ['_variants'],
|
|
180
|
+
conditionalDeps: fluentLibraryDeps(),
|
|
181
|
+
exportTarget: 'web-resource',
|
|
182
|
+
templateVersion: '2.0.0',
|
|
183
|
+
available: true,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: 'pcf-dataset',
|
|
187
|
+
label: '🗂️ PCF Dataset Control — grid/dataset PCF control (Fluent v8)',
|
|
188
|
+
description: 'PCF dataset control: binds a grid/view, renders records with a DetailsList.',
|
|
189
|
+
templateDir: 'pcf-dataset',
|
|
190
|
+
supportsLibraryChoice: false,
|
|
191
|
+
devTools: [],
|
|
192
|
+
prompts: PCF_NAMING_PROMPTS,
|
|
193
|
+
derive: derivePcfNaming,
|
|
194
|
+
exportTarget: 'pcf',
|
|
195
|
+
templateVersion: '2.0.0',
|
|
196
|
+
available: true,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: 'grid-customizer',
|
|
200
|
+
label: '🧩 Grid Customizer — editable-grid cell renderers (Fluent v9)',
|
|
201
|
+
description: 'Editable-grid customizer: map column types/names to Fluent v9 cell renderers.',
|
|
202
|
+
templateDir: 'grid-customizer',
|
|
203
|
+
supportsLibraryChoice: false,
|
|
204
|
+
devTools: [],
|
|
205
|
+
prompts: PCF_NAMING_PROMPTS,
|
|
206
|
+
derive: derivePcfNaming,
|
|
207
|
+
// No exportTarget: grid customizers use a separate export-engine generator,
|
|
208
|
+
// not the previewExport from-design path.
|
|
209
|
+
templateVersion: '2.0.0',
|
|
210
|
+
available: true,
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: 'dialog-form',
|
|
214
|
+
label: '🪟 Dialog / Form — single React form (Fluent v8/v9) web-resource host',
|
|
215
|
+
description: 'Single-form host (opened as a dialog), React + Fluent UI. From-design capable.',
|
|
216
|
+
templateDir: 'dialog-form',
|
|
217
|
+
supportsLibraryChoice: true,
|
|
218
|
+
defaultLibrary: 'fluent-v8',
|
|
219
|
+
devTools: ['token', 'serve', 'codegen'],
|
|
220
|
+
prompts: [],
|
|
221
|
+
variants: [
|
|
222
|
+
{
|
|
223
|
+
choose: 'componentLibrary',
|
|
224
|
+
cases: {
|
|
225
|
+
'fluent-v8': '_variants/App.v8.tsx',
|
|
226
|
+
'fluent-v9': '_variants/App.v9.tsx',
|
|
227
|
+
},
|
|
228
|
+
to: 'src/App.tsx',
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
prune: ['_variants'],
|
|
232
|
+
conditionalDeps: fluentLibraryDeps(),
|
|
233
|
+
exportTarget: 'web-resource',
|
|
234
|
+
templateVersion: '2.0.0',
|
|
235
|
+
available: true,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: 'teams-app',
|
|
239
|
+
label: '💬 Teams App — Teams tab (React, Fluent v9, optional Graph)',
|
|
240
|
+
description: 'Microsoft Teams tab: React + Fluent v9 + teams-js, with optional Graph integration.',
|
|
241
|
+
templateDir: 'teams-app',
|
|
242
|
+
supportsLibraryChoice: false,
|
|
243
|
+
devTools: ['token', 'serve'],
|
|
244
|
+
prompts: [
|
|
245
|
+
{
|
|
246
|
+
name: 'graph',
|
|
247
|
+
message: 'Include Microsoft Graph integration?',
|
|
248
|
+
type: 'confirm',
|
|
249
|
+
default: 'false',
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
// Map the Graph answer to a variant key for src/services/graph.ts.
|
|
253
|
+
derive: (answers) => ({ graphKind: answers.graph === 'true' ? 'on' : 'off' }),
|
|
254
|
+
variants: [
|
|
255
|
+
{
|
|
256
|
+
choose: 'graphKind',
|
|
257
|
+
cases: { on: '_variants/graph.on.ts', off: '_variants/graph.off.ts' },
|
|
258
|
+
to: 'src/services/graph.ts',
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
prune: ['_variants'],
|
|
262
|
+
// Graph client is added only when Graph integration is enabled.
|
|
263
|
+
conditionalDeps: [
|
|
264
|
+
{
|
|
265
|
+
when: (vars) => vars.graphKind === 'on',
|
|
266
|
+
dependencies: { '@microsoft/microsoft-graph-client': '^3.0.7' },
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
templateVersion: '2.0.0',
|
|
270
|
+
available: true,
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
id: 'static-web-app',
|
|
274
|
+
label: '☁️ Azure Static Web App — React frontend + managed Functions api/',
|
|
275
|
+
description: 'Azure SWA: React + Fluent UI (v8/v9) frontend with an Azure Functions api/.',
|
|
276
|
+
templateDir: 'static-web-app',
|
|
277
|
+
supportsLibraryChoice: true,
|
|
278
|
+
defaultLibrary: 'fluent-v9',
|
|
279
|
+
devTools: ['token', 'serve', 'codegen', 'smoke'],
|
|
280
|
+
prompts: [],
|
|
281
|
+
variants: [
|
|
282
|
+
{
|
|
283
|
+
choose: 'componentLibrary',
|
|
284
|
+
cases: {
|
|
285
|
+
'fluent-v8': '_variants/App.v8.tsx',
|
|
286
|
+
'fluent-v9': '_variants/App.v9.tsx',
|
|
287
|
+
},
|
|
288
|
+
to: 'frontend/src/App.tsx',
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
prune: ['_variants'],
|
|
292
|
+
conditionalDeps: fluentLibraryDeps('frontend'),
|
|
293
|
+
exportTarget: 'static-web-app',
|
|
294
|
+
templateVersion: '2.0.0',
|
|
295
|
+
available: true,
|
|
296
|
+
},
|
|
297
|
+
];
|
|
298
|
+
export function getArtifact(id) {
|
|
299
|
+
return ARTIFACTS.find((a) => a.id === id);
|
|
300
|
+
}
|
|
301
|
+
export function availableArtifacts() {
|
|
302
|
+
return ARTIFACTS.filter((a) => a.available);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Legacy `--template <flag>` migration. `power-pages` is an honest passthrough
|
|
306
|
+
* (template unchanged). `dynamics-365` / `pcf-control` hard-deprecate: the old
|
|
307
|
+
* flows generated entity/page/deploy code (now removed) and PCF output changed,
|
|
308
|
+
* so silently remapping would break the published-CLI contract — we error out
|
|
309
|
+
* with migration guidance instead.
|
|
310
|
+
*/
|
|
311
|
+
export const TEMPLATE_FLAG_MIGRATIONS = {
|
|
312
|
+
'power-pages': { mode: 'passthrough', artifact: 'power-pages' },
|
|
313
|
+
'dynamics-365': { mode: 'hard-deprecate', artifact: 'react-custom-page' },
|
|
314
|
+
'pcf-control': { mode: 'hard-deprecate', artifact: 'pcf-field' },
|
|
315
|
+
};
|
|
316
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/artifacts/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact registry types. The registry replaces the old hard-coded
|
|
3
|
+
* three-template `if/else` in `index.ts` — every scaffoldable artifact is one
|
|
4
|
+
* `ArtifactDescriptor`, and the CLI is a thin driver over the registry.
|
|
5
|
+
*/
|
|
6
|
+
/** Fluent UI version the generated React output targets. */
|
|
7
|
+
export type ComponentLibrary = 'fluent-v8' | 'fluent-v9';
|
|
8
|
+
/**
|
|
9
|
+
* export-engine target an artifact maps to for the (Phase B) from-design path.
|
|
10
|
+
* Mirrors the export engine's own ExportTarget — grid-customizer is NOT a
|
|
11
|
+
* from-design target (it uses a separate generator), so it carries no exportTarget.
|
|
12
|
+
*/
|
|
13
|
+
export type ExportTarget = 'web-resource' | 'pcf' | 'static-web-app';
|
|
14
|
+
/** Dev-tools that `injectDevTools` (Phase A) can wire into a generated project. */
|
|
15
|
+
export type DevToolId = 'token' | 'serve' | 'codegen' | 'smoke';
|
|
16
|
+
/** The full set of artifact ids the unified CLI will produce. */
|
|
17
|
+
export type ArtifactId = 'react-custom-page' | 'power-pages' | 'pcf-field' | 'pcf-dataset' | 'grid-customizer' | 'web-resource' | 'dialog-form' | 'teams-app' | 'static-web-app';
|
|
18
|
+
/**
|
|
19
|
+
* A single interactive prompt for an artifact. The answer is written into the
|
|
20
|
+
* `{{name}}` substitution bag. `when` gates conditional prompts (e.g. a PCF
|
|
21
|
+
* property type only asked for field controls).
|
|
22
|
+
*/
|
|
23
|
+
export interface PromptSpec {
|
|
24
|
+
/** Substitution-variable key (also the inquirer answer name). */
|
|
25
|
+
name: string;
|
|
26
|
+
message: string;
|
|
27
|
+
type?: 'input' | 'list' | 'confirm';
|
|
28
|
+
default?: string;
|
|
29
|
+
choices?: Array<{
|
|
30
|
+
name: string;
|
|
31
|
+
value: string;
|
|
32
|
+
}>;
|
|
33
|
+
when?: (answers: Record<string, unknown>) => boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Validate the answer. Returns `true` if valid, or an error message string.
|
|
36
|
+
* Enforced for BOTH the interactive prompt AND values supplied via flags
|
|
37
|
+
* (flags bypass the prompt, so a prompt-only validator would be insufficient).
|
|
38
|
+
*/
|
|
39
|
+
validate?: (value: string) => true | string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Select one file from a variant set based on the value of a (usually derived)
|
|
43
|
+
* substitution variable, then copy it to `to`. Lets a single template express
|
|
44
|
+
* divergent file bodies (e.g. a PCF control's input renderer per property type)
|
|
45
|
+
* without a separate template per case. `from`/`to` are template-relative paths.
|
|
46
|
+
*/
|
|
47
|
+
export interface VariantSelect {
|
|
48
|
+
/** Substitution-variable name whose value picks the case (e.g. 'renderKind'). */
|
|
49
|
+
choose: string;
|
|
50
|
+
/** value → source path within the template (e.g. { number: '_variants/input.number.tsx' }). */
|
|
51
|
+
cases: Record<string, string>;
|
|
52
|
+
/** Destination path the chosen case is copied to (e.g. 'src/ValueInput.tsx'). */
|
|
53
|
+
to: string;
|
|
54
|
+
}
|
|
55
|
+
/** Conditionally add dependencies to a generated package.json (e.g. Teams Graph). */
|
|
56
|
+
export interface ConditionalDeps {
|
|
57
|
+
/** Predicate over the full substitution bag (answers + derived vars). */
|
|
58
|
+
when: (vars: Record<string, string>) => boolean;
|
|
59
|
+
dependencies?: Record<string, string>;
|
|
60
|
+
devDependencies?: Record<string, string>;
|
|
61
|
+
/** Project-relative directory of the target package.json (default: root). */
|
|
62
|
+
packagePath?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface ArtifactDescriptor {
|
|
65
|
+
id: ArtifactId;
|
|
66
|
+
/** Display label for the interactive picker. */
|
|
67
|
+
label: string;
|
|
68
|
+
description: string;
|
|
69
|
+
/** Literal directory name under `templates/` (no suffix heuristic). */
|
|
70
|
+
templateDir: string;
|
|
71
|
+
/** Whether this artifact prompts for fluent-v8 vs fluent-v9 output. */
|
|
72
|
+
supportsLibraryChoice: boolean;
|
|
73
|
+
defaultLibrary?: ComponentLibrary;
|
|
74
|
+
/** Dev-tools injected into the generated project (Phase A). */
|
|
75
|
+
devTools: DevToolId[];
|
|
76
|
+
/** Artifact-specific prompts → substitution variables. */
|
|
77
|
+
prompts: PromptSpec[];
|
|
78
|
+
/** export-engine target for the from-design path (Phase B); omitted = no from-design. */
|
|
79
|
+
exportTarget?: ExportTarget;
|
|
80
|
+
/**
|
|
81
|
+
* Derive additional substitution variables from the collected answers — the
|
|
82
|
+
* data-driven replacement for hard-coded per-id logic in the driver (e.g. a PCF
|
|
83
|
+
* control deriving `tsType`/`renderKind`/`prefix` from `propertyType`/`namespace`).
|
|
84
|
+
*/
|
|
85
|
+
derive?: (answers: Record<string, string>, ctx: {
|
|
86
|
+
projectName: string;
|
|
87
|
+
}) => Record<string, string>;
|
|
88
|
+
/** File-variant selections applied after copy (e.g. property-type-specific renderer). */
|
|
89
|
+
variants?: VariantSelect[];
|
|
90
|
+
/** Template-relative files/dirs to delete after variant selection (scaffolding leftovers). */
|
|
91
|
+
prune?: string[];
|
|
92
|
+
/** Conditional dependency additions (consumed by injectDevTools/updatePackageJson). */
|
|
93
|
+
conditionalDeps?: ConditionalDeps[];
|
|
94
|
+
/** Template schema version, stamped into the generated package.json provenance. */
|
|
95
|
+
templateVersion: string;
|
|
96
|
+
/**
|
|
97
|
+
* Whether a template directory exists yet. Artifacts whose templates land in
|
|
98
|
+
* Phase A are declared here (for the type union + planning) but not offered
|
|
99
|
+
* until `available` flips true.
|
|
100
|
+
*/
|
|
101
|
+
available: boolean;
|
|
102
|
+
}
|
|
103
|
+
/** How a legacy `--template <flag>` value migrates to the new artifact model. */
|
|
104
|
+
export interface TemplateFlagMigration {
|
|
105
|
+
/**
|
|
106
|
+
* `passthrough` — the artifact is unchanged, run it (e.g. power-pages).
|
|
107
|
+
* `hard-deprecate` — print a notice and exit non-zero; output differs, so we
|
|
108
|
+
* never silently remap (would violate the published-CLI contract).
|
|
109
|
+
*/
|
|
110
|
+
mode: 'passthrough' | 'hard-deprecate';
|
|
111
|
+
artifact: ArtifactId;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/artifacts/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact registry types. The registry replaces the old hard-coded
|
|
3
|
+
* three-template `if/else` in `index.ts` — every scaffoldable artifact is one
|
|
4
|
+
* `ArtifactDescriptor`, and the CLI is a thin driver over the registry.
|
|
5
|
+
*/
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifacts/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validators. User-supplied values (project name, PCF namespace /
|
|
3
|
+
* component name) are substituted raw into XML manifests, JSON, TypeScript
|
|
4
|
+
* identifiers, and filenames — so they must be format-checked before they enter
|
|
5
|
+
* the substitution bag, both from interactive prompts and from CLI flags.
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateComponentName(value: string): true | string;
|
|
8
|
+
export declare function validateNamespace(value: string): true | string;
|
|
9
|
+
/**
|
|
10
|
+
* Coerce an arbitrary name (e.g. a hyphenated project name) into a valid PCF
|
|
11
|
+
* identifier — PascalCase, alphanumeric, starting with a letter. Used to derive
|
|
12
|
+
* a safe default `componentName` so we never offer an invalid PCF constructor.
|
|
13
|
+
*/
|
|
14
|
+
export declare function toIdentifier(value: string): string;
|
|
15
|
+
export declare function validateProjectName(value: string): true | string;
|
|
16
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/artifacts/validators.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAIlE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAMhE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validators. User-supplied values (project name, PCF namespace /
|
|
3
|
+
* component name) are substituted raw into XML manifests, JSON, TypeScript
|
|
4
|
+
* identifiers, and filenames — so they must be format-checked before they enter
|
|
5
|
+
* the substitution bag, both from interactive prompts and from CLI flags.
|
|
6
|
+
*/
|
|
7
|
+
/** A single PascalCase-ish identifier (PCF constructor / component name). */
|
|
8
|
+
const PCF_IDENTIFIER = /^[A-Za-z][A-Za-z0-9]*$/;
|
|
9
|
+
/** A dot-separated set of identifiers (PCF namespace). */
|
|
10
|
+
const PCF_NAMESPACE = /^[A-Za-z][A-Za-z0-9]*(\.[A-Za-z][A-Za-z0-9]*)*$/;
|
|
11
|
+
/** npm-name-safe + filesystem-safe project name. */
|
|
12
|
+
const PROJECT_NAME = /^[A-Za-z0-9._-]+$/;
|
|
13
|
+
export function validateComponentName(value) {
|
|
14
|
+
return PCF_IDENTIFIER.test(value)
|
|
15
|
+
? true
|
|
16
|
+
: `Component name must be a single identifier (letters/digits, starting with a letter), e.g. "RatingField". Got: ${JSON.stringify(value)}`;
|
|
17
|
+
}
|
|
18
|
+
export function validateNamespace(value) {
|
|
19
|
+
return PCF_NAMESPACE.test(value)
|
|
20
|
+
? true
|
|
21
|
+
: `Namespace must be one or more dot-separated identifiers, e.g. "Contoso" or "Contoso.Controls". Got: ${JSON.stringify(value)}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Coerce an arbitrary name (e.g. a hyphenated project name) into a valid PCF
|
|
25
|
+
* identifier — PascalCase, alphanumeric, starting with a letter. Used to derive
|
|
26
|
+
* a safe default `componentName` so we never offer an invalid PCF constructor.
|
|
27
|
+
*/
|
|
28
|
+
export function toIdentifier(value) {
|
|
29
|
+
const joined = value
|
|
30
|
+
.split(/[^A-Za-z0-9]+/)
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
33
|
+
.join('');
|
|
34
|
+
return /^[A-Za-z]/.test(joined) ? joined : `Control${joined}`;
|
|
35
|
+
}
|
|
36
|
+
export function validateProjectName(value) {
|
|
37
|
+
if (!value)
|
|
38
|
+
return 'Project name is required.';
|
|
39
|
+
if (value === '.' || value === '..')
|
|
40
|
+
return 'Project name cannot be "." or "..".';
|
|
41
|
+
return PROJECT_NAME.test(value)
|
|
42
|
+
? true
|
|
43
|
+
: `Project name may only contain letters, digits, ".", "_" and "-" (no spaces, slashes, or quotes). Got: ${JSON.stringify(value)}`;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/artifacts/validators.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6EAA6E;AAC7E,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAChD,0DAA0D;AAC1D,MAAM,aAAa,GAAG,iDAAiD,CAAC;AACxE,oDAAoD;AACpD,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAEzC,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,OAAO,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,iHAAiH,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/I,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,uGAAuG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AACrI,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,MAAM,GAAG,KAAK;SACjB,KAAK,CAAC,eAAe,CAAC;SACtB,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,2BAA2B,CAAC;IAC/C,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,qCAAqC,CAAC;IAClF,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,yGAAyG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AACvI,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ArtifactDescriptor, ComponentLibrary } from './artifacts/types.js';
|
|
2
|
+
/** Whether `--from-design` is available for an artifact. */
|
|
3
|
+
export declare function supportsFromDesign(descriptor: ArtifactDescriptor): boolean;
|
|
4
|
+
export declare function scaffoldFromDesign(descriptor: ArtifactDescriptor, projectName: string, projectPath: string, library: ComponentLibrary | undefined, designPath: string): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=fromDesign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fromDesign.d.ts","sourceRoot":"","sources":["../src/fromDesign.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgBjF,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAE1E;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,kBAAkB,EAC9B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,gBAAgB,GAAG,SAAS,EACrC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAqFf"}
|