@salesforce/afv-skills 1.13.0 → 1.14.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/package.json +3 -3
- package/skills/building-ui-bundle-app/SKILL.md +33 -8
- package/skills/generating-custom-application/SKILL.md +1 -1
- package/skills/generating-ui-bundle-custom-app/SKILL.md +93 -0
- package/skills/generating-ui-bundle-custom-app/docs/configure-metadata-custom-application.md +70 -0
- package/skills/generating-ui-bundle-metadata/SKILL.md +39 -1
- package/skills/reviewing-lwc-mobile-offline/SKILL.md +168 -0
- package/skills/reviewing-lwc-mobile-offline/references/grounding.md +7 -0
- package/skills/reviewing-lwc-mobile-offline/references/inline-graphql.md +43 -0
- package/skills/reviewing-lwc-mobile-offline/references/komaci-eslint.md +125 -0
- package/skills/reviewing-lwc-mobile-offline/references/lwc-if.md +78 -0
- package/skills/reviewing-lwc-mobile-offline/scripts/komaci.config.mjs +18 -0
- package/skills/reviewing-lwc-mobile-offline/scripts/package.json +10 -0
- package/skills/reviewing-lwc-mobile-offline/scripts/run-komaci.sh +69 -0
- package/skills/using-mobile-native-capabilities/SKILL.md +182 -0
- package/skills/using-mobile-native-capabilities/references/app-review.md +68 -0
- package/skills/using-mobile-native-capabilities/references/ar-space-capture.md +125 -0
- package/skills/using-mobile-native-capabilities/references/barcode-scanner.md +219 -0
- package/skills/using-mobile-native-capabilities/references/base-capability.md +22 -0
- package/skills/using-mobile-native-capabilities/references/biometrics.md +90 -0
- package/skills/using-mobile-native-capabilities/references/calendar.md +213 -0
- package/skills/using-mobile-native-capabilities/references/contacts.md +232 -0
- package/skills/using-mobile-native-capabilities/references/document-scanner.md +342 -0
- package/skills/using-mobile-native-capabilities/references/geofencing.md +123 -0
- package/skills/using-mobile-native-capabilities/references/location.md +158 -0
- package/skills/using-mobile-native-capabilities/references/mobile-capabilities.md +30 -0
- package/skills/using-mobile-native-capabilities/references/nfc.md +181 -0
- package/skills/using-mobile-native-capabilities/references/payments.md +95 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Komaci ESLint Static Analysis (`@salesforce/eslint-plugin-lwc-graph-analyzer`)
|
|
2
|
+
|
|
3
|
+
## Framework for the analysis
|
|
4
|
+
|
|
5
|
+
The Komaci offline analyzer is exposed as the ESLint plugin `@salesforce/eslint-plugin-lwc-graph-analyzer`. Its **recommended** ruleset catches LWC patterns that prevent offline data priming. This reviewer runs the plugin against the component's JS file and translates each lint message into an actionable remediation.
|
|
6
|
+
|
|
7
|
+
Use the documented per-rule remediations below — do not invent new ones — and only emit findings for rules that actually fired against the file in scope.
|
|
8
|
+
|
|
9
|
+
The recommended preset enables ~36 rules; only the 7 rules documented in **Per-rule remediation** below are surfaced as findings. Other recommended-preset rules (e.g. `no-eval-usage`, `no-functions-declared-within-getter-method`) may fire but are intentionally not mapped to remediations and must be dropped from the report.
|
|
10
|
+
|
|
11
|
+
## How to run the analyzer
|
|
12
|
+
|
|
13
|
+
Use the bundled script. It applies the plugin's recommended ruleset with the `bundleAnalyzer` processor enabled, and on first run installs the pinned versions of `@salesforce/eslint-plugin-lwc-graph-analyzer` and `eslint` into `scripts/node_modules` so the runner is isolated from whatever versions the host project happens to ship.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
scripts/run-komaci.sh path/to/component/component.js
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Prerequisites:
|
|
20
|
+
|
|
21
|
+
- The component's sibling HTML templates must live in the same directory as the JS file. The plugin's `bundleAnalyzer` processor discovers them automatically (via `readdirSync` on the bundle directory) and uses them to resolve the offline data graph across the bundle.
|
|
22
|
+
- A working `npm` and Node ≥ 18 on `PATH` for the first-run install.
|
|
23
|
+
|
|
24
|
+
The script emits ESLint's `--format json` output on stdout. Each `messages[*]` entry has `ruleId`, `severity`, `message`, `line`, `column`, `endLine`, `endColumn`, and `fix` (optional). Group messages by `ruleId`, then apply the per-rule remediation guidance below.
|
|
25
|
+
|
|
26
|
+
To run ESLint manually outside the script — using the same pinned versions, so the recommended config resolves to the flat-config-shaped form — install once and invoke the local binary:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd scripts
|
|
30
|
+
npm install # only on first run
|
|
31
|
+
node_modules/.bin/eslint \
|
|
32
|
+
--no-config-lookup \
|
|
33
|
+
--config komaci.config.mjs \
|
|
34
|
+
--format json \
|
|
35
|
+
path/to/component/component.js
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`scripts/komaci.config.mjs` and `scripts/package.json` ship together; the package pin (`@salesforce/eslint-plugin-lwc-graph-analyzer ^1.1.0-beta.2`, `eslint ^9.35.0`) ensures the plugin's `recommended` config is flat-config-shaped (no legacy `extends:` key).
|
|
39
|
+
|
|
40
|
+
## Per-rule remediation
|
|
41
|
+
|
|
42
|
+
For each rule below, the `Type`, `Description`, `Intent analysis`, and `Suggested action` strings are canonical and must be emitted unchanged in the finding. Do not paraphrase or augment them.
|
|
43
|
+
|
|
44
|
+
### `@salesforce/lwc-graph-analyzer/no-private-wire-config-property`
|
|
45
|
+
|
|
46
|
+
- **Type:** Private Wire Configuration Property
|
|
47
|
+
- **Description:** Properties used in wire configurations must be decorated with `@api` to be public and resolvable by the wire service.
|
|
48
|
+
- **Intent analysis:** The developer used properties in wire configurations without making them public using the `@api` decorator.
|
|
49
|
+
- **Suggested action:**
|
|
50
|
+
|
|
51
|
+
Make the properties public by using the `@api` decorator:
|
|
52
|
+
|
|
53
|
+
- Add `@api` decorator to properties used in wire configurations.
|
|
54
|
+
|
|
55
|
+
### `@salesforce/lwc-graph-analyzer/no-wire-config-references-non-local-property-reactive-value`
|
|
56
|
+
|
|
57
|
+
- **Type:** Wire Configuration References Non-Local Property
|
|
58
|
+
- **Description:** Wire configurations with reactive values (`$prop`) must reference only component properties, not imported values or values defined outside the component class.
|
|
59
|
+
- **Intent analysis:** The developer is trying to use a non-local value (imported or module-level) as a reactive parameter in a wire configuration.
|
|
60
|
+
- **Suggested action:** Wrap the non-local value in a getter:
|
|
61
|
+
|
|
62
|
+
- Introduce a getter which returns the imported value or the value of a module-level constant.
|
|
63
|
+
- Update the wire configuration to use the getter name as the reactive parameter.
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
// Instead of:
|
|
67
|
+
@wire(getData, { param: '$importedValue' })
|
|
68
|
+
|
|
69
|
+
// Use:
|
|
70
|
+
get localValue() {
|
|
71
|
+
return importedValue;
|
|
72
|
+
}
|
|
73
|
+
@wire(getData, { param: '$localValue' })
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Getter-related violations
|
|
77
|
+
|
|
78
|
+
The five rules below all share the **Violations in Getter** classification and emit the same `description`, `intentAnalysis`, and `suggestedAction`. When any of them fires, emit one finding per (rule, line) pair with the strings reproduced below.
|
|
79
|
+
|
|
80
|
+
Rules:
|
|
81
|
+
|
|
82
|
+
- `@salesforce/lwc-graph-analyzer/no-assignment-expression-assigns-value-to-member-variable`
|
|
83
|
+
- `@salesforce/lwc-graph-analyzer/no-reference-to-class-functions`
|
|
84
|
+
- `@salesforce/lwc-graph-analyzer/no-reference-to-module-functions`
|
|
85
|
+
- `@salesforce/lwc-graph-analyzer/no-getter-contains-more-than-return-statement`
|
|
86
|
+
- `@salesforce/lwc-graph-analyzer/no-unsupported-member-variable-in-member-expression`
|
|
87
|
+
|
|
88
|
+
Canonical fields:
|
|
89
|
+
|
|
90
|
+
- **Type:** Violations in Getter
|
|
91
|
+
- **Description:** A getter method does more than just returning a value
|
|
92
|
+
- **Intent analysis:** The developer attempted to modify component state, prepare data for consumption, or reference functions within a getter function.
|
|
93
|
+
- **Suggested action:**
|
|
94
|
+
|
|
95
|
+
**Compliant getter implementations**
|
|
96
|
+
|
|
97
|
+
Getters that:
|
|
98
|
+
- Directly access and return property values
|
|
99
|
+
- Return a literal value
|
|
100
|
+
- Compute and return values derived from existing properties
|
|
101
|
+
|
|
102
|
+
**Non-compliant getter implementations**
|
|
103
|
+
|
|
104
|
+
- **Violation: getters that call functions.** Getters that call functions cannot be primed for offline use cases.
|
|
105
|
+
*Remediation:* Reorganize any getter implementation code that calls a function, to move such calls out of the getter. Avoid invoking any function calls within getters.
|
|
106
|
+
- **Violation: getters with side effects.** Getters that assign values to member variables or modify state create unpredictable side effects and are not suitable for offline scenarios.
|
|
107
|
+
*Remediation:* Never assign values to member variables within a getter. LWC getters should only retrieve data without modifying any state. If you need to compute and cache a value, perform the computation and assignment in a lifecycle hook or method, then have the getter simply return the cached value.
|
|
108
|
+
- **Violation: getters that do more than just return a value.** Getters that perform complex operations beyond returning a value cannot be primed for offline use cases.
|
|
109
|
+
*Remediation:* Review the getters and make sure that they're composed to only return a value. Move any complex logic, data processing, or multiple operations into separate methods or lifecycle hooks, and have the getter simply return the result.
|
|
110
|
+
|
|
111
|
+
## Rules to follow
|
|
112
|
+
|
|
113
|
+
- If no action is required, return an empty list. Do not return null or any other value — return an empty array.
|
|
114
|
+
- Keep issues concise; avoid duplicated issues or unnecessary analysis for things that are not real violations.
|
|
115
|
+
- Stick to the instructions for the specific reviewer in scope. Issues outside that scope will be analyzed by other reviewers.
|
|
116
|
+
- For each violation, provide:
|
|
117
|
+
- `type` — verbatim from the rule entry above.
|
|
118
|
+
- `description` — verbatim from the rule entry above.
|
|
119
|
+
- `intentAnalysis` — verbatim from the rule entry above.
|
|
120
|
+
- `suggestedAction` — verbatim from the rule entry above.
|
|
121
|
+
- `filePath` — the path passed to ESLint.
|
|
122
|
+
- `location` — `{ startLine, startColumn, endLine, endColumn }` taken from the ESLint message's `line`, `column`, `endLine`, `endColumn`.
|
|
123
|
+
- `code` — *optional* — the source snippet from `startLine` through `endLine`, useful when the violation spans multiple lines.
|
|
124
|
+
- Drop messages whose `ruleId` is not in the seven rules above.
|
|
125
|
+
- Do not make assumptions about other components that may be referenced.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Conditional Rendering Compatibility (`lwc:if` → `if:true`/`if:false`)
|
|
2
|
+
|
|
3
|
+
## Framework for the analysis
|
|
4
|
+
|
|
5
|
+
The Komaci offline static analysis engine used by Salesforce Mobile App Plus and Field Service Mobile App does not support modern conditional rendering directives (`lwc:if={property}`, `lwc:elseif={property}`, `lwc:else`). These directives must be replaced with `if:true={property}` and `if:false={property}` to ensure compatibility with offline data priming.
|
|
6
|
+
|
|
7
|
+
Your task:
|
|
8
|
+
|
|
9
|
+
1. Inspect HTML.
|
|
10
|
+
2. Identify any usage of `lwc:if={property}`, `lwc:elseif={property}`, or `lwc:else`.
|
|
11
|
+
3. Recommend exactly how to replace them with `if:true` / `if:false` directives, preserving the original branching logic.
|
|
12
|
+
|
|
13
|
+
**FOCUS:**
|
|
14
|
+
|
|
15
|
+
- Only analyze and provide feedback on occurrences of `lwc:if={property}`, `lwc:elseif={property}`, and `lwc:else`.
|
|
16
|
+
- Ignore any other directives or potential issues unrelated to those three.
|
|
17
|
+
|
|
18
|
+
## Conversion rules
|
|
19
|
+
|
|
20
|
+
- **`lwc:if={property}`** → replace with `if:true={property}`.
|
|
21
|
+
- **`lwc:elseif={property}`** → typically requires a nested `if:false={previousCondition}` that wraps an `if:true={property}`.
|
|
22
|
+
- **`lwc:else`** → has no condition of its own, so it must be wrapped by `if:false={previousCondition}` (the inverse of the relevant condition chain).
|
|
23
|
+
- **Standalone `lwc:if`** (not followed by `lwc:elseif`/`lwc:else`) → still must be replaced with `if:true={property}`.
|
|
24
|
+
- **Multiple condition chains** → review every template; do not stop at the first occurrence.
|
|
25
|
+
|
|
26
|
+
## Conversion example
|
|
27
|
+
|
|
28
|
+
`before.html`:
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<template>
|
|
32
|
+
<template lwc:if="{conditionOne}">
|
|
33
|
+
<div>show condition one</div>
|
|
34
|
+
</template>
|
|
35
|
+
<template lwc:elseif="{conditionTwo}">
|
|
36
|
+
<div>show condition two</div>
|
|
37
|
+
</template>
|
|
38
|
+
<template lwc:else>
|
|
39
|
+
<div>show default condition</div>
|
|
40
|
+
</template>
|
|
41
|
+
</template>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`after.html`:
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<template>
|
|
48
|
+
<template if:true="{conditionOne}">
|
|
49
|
+
<div>show condition one</div>
|
|
50
|
+
</template>
|
|
51
|
+
<template if:false="{conditionOne}">
|
|
52
|
+
<template if:true="{conditionTwo}">
|
|
53
|
+
<div>show condition two</div>
|
|
54
|
+
</template>
|
|
55
|
+
<template if:false="{conditionTwo}">
|
|
56
|
+
<div>show default condition</div>
|
|
57
|
+
</template>
|
|
58
|
+
</template>
|
|
59
|
+
</template>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The proper review feedback for the example above:
|
|
63
|
+
|
|
64
|
+
- replace `lwc:if={conditionOne}` with `if:true={conditionOne}`
|
|
65
|
+
- replace `lwc:elseif={conditionTwo}` with `if:false={conditionOne}`, then create a nested template with `if:true={conditionTwo}` wrapping the remainder of the component
|
|
66
|
+
- replace `lwc:else` with `if:false={conditionTwo}`
|
|
67
|
+
|
|
68
|
+
Rules to follow:
|
|
69
|
+
|
|
70
|
+
- If no action is required, return an empty list. Do not return null or any other value — return an empty array.
|
|
71
|
+
- Keep issues concise; avoid duplicated issues or unnecessary analysis for things that are not real violations.
|
|
72
|
+
- Stick to the instructions for the specific reviewer in scope. Issues outside that scope will be analyzed by other reviewers.
|
|
73
|
+
- For each violation, provide:
|
|
74
|
+
- The exact violation type as defined by the reviewer in scope.
|
|
75
|
+
- A description of why it is a problem in the context of mobile offline priming.
|
|
76
|
+
- An intent analysis explaining what the developer likely intended.
|
|
77
|
+
- A suggested action with concrete code-level remediation.
|
|
78
|
+
- Do not make assumptions about other components that may be referenced.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// ESLint flat config for the Komaci offline static analyzer.
|
|
2
|
+
// Applies the recommended ruleset from
|
|
3
|
+
// @salesforce/eslint-plugin-lwc-graph-analyzer with the bundleAnalyzer
|
|
4
|
+
// processor wired in via the recommended config.
|
|
5
|
+
import lwcGraphAnalyzerPlugin from '@salesforce/eslint-plugin-lwc-graph-analyzer';
|
|
6
|
+
|
|
7
|
+
const PLUGIN_NAME = '@salesforce/lwc-graph-analyzer';
|
|
8
|
+
const RECOMMENDED = lwcGraphAnalyzerPlugin.configs.recommended;
|
|
9
|
+
|
|
10
|
+
export default [
|
|
11
|
+
{
|
|
12
|
+
name: `config: ${PLUGIN_NAME}`,
|
|
13
|
+
plugins: {
|
|
14
|
+
[PLUGIN_NAME]: lwcGraphAnalyzerPlugin,
|
|
15
|
+
},
|
|
16
|
+
...RECOMMENDED,
|
|
17
|
+
},
|
|
18
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "reviewing-lwc-mobile-offline-runner",
|
|
3
|
+
"private": true,
|
|
4
|
+
"description": "Pinned ESLint + Komaci plugin used by run-komaci.sh.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@salesforce/eslint-plugin-lwc-graph-analyzer": "^1.1.0-beta.2",
|
|
8
|
+
"eslint": "^9.35.0"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Komaci offline static analysis runner
|
|
4
|
+
#
|
|
5
|
+
# Runs @salesforce/eslint-plugin-lwc-graph-analyzer against an LWC bundle
|
|
6
|
+
# with the plugin's recommended ruleset and emits ESLint's JSON
|
|
7
|
+
# formatter output on stdout.
|
|
8
|
+
#
|
|
9
|
+
# The plugin's `bundleAnalyzer` processor expects the JS file to live
|
|
10
|
+
# next to its sibling HTML templates so the offline data graph can be
|
|
11
|
+
# resolved across the bundle.
|
|
12
|
+
#
|
|
13
|
+
# Plugin + ESLint versions are pinned in scripts/package.json and
|
|
14
|
+
# installed into scripts/node_modules on first run so the runner is
|
|
15
|
+
# isolated from whatever versions the host project happens to ship.
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
# run-komaci.sh path/to/component.js
|
|
19
|
+
#
|
|
20
|
+
# Arguments:
|
|
21
|
+
# $1 Path to the LWC component's JS file (required). The component's
|
|
22
|
+
# sibling HTML templates must live in the same directory; the
|
|
23
|
+
# plugin discovers them automatically via the bundle processor.
|
|
24
|
+
#
|
|
25
|
+
# Environment:
|
|
26
|
+
# KOMACI_ESLINT_BIN Override the eslint binary (default: scripts/node_modules/.bin/eslint)
|
|
27
|
+
#
|
|
28
|
+
# Output:
|
|
29
|
+
# ESLint --format json on stdout. Non-zero exit if eslint reports
|
|
30
|
+
# errors; the JSON is still emitted on stdout in either case.
|
|
31
|
+
|
|
32
|
+
set -euo pipefail
|
|
33
|
+
|
|
34
|
+
if [ $# -lt 1 ]; then
|
|
35
|
+
echo "Usage: $0 path/to/component.js" >&2
|
|
36
|
+
exit 2
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
JS_PATH="$1"
|
|
40
|
+
|
|
41
|
+
if [ ! -f "$JS_PATH" ]; then
|
|
42
|
+
echo "Error: $JS_PATH does not exist" >&2
|
|
43
|
+
exit 2
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
47
|
+
CONFIG_PATH="$SCRIPT_DIR/komaci.config.mjs"
|
|
48
|
+
PLUGIN_DIR="$SCRIPT_DIR/node_modules/@salesforce/eslint-plugin-lwc-graph-analyzer"
|
|
49
|
+
|
|
50
|
+
# Install the pinned ESLint + plugin versions on first run. We resolve
|
|
51
|
+
# them from SCRIPT_DIR so Node ESM picks up the right copy regardless
|
|
52
|
+
# of the caller's cwd or the host project's node_modules.
|
|
53
|
+
if [ ! -d "$PLUGIN_DIR" ]; then
|
|
54
|
+
echo "Installing pinned Komaci runner deps in $SCRIPT_DIR ..." >&2
|
|
55
|
+
(cd "$SCRIPT_DIR" && npm install --no-fund --no-save --silent) >&2
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
ESLINT="${KOMACI_ESLINT_BIN:-$SCRIPT_DIR/node_modules/.bin/eslint}"
|
|
59
|
+
|
|
60
|
+
# Run eslint with the plugin's recommended config and emit JSON.
|
|
61
|
+
# `--no-config-lookup` ignores any host-project ESLint config so only
|
|
62
|
+
# the Komaci recommended ruleset applies; `--no-error-on-unmatched-pattern`
|
|
63
|
+
# avoids hard failure if the component path is empty.
|
|
64
|
+
$ESLINT \
|
|
65
|
+
--no-config-lookup \
|
|
66
|
+
--no-error-on-unmatched-pattern \
|
|
67
|
+
--config "$CONFIG_PATH" \
|
|
68
|
+
--format json \
|
|
69
|
+
"$JS_PATH"
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: using-mobile-native-capabilities
|
|
3
|
+
description: "Build a Salesforce LWC that uses native mobile device capabilities — barcode scanner, biometrics, location, NFC, calendar, contacts, document scanner, geofencing, AR space capture, app review, and payments. Use this skill when the user asks for an LWC that scans a barcode, captures a photo of a document, reads location or geofences, prompts for biometrics, reads/writes the device calendar or contacts, taps NFC, takes a payment, prompts for an app review, or scans an AR space. Also triggers on \"lightning/mobileCapabilities\", \"mobile capability\", \"Nimbus\", \"device capability\". Do not use for mobile offline / Komaci priming reviews (use `reviewing-lwc-mobile-offline`) or for picking generic Lightning base components (use a generic Lightning base components skill)."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0"
|
|
6
|
+
---
|
|
7
|
+
<!-- adk-managed-skill -->
|
|
8
|
+
|
|
9
|
+
# Using Mobile Native Capabilities
|
|
10
|
+
|
|
11
|
+
The `lightning/mobileCapabilities` module exposes a set of factory functions
|
|
12
|
+
that return service objects for native device features (barcode scanning,
|
|
13
|
+
biometrics, location, etc.). Each service extends a common
|
|
14
|
+
[BaseCapability](references/base-capability.md) with an `isAvailable()`
|
|
15
|
+
method, so an LWC can degrade gracefully on surfaces where the capability is
|
|
16
|
+
not present (desktop, mobile web).
|
|
17
|
+
|
|
18
|
+
This skill routes an agent through (1) picking the right capability, (2)
|
|
19
|
+
loading the authoritative type definitions, and (3) wiring the service into
|
|
20
|
+
an LWC with the correct availability gating, error handling, and
|
|
21
|
+
deprecation-aware API choice.
|
|
22
|
+
|
|
23
|
+
## When to Use This Skill
|
|
24
|
+
|
|
25
|
+
- User asks for an LWC that uses a device capability listed in the index
|
|
26
|
+
below.
|
|
27
|
+
- User mentions `lightning/mobileCapabilities`, "mobile capability", or
|
|
28
|
+
"Nimbus" by name.
|
|
29
|
+
- User wants to know which mobile native APIs are available, or which one
|
|
30
|
+
fits their feature.
|
|
31
|
+
|
|
32
|
+
Do NOT use this skill for:
|
|
33
|
+
|
|
34
|
+
- Mobile-offline review of an LWC (lwc:if, inline GraphQL, Komaci-priming
|
|
35
|
+
violations) — use `reviewing-lwc-mobile-offline`.
|
|
36
|
+
- Picking generic Lightning Base Components — use
|
|
37
|
+
`using-lightning-base-components`.
|
|
38
|
+
|
|
39
|
+
## Prerequisites
|
|
40
|
+
|
|
41
|
+
- Knowledge that the LWC will run inside a supported mobile container
|
|
42
|
+
(Salesforce Mobile App, Field Service Mobile App). These capabilities are
|
|
43
|
+
unavailable on desktop and mobile web; gate every call behind
|
|
44
|
+
`isAvailable()`.
|
|
45
|
+
- Familiarity with the `lightning/mobileCapabilities` module declaration
|
|
46
|
+
(see [mobile-capabilities](references/mobile-capabilities.md)).
|
|
47
|
+
|
|
48
|
+
## Capability Index
|
|
49
|
+
|
|
50
|
+
| Capability | Reference | One-line use |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| App Review | [App Review](references/app-review.md) | Prompt the user for a native in-app review. |
|
|
53
|
+
| AR Space Capture | [AR Space Capture](references/ar-space-capture.md) | Capture a 3D scan of a physical space using AR. |
|
|
54
|
+
| Barcode Scanner | [Barcode Scanner](references/barcode-scanner.md) | Read QR / UPC / EAN / Code-128 / etc. from the camera. |
|
|
55
|
+
| Biometrics | [Biometrics](references/biometrics.md) | Authenticate via Face ID / fingerprint. |
|
|
56
|
+
| Calendar | [Calendar](references/calendar.md) | Read or create events on the device calendar. |
|
|
57
|
+
| Contacts | [Contacts](references/contacts.md) | Read or create entries in the device address book. |
|
|
58
|
+
| Document Scanner | [Document Scanner](references/document-scanner.md) | Scan paper documents using the camera with edge detection. |
|
|
59
|
+
| Geofencing | [Geofencing](references/geofencing.md) | Trigger logic when the device crosses a geographic boundary. |
|
|
60
|
+
| Location | [Location](references/location.md) | Read GPS coordinates and watch for updates. |
|
|
61
|
+
| NFC | [NFC](references/nfc.md) | Read or write NFC tags. |
|
|
62
|
+
| Payments | [Payments](references/payments.md) | Take an Apple Pay / Google Pay payment. |
|
|
63
|
+
|
|
64
|
+
## Workflow
|
|
65
|
+
|
|
66
|
+
### Step 1 — Identify the capability
|
|
67
|
+
|
|
68
|
+
Map the user's feature ask to one row of the capability index. If the ask
|
|
69
|
+
spans multiple capabilities (e.g. "scan a barcode and store it on a
|
|
70
|
+
contact"), plan for **each** capability separately — there is one factory
|
|
71
|
+
function per capability.
|
|
72
|
+
|
|
73
|
+
### Step 2 — Load the shared and capability-specific references
|
|
74
|
+
|
|
75
|
+
Read these two shared references **once** per session — they apply to every
|
|
76
|
+
capability and are not duplicated in the per-capability files:
|
|
77
|
+
|
|
78
|
+
- [BaseCapability](references/base-capability.md) — the common interface
|
|
79
|
+
with `isAvailable()` that every service extends.
|
|
80
|
+
- [mobile-capabilities](references/mobile-capabilities.md) — the
|
|
81
|
+
`lightning/mobileCapabilities` module declaration showing every
|
|
82
|
+
re-exported service.
|
|
83
|
+
|
|
84
|
+
Then open the capability's reference file from the table above. Each
|
|
85
|
+
per-capability reference contains the service-specific TypeScript API
|
|
86
|
+
(factory function, service interface, options types, result types, error
|
|
87
|
+
types) and assumes the two shared references above are already in context.
|
|
88
|
+
|
|
89
|
+
Do not infer the API from memory — read it. The services evolve and some
|
|
90
|
+
methods are explicitly `@deprecated` in favor of newer alternatives.
|
|
91
|
+
|
|
92
|
+
### Step 3 — Wire the service into the LWC
|
|
93
|
+
|
|
94
|
+
For each capability:
|
|
95
|
+
|
|
96
|
+
1. Import the factory from `lightning/mobileCapabilities`:
|
|
97
|
+
```js
|
|
98
|
+
import { getBarcodeScanner } from 'lightning/mobileCapabilities';
|
|
99
|
+
```
|
|
100
|
+
2. Get an instance: `const scanner = getBarcodeScanner();`
|
|
101
|
+
3. Gate the call behind `isAvailable()`:
|
|
102
|
+
```js
|
|
103
|
+
if (!scanner.isAvailable()) {
|
|
104
|
+
// graceful fallback or user message
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
4. Call the **non-deprecated** entry point. Several services keep older
|
|
109
|
+
methods marked `@deprecated` alongside the recommended one — always
|
|
110
|
+
prefer the recommended method in the reference.
|
|
111
|
+
5. Wrap the promise in `try/catch` and handle the typed failure codes the
|
|
112
|
+
service exposes (e.g. `BarcodeScannerFailureCode`,
|
|
113
|
+
`LocationServiceFailureCode`). User-cancelled vs. permission-denied vs.
|
|
114
|
+
service-unavailable are distinct UX states.
|
|
115
|
+
|
|
116
|
+
### Step 4 — Surface failure modes to the user
|
|
117
|
+
|
|
118
|
+
Each service defines its own failure-code enum. Translate codes into
|
|
119
|
+
user-actionable messages: a `USER_DENIED_PERMISSION` should ask the user to
|
|
120
|
+
grant permission; a `USER_DISABLED_PERMISSION` must direct them to the OS
|
|
121
|
+
settings; a `SERVICE_NOT_ENABLED` should be a developer-visible error, not
|
|
122
|
+
shown to the user.
|
|
123
|
+
|
|
124
|
+
### Step 5 — Stay inside the supported surface
|
|
125
|
+
|
|
126
|
+
Mobile capabilities are available **only** when the LWC runs inside a
|
|
127
|
+
supported Salesforce mobile app. If the same component is rendered on
|
|
128
|
+
desktop or mobile web, the factory will still return an object but
|
|
129
|
+
`isAvailable()` will return `false`. Never assume availability — gate every
|
|
130
|
+
call.
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
## Examples
|
|
134
|
+
|
|
135
|
+
### Example — "Scan a barcode and write it into a field"
|
|
136
|
+
|
|
137
|
+
1. Map to: Barcode Scanner.
|
|
138
|
+
2. Read [Barcode Scanner](references/barcode-scanner.md).
|
|
139
|
+
3. Use `scan(options)` (not the deprecated `beginCapture` / `resumeCapture`
|
|
140
|
+
/ `endCapture` triple).
|
|
141
|
+
4. In options, set the `barcodeTypes` to the symbologies needed (default is
|
|
142
|
+
all supported types) and `enableMultiScan: false` for a single read.
|
|
143
|
+
5. On resolve, write `result[0].value` to the bound field. On reject,
|
|
144
|
+
inspect `error.code` against `BarcodeScannerFailureCode`.
|
|
145
|
+
|
|
146
|
+
### Example — "Take an Apple Pay payment for an order total"
|
|
147
|
+
|
|
148
|
+
1. Map to: Payments.
|
|
149
|
+
2. Read [Payments](references/payments.md).
|
|
150
|
+
3. Gate on `isAvailable()`.
|
|
151
|
+
4. Build the payment request object per the reference.
|
|
152
|
+
5. On resolve, surface the transaction id to the calling flow. On reject,
|
|
153
|
+
handle user-cancelled and payment-failed paths separately.
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
## Verification Checklist
|
|
157
|
+
|
|
158
|
+
- [ ] Every capability call is preceded by `isAvailable()`.
|
|
159
|
+
- [ ] The non-deprecated entry point is used (no `beginCapture` /
|
|
160
|
+
`resumeCapture` / `endCapture` for barcode, etc.).
|
|
161
|
+
- [ ] Each rejection path is mapped to the typed failure code enum.
|
|
162
|
+
- [ ] Imports come from `lightning/mobileCapabilities`, not from a private
|
|
163
|
+
path.
|
|
164
|
+
- [ ] No assumption that the capability runs on desktop or mobile web.
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
## Troubleshooting
|
|
168
|
+
|
|
169
|
+
- **`isAvailable()` returns `false` on a real device** — the device is
|
|
170
|
+
running an unsupported app surface (not Salesforce Mobile or Field
|
|
171
|
+
Service Mobile), or the service is gated by an org-level setting. The
|
|
172
|
+
fix is org configuration, not code.
|
|
173
|
+
- **TypeScript can't find the import** — confirm the LWC has access to
|
|
174
|
+
`lightning/mobileCapabilities`. The module is declared globally inside
|
|
175
|
+
Salesforce mobile containers; outside that, the types must be installed
|
|
176
|
+
separately.
|
|
177
|
+
- **Deprecated barcode methods still work** — yes, but new code must use
|
|
178
|
+
`scan()` and `dismiss()`. Refactor any sample code the agent received
|
|
179
|
+
before returning it.
|
|
180
|
+
- **Multiple capabilities in one component** — get separate instances per
|
|
181
|
+
capability (they are independent service objects); do not try to share
|
|
182
|
+
state between them.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# App Review Service Grounding Context
|
|
2
|
+
|
|
3
|
+
The following content provides grounding information for generating a Salesforce LWC that leverages app review facilities on mobile devices. Specifically, this context will cover the API types and methods available to leverage the app review API of the mobile device, within the LWC.
|
|
4
|
+
|
|
5
|
+
## App Review Service API
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
/*
|
|
9
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
10
|
+
* All rights reserved.
|
|
11
|
+
* For full license text, see the LICENSE.txt file
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { BaseCapability } from '../BaseCapability.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Use this factory function to get an instance of {@linkcode AppReviewService}.
|
|
18
|
+
* @returns An instance of {@linkcode AppReviewService}.
|
|
19
|
+
*/
|
|
20
|
+
export function getAppReviewService(): AppReviewService;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Request an app review from a Lightning web component.
|
|
24
|
+
* @see {@link https://developer.salesforce.com/docs/platform/lwc/guide/reference-lightning-appreviewservice.html|AppReviewService API}
|
|
25
|
+
*/
|
|
26
|
+
export interface AppReviewService extends BaseCapability {
|
|
27
|
+
/**
|
|
28
|
+
* Requests an app review.
|
|
29
|
+
* @param options An {@linkcode AppReviewServiceOptions} object to configure the {@linkcode AppReviewService} request.
|
|
30
|
+
* @returns A resolved promise returns null.
|
|
31
|
+
*/
|
|
32
|
+
requestAppReview(options?: AppReviewServiceOptions): Promise<null>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* An object representing configuration details for an {@linkcode AppReviewService} session.
|
|
37
|
+
*/
|
|
38
|
+
export interface AppReviewServiceOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Ignore the app review request if already asked for the current version of the app.
|
|
41
|
+
*/
|
|
42
|
+
ignoreIfAlreadyRequestedForCurrentAppVersion: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* An object representing an error that occurred when accessing {@linkcode AppReviewService} features.
|
|
47
|
+
*/
|
|
48
|
+
export interface AppReviewServiceFailure {
|
|
49
|
+
/**
|
|
50
|
+
* A value representing the reason for an app review error.
|
|
51
|
+
*/
|
|
52
|
+
code: AppReviewServiceFailureCode;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A string value describing the reason for the failure. This value is suitable for use in user interface messages. The message is provided in English and isn’t localized.
|
|
56
|
+
*/
|
|
57
|
+
message: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Possible failure codes.
|
|
62
|
+
*/
|
|
63
|
+
type AppReviewServiceFailureCode =
|
|
64
|
+
| 'ALREADY_REQUESTED_FOR_CURRENT_APP_VERSION'
|
|
65
|
+
| 'IN_APP_REVIEW_ERROR'
|
|
66
|
+
| 'SERVICE_NOT_ENABLED'
|
|
67
|
+
| 'UNKNOWN_REASON';
|
|
68
|
+
```
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# AR Space Capture Service Grounding Context
|
|
2
|
+
|
|
3
|
+
The following content provides grounding information for generating a Salesforce LWC that leverages AR Space Capture facilities on mobile devices. Specifically, this context will cover the API types and methods available to leverage the AR Space Capture API of the mobile device, within the LWC.
|
|
4
|
+
|
|
5
|
+
## AR Space Capture Service API
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
/*
|
|
9
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
10
|
+
* All rights reserved.
|
|
11
|
+
* For full license text, see the LICENSE.txt file
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { BaseCapability } from '../BaseCapability.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Use this factory function to get an instance of {@linkcode ARSpaceCapture}.
|
|
18
|
+
* @returns An instance of {@linkcode ARSpaceCapture}.
|
|
19
|
+
*/
|
|
20
|
+
export function getARSpaceCapture(): ARSpaceCapture;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Scan a room using Apple's RoomPlan AR Capabilities.
|
|
24
|
+
*/
|
|
25
|
+
export interface ARSpaceCapture extends BaseCapability {
|
|
26
|
+
/**
|
|
27
|
+
* Scan Room using Apple's AR Capabilities.
|
|
28
|
+
* @param options The customization options for the {@linkcode ARSpaceCapture} Plugin.
|
|
29
|
+
* @returns A resolved promise returns {@linkcode ARSpaceCaptureResult} object.
|
|
30
|
+
*/
|
|
31
|
+
scanRoom(options?: ARSpaceCaptureOptions): Promise<ARSpaceCaptureResult>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* ARSpaceCaptureResult interface.
|
|
36
|
+
*/
|
|
37
|
+
export interface ARSpaceCaptureResult {
|
|
38
|
+
capturedRooms: CapturedRoom[] | null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* CapturedRoom interface.
|
|
43
|
+
*/
|
|
44
|
+
export interface CapturedRoom {
|
|
45
|
+
/**
|
|
46
|
+
* An array of walls that the framework identifies during a scan.
|
|
47
|
+
*/
|
|
48
|
+
walls: unknown[];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* An array of doors that the framework identifies during a scan.
|
|
52
|
+
*/
|
|
53
|
+
doors: unknown[];
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* An array of windows that the framework identifies during a scan.
|
|
57
|
+
*/
|
|
58
|
+
windows: unknown[];
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* An array of openings that the framework identifies during a scan.
|
|
62
|
+
*/
|
|
63
|
+
openings: unknown[];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* An array of floors that the framework identifies during a scan.
|
|
67
|
+
* Available iOS 17.0+.
|
|
68
|
+
*/
|
|
69
|
+
floors: unknown[];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* An array of objects that the framework identifies during a scan.
|
|
73
|
+
*/
|
|
74
|
+
objects: unknown[];
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A unique alphanumeric value that the framework assigns the room.
|
|
78
|
+
*/
|
|
79
|
+
identifier: string;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* One or more room types that the framework observes in the room.
|
|
83
|
+
* Available iOS 17.0+.
|
|
84
|
+
*/
|
|
85
|
+
sections: unknown[];
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The story, floor number, or level on which the captured room resides within a larger structure.
|
|
89
|
+
* Available iOS 17.0+.
|
|
90
|
+
*/
|
|
91
|
+
story: number;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* A version number for the captured room.
|
|
95
|
+
* Available iOS 17.0+.
|
|
96
|
+
*/
|
|
97
|
+
version: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* ARSpaceCaptureOptions interface.
|
|
102
|
+
*/
|
|
103
|
+
export interface ARSpaceCaptureOptions {
|
|
104
|
+
permissionRationaleText?: string;
|
|
105
|
+
presentWithAnimation: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* ARSpaceCaptureFailure interface.
|
|
110
|
+
*/
|
|
111
|
+
export interface ARSpaceCaptureFailure {
|
|
112
|
+
code: ARSpaceCaptureFailureCode;
|
|
113
|
+
message: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Possible failure codes.
|
|
118
|
+
*/
|
|
119
|
+
type ARSpaceCaptureFailureCode =
|
|
120
|
+
| 'USER_DISMISSED' // User cancelled the operation.
|
|
121
|
+
| 'USER_DENIED_PERMISSION' // The user denied permissions to use the device camera.
|
|
122
|
+
| 'AR_NOT_SUPPORTED' // The AR capabilities are not enabled/available on the device.
|
|
123
|
+
| 'SERVICE_NOT_ENABLED' // The service is not enabled and therefore cannot be used.
|
|
124
|
+
| 'UNKNOWN_REASON'; // An error happened in the native code that is not permission based. Will give more information in the ARSpaceCaptureFailure message
|
|
125
|
+
```
|