@salesforce/ui-bundle-template-app-angular-template-b2e 11.30.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/LICENSE.txt +82 -0
- package/dist/.forceignore +15 -0
- package/dist/.husky/pre-commit +4 -0
- package/dist/.prettierignore +11 -0
- package/dist/.prettierrc +17 -0
- package/dist/CHANGELOG.md +3966 -0
- package/dist/README.md +77 -0
- package/dist/config/project-scratch-def.json +13 -0
- package/dist/eslint.config.js +7 -0
- package/dist/force-app/main/default/applications/angularinternalapp.app-meta.xml +17 -0
- package/dist/force-app/main/default/permissionsets/angularinternalapp_Access.permissionset-meta.xml +13 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.forceignore +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.postcssrc.json +5 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.prettierignore +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/.prettierrc +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/CHANGELOG.md +4 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/README.md +85 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/angular.json +98 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/angularinternalapp.uibundle-meta.xml +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/e2e/app.spec.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/esbuild/api-version.mjs +17 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/eslint.config.js +60 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/middleware/html.mjs +3 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/middleware/proxy.mjs +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/package.json +57 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/playwright.config.ts +25 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/public/favicon.ico +0 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/scripts/rewrite-e2e-assets.mjs +30 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/account-search.service.ts +196 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/distinctAccountIndustries.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/distinctAccountTypes.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/getAccountDetail.ts +128 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/account/searchAccounts.ts +58 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/data-client.service.spec.ts +184 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/api/data-client.service.ts +74 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.config.ts +22 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.routes.ts +31 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.spec.ts +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/app.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/layout/app-layout/app-layout.component.html +52 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/layout/app-layout/app-layout.component.spec.ts +90 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/layout/app-layout/app-layout.component.ts +67 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/_field-size.scss +42 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/alert/alert.component.html +31 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/alert/alert.component.ts +53 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/button/button.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/button/button.component.scss +112 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/button/button.component.ts +57 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/card/card.component.scss +34 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/card/card.component.ts +110 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/collapsible/collapsible.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/collapsible/collapsible.component.ts +26 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-picker/date-picker.component.html +25 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-picker/date-picker.component.scss +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-picker/date-picker.component.ts +41 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.html +34 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.scss +33 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/date-range-picker/date-range-picker.component.ts +66 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/dialog/dialog.component.html +37 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/dialog/dialog.component.ts +55 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/field/field.component.html +21 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/field/field.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/field-size.ts +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/input/input.component.html +19 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/input/input.component.scss +35 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/input/input.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/label/label.component.html +3 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/label/label.component.ts +17 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/paginator/paginator.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/paginator/paginator.component.ts +37 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/popover/popover.component.html +41 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/popover/popover.component.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/select/select.component.html +24 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/select/select.component.scss +35 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/select/select.component.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/separator/separator.component.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/separator/separator.component.scss +23 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/separator/separator.component.ts +56 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/skeleton/skeleton.component.html +1 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/skeleton/skeleton.component.scss +28 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/skeleton/skeleton.component.ts +24 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/components/ui/spinner/spinner.component.ts +35 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/agentforce/agentforce-conversation-client/agentforce-conversation-client.component.html +3 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/agentforce/agentforce-conversation-client/agentforce-conversation-client.component.ts +119 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/agentforce/agentforce-embed.service.ts +177 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/active-filters/active-filters.component.html +23 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/active-filters/active-filters.component.ts +78 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-filter/date-filter.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-filter/date-filter.component.ts +137 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-range-filter/date-range-filter.component.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/date-range-filter/date-range-filter.component.ts +69 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/filter-field-wrapper/filter-field-wrapper.component.html +11 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/filter-field-wrapper/filter-field-wrapper.component.ts +36 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/multi-select-filter/multi-select-filter.component.html +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/multi-select-filter/multi-select-filter.component.ts +58 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/numeric-range-filter/numeric-range-filter.component.html +22 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/numeric-range-filter/numeric-range-filter.component.ts +146 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/search-filter/search-filter.component.html +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/search-filter/search-filter.component.ts +82 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/select-filter/select-filter.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/select-filter/select-filter.component.ts +65 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/text-filter/text-filter.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/filters/text-filter/text-filter.component.ts +90 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/object-breadcrumb/object-breadcrumb.component.html +55 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/object-breadcrumb/object-breadcrumb.component.ts +40 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/pagination-controls/pagination-controls.component.html +8 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/pagination-controls/pagination-controls.component.ts +61 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/search-bar/search-bar.component.html +59 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/search-bar/search-bar.component.ts +108 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/sort-control/sort-control.component.html +50 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/components/sort-control/sort-control.component.ts +72 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/object-search-state.service.ts +232 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/debounce.ts +31 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/field-utils.ts +54 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/filter-utils.ts +354 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/index.ts +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/features/object-search/utils/sort-utils.ts +46 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-detail/account-detail-page.component.html +174 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-detail/account-detail-page.component.scss +7 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-detail/account-detail-page.component.ts +199 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-search/account-search-page.component.html +111 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/account-search/account-search-page.component.ts +217 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home-page.component.html +18 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home-page.component.ts +47 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home.component.html +6 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home.component.spec.ts +23 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/home/home.component.ts +13 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/not-found/not-found.component.html +12 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/not-found/not-found.component.spec.ts +33 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/pages/not-found/not-found.component.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/types/conversation.ts +55 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/types/globals.d.ts +13 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/app/utils/async-data.ts +99 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/index.html +14 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/index.ts +15 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/main.ts +5 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/styles.scss +170 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/theme.scss +39 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/src/types/sf-globals.d.ts +9 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/tsconfig.app.json +11 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/tsconfig.json +33 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/tsconfig.spec.json +10 -0
- package/dist/force-app/main/default/uiBundles/angularinternalapp/ui-bundle.json +7 -0
- package/dist/jest.config.js +6 -0
- package/dist/package-lock.json +10066 -0
- package/dist/package.json +46 -0
- package/dist/scripts/apex/hello.apex +10 -0
- package/dist/scripts/gitignore-templates.json +4 -0
- package/dist/scripts/graphql-search.sh +191 -0
- package/dist/scripts/org-setup-config-schema.mjs +103 -0
- package/dist/scripts/org-setup-dev.mjs +87 -0
- package/dist/scripts/org-setup-utils.mjs +369 -0
- package/dist/scripts/org-setup-xml.mjs +182 -0
- package/dist/scripts/org-setup.config.json +9 -0
- package/dist/scripts/org-setup.mjs +1702 -0
- package/dist/scripts/sf-project-setup.mjs +103 -0
- package/dist/scripts/soql/account.soql +6 -0
- package/dist/scripts/validate-org-setup-config.mjs +38 -0
- package/dist/sfdx-project.json +12 -0
- package/package.json +40 -0
package/dist/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Salesforce DX Project: Next Steps
|
|
2
|
+
|
|
3
|
+
Now that you’ve created a Salesforce DX project, what’s next? Here are some documentation resources to get you started.
|
|
4
|
+
|
|
5
|
+
## Web app: install, build, and dev server
|
|
6
|
+
|
|
7
|
+
From the **SFDX project root** (this directory), run:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm run sf-project-setup
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This installs dependencies in the UI Bundle, builds it, and starts the Vite dev server. Use this after cloning or extracting the project.
|
|
14
|
+
|
|
15
|
+
## Set up the org
|
|
16
|
+
|
|
17
|
+
`npm run setup` configures a target org from this project in one command: it logs in
|
|
18
|
+
(a required precondition — auto-skipped if the org is already connected), deploys
|
|
19
|
+
metadata, assigns permission sets, imports sample data, refreshes the GraphQL
|
|
20
|
+
schema/types, and builds the UI Bundle. When `--target-org` is omitted it uses your
|
|
21
|
+
default org or, in an interactive terminal, prompts you to pick one.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm run setup -- --target-org <alias> # or omit --target-org to use the default / pick
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Setup does **not** start the dev server. Once the org is set up, use `dev:preview` to
|
|
28
|
+
refresh the GraphQL types against the org and launch the Vite dev server on its own:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run dev:preview
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Setup configuration (`scripts/org-setup.config.json`)
|
|
35
|
+
|
|
36
|
+
`org-setup.config.json` controls which steps run and how. Every top-level section is
|
|
37
|
+
optional; an absent section hides its step. It is validated against a shared schema
|
|
38
|
+
at build/CI time and again at the start of every `npm run setup`, so a malformed
|
|
39
|
+
config fails fast rather than misbehaving.
|
|
40
|
+
|
|
41
|
+
```jsonc
|
|
42
|
+
{
|
|
43
|
+
"permsetAssignments": {
|
|
44
|
+
"assignments": {
|
|
45
|
+
"My_Access": { "assignee": "currentUser" }
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"role": { "assignee": "currentUser", "roleName": "Admin" },
|
|
49
|
+
"selfRegistration": {
|
|
50
|
+
"selfRegProfile": "My Prospect Profile",
|
|
51
|
+
"accountName": "My Self-Registration"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
When a `selfRegistration` section is present, setup runs a **license pre-check**
|
|
57
|
+
before configuring self-registration: it derives the required `UserLicense` from the
|
|
58
|
+
configured `selfRegProfile` (matched on the stable `LicenseDefinitionKey`, not the
|
|
59
|
+
display name) and, if the org lacks that license or has no available seats, **warns
|
|
60
|
+
and skips** self-registration instead of reporting success — so prospect login can't
|
|
61
|
+
silently fail on an under-provisioned org. No separate license field is configured;
|
|
62
|
+
the requirement always follows the profile the flow assigns.
|
|
63
|
+
|
|
64
|
+
## How Do You Plan to Deploy Your Changes?
|
|
65
|
+
|
|
66
|
+
Do you want to deploy a set of changes, or create a self-contained application? Choose a [development model](https://developer.salesforce.com/tools/vscode/en/user-guide/development-models).
|
|
67
|
+
|
|
68
|
+
## Configure Your Salesforce DX Project
|
|
69
|
+
|
|
70
|
+
The `sfdx-project.json` file contains useful configuration information for your project. See [Salesforce DX Project Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm) in the _Salesforce DX Developer Guide_ for details about this file.
|
|
71
|
+
|
|
72
|
+
## Read All About It
|
|
73
|
+
|
|
74
|
+
- [Salesforce Extensions Documentation](https://developer.salesforce.com/tools/vscode/)
|
|
75
|
+
- [Salesforce CLI Setup Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm)
|
|
76
|
+
- [Salesforce DX Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm)
|
|
77
|
+
- [Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference.htm)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"orgName": "My Saleforce Org",
|
|
3
|
+
"edition": "Developer",
|
|
4
|
+
"features": ["EnableSetPasswordInApi"],
|
|
5
|
+
"settings": {
|
|
6
|
+
"lightningExperienceSettings": {
|
|
7
|
+
"enableS1DesktopEnabled": true
|
|
8
|
+
},
|
|
9
|
+
"mobileSettings": {
|
|
10
|
+
"enableS1EncryptedStoragePref2": false
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<CustomApplication xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
3
|
+
<brand>
|
|
4
|
+
<headerColor>#0070D2</headerColor>
|
|
5
|
+
<shouldOverrideOrgTheme>false</shouldOverrideOrgTheme>
|
|
6
|
+
</brand>
|
|
7
|
+
<formFactors>Small</formFactors>
|
|
8
|
+
<formFactors>Large</formFactors>
|
|
9
|
+
<isNavAutoTempTabsDisabled>false</isNavAutoTempTabsDisabled>
|
|
10
|
+
<isNavPersonalizationDisabled>false</isNavPersonalizationDisabled>
|
|
11
|
+
<isNavTabPersistenceDisabled>false</isNavTabPersistenceDisabled>
|
|
12
|
+
<isOmniPinnedViewEnabled>false</isOmniPinnedViewEnabled>
|
|
13
|
+
<label>angularinternalapp</label>
|
|
14
|
+
<navType>Standard</navType>
|
|
15
|
+
<uiBundle>c__angularinternalapp</uiBundle>
|
|
16
|
+
<uiType>Lightning</uiType>
|
|
17
|
+
</CustomApplication>
|
package/dist/force-app/main/default/permissionsets/angularinternalapp_Access.permissionset-meta.xml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
3
|
+
<applicationVisibilities>
|
|
4
|
+
<application>angularinternalapp</application>
|
|
5
|
+
<visible>true</visible>
|
|
6
|
+
</applicationVisibilities>
|
|
7
|
+
<hasActivationRequired>false</hasActivationRequired>
|
|
8
|
+
<label>angularinternalapp Access</label>
|
|
9
|
+
<userPermissions>
|
|
10
|
+
<enabled>true</enabled>
|
|
11
|
+
<name>ApiEnabled</name>
|
|
12
|
+
</userPermissions>
|
|
13
|
+
</PermissionSet>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
|
|
2
|
+
# More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
package.xml
|
|
6
|
+
|
|
7
|
+
# LWC configuration files
|
|
8
|
+
**/jsconfig.json
|
|
9
|
+
**/.eslintrc.json
|
|
10
|
+
|
|
11
|
+
# LWC Jest
|
|
12
|
+
**/__tests__/**
|
|
13
|
+
|
|
14
|
+
node_modules/
|
|
15
|
+
.DS_Store
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Base Angular App
|
|
2
|
+
|
|
3
|
+
Base Angular App is a template application that demonstrates how to build an Angular UI Bundle on the Salesforce platform with the Angular CLI, TypeScript, Tailwind, and the Salesforce UI Bundle SDK. It provides a minimal shell (home, 404), routing with standalone components and signals, so feature apps can extend it via the patches pipeline.
|
|
4
|
+
|
|
5
|
+
This UI Bundle lives inside an SFDX project. The project root is the directory that contains `force-app/` and `sfdx-project.json`. Run the commands in the sections below from the paths indicated.
|
|
6
|
+
|
|
7
|
+
## Table of contents
|
|
8
|
+
|
|
9
|
+
- [Run (development)](#run-development)
|
|
10
|
+
- [Build](#build)
|
|
11
|
+
- [Deploy](#deploy)
|
|
12
|
+
- [Test](#test)
|
|
13
|
+
- [Lint](#lint)
|
|
14
|
+
|
|
15
|
+
## Run (development)
|
|
16
|
+
|
|
17
|
+
From the UI Bundle directory (`force-app/main/default/uiBundles/base-angular-app`):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install
|
|
21
|
+
npm run dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This starts the Salesforce Angular dev server (`sf-angular-serve`).
|
|
25
|
+
|
|
26
|
+
## Build
|
|
27
|
+
|
|
28
|
+
From the UI Bundle directory:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install
|
|
32
|
+
npm run build
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The production build is written to `dist/` inside the UI Bundle folder. Use `npm run watch` to rebuild on change in development mode. Deploy using the steps in [Deploy](#deploy).
|
|
36
|
+
|
|
37
|
+
## Deploy
|
|
38
|
+
|
|
39
|
+
From the **SFDX project root** (the directory that contains `force-app/`):
|
|
40
|
+
|
|
41
|
+
1. Build the UI Bundle:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cd force-app/main/default/uiBundles/base-angular-app && npm install && npm run build && cd -
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
2. Deploy the UI Bundle only:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
sf project deploy start --source-dir force-app/main/default/ui-bundles --target-org <alias>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Or deploy all metadata:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
sf project deploy start --source-dir force-app --target-org <alias>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Replace `<alias>` with your target org alias.
|
|
60
|
+
|
|
61
|
+
## Test
|
|
62
|
+
|
|
63
|
+
From the UI Bundle directory:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install
|
|
67
|
+
npm run test
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This runs the unit test suite via `ng test`. For end-to-end tests:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run build:e2e
|
|
74
|
+
npm run e2e
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This builds with E2E asset rewrites and runs Playwright against the static build. Ensure Chromium is installed (`npx playwright install chromium` if needed).
|
|
78
|
+
|
|
79
|
+
## Lint
|
|
80
|
+
|
|
81
|
+
From the UI Bundle directory:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm run lint
|
|
85
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"cli": {
|
|
5
|
+
"packageManager": "npm",
|
|
6
|
+
"analytics": false
|
|
7
|
+
},
|
|
8
|
+
"newProjectRoot": "projects",
|
|
9
|
+
"projects": {
|
|
10
|
+
"angularinternalapp": {
|
|
11
|
+
"projectType": "application",
|
|
12
|
+
"schematics": {
|
|
13
|
+
"@schematics/angular:component": {
|
|
14
|
+
"style": "scss"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"root": "",
|
|
18
|
+
"sourceRoot": "src",
|
|
19
|
+
"prefix": "app",
|
|
20
|
+
"architect": {
|
|
21
|
+
"build": {
|
|
22
|
+
"builder": "@angular-builders/custom-esbuild:application",
|
|
23
|
+
"options": {
|
|
24
|
+
"outputPath": {
|
|
25
|
+
"base": "dist",
|
|
26
|
+
"browser": ""
|
|
27
|
+
},
|
|
28
|
+
"deployUrl": "./",
|
|
29
|
+
"browser": "src/main.ts",
|
|
30
|
+
"tsConfig": "tsconfig.app.json",
|
|
31
|
+
"assets": [
|
|
32
|
+
{
|
|
33
|
+
"glob": "**/*",
|
|
34
|
+
"input": "public"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"styles": ["src/theme.scss", "src/styles.scss"],
|
|
38
|
+
"stylePreprocessorOptions": {
|
|
39
|
+
"sass": {
|
|
40
|
+
"silenceDeprecations": ["import"]
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"plugins": ["./esbuild/api-version.mjs"]
|
|
44
|
+
},
|
|
45
|
+
"configurations": {
|
|
46
|
+
"production": {
|
|
47
|
+
"budgets": [
|
|
48
|
+
{
|
|
49
|
+
"type": "anyComponentStyle",
|
|
50
|
+
"maximumWarning": "4kB",
|
|
51
|
+
"maximumError": "8kB"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"outputHashing": "all",
|
|
55
|
+
"optimization": {
|
|
56
|
+
"scripts": true,
|
|
57
|
+
"styles": {
|
|
58
|
+
"minify": true,
|
|
59
|
+
"inlineCritical": false
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"development": {
|
|
64
|
+
"optimization": false,
|
|
65
|
+
"extractLicenses": false,
|
|
66
|
+
"sourceMap": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"defaultConfiguration": "production"
|
|
70
|
+
},
|
|
71
|
+
"serve": {
|
|
72
|
+
"builder": "@angular-builders/custom-esbuild:dev-server",
|
|
73
|
+
"options": {
|
|
74
|
+
"middlewares": ["./middleware/html.mjs", "./middleware/proxy.mjs"]
|
|
75
|
+
},
|
|
76
|
+
"configurations": {
|
|
77
|
+
"production": {
|
|
78
|
+
"buildTarget": "angularinternalapp:build:production"
|
|
79
|
+
},
|
|
80
|
+
"development": {
|
|
81
|
+
"buildTarget": "angularinternalapp:build:development"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"defaultConfiguration": "development"
|
|
85
|
+
},
|
|
86
|
+
"test": {
|
|
87
|
+
"builder": "@angular/build:unit-test"
|
|
88
|
+
},
|
|
89
|
+
"lint": {
|
|
90
|
+
"builder": "@angular-eslint/builder:lint",
|
|
91
|
+
"options": {
|
|
92
|
+
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
3
|
+
<masterLabel>angularinternalapp</masterLabel>
|
|
4
|
+
<description>A Salesforce UI Bundle.</description>
|
|
5
|
+
<isActive>true</isActive>
|
|
6
|
+
<version>1</version>
|
|
7
|
+
<target>CustomApplication</target>
|
|
8
|
+
</UIBundle>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test.describe('base-angular-app', () => {
|
|
4
|
+
test('home page loads and shows welcome content', async ({ page }) => {
|
|
5
|
+
await page.goto('/');
|
|
6
|
+
await expect(page.getByRole('heading', { name: 'Home' })).toBeVisible();
|
|
7
|
+
await expect(page.getByText('Welcome to your Angular application.')).toBeVisible();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('not found route shows 404', async ({ page }) => {
|
|
11
|
+
await page.goto('/non-existent-route');
|
|
12
|
+
await expect(page.getByRole('heading', { name: '404' })).toBeVisible();
|
|
13
|
+
await expect(page.getByText('Page not found')).toBeVisible();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time substitution of `__SF_API_VERSION__` (production + main app code in dev).
|
|
3
|
+
*
|
|
4
|
+
* Resolves the connected org's API version (from `sf` CLI session) once at
|
|
5
|
+
* builder startup and injects it via esbuild's `define`. Falls back to "65.0"
|
|
6
|
+
* if no session is available — matches @salesforce/platform-sdk's default.
|
|
7
|
+
*
|
|
8
|
+
* In `ng serve`, this plugin runs on the application esbuild pass but does NOT
|
|
9
|
+
* reach Vite's optimizeDeps prebundle of node_modules. `scripts/dev.mjs` covers
|
|
10
|
+
* that gap by passing the same value via `ng serve --define`.
|
|
11
|
+
*
|
|
12
|
+
* Referenced from angular.json: architect.build.options.plugins[].
|
|
13
|
+
*/
|
|
14
|
+
import { createApiVersionPlugin } from '@salesforce/angular-plugin-ui-bundle';
|
|
15
|
+
|
|
16
|
+
const { plugin } = await createApiVersionPlugin();
|
|
17
|
+
export default plugin;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import angular from 'angular-eslint';
|
|
3
|
+
import tseslint from 'typescript-eslint';
|
|
4
|
+
|
|
5
|
+
export default tseslint.config(
|
|
6
|
+
// Global ignores
|
|
7
|
+
{
|
|
8
|
+
ignores: ['dist/**/*', '.angular/**/*', 'coverage/**/*', 'node_modules/**/*'],
|
|
9
|
+
},
|
|
10
|
+
// TypeScript files
|
|
11
|
+
{
|
|
12
|
+
files: ['**/*.ts'],
|
|
13
|
+
extends: [
|
|
14
|
+
js.configs.recommended,
|
|
15
|
+
...tseslint.configs.recommended,
|
|
16
|
+
...angular.configs.tsRecommended,
|
|
17
|
+
],
|
|
18
|
+
processor: angular.processInlineTemplates,
|
|
19
|
+
rules: {
|
|
20
|
+
'@angular-eslint/directive-selector': [
|
|
21
|
+
'error',
|
|
22
|
+
{
|
|
23
|
+
type: 'attribute',
|
|
24
|
+
prefix: 'app',
|
|
25
|
+
style: 'camelCase',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
'@angular-eslint/component-selector': [
|
|
29
|
+
'error',
|
|
30
|
+
{
|
|
31
|
+
type: 'element',
|
|
32
|
+
prefix: 'app',
|
|
33
|
+
style: 'kebab-case',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
// The UI wrapper components (app-button, app-card, …) intentionally
|
|
37
|
+
// alias an input to `class` so callers can write `class="…"` on the host
|
|
38
|
+
// and have it forward to the inner Material element. Allow that one name.
|
|
39
|
+
'@angular-eslint/no-input-rename': ['error', { allowedNames: ['class'] }],
|
|
40
|
+
'@typescript-eslint/no-unused-vars': [
|
|
41
|
+
'error',
|
|
42
|
+
{
|
|
43
|
+
argsIgnorePattern: '^_',
|
|
44
|
+
varsIgnorePattern: '^_',
|
|
45
|
+
caughtErrorsIgnorePattern: '^_',
|
|
46
|
+
ignoreRestSiblings: true,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
50
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
51
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
// Template files
|
|
55
|
+
{
|
|
56
|
+
files: ['**/*.html'],
|
|
57
|
+
extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility],
|
|
58
|
+
rules: {},
|
|
59
|
+
},
|
|
60
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy middleware for Angular CLI dev server.
|
|
3
|
+
*
|
|
4
|
+
* Forwards `/services/*` and other manifest-routed paths to the connected
|
|
5
|
+
* Salesforce org with authentication. Watches `ui-bundle.json` for changes
|
|
6
|
+
* and recreates the proxy handler automatically (manual browser refresh needed).
|
|
7
|
+
*
|
|
8
|
+
* Referenced from angular.json: architect.serve.options.middlewares[].
|
|
9
|
+
*/
|
|
10
|
+
import { createProxyMiddleware } from '@salesforce/angular-plugin-ui-bundle';
|
|
11
|
+
|
|
12
|
+
export default await createProxyMiddleware();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "base-angular-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "sf-angular-serve",
|
|
11
|
+
"dev:design": "sf-angular-serve",
|
|
12
|
+
"build": "ng build",
|
|
13
|
+
"watch": "ng build --watch --configuration development",
|
|
14
|
+
"test": "ng test",
|
|
15
|
+
"lint": "ng lint",
|
|
16
|
+
"build:e2e": "ng build && node scripts/rewrite-e2e-assets.mjs",
|
|
17
|
+
"e2e": "playwright test"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@angular/animations": "^21.2.0",
|
|
21
|
+
"@angular/cdk": "^21.2.0",
|
|
22
|
+
"@angular/common": "^21.2.0",
|
|
23
|
+
"@angular/compiler": "^21.2.0",
|
|
24
|
+
"@angular/core": "^21.2.0",
|
|
25
|
+
"@angular/forms": "^21.2.0",
|
|
26
|
+
"@angular/material": "^21.2.0",
|
|
27
|
+
"@angular/platform-browser": "^21.2.0",
|
|
28
|
+
"@angular/router": "^21.2.0",
|
|
29
|
+
"@salesforce/angular-plugin-ui-bundle": "^11.4.4",
|
|
30
|
+
"@salesforce/platform-sdk": "^11.4.4",
|
|
31
|
+
"rxjs": "~7.8.0",
|
|
32
|
+
"tslib": "^2.3.0",
|
|
33
|
+
"@salesforce/agentforce-conversation-client": "^11.12.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@angular-builders/custom-esbuild": "^21.0.0",
|
|
37
|
+
"@angular-eslint/builder": "^21.0.0",
|
|
38
|
+
"@angular/build": "^21.2.11",
|
|
39
|
+
"@angular/cli": "^21.2.11",
|
|
40
|
+
"@angular/compiler-cli": "^21.2.0",
|
|
41
|
+
"@eslint/js": "^9.0.0",
|
|
42
|
+
"@playwright/test": "^1.49.0",
|
|
43
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
44
|
+
"angular-eslint": "^21.0.0",
|
|
45
|
+
"eslint": "^9.0.0",
|
|
46
|
+
"jsdom": "^28.0.0",
|
|
47
|
+
"postcss": "^8.5.0",
|
|
48
|
+
"serve": "^14.2.5",
|
|
49
|
+
"tailwindcss": "^4.0.0",
|
|
50
|
+
"typescript": "~5.9.2",
|
|
51
|
+
"typescript-eslint": "^8.0.0",
|
|
52
|
+
"vitest": "^4.1.0"
|
|
53
|
+
},
|
|
54
|
+
"overrides": {
|
|
55
|
+
"undici": "^7.28.0"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
const E2E_PORT = 5176;
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
testDir: './e2e',
|
|
7
|
+
fullyParallel: true,
|
|
8
|
+
forbidOnly: !!process.env.CI,
|
|
9
|
+
retries: process.env.CI ? 2 : 0,
|
|
10
|
+
workers: process.env.CI ? 1 : undefined,
|
|
11
|
+
reporter: 'html',
|
|
12
|
+
use: {
|
|
13
|
+
baseURL: `http://localhost:${E2E_PORT}`,
|
|
14
|
+
trace: 'on-first-retry',
|
|
15
|
+
},
|
|
16
|
+
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
17
|
+
webServer: {
|
|
18
|
+
// Serve built dist/ with a static server so e2e works in CI without an SF org
|
|
19
|
+
// (ng serve runs the SF plugin/proxy middleware and can fail without an org).
|
|
20
|
+
command: `npx serve dist -l ${E2E_PORT}`,
|
|
21
|
+
url: `http://localhost:${E2E_PORT}`,
|
|
22
|
+
reuseExistingServer: !process.env.CI,
|
|
23
|
+
timeout: process.env.CI ? 120_000 : 60_000,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
Binary file
|
package/dist/force-app/main/default/uiBundles/angularinternalapp/scripts/rewrite-e2e-assets.mjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepares dist/ for e2e: root-relative asset paths + SPA fallback for serve.
|
|
3
|
+
*
|
|
4
|
+
* angular.json sets deployUrl: "./", so the built index.html references
|
|
5
|
+
* scripts/styles with a relative "./" prefix (e.g. ./main-HASH.js). When the
|
|
6
|
+
* SPA fallback serves index.html for a deep route like /non-existent-route,
|
|
7
|
+
* those "./" paths resolve against the wrong base and 404, so the app never
|
|
8
|
+
* boots. Rewrite them to root-relative "/" paths.
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
11
|
+
import { join, dirname } from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
// angular.json outputPath: { base: "dist", browser: "" } -> files land in dist/
|
|
16
|
+
const distDir = join(__dirname, '..', 'dist');
|
|
17
|
+
|
|
18
|
+
// Rewrite index.html so asset paths are root-relative (./main-x.js -> /main-x.js)
|
|
19
|
+
const indexPath = join(distDir, 'index.html');
|
|
20
|
+
let html = readFileSync(indexPath, 'utf8');
|
|
21
|
+
html = html.replace(/(src|href)="\.\//g, '$1="/');
|
|
22
|
+
writeFileSync(indexPath, html);
|
|
23
|
+
|
|
24
|
+
// SPA fallback so /non-existent-route etc. serve index.html
|
|
25
|
+
writeFileSync(
|
|
26
|
+
join(distDir, 'serve.json'),
|
|
27
|
+
JSON.stringify({
|
|
28
|
+
rewrites: [{ source: '**', destination: '/index.html' }],
|
|
29
|
+
}),
|
|
30
|
+
);
|