@cap-kit/people 8.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/CapKitPeople.podspec +20 -0
- package/LICENSE +21 -0
- package/Package.swift +28 -0
- package/README.md +1177 -0
- package/android/build.gradle +101 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/io/capkit/people/PeopleImpl.kt +1003 -0
- package/android/src/main/java/io/capkit/people/PeopleObserver.kt +80 -0
- package/android/src/main/java/io/capkit/people/PeoplePlugin.kt +766 -0
- package/android/src/main/java/io/capkit/people/config/PeopleConfig.kt +44 -0
- package/android/src/main/java/io/capkit/people/error/PeopleError.kt +90 -0
- package/android/src/main/java/io/capkit/people/error/PeopleErrorMessages.kt +39 -0
- package/android/src/main/java/io/capkit/people/logger/PeopleLogger.kt +85 -0
- package/android/src/main/java/io/capkit/people/models/ContactModels.kt +64 -0
- package/android/src/main/java/io/capkit/people/utils/PeopleUtils.kt +133 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +1449 -0
- package/dist/esm/definitions.d.ts +775 -0
- package/dist/esm/definitions.js +31 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +15 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +120 -0
- package/dist/esm/web.js +252 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs +300 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.js +303 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/PeoplePlugin/PeopleImpl.swift +463 -0
- package/ios/Sources/PeoplePlugin/PeoplePlugin.swift +627 -0
- package/ios/Sources/PeoplePlugin/PrivacyInfo.xcprivacy +13 -0
- package/ios/Sources/PeoplePlugin/Utils/PeopleUtils.swift +120 -0
- package/ios/Sources/PeoplePlugin/Version.swift +16 -0
- package/ios/Sources/PeoplePlugin/config/PeopleConfig.swift +56 -0
- package/ios/Sources/PeoplePlugin/error/PeopleError.swift +89 -0
- package/ios/Sources/PeoplePlugin/error/PeopleErrorMessages.swift +25 -0
- package/ios/Sources/PeoplePlugin/logger/PeopleLogging.swift +69 -0
- package/ios/Sources/PeoplePlugin/models/ContactModels.swift +68 -0
- package/ios/Tests/PeoplePluginTests/PeoplePluginTests.swift +10 -0
- package/package.json +119 -0
package/README.md
ADDED
|
@@ -0,0 +1,1177 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img
|
|
3
|
+
src="https://raw.githubusercontent.com/cap-kit/capacitor-plugins/main/assets/logo.png"
|
|
4
|
+
alt="CapKit Logo"
|
|
5
|
+
width="128"
|
|
6
|
+
/>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h3 align="center">People</h3>
|
|
10
|
+
<p align="center">
|
|
11
|
+
<strong>
|
|
12
|
+
<code>@cap-kit/people</code>
|
|
13
|
+
</strong>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
Enterprise-grade People Directory for Capacitor. Provides a unified, capability-based abstraction over native contact
|
|
18
|
+
systems, featuring native projection queries, zero-permission contact picking, systemic access with fine-grained
|
|
19
|
+
capabilities, live change observation, native semantic search, and first-class vCard import/export. Designed for
|
|
20
|
+
performance, privacy, and large datasets without memory bloat.
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<a href="https://www.npmjs.com/package/@cap-kit/people">
|
|
25
|
+
<img src="https://img.shields.io/npm/v/@cap-kit/people?color=blue&label=npm&logo=npm&style=flat-square" alt="npm version">
|
|
26
|
+
</a>
|
|
27
|
+
<a href="https://github.com/cap-kit/capacitor-plugins/actions">
|
|
28
|
+
<img src="https://img.shields.io/github/actions/workflow/status/cap-kit/capacitor-plugins/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" />
|
|
29
|
+
</a>
|
|
30
|
+
<a href="https://capacitorjs.com/">
|
|
31
|
+
<img src="https://img.shields.io/badge/Capacitor-Plugin-blue?logo=capacitor&style=flat-square" alt="Capacitor Plugin">
|
|
32
|
+
</a>
|
|
33
|
+
<a href="https://www.npmjs.com/package/@cap-kit/people">
|
|
34
|
+
<img src="https://img.shields.io/npm/dm/@cap-kit/people?style=flat-square" alt="Downloads" />
|
|
35
|
+
</a>
|
|
36
|
+
<a href="./LICENSE">
|
|
37
|
+
<img src="https://img.shields.io/npm/l/@cap-kit/people?style=flat-square&logo=open-source-initiative&logoColor=white&color=green" alt="License" />
|
|
38
|
+
</a>
|
|
39
|
+
<img src="https://img.shields.io/maintenance/yes/2026?style=flat-square" alt="Maintained" />
|
|
40
|
+
</p>
|
|
41
|
+
<br>
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pnpm add @cap-kit/people
|
|
47
|
+
# or
|
|
48
|
+
npm install @cap-kit/people
|
|
49
|
+
# or
|
|
50
|
+
yarn add @cap-kit/people
|
|
51
|
+
# then run:
|
|
52
|
+
npx cap sync
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Apple Privacy Manifest
|
|
56
|
+
|
|
57
|
+
Apple mandates that app developers specify approved reasons for API usage to enhance user privacy.
|
|
58
|
+
|
|
59
|
+
This plugin includes a skeleton `PrivacyInfo.xcprivacy` file located in `ios/Sources/PeoplePlugin/PrivacyInfo.xcprivacy`.
|
|
60
|
+
|
|
61
|
+
**You must populate this file if your plugin uses any [Required Reason APIs](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api).**
|
|
62
|
+
|
|
63
|
+
### Example: User Defaults
|
|
64
|
+
|
|
65
|
+
If your plugin uses `UserDefaults`, you must declare it in the manifest:
|
|
66
|
+
|
|
67
|
+
```xml
|
|
68
|
+
<dict>
|
|
69
|
+
<key>NSPrivacyAccessedAPIType</key>
|
|
70
|
+
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
|
71
|
+
<key>NSPrivacyAccessedAPITypeReasons</key>
|
|
72
|
+
<array>
|
|
73
|
+
<string>CA92.1</string>
|
|
74
|
+
</array>
|
|
75
|
+
</dict>
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
For detailed steps, please see the [Capacitor Docs](https://capacitorjs.com/docs/ios/privacy-manifest).
|
|
80
|
+
|
|
81
|
+
## Configuration
|
|
82
|
+
|
|
83
|
+
<docgen-config>
|
|
84
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
85
|
+
|
|
86
|
+
Configuration options for the People plugin.
|
|
87
|
+
|
|
88
|
+
| Prop | Type | Description | Default | Since |
|
|
89
|
+
| -------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
|
|
90
|
+
| **`verboseLogging`** | <code>boolean</code> | Enables verbose native logging. When enabled, additional debug information is printed to the native console (Logcat on Android, Xcode on iOS). This option affects native logging behavior only and has no impact on the JavaScript API. | <code>false</code> | 8.0.0 |
|
|
91
|
+
|
|
92
|
+
### Examples
|
|
93
|
+
|
|
94
|
+
In `capacitor.config.json`:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"plugins": {
|
|
99
|
+
"People": {
|
|
100
|
+
"verboseLogging": true
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
In `capacitor.config.ts`:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
/// <reference types="@cap-kit/people" />
|
|
110
|
+
|
|
111
|
+
import { CapacitorConfig } from '@capacitor/cli';
|
|
112
|
+
|
|
113
|
+
const config: CapacitorConfig = {
|
|
114
|
+
plugins: {
|
|
115
|
+
People: {
|
|
116
|
+
verboseLogging: true,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export default config;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
</docgen-config>
|
|
125
|
+
|
|
126
|
+
## Permissions
|
|
127
|
+
|
|
128
|
+
### Android
|
|
129
|
+
|
|
130
|
+
This plugin requires the following permissions be added to your `AndroidManifest.xml`:
|
|
131
|
+
|
|
132
|
+
```xml
|
|
133
|
+
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
|
134
|
+
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Read about [Setting Permissions](https://capacitorjs.com/docs/android/configuration#setting-permissions) in the [Android Guide](https://capacitorjs.com/docs/android) for more information on setting Android permissions.
|
|
139
|
+
|
|
140
|
+
### iOS
|
|
141
|
+
|
|
142
|
+
To use the plugin on iOS, you need to add the following keys to your `Info.plist` file:
|
|
143
|
+
|
|
144
|
+
#### Contacts
|
|
145
|
+
|
|
146
|
+
- `NSContactsUsageDescription`
|
|
147
|
+
- _Privacy - Contacts Usage Description_
|
|
148
|
+
|
|
149
|
+
Read about [Configuring `Info.plist`](https://capacitorjs.com/docs/ios/configuration#configuring-infoplist) in the [iOS Guide](https://capacitorjs.com/docs/ios) for more information on setting iOS permissions in Xcode.
|
|
150
|
+
|
|
151
|
+
### Web
|
|
152
|
+
|
|
153
|
+
On the Web platform, only the zero-permission contact picker is supported via the Contact Picker API when available.
|
|
154
|
+
All systemic access operations (`getContacts`, `getContact`, `searchPeople`, CRUD operations, group management, and `peopleChange` listeners) are not implemented on Web and will reject as unimplemented.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### ✅ Correct Usage
|
|
159
|
+
|
|
160
|
+
All People plugin APIs are based on Promise and follow the standard Capacitor v8 reject paradigm. Use `try / catch` to handle native cancellations and errors.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import { People, PeopleErrorCode } from '@cap-kit/people';
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const { contact } = await People.pickContact({
|
|
167
|
+
projection: ['name', 'phones', 'emails'],
|
|
168
|
+
});
|
|
169
|
+
console.log('Picked contact:', contact);
|
|
170
|
+
} catch (err: any) {
|
|
171
|
+
if (err.code === PeopleErrorCode.CANCELLED) {
|
|
172
|
+
// User canceled selection
|
|
173
|
+
console.log('Picker cancelled');
|
|
174
|
+
} else {
|
|
175
|
+
console.error('Error:', err.message);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### ❌ Incorrect Usage
|
|
183
|
+
|
|
184
|
+
Do not use checks based on the `success` property in the result, as the methods reject the Promise on error.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
// ❌ DO NOT DO THIS
|
|
188
|
+
const result = await People.pickContact();
|
|
189
|
+
if (result.success) { ... }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Error Handling
|
|
195
|
+
|
|
196
|
+
All People plugin methods can reject the Promise if they fail. It is recommended to handle standardized error codes using `PeopleErrorCode`.
|
|
197
|
+
|
|
198
|
+
### Error Codes
|
|
199
|
+
|
|
200
|
+
All error codes are standardized and exposed via `PeopleErrorCode`:
|
|
201
|
+
|
|
202
|
+
- `UNAVAILABLE` – Feature not available or OS limitation
|
|
203
|
+
- `CANCELLED` – User cancelled an interactive flow (e.g., contact picker)
|
|
204
|
+
- `PERMISSION_DENIED` – Permission denied or restricted
|
|
205
|
+
- `INIT_FAILED` – Internal initialization or processing failure
|
|
206
|
+
- `INVALID_INPUT` – Invalid, missing, or malformed input
|
|
207
|
+
- `UNKNOWN_TYPE` – Invalid or unsupported projection/type
|
|
208
|
+
|
|
209
|
+
These codes are consistent across **iOS**, **Android**, and **Web**.
|
|
210
|
+
|
|
211
|
+
### Example
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import { People, PeopleErrorCode } from '@cap-kit/people';
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
const { contact } = await People.pickContact();
|
|
218
|
+
console.log('Contact selected:', contact);
|
|
219
|
+
} catch (err: any) {
|
|
220
|
+
switch (err.code) {
|
|
221
|
+
case PeopleErrorCode.CANCELLED:
|
|
222
|
+
// The user canceled the selection
|
|
223
|
+
console.log('Picker cancelled by user');
|
|
224
|
+
break;
|
|
225
|
+
|
|
226
|
+
case PeopleErrorCode.UNAVAILABLE:
|
|
227
|
+
// The user canceled the selection or the picker is not available
|
|
228
|
+
console.log('Picker unavailable or cancelled by user');
|
|
229
|
+
break;
|
|
230
|
+
|
|
231
|
+
case PeopleErrorCode.PERMISSION_DENIED:
|
|
232
|
+
// User has denied access to contacts (for methods that require permissions)
|
|
233
|
+
console.error('Permission to access contacts was denied');
|
|
234
|
+
break;
|
|
235
|
+
|
|
236
|
+
case PeopleErrorCode.INIT_FAILED:
|
|
237
|
+
// Internal error while processing native data
|
|
238
|
+
console.error('Native initialization or processing failure');
|
|
239
|
+
break;
|
|
240
|
+
|
|
241
|
+
default:
|
|
242
|
+
// Generic or unexpected error
|
|
243
|
+
console.error('An unexpected error occurred:', err.message);
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## API
|
|
252
|
+
|
|
253
|
+
<docgen-index>
|
|
254
|
+
|
|
255
|
+
* [`createContact(...)`](#createcontact)
|
|
256
|
+
* [`updateContact(...)`](#updatecontact)
|
|
257
|
+
* [`deleteContact(...)`](#deletecontact)
|
|
258
|
+
* [`mergeContacts(...)`](#mergecontacts)
|
|
259
|
+
* [`listGroups()`](#listgroups)
|
|
260
|
+
* [`createGroup(...)`](#creategroup)
|
|
261
|
+
* [`deleteGroup(...)`](#deletegroup)
|
|
262
|
+
* [`addPeopleToGroup(...)`](#addpeopletogroup)
|
|
263
|
+
* [`removePeopleFromGroup(...)`](#removepeoplefromgroup)
|
|
264
|
+
* [`checkPermissions()`](#checkpermissions)
|
|
265
|
+
* [`requestPermissions(...)`](#requestpermissions)
|
|
266
|
+
* [`pickContact(...)`](#pickcontact)
|
|
267
|
+
* [`getContacts(...)`](#getcontacts)
|
|
268
|
+
* [`getContact(...)`](#getcontact)
|
|
269
|
+
* [`getCapabilities()`](#getcapabilities)
|
|
270
|
+
* [`getPluginVersion()`](#getpluginversion)
|
|
271
|
+
* [`searchPeople(...)`](#searchpeople)
|
|
272
|
+
* [`addListener('peopleChange', ...)`](#addlistenerpeoplechange-)
|
|
273
|
+
* [`addListener(string, ...)`](#addlistenerstring-)
|
|
274
|
+
* [`removeAllListeners()`](#removealllisteners)
|
|
275
|
+
* [Interfaces](#interfaces)
|
|
276
|
+
* [Type Aliases](#type-aliases)
|
|
277
|
+
|
|
278
|
+
</docgen-index>
|
|
279
|
+
|
|
280
|
+
<docgen-api>
|
|
281
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
282
|
+
|
|
283
|
+
Capacitor People plugin interface.
|
|
284
|
+
* This interface defines the contract between the JavaScript layer and the
|
|
285
|
+
native implementations (Android and iOS).
|
|
286
|
+
|
|
287
|
+
### createContact(...)
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
createContact(options: CreateContactOptions) => Promise<CreateContactResult>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
[CRUD]
|
|
294
|
+
Creates a new contact in the device's address book.
|
|
295
|
+
* @throws {PeopleError} PERMISSION_DENIED if contacts permission is missing.
|
|
296
|
+
|
|
297
|
+
| Param | Type |
|
|
298
|
+
| ------------- | --------------------------------------------------------------------- |
|
|
299
|
+
| **`options`** | <code><a href="#createcontactoptions">CreateContactOptions</a></code> |
|
|
300
|
+
|
|
301
|
+
**Returns:** <code>Promise<<a href="#createcontactresult">CreateContactResult</a>></code>
|
|
302
|
+
|
|
303
|
+
**Since:** 8.0.0
|
|
304
|
+
|
|
305
|
+
#### Example
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import { People } from '@cap-kit/people';
|
|
309
|
+
|
|
310
|
+
try {
|
|
311
|
+
const { contact } = await People.createContact({
|
|
312
|
+
contact: {
|
|
313
|
+
name: { given: 'John', family: 'Appleseed' },
|
|
314
|
+
emails: [{ address: 'john.appleseed@example.com', label: 'work' }],
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
console.log('Created contact ID:', contact.id);
|
|
318
|
+
} catch (error) {
|
|
319
|
+
console.error('Failed to create contact:', error.code);
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
--------------------
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
### updateContact(...)
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
updateContact(options: UpdateContactOptions) => Promise<UpdateContactResult>
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
[CRUD]
|
|
333
|
+
Updates an existing contact using a patch-based approach.
|
|
334
|
+
* @throws {PeopleError} PERMISSION_DENIED if permission is missing.
|
|
335
|
+
|
|
336
|
+
| Param | Type |
|
|
337
|
+
| ------------- | --------------------------------------------------------------------- |
|
|
338
|
+
| **`options`** | <code><a href="#updatecontactoptions">UpdateContactOptions</a></code> |
|
|
339
|
+
|
|
340
|
+
**Returns:** <code>Promise<<a href="#updatecontactresult">UpdateContactResult</a>></code>
|
|
341
|
+
|
|
342
|
+
**Since:** 8.0.0
|
|
343
|
+
|
|
344
|
+
#### Example
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
import { People } from '@cap-kit/people';
|
|
348
|
+
|
|
349
|
+
try {
|
|
350
|
+
const { contact } = await People.updateContact({
|
|
351
|
+
contactId: 'some-contact-id',
|
|
352
|
+
contact: {
|
|
353
|
+
organization: { company: 'New Company Inc.' },
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
console.log('Updated contact company:', contact.organization?.company);
|
|
357
|
+
} catch (error) {
|
|
358
|
+
console.error('Update failed:', error.message);
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
--------------------
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
### deleteContact(...)
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
deleteContact(options: DeleteContactOptions) => Promise<void>
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
[CRUD]
|
|
372
|
+
Deletes a contact from the device's address book.
|
|
373
|
+
Only contacts owned by the app can be deleted.
|
|
374
|
+
* @throws {PeopleError} UNAVAILABLE if deletion fails or contact is not app-owned.
|
|
375
|
+
|
|
376
|
+
| Param | Type |
|
|
377
|
+
| ------------- | --------------------------------------------------------------------- |
|
|
378
|
+
| **`options`** | <code><a href="#deletecontactoptions">DeleteContactOptions</a></code> |
|
|
379
|
+
|
|
380
|
+
**Since:** 8.0.0
|
|
381
|
+
|
|
382
|
+
#### Example
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
import { People } from '@cap-kit/people';
|
|
386
|
+
|
|
387
|
+
await People.deleteContact({ contactId: 'contact-id-to-delete' });
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
--------------------
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
### mergeContacts(...)
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
mergeContacts(options: MergeContactsOptions) => Promise<MergeContactsResult>
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
[CRUD]
|
|
400
|
+
Merges a source contact into a destination contact.
|
|
401
|
+
The source contact is deleted after the merge.
|
|
402
|
+
* @throws {PeopleError} PERMISSION_DENIED if permission is missing.
|
|
403
|
+
|
|
404
|
+
| Param | Type |
|
|
405
|
+
| ------------- | --------------------------------------------------------------------- |
|
|
406
|
+
| **`options`** | <code><a href="#mergecontactsoptions">MergeContactsOptions</a></code> |
|
|
407
|
+
|
|
408
|
+
**Returns:** <code>Promise<<a href="#mergecontactsresult">MergeContactsResult</a>></code>
|
|
409
|
+
|
|
410
|
+
**Since:** 8.0.0
|
|
411
|
+
|
|
412
|
+
#### Example
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
import { People } from '@cap-kit/people';
|
|
416
|
+
|
|
417
|
+
const { contact } = await People.mergeContacts({
|
|
418
|
+
sourceContactId: 'duplicate-contact-id',
|
|
419
|
+
destinationContactId: 'main-contact-id',
|
|
420
|
+
});
|
|
421
|
+
console.log('Final contact state:', contact);
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
--------------------
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
### listGroups()
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
listGroups() => Promise<ListGroupsResult>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
[GROUPS]
|
|
434
|
+
Lists all available contact groups.
|
|
435
|
+
|
|
436
|
+
**Returns:** <code>Promise<<a href="#listgroupsresult">ListGroupsResult</a>></code>
|
|
437
|
+
|
|
438
|
+
**Since:** 8.0.0
|
|
439
|
+
|
|
440
|
+
#### Example
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
const { groups } = await People.listGroups();
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
--------------------
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
### createGroup(...)
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
createGroup(options: CreateGroupOptions) => Promise<CreateGroupResult>
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
[GROUPS]
|
|
456
|
+
Creates a new contact group.
|
|
457
|
+
* @example
|
|
458
|
+
```typescript
|
|
459
|
+
const { group } = await People.createGroup({ name: 'Family' });
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
| Param | Type |
|
|
463
|
+
| ------------- | ----------------------------------------------------------------- |
|
|
464
|
+
| **`options`** | <code><a href="#creategroupoptions">CreateGroupOptions</a></code> |
|
|
465
|
+
|
|
466
|
+
**Returns:** <code>Promise<<a href="#creategroupresult">CreateGroupResult</a>></code>
|
|
467
|
+
|
|
468
|
+
**Since:** 8.0.0
|
|
469
|
+
|
|
470
|
+
--------------------
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
### deleteGroup(...)
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
deleteGroup(options: DeleteGroupOptions) => Promise<void>
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
[GROUPS]
|
|
480
|
+
Deletes a contact group.
|
|
481
|
+
|
|
482
|
+
| Param | Type |
|
|
483
|
+
| ------------- | ----------------------------------------------------------------- |
|
|
484
|
+
| **`options`** | <code><a href="#deletegroupoptions">DeleteGroupOptions</a></code> |
|
|
485
|
+
|
|
486
|
+
**Since:** 8.0.0
|
|
487
|
+
|
|
488
|
+
#### Example
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
import { People } from '@cap-kit/people';
|
|
492
|
+
|
|
493
|
+
await People.deleteGroup({ groupId: 'group-id-to-delete' });
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
--------------------
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
### addPeopleToGroup(...)
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
addPeopleToGroup(options: AddPeopleToGroupOptions) => Promise<void>
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
[GROUPS]
|
|
506
|
+
Adds contacts to a group.
|
|
507
|
+
|
|
508
|
+
| Param | Type |
|
|
509
|
+
| ------------- | --------------------------------------------------------------------------- |
|
|
510
|
+
| **`options`** | <code><a href="#addpeopletogroupoptions">AddPeopleToGroupOptions</a></code> |
|
|
511
|
+
|
|
512
|
+
**Since:** 8.0.0
|
|
513
|
+
|
|
514
|
+
#### Example
|
|
515
|
+
|
|
516
|
+
```typescript
|
|
517
|
+
import { People } from '@cap-kit/people';
|
|
518
|
+
|
|
519
|
+
await People.addPeopleToGroup({
|
|
520
|
+
groupId: 'group-id',
|
|
521
|
+
contactIds: ['contact-id-1', 'contact-id-2'],
|
|
522
|
+
});
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
--------------------
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
### removePeopleFromGroup(...)
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
removePeopleFromGroup(options: RemovePeopleFromGroupOptions) => Promise<void>
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
[GROUPS]
|
|
535
|
+
Removes contacts from a group.
|
|
536
|
+
|
|
537
|
+
| Param | Type |
|
|
538
|
+
| ------------- | ------------------------------------------------------------------------------------- |
|
|
539
|
+
| **`options`** | <code><a href="#removepeoplefromgroupoptions">RemovePeopleFromGroupOptions</a></code> |
|
|
540
|
+
|
|
541
|
+
**Since:** 8.0.0
|
|
542
|
+
|
|
543
|
+
#### Example
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
import { People } from '@cap-kit/people';
|
|
547
|
+
|
|
548
|
+
await People.removePeopleFromGroup({
|
|
549
|
+
groupId: 'group-id',
|
|
550
|
+
contactIds: ['contact-id-1'],
|
|
551
|
+
});
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
--------------------
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
### checkPermissions()
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
checkPermissions() => Promise<PeoplePluginPermissions>
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Check the status of permissions.
|
|
564
|
+
|
|
565
|
+
**Returns:** <code>Promise<<a href="#peoplepluginpermissions">PeoplePluginPermissions</a>></code>
|
|
566
|
+
|
|
567
|
+
**Since:** 8.0.0
|
|
568
|
+
|
|
569
|
+
#### Example
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
import { People } from '@cap-kit/people';
|
|
573
|
+
const permissions = await People.checkPermissions();
|
|
574
|
+
console.log(permissions.contacts); // Output: 'granted' | 'denied' | 'prompt'
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
--------------------
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
### requestPermissions(...)
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
requestPermissions(permissions?: { permissions: 'contacts'[]; } | undefined) => Promise<PeoplePluginPermissions>
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
Request permissions.
|
|
587
|
+
|
|
588
|
+
| Param | Type | Description |
|
|
589
|
+
| ----------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
590
|
+
| **`permissions`** | <code>{ permissions: 'contacts'[]; }</code> | - An optional object specifying which permissions to request. If not provided, all permissions defined in the plugin will be requested. |
|
|
591
|
+
|
|
592
|
+
**Returns:** <code>Promise<<a href="#peoplepluginpermissions">PeoplePluginPermissions</a>></code>
|
|
593
|
+
|
|
594
|
+
**Since:** 8.0.0
|
|
595
|
+
|
|
596
|
+
#### Example
|
|
597
|
+
|
|
598
|
+
```typescript
|
|
599
|
+
import { People } from '@cap-kit/people';
|
|
600
|
+
const permissions = await People.requestPermissions();
|
|
601
|
+
// OR
|
|
602
|
+
// const permissions = await People.requestPermissions({ permissions: ['contacts'] });
|
|
603
|
+
console.log(permissions.contacts); // Output: 'granted' | 'denied'
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
--------------------
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
### pickContact(...)
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
pickContact(options?: { projection?: PeopleProjection[] | undefined; } | undefined) => Promise<PickContactResult>
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
[ZERO-PERMISSION]
|
|
616
|
+
Launches the native OS contact picker UI.
|
|
617
|
+
This method does NOT require any entries in AndroidManifest.xml or Info.plist
|
|
618
|
+
as the user explicitly selects the data via the system UI.
|
|
619
|
+
|
|
620
|
+
| Param | Type |
|
|
621
|
+
| ------------- | ------------------------------------------------- |
|
|
622
|
+
| **`options`** | <code>{ projection?: PeopleProjection[]; }</code> |
|
|
623
|
+
|
|
624
|
+
**Returns:** <code>Promise<<a href="#pickcontactresult">PickContactResult</a>></code>
|
|
625
|
+
|
|
626
|
+
**Since:** 8.0.0
|
|
627
|
+
|
|
628
|
+
#### Example
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
try {
|
|
632
|
+
const { contact } = await People.pickContact({
|
|
633
|
+
projection: ['name', 'phones', 'emails']
|
|
634
|
+
});
|
|
635
|
+
console.log('User selected:', contact);
|
|
636
|
+
} catch (error) {
|
|
637
|
+
if (error.code === 'CANCELLED') {
|
|
638
|
+
console.log('User cancelled the picker.');
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
--------------------
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
### getContacts(...)
|
|
647
|
+
|
|
648
|
+
```typescript
|
|
649
|
+
getContacts(options?: GetContactsOptions | undefined) => Promise<GetContactsResult>
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
[SYSTEMIC-ACCESS]
|
|
653
|
+
Queries the entire contact database with specific projection and pagination.
|
|
654
|
+
REQUIRES 'contacts' permission.
|
|
655
|
+
Use `includeTotal` only when needed: computing `totalCount` may require scanning/counting across the full contacts set and can be expensive on large address books. Default is `false`.
|
|
656
|
+
|
|
657
|
+
| Param | Type |
|
|
658
|
+
| ------------- | ----------------------------------------------------------------- |
|
|
659
|
+
| **`options`** | <code><a href="#getcontactsoptions">GetContactsOptions</a></code> |
|
|
660
|
+
|
|
661
|
+
**Returns:** <code>Promise<<a href="#getcontactsresult">GetContactsResult</a>></code>
|
|
662
|
+
|
|
663
|
+
**Since:** 8.0.0
|
|
664
|
+
|
|
665
|
+
#### Example
|
|
666
|
+
|
|
667
|
+
```typescript
|
|
668
|
+
const result = await People.getContacts({
|
|
669
|
+
projection: ['name', 'phones'],
|
|
670
|
+
limit: 20,
|
|
671
|
+
offset: 0
|
|
672
|
+
});
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
--------------------
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
### getContact(...)
|
|
679
|
+
|
|
680
|
+
```typescript
|
|
681
|
+
getContact(options: { id: string; projection?: PeopleProjection[]; }) => Promise<{ contact: UnifiedContact; }>
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
Retrieves a single contact by ID.
|
|
685
|
+
* @throws {PeopleError} UNAVAILABLE if contact is not found.
|
|
686
|
+
|
|
687
|
+
| Param | Type |
|
|
688
|
+
| ------------- | ------------------------------------------------------------- |
|
|
689
|
+
| **`options`** | <code>{ id: string; projection?: PeopleProjection[]; }</code> |
|
|
690
|
+
|
|
691
|
+
**Returns:** <code>Promise<{ contact: <a href="#unifiedcontact">UnifiedContact</a>; }></code>
|
|
692
|
+
|
|
693
|
+
**Since:** 8.0.0
|
|
694
|
+
|
|
695
|
+
#### Example
|
|
696
|
+
|
|
697
|
+
```typescript
|
|
698
|
+
import { People } from '@cap-kit/people';
|
|
699
|
+
|
|
700
|
+
const { contact } = await People.getContact({ id: 'contact-id', projection: ['name', 'emails'] });
|
|
701
|
+
console.log('Contact details:', contact);
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
--------------------
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
### getCapabilities()
|
|
708
|
+
|
|
709
|
+
```typescript
|
|
710
|
+
getCapabilities() => Promise<PeopleCapabilities>
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
Returns what this device/implementation is capable of.
|
|
714
|
+
Useful for UI adaptation (e.g. hiding "Edit" buttons).
|
|
715
|
+
|
|
716
|
+
**Returns:** <code>Promise<<a href="#peoplecapabilities">PeopleCapabilities</a>></code>
|
|
717
|
+
|
|
718
|
+
**Since:** 8.0.0
|
|
719
|
+
|
|
720
|
+
#### Example
|
|
721
|
+
|
|
722
|
+
```typescript
|
|
723
|
+
import { People } from '@cap-kit/people';
|
|
724
|
+
|
|
725
|
+
const capabilities = await People.getCapabilities();
|
|
726
|
+
console.log('Can Read Contacts:', capabilities.canRead);
|
|
727
|
+
console.log('Can Write Contacts:', capabilities.canWrite);
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
--------------------
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
### getPluginVersion()
|
|
734
|
+
|
|
735
|
+
```typescript
|
|
736
|
+
getPluginVersion() => Promise<PluginVersionResult>
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
Returns the native plugin version.
|
|
740
|
+
|
|
741
|
+
The returned version corresponds to the native implementation
|
|
742
|
+
bundled with the application.
|
|
743
|
+
|
|
744
|
+
**Returns:** <code>Promise<<a href="#pluginversionresult">PluginVersionResult</a>></code>
|
|
745
|
+
|
|
746
|
+
**Since:** 8.0.0
|
|
747
|
+
|
|
748
|
+
#### Example
|
|
749
|
+
|
|
750
|
+
```ts
|
|
751
|
+
const { version } = await People.getPluginVersion();
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
--------------------
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
### searchPeople(...)
|
|
758
|
+
|
|
759
|
+
```typescript
|
|
760
|
+
searchPeople(options: { query: string; projection?: PeopleProjection[]; limit?: number; }) => Promise<GetContactsResult>
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
[SYSTEMIC-ACCESS]
|
|
764
|
+
Searches the database with projection.
|
|
765
|
+
REQUIRES 'contacts' permission.
|
|
766
|
+
|
|
767
|
+
| Param | Type |
|
|
768
|
+
| ------------- | -------------------------------------------------------------------------------- |
|
|
769
|
+
| **`options`** | <code>{ query: string; projection?: PeopleProjection[]; limit?: number; }</code> |
|
|
770
|
+
|
|
771
|
+
**Returns:** <code>Promise<<a href="#getcontactsresult">GetContactsResult</a>></code>
|
|
772
|
+
|
|
773
|
+
**Since:** 8.0.0
|
|
774
|
+
|
|
775
|
+
#### Example
|
|
776
|
+
|
|
777
|
+
```typescript
|
|
778
|
+
import { People } from '@cap-kit/people';
|
|
779
|
+
|
|
780
|
+
const result = await People.searchPeople({ query: 'John', projection: ['name', 'phones'], limit: 10 });
|
|
781
|
+
console.log('Fetched contacts:', result.contacts);
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
--------------------
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
### addListener('peopleChange', ...)
|
|
788
|
+
|
|
789
|
+
```typescript
|
|
790
|
+
addListener(eventName: 'peopleChange', listenerFunc: (payload: PeopleChangeEvent) => void) => Promise<PluginListenerHandle>
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
Listen for changes in the system address book.
|
|
794
|
+
REQUIRES 'contacts' permission.
|
|
795
|
+
* @returns A promise that resolves to a handle to remove the listener.
|
|
796
|
+
|
|
797
|
+
| Param | Type |
|
|
798
|
+
| ------------------ | ------------------------------------------------------------------------------------- |
|
|
799
|
+
| **`eventName`** | <code>'peopleChange'</code> |
|
|
800
|
+
| **`listenerFunc`** | <code>(payload: <a href="#peoplechangeevent">PeopleChangeEvent</a>) => void</code> |
|
|
801
|
+
|
|
802
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
803
|
+
|
|
804
|
+
**Since:** 8.0.0
|
|
805
|
+
|
|
806
|
+
#### Example
|
|
807
|
+
|
|
808
|
+
```typescript
|
|
809
|
+
import { People } from '@cap-kit/people';
|
|
810
|
+
|
|
811
|
+
const handle = await People.addListener('peopleChange', (event) => {
|
|
812
|
+
console.log('People change detected:', event.type);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
// To remove the listener later:
|
|
816
|
+
// await handle.remove();
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
--------------------
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
### addListener(string, ...)
|
|
823
|
+
|
|
824
|
+
```typescript
|
|
825
|
+
addListener(eventName: string, listenerFunc: (...args: unknown[]) => void) => Promise<PluginListenerHandle>
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
Registers a listener for plugin events using a generic event name.
|
|
829
|
+
|
|
830
|
+
Prefer the typed `peopleChange` overload for full payload type safety.
|
|
831
|
+
|
|
832
|
+
| Param | Type |
|
|
833
|
+
| ------------------ | -------------------------------------------- |
|
|
834
|
+
| **`eventName`** | <code>string</code> |
|
|
835
|
+
| **`listenerFunc`** | <code>(...args: unknown[]) => void</code> |
|
|
836
|
+
|
|
837
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
838
|
+
|
|
839
|
+
**Since:** 8.0.0
|
|
840
|
+
|
|
841
|
+
--------------------
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
### removeAllListeners()
|
|
845
|
+
|
|
846
|
+
```typescript
|
|
847
|
+
removeAllListeners() => Promise<void>
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
Removes all registered listeners for this plugin.
|
|
851
|
+
|
|
852
|
+
**Since:** 8.0.0
|
|
853
|
+
|
|
854
|
+
#### Example
|
|
855
|
+
|
|
856
|
+
```typescript
|
|
857
|
+
import { People } from '@cap-kit/people';
|
|
858
|
+
|
|
859
|
+
await People.removeAllListeners();
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
--------------------
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
### Interfaces
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
#### CreateContactResult
|
|
869
|
+
|
|
870
|
+
Result returned by `createContact`.
|
|
871
|
+
|
|
872
|
+
| Prop | Type | Description |
|
|
873
|
+
| ------------- | --------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
874
|
+
| **`contact`** | <code><a href="#unifiedcontact">UnifiedContact</a></code> | The full contact object as it was saved, including its new unique ID. |
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
#### UnifiedContact
|
|
878
|
+
|
|
879
|
+
Represents a Unified Person in the directory.
|
|
880
|
+
Maps to CNContact (iOS) and Aggregated Contact (Android).
|
|
881
|
+
|
|
882
|
+
| Prop | Type | Description |
|
|
883
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
|
884
|
+
| **`id`** | <code>string</code> | The platform-specific unique identifier (UUID or Long) |
|
|
885
|
+
| **`name`** | <code>{ display: string; given?: string; middle?: string; family?: string; prefix?: string; suffix?: string; }</code> | The unified display name |
|
|
886
|
+
| **`organization`** | <code>{ company?: string; title?: string; department?: string; }</code> | |
|
|
887
|
+
| **`birthday`** | <code>{ year?: number; month: number; day: number; }</code> | |
|
|
888
|
+
| **`phones`** | <code>PhoneNumber[]</code> | |
|
|
889
|
+
| **`emails`** | <code>EmailAddress[]</code> | |
|
|
890
|
+
| **`addresses`** | <code>PostalAddress[]</code> | |
|
|
891
|
+
| **`urls`** | <code>string[]</code> | |
|
|
892
|
+
| **`note`** | <code>string</code> | |
|
|
893
|
+
| **`image`** | <code>string</code> | Base64 thumbnail string (iOS only, only if projected). |
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
#### PhoneNumber
|
|
897
|
+
|
|
898
|
+
Phone number representation.
|
|
899
|
+
|
|
900
|
+
| Prop | Type | Description |
|
|
901
|
+
| ---------------- | ------------------- | ------------------------------------------------- |
|
|
902
|
+
| **`label`** | <code>string</code> | Normalized label (e.g., 'mobile', 'home', 'work') |
|
|
903
|
+
| **`number`** | <code>string</code> | The raw input string |
|
|
904
|
+
| **`normalized`** | <code>string</code> | E.164 formatted number (if parsing succeeded) |
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
#### EmailAddress
|
|
908
|
+
|
|
909
|
+
Email address representation.
|
|
910
|
+
|
|
911
|
+
| Prop | Type |
|
|
912
|
+
| ------------- | ------------------- |
|
|
913
|
+
| **`label`** | <code>string</code> |
|
|
914
|
+
| **`address`** | <code>string</code> |
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
#### PostalAddress
|
|
918
|
+
|
|
919
|
+
Postal address representation.
|
|
920
|
+
|
|
921
|
+
| Prop | Type |
|
|
922
|
+
| --------------- | ------------------- |
|
|
923
|
+
| **`label`** | <code>string</code> |
|
|
924
|
+
| **`formatted`** | <code>string</code> |
|
|
925
|
+
| **`street`** | <code>string</code> |
|
|
926
|
+
| **`city`** | <code>string</code> |
|
|
927
|
+
| **`region`** | <code>string</code> |
|
|
928
|
+
| **`postcode`** | <code>string</code> |
|
|
929
|
+
| **`country`** | <code>string</code> |
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
#### CreateContactOptions
|
|
933
|
+
|
|
934
|
+
Options for creating a new contact.
|
|
935
|
+
The contact data is provided as a partial <a href="#unifiedcontact">UnifiedContact</a>.
|
|
936
|
+
|
|
937
|
+
| Prop | Type | Description |
|
|
938
|
+
| ------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
|
|
939
|
+
| **`contact`** | <code>Partial<Omit<<a href="#unifiedcontact">UnifiedContact</a>, 'id'>></code> | The contact data to be saved. At least one writable field (e.g., name, email) must be provided. |
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
#### UpdateContactResult
|
|
943
|
+
|
|
944
|
+
Result returned by `updateContact`.
|
|
945
|
+
|
|
946
|
+
| Prop | Type | Description |
|
|
947
|
+
| ------------- | --------------------------------------------------------- | ---------------------------------------------------------- |
|
|
948
|
+
| **`contact`** | <code><a href="#unifiedcontact">UnifiedContact</a></code> | The full contact object after the update has been applied. |
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
#### UpdateContactOptions
|
|
952
|
+
|
|
953
|
+
Options for updating an existing contact.
|
|
954
|
+
This operation performs a patch, not a full replacement.
|
|
955
|
+
|
|
956
|
+
| Prop | Type | Description |
|
|
957
|
+
| --------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
|
|
958
|
+
| **`contactId`** | <code>string</code> | The unique identifier of the contact to update. |
|
|
959
|
+
| **`contact`** | <code>Partial<Omit<<a href="#unifiedcontact">UnifiedContact</a>, 'id'>></code> | An object containing the fields to be updated. Only the provided fields will be modified. |
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
#### DeleteContactOptions
|
|
963
|
+
|
|
964
|
+
Options for deleting a contact.
|
|
965
|
+
|
|
966
|
+
| Prop | Type | Description |
|
|
967
|
+
| --------------- | ------------------- | ----------------------------------------------- |
|
|
968
|
+
| **`contactId`** | <code>string</code> | The unique identifier of the contact to delete. |
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
#### MergeContactsResult
|
|
972
|
+
|
|
973
|
+
Result returned by `mergeContacts`.
|
|
974
|
+
|
|
975
|
+
| Prop | Type | Description |
|
|
976
|
+
| ------------- | --------------------------------------------------------- | ----------------------------------------------------- |
|
|
977
|
+
| **`contact`** | <code><a href="#unifiedcontact">UnifiedContact</a></code> | The state of the destination contact after the merge. |
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
#### MergeContactsOptions
|
|
981
|
+
|
|
982
|
+
Options for merging two contacts.
|
|
983
|
+
|
|
984
|
+
| Prop | Type | Description |
|
|
985
|
+
| -------------------------- | ------------------- | ---------------------------------------------------------------- |
|
|
986
|
+
| **`sourceContactId`** | <code>string</code> | The identifier of the contact that will be subsumed and deleted. |
|
|
987
|
+
| **`destinationContactId`** | <code>string</code> | The identifier of the contact that will be kept and updated. |
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
#### ListGroupsResult
|
|
991
|
+
|
|
992
|
+
Result returned by `listGroups`.
|
|
993
|
+
|
|
994
|
+
| Prop | Type | Description |
|
|
995
|
+
| ------------ | -------------------- | --------------------------------------------- |
|
|
996
|
+
| **`groups`** | <code>Group[]</code> | An array of groups found in the address book. |
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
#### Group
|
|
1000
|
+
|
|
1001
|
+
Represents a group in the address book.
|
|
1002
|
+
A group can be system-generated (e.g., "All Contacts") or user-created.
|
|
1003
|
+
|
|
1004
|
+
| Prop | Type | Description |
|
|
1005
|
+
| -------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1006
|
+
| **`id`** | <code>string</code> | A unique identifier for the group. This ID is stable and can be used for subsequent operations. |
|
|
1007
|
+
| **`name`** | <code>string</code> | The display name of the group. e.g., "Family", "Work", "Book Club" |
|
|
1008
|
+
| **`source`** | <code>string</code> | The source or account where the group originates. On iOS, this could be "iCloud" or "Local". On Android, this corresponds to the account name (e.g., "user@gmail.com"). For logical groups, this will be 'local'. |
|
|
1009
|
+
| **`readOnly`** | <code>boolean</code> | Indicates if the group is read-only. System groups are typically read-only and cannot be deleted or renamed. |
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
#### CreateGroupResult
|
|
1013
|
+
|
|
1014
|
+
Result returned by `createGroup`.
|
|
1015
|
+
|
|
1016
|
+
| Prop | Type | Description |
|
|
1017
|
+
| ----------- | --------------------------------------- | ------------------------ |
|
|
1018
|
+
| **`group`** | <code><a href="#group">Group</a></code> | The newly created group. |
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
#### CreateGroupOptions
|
|
1022
|
+
|
|
1023
|
+
Options for creating a new group.
|
|
1024
|
+
|
|
1025
|
+
| Prop | Type | Description |
|
|
1026
|
+
| ---------- | ------------------- | --------------------------- |
|
|
1027
|
+
| **`name`** | <code>string</code> | The name for the new group. |
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
#### DeleteGroupOptions
|
|
1031
|
+
|
|
1032
|
+
Options for deleting a group.
|
|
1033
|
+
|
|
1034
|
+
| Prop | Type | Description |
|
|
1035
|
+
| ------------- | ------------------- | --------------------------------------------- |
|
|
1036
|
+
| **`groupId`** | <code>string</code> | The unique identifier of the group to delete. |
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
#### AddPeopleToGroupOptions
|
|
1040
|
+
|
|
1041
|
+
Options for adding people to a group.
|
|
1042
|
+
|
|
1043
|
+
| Prop | Type | Description |
|
|
1044
|
+
| ---------------- | --------------------- | ---------------------------------------------------- |
|
|
1045
|
+
| **`groupId`** | <code>string</code> | The unique identifier of the group. |
|
|
1046
|
+
| **`contactIds`** | <code>string[]</code> | An array of contact identifiers to add to the group. |
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
#### RemovePeopleFromGroupOptions
|
|
1050
|
+
|
|
1051
|
+
Options for removing people from a group.
|
|
1052
|
+
|
|
1053
|
+
| Prop | Type | Description |
|
|
1054
|
+
| ---------------- | --------------------- | --------------------------------------------------------- |
|
|
1055
|
+
| **`groupId`** | <code>string</code> | The unique identifier of the group. |
|
|
1056
|
+
| **`contactIds`** | <code>string[]</code> | An array of contact identifiers to remove from the group. |
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
#### PeoplePluginPermissions
|
|
1060
|
+
|
|
1061
|
+
Permissions status interface.
|
|
1062
|
+
|
|
1063
|
+
| Prop | Type |
|
|
1064
|
+
| -------------- | ----------------------------------------------------------- |
|
|
1065
|
+
| **`contacts`** | <code><a href="#permissionstate">PermissionState</a></code> |
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
#### PickContactResult
|
|
1069
|
+
|
|
1070
|
+
Result returned by pickContact().
|
|
1071
|
+
Now strictly returns the contact object on success.
|
|
1072
|
+
|
|
1073
|
+
| Prop | Type |
|
|
1074
|
+
| ------------- | --------------------------------------------------------- |
|
|
1075
|
+
| **`contact`** | <code><a href="#unifiedcontact">UnifiedContact</a></code> |
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
#### GetContactsResult
|
|
1079
|
+
|
|
1080
|
+
Result returned by getContacts().
|
|
1081
|
+
|
|
1082
|
+
| Prop | Type | Description |
|
|
1083
|
+
| ---------------- | ----------------------------- | ---------------------------------------------- |
|
|
1084
|
+
| **`contacts`** | <code>UnifiedContact[]</code> | |
|
|
1085
|
+
| **`totalCount`** | <code>number</code> | Total count in the DB (permissions permitting) |
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
#### GetContactsOptions
|
|
1089
|
+
|
|
1090
|
+
Options for querying contacts.
|
|
1091
|
+
|
|
1092
|
+
| Prop | Type | Description | Default |
|
|
1093
|
+
| ------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- |
|
|
1094
|
+
| **`projection`** | <code>PeopleProjection[]</code> | Array of fields to fetch. MISSING fields will not be read from DB (Performance). | <code>['name']</code> |
|
|
1095
|
+
| **`limit`** | <code>number</code> | Max number of records to return | |
|
|
1096
|
+
| **`offset`** | <code>number</code> | Skip count (implement pagination via cursor usually better, but offset for now) | |
|
|
1097
|
+
| **`includeTotal`** | <code>boolean</code> | Whether to compute totalCount across the full contacts set. This may require scanning/counting the full address book and can be expensive on large datasets. | <code>false</code> |
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
#### PeopleCapabilities
|
|
1101
|
+
|
|
1102
|
+
Capabilities of the People plugin on this device/implementation.
|
|
1103
|
+
|
|
1104
|
+
| Prop | Type |
|
|
1105
|
+
| --------------------- | -------------------- |
|
|
1106
|
+
| **`canRead`** | <code>boolean</code> |
|
|
1107
|
+
| **`canWrite`** | <code>boolean</code> |
|
|
1108
|
+
| **`canObserve`** | <code>boolean</code> |
|
|
1109
|
+
| **`canManageGroups`** | <code>boolean</code> |
|
|
1110
|
+
| **`canPickContact`** | <code>boolean</code> |
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
#### PluginVersionResult
|
|
1114
|
+
|
|
1115
|
+
Result object returned by the `getPluginVersion()` method.
|
|
1116
|
+
|
|
1117
|
+
| Prop | Type | Description |
|
|
1118
|
+
| ------------- | ------------------- | --------------------------------- |
|
|
1119
|
+
| **`version`** | <code>string</code> | The native plugin version string. |
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
#### PluginListenerHandle
|
|
1123
|
+
|
|
1124
|
+
| Prop | Type |
|
|
1125
|
+
| ------------ | ----------------------------------------- |
|
|
1126
|
+
| **`remove`** | <code>() => Promise<void></code> |
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
#### PeopleChangeEvent
|
|
1130
|
+
|
|
1131
|
+
Event emitted when changes are detected in the device's address book.
|
|
1132
|
+
|
|
1133
|
+
| Prop | Type | Description |
|
|
1134
|
+
| ---------- | ------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
1135
|
+
| **`ids`** | <code>string[]</code> | Array of affected contact IDs (always present, may be empty) |
|
|
1136
|
+
| **`type`** | <code><a href="#peoplechangetype">PeopleChangeType</a></code> | The type of change detected |
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
### Type Aliases
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
#### PermissionState
|
|
1143
|
+
|
|
1144
|
+
<code>'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'</code>
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
#### PeopleProjection
|
|
1148
|
+
|
|
1149
|
+
Supported fields for the Projection Engine.
|
|
1150
|
+
Requesting only what you need reduces memory usage by O(N).
|
|
1151
|
+
`image` projection support is iOS-only. On Android and Web, requesting `image` is rejected with `UNKNOWN_TYPE` and message `Unsupported projection field: image`.
|
|
1152
|
+
|
|
1153
|
+
<code>'name' | 'organization' | 'birthday' | 'phones' | 'emails' | 'addresses' | 'urls' | 'image' | 'note'</code>
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
#### PeopleChangeType
|
|
1157
|
+
|
|
1158
|
+
Payload delivered to listeners registered for "peopleChange".
|
|
1159
|
+
- `ids`: always present, contains changed contact IDs (may be empty).
|
|
1160
|
+
- `type`: one of 'insert' | 'update' | 'delete' (default 'update').
|
|
1161
|
+
Current native implementations emit `update`.
|
|
1162
|
+
|
|
1163
|
+
<code>'insert' | 'update' | 'delete'</code>
|
|
1164
|
+
|
|
1165
|
+
</docgen-api>
|
|
1166
|
+
|
|
1167
|
+
---
|
|
1168
|
+
|
|
1169
|
+
## Contributing
|
|
1170
|
+
|
|
1171
|
+
Contributions are welcome! Please read the [contributing guide](CONTRIBUTING.md) before submitting a pull request.
|
|
1172
|
+
|
|
1173
|
+
---
|
|
1174
|
+
|
|
1175
|
+
## License
|
|
1176
|
+
|
|
1177
|
+
MIT
|