@rachelallyson/planning-center-people-ts 1.1.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +181 -0
- package/README.md +16 -0
- package/dist/batch.d.ts +47 -0
- package/dist/batch.js +376 -0
- package/dist/client-manager.d.ts +66 -0
- package/dist/client-manager.js +156 -0
- package/dist/client.d.ts +71 -0
- package/dist/client.js +123 -0
- package/dist/core/http.d.ts +48 -0
- package/dist/core/http.js +265 -0
- package/dist/core/pagination.d.ts +34 -0
- package/dist/core/pagination.js +164 -0
- package/dist/index.d.ts +13 -3
- package/dist/index.js +23 -5
- package/dist/matching/matcher.d.ts +41 -0
- package/dist/matching/matcher.js +161 -0
- package/dist/matching/scoring.d.ts +35 -0
- package/dist/matching/scoring.js +141 -0
- package/dist/matching/strategies.d.ts +35 -0
- package/dist/matching/strategies.js +79 -0
- package/dist/modules/base.d.ts +46 -0
- package/dist/modules/base.js +82 -0
- package/dist/modules/contacts.d.ts +103 -0
- package/dist/modules/contacts.js +130 -0
- package/dist/modules/fields.d.ts +157 -0
- package/dist/modules/fields.js +294 -0
- package/dist/modules/households.d.ts +42 -0
- package/dist/modules/households.js +74 -0
- package/dist/modules/lists.d.ts +62 -0
- package/dist/modules/lists.js +92 -0
- package/dist/modules/notes.d.ts +74 -0
- package/dist/modules/notes.js +125 -0
- package/dist/modules/people.d.ts +196 -0
- package/dist/modules/people.js +221 -0
- package/dist/modules/workflows.d.ts +131 -0
- package/dist/modules/workflows.js +221 -0
- package/dist/monitoring.d.ts +53 -0
- package/dist/monitoring.js +142 -0
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.js +24 -0
- package/dist/testing/recorder.d.ts +58 -0
- package/dist/testing/recorder.js +195 -0
- package/dist/testing/simple-builders.d.ts +33 -0
- package/dist/testing/simple-builders.js +124 -0
- package/dist/testing/simple-factories.d.ts +91 -0
- package/dist/testing/simple-factories.js +288 -0
- package/dist/testing/types.d.ts +160 -0
- package/dist/testing/types.js +5 -0
- package/dist/types/batch.d.ts +50 -0
- package/dist/types/batch.js +5 -0
- package/dist/types/client.d.ts +89 -0
- package/dist/types/client.js +5 -0
- package/dist/types/events.d.ts +85 -0
- package/dist/types/events.js +5 -0
- package/dist/types/people.d.ts +20 -1
- package/package.json +9 -3
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* v2.0.0 Contacts Module
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ContactsModule = void 0;
|
|
7
|
+
const base_1 = require("./base");
|
|
8
|
+
class ContactsModule extends base_1.BaseModule {
|
|
9
|
+
/**
|
|
10
|
+
* Get all emails
|
|
11
|
+
*/
|
|
12
|
+
async getAllEmails() {
|
|
13
|
+
return this.getList('/emails');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get a single email by ID
|
|
17
|
+
*/
|
|
18
|
+
async getEmailById(id) {
|
|
19
|
+
return this.getSingle(`/emails/${id}`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create an email
|
|
23
|
+
*/
|
|
24
|
+
async createEmail(data) {
|
|
25
|
+
return this.createResource('/emails', data);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Update an email
|
|
29
|
+
*/
|
|
30
|
+
async updateEmail(id, data) {
|
|
31
|
+
return this.updateResource(`/emails/${id}`, data);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Delete an email
|
|
35
|
+
*/
|
|
36
|
+
async deleteEmail(id) {
|
|
37
|
+
return this.deleteResource(`/emails/${id}`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get all phone numbers
|
|
41
|
+
*/
|
|
42
|
+
async getAllPhoneNumbers() {
|
|
43
|
+
return this.getList('/phone_numbers');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a single phone number by ID
|
|
47
|
+
*/
|
|
48
|
+
async getPhoneNumberById(id) {
|
|
49
|
+
return this.getSingle(`/phone_numbers/${id}`);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a phone number
|
|
53
|
+
*/
|
|
54
|
+
async createPhoneNumber(data) {
|
|
55
|
+
return this.createResource('/phone_numbers', data);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Update a phone number
|
|
59
|
+
*/
|
|
60
|
+
async updatePhoneNumber(id, data) {
|
|
61
|
+
return this.updateResource(`/phone_numbers/${id}`, data);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Delete a phone number
|
|
65
|
+
*/
|
|
66
|
+
async deletePhoneNumber(id) {
|
|
67
|
+
return this.deleteResource(`/phone_numbers/${id}`);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get all addresses
|
|
71
|
+
*/
|
|
72
|
+
async getAllAddresses() {
|
|
73
|
+
return this.getList('/addresses');
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get a single address by ID
|
|
77
|
+
*/
|
|
78
|
+
async getAddressById(id) {
|
|
79
|
+
return this.getSingle(`/addresses/${id}`);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create an address
|
|
83
|
+
*/
|
|
84
|
+
async createAddress(data) {
|
|
85
|
+
return this.createResource('/addresses', data);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Update an address
|
|
89
|
+
*/
|
|
90
|
+
async updateAddress(id, data) {
|
|
91
|
+
return this.updateResource(`/addresses/${id}`, data);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Delete an address
|
|
95
|
+
*/
|
|
96
|
+
async deleteAddress(id) {
|
|
97
|
+
return this.deleteResource(`/addresses/${id}`);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get all social profiles
|
|
101
|
+
*/
|
|
102
|
+
async getAllSocialProfiles() {
|
|
103
|
+
return this.getList('/social_profiles');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get a single social profile by ID
|
|
107
|
+
*/
|
|
108
|
+
async getSocialProfileById(id) {
|
|
109
|
+
return this.getSingle(`/social_profiles/${id}`);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Create a social profile
|
|
113
|
+
*/
|
|
114
|
+
async createSocialProfile(data) {
|
|
115
|
+
return this.createResource('/social_profiles', data);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Update a social profile
|
|
119
|
+
*/
|
|
120
|
+
async updateSocialProfile(id, data) {
|
|
121
|
+
return this.updateResource(`/social_profiles/${id}`, data);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Delete a social profile
|
|
125
|
+
*/
|
|
126
|
+
async deleteSocialProfile(id) {
|
|
127
|
+
return this.deleteResource(`/social_profiles/${id}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.ContactsModule = ContactsModule;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.0.0 Fields Module
|
|
3
|
+
*/
|
|
4
|
+
import { BaseModule } from './base';
|
|
5
|
+
import type { PcoHttpClient } from '../core/http';
|
|
6
|
+
import type { PaginationHelper } from '../core/pagination';
|
|
7
|
+
import type { PcoEventEmitter } from '../monitoring';
|
|
8
|
+
import type { FieldDefinitionResource, FieldDefinitionAttributes, FieldDatumResource, FieldOptionResource, FieldOptionAttributes, TabResource, TabAttributes } from '../types';
|
|
9
|
+
export interface FieldDefinitionCache {
|
|
10
|
+
byId: Map<string, FieldDefinitionResource>;
|
|
11
|
+
bySlug: Map<string, FieldDefinitionResource>;
|
|
12
|
+
byName: Map<string, FieldDefinitionResource>;
|
|
13
|
+
lastUpdated: number;
|
|
14
|
+
}
|
|
15
|
+
export interface FieldSetOptions {
|
|
16
|
+
/** Field definition ID */
|
|
17
|
+
fieldId?: string;
|
|
18
|
+
/** Field definition slug */
|
|
19
|
+
fieldSlug?: string;
|
|
20
|
+
/** Field definition name */
|
|
21
|
+
fieldName?: string;
|
|
22
|
+
/** Value to set */
|
|
23
|
+
value: string;
|
|
24
|
+
/** Whether to handle file uploads automatically */
|
|
25
|
+
handleFileUploads?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare class FieldsModule extends BaseModule {
|
|
28
|
+
private fieldDefinitionCache;
|
|
29
|
+
private cacheTtl;
|
|
30
|
+
constructor(httpClient: PcoHttpClient, paginationHelper: PaginationHelper, eventEmitter: PcoEventEmitter);
|
|
31
|
+
/**
|
|
32
|
+
* Get all field definitions with caching
|
|
33
|
+
*/
|
|
34
|
+
getAllFieldDefinitions(useCache?: boolean): Promise<FieldDefinitionResource[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Get a single field definition by ID
|
|
37
|
+
*/
|
|
38
|
+
getFieldDefinition(id: string): Promise<FieldDefinitionResource>;
|
|
39
|
+
/**
|
|
40
|
+
* Get field definition by slug
|
|
41
|
+
*/
|
|
42
|
+
getFieldDefinitionBySlug(slug: string): Promise<FieldDefinitionResource | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Get field definition by name
|
|
45
|
+
*/
|
|
46
|
+
getFieldDefinitionByName(name: string): Promise<FieldDefinitionResource | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Create a field definition
|
|
49
|
+
*/
|
|
50
|
+
createFieldDefinition(tabId: string, data: FieldDefinitionAttributes): Promise<FieldDefinitionResource>;
|
|
51
|
+
/**
|
|
52
|
+
* Update a field definition
|
|
53
|
+
*/
|
|
54
|
+
updateFieldDefinition(id: string, data: Partial<FieldDefinitionAttributes>): Promise<FieldDefinitionResource>;
|
|
55
|
+
/**
|
|
56
|
+
* Delete a field definition
|
|
57
|
+
*/
|
|
58
|
+
deleteFieldDefinition(id: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Get field options for a field definition
|
|
61
|
+
*/
|
|
62
|
+
getFieldOptions(fieldDefinitionId: string): Promise<{
|
|
63
|
+
data: FieldOptionResource[];
|
|
64
|
+
meta?: any;
|
|
65
|
+
links?: any;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Create a field option
|
|
69
|
+
*/
|
|
70
|
+
createFieldOption(fieldDefinitionId: string, data: FieldOptionAttributes): Promise<FieldOptionResource>;
|
|
71
|
+
/**
|
|
72
|
+
* Get person's field data
|
|
73
|
+
*/
|
|
74
|
+
getPersonFieldData(personId: string): Promise<{
|
|
75
|
+
data: FieldDatumResource[];
|
|
76
|
+
meta?: any;
|
|
77
|
+
links?: any;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Set a person's field value with automatic field lookup
|
|
81
|
+
*/
|
|
82
|
+
setPersonField(personId: string, options: FieldSetOptions): Promise<FieldDatumResource>;
|
|
83
|
+
/**
|
|
84
|
+
* Set a person's field value by field definition ID
|
|
85
|
+
*/
|
|
86
|
+
setPersonFieldById(personId: string, fieldId: string, value: string): Promise<FieldDatumResource>;
|
|
87
|
+
/**
|
|
88
|
+
* Set a person's field value by field slug
|
|
89
|
+
*/
|
|
90
|
+
setPersonFieldBySlug(personId: string, fieldSlug: string, value: string): Promise<FieldDatumResource>;
|
|
91
|
+
/**
|
|
92
|
+
* Set a person's field value by field name
|
|
93
|
+
*/
|
|
94
|
+
setPersonFieldByName(personId: string, fieldName: string, value: string): Promise<FieldDatumResource>;
|
|
95
|
+
/**
|
|
96
|
+
* Create field data for a person
|
|
97
|
+
*/
|
|
98
|
+
createPersonFieldData(personId: string, fieldDefinitionId: string, value: string, options?: {
|
|
99
|
+
handleFileUploads?: boolean;
|
|
100
|
+
}): Promise<FieldDatumResource>;
|
|
101
|
+
/**
|
|
102
|
+
* Delete person's field data
|
|
103
|
+
*/
|
|
104
|
+
deletePersonFieldData(personId: string, fieldDataId: string): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Get all tabs
|
|
107
|
+
*/
|
|
108
|
+
getTabs(): Promise<{
|
|
109
|
+
data: TabResource[];
|
|
110
|
+
meta?: any;
|
|
111
|
+
links?: any;
|
|
112
|
+
}>;
|
|
113
|
+
/**
|
|
114
|
+
* Create a tab
|
|
115
|
+
*/
|
|
116
|
+
createTab(data: TabAttributes): Promise<TabResource>;
|
|
117
|
+
/**
|
|
118
|
+
* Update a tab
|
|
119
|
+
*/
|
|
120
|
+
updateTab(id: string, data: Partial<TabAttributes>): Promise<TabResource>;
|
|
121
|
+
/**
|
|
122
|
+
* Delete a tab
|
|
123
|
+
*/
|
|
124
|
+
deleteTab(id: string): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Resolve field definition from options
|
|
127
|
+
*/
|
|
128
|
+
private resolveFieldDefinition;
|
|
129
|
+
/**
|
|
130
|
+
* Create field data for file uploads
|
|
131
|
+
*/
|
|
132
|
+
private createPersonFileFieldData;
|
|
133
|
+
/**
|
|
134
|
+
* Check if cache is valid
|
|
135
|
+
*/
|
|
136
|
+
private isCacheValid;
|
|
137
|
+
/**
|
|
138
|
+
* Ensure cache is loaded
|
|
139
|
+
*/
|
|
140
|
+
private ensureCacheLoaded;
|
|
141
|
+
/**
|
|
142
|
+
* Update field definition cache
|
|
143
|
+
*/
|
|
144
|
+
private updateFieldDefinitionCache;
|
|
145
|
+
/**
|
|
146
|
+
* Invalidate cache
|
|
147
|
+
*/
|
|
148
|
+
private invalidateCache;
|
|
149
|
+
/**
|
|
150
|
+
* Check if a value is a file URL
|
|
151
|
+
*/
|
|
152
|
+
private isFileUrl;
|
|
153
|
+
/**
|
|
154
|
+
* Extract file URL from HTML markup
|
|
155
|
+
*/
|
|
156
|
+
private extractFileUrl;
|
|
157
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* v2.0.0 Fields Module
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FieldsModule = void 0;
|
|
7
|
+
const base_1 = require("./base");
|
|
8
|
+
class FieldsModule extends base_1.BaseModule {
|
|
9
|
+
constructor(httpClient, paginationHelper, eventEmitter) {
|
|
10
|
+
super(httpClient, paginationHelper, eventEmitter);
|
|
11
|
+
this.fieldDefinitionCache = null;
|
|
12
|
+
this.cacheTtl = 300000; // 5 minutes
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get all field definitions with caching
|
|
16
|
+
*/
|
|
17
|
+
async getAllFieldDefinitions(useCache = true) {
|
|
18
|
+
if (useCache && this.isCacheValid()) {
|
|
19
|
+
return Array.from(this.fieldDefinitionCache.byId.values());
|
|
20
|
+
}
|
|
21
|
+
const result = await this.getAllPages('/field_definitions', {
|
|
22
|
+
include: ['tab'],
|
|
23
|
+
});
|
|
24
|
+
// Update cache
|
|
25
|
+
this.updateFieldDefinitionCache(result.data);
|
|
26
|
+
return result.data;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get a single field definition by ID
|
|
30
|
+
*/
|
|
31
|
+
async getFieldDefinition(id) {
|
|
32
|
+
return this.getSingle(`/field_definitions/${id}`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get field definition by slug
|
|
36
|
+
*/
|
|
37
|
+
async getFieldDefinitionBySlug(slug) {
|
|
38
|
+
await this.ensureCacheLoaded();
|
|
39
|
+
return this.fieldDefinitionCache?.bySlug.get(slug) || null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get field definition by name
|
|
43
|
+
*/
|
|
44
|
+
async getFieldDefinitionByName(name) {
|
|
45
|
+
await this.ensureCacheLoaded();
|
|
46
|
+
return this.fieldDefinitionCache?.byName.get(name) || null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create a field definition
|
|
50
|
+
*/
|
|
51
|
+
async createFieldDefinition(tabId, data) {
|
|
52
|
+
const fieldDef = await this.createResource(`/tabs/${tabId}/field_definitions`, data);
|
|
53
|
+
// Invalidate cache
|
|
54
|
+
this.invalidateCache();
|
|
55
|
+
return fieldDef;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Update a field definition
|
|
59
|
+
*/
|
|
60
|
+
async updateFieldDefinition(id, data) {
|
|
61
|
+
const fieldDef = await this.updateResource(`/field_definitions/${id}`, data);
|
|
62
|
+
// Update cache
|
|
63
|
+
if (this.fieldDefinitionCache && fieldDef.attributes) {
|
|
64
|
+
this.fieldDefinitionCache.byId.set(id, fieldDef);
|
|
65
|
+
this.fieldDefinitionCache.bySlug.set(fieldDef.attributes.slug, fieldDef);
|
|
66
|
+
this.fieldDefinitionCache.byName.set(fieldDef.attributes.name, fieldDef);
|
|
67
|
+
}
|
|
68
|
+
return fieldDef;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Delete a field definition
|
|
72
|
+
*/
|
|
73
|
+
async deleteFieldDefinition(id) {
|
|
74
|
+
await this.deleteResource(`/field_definitions/${id}`);
|
|
75
|
+
// Remove from cache
|
|
76
|
+
if (this.fieldDefinitionCache) {
|
|
77
|
+
const fieldDef = this.fieldDefinitionCache.byId.get(id);
|
|
78
|
+
if (fieldDef && fieldDef.attributes) {
|
|
79
|
+
this.fieldDefinitionCache.byId.delete(id);
|
|
80
|
+
this.fieldDefinitionCache.bySlug.delete(fieldDef.attributes.slug);
|
|
81
|
+
this.fieldDefinitionCache.byName.delete(fieldDef.attributes.name);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get field options for a field definition
|
|
87
|
+
*/
|
|
88
|
+
async getFieldOptions(fieldDefinitionId) {
|
|
89
|
+
return this.getList(`/field_definitions/${fieldDefinitionId}/field_options`);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a field option
|
|
93
|
+
*/
|
|
94
|
+
async createFieldOption(fieldDefinitionId, data) {
|
|
95
|
+
return this.createResource(`/field_definitions/${fieldDefinitionId}/field_options`, data);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get person's field data
|
|
99
|
+
*/
|
|
100
|
+
async getPersonFieldData(personId) {
|
|
101
|
+
return this.getList(`/people/${personId}/field_data`);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Set a person's field value with automatic field lookup
|
|
105
|
+
*/
|
|
106
|
+
async setPersonField(personId, options) {
|
|
107
|
+
const fieldDef = await this.resolveFieldDefinition(options);
|
|
108
|
+
if (!fieldDef) {
|
|
109
|
+
throw new Error(`Field definition not found for: ${options.fieldId || options.fieldSlug || options.fieldName}`);
|
|
110
|
+
}
|
|
111
|
+
return this.createPersonFieldData(personId, fieldDef.id, options.value, {
|
|
112
|
+
handleFileUploads: options.handleFileUploads ?? true,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Set a person's field value by field definition ID
|
|
117
|
+
*/
|
|
118
|
+
async setPersonFieldById(personId, fieldId, value) {
|
|
119
|
+
return this.createPersonFieldData(personId, fieldId, value);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Set a person's field value by field slug
|
|
123
|
+
*/
|
|
124
|
+
async setPersonFieldBySlug(personId, fieldSlug, value) {
|
|
125
|
+
const fieldDef = await this.getFieldDefinitionBySlug(fieldSlug);
|
|
126
|
+
if (!fieldDef) {
|
|
127
|
+
throw new Error(`Field definition not found for slug: ${fieldSlug}`);
|
|
128
|
+
}
|
|
129
|
+
return this.createPersonFieldData(personId, fieldDef.id, value);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Set a person's field value by field name
|
|
133
|
+
*/
|
|
134
|
+
async setPersonFieldByName(personId, fieldName, value) {
|
|
135
|
+
const fieldDef = await this.getFieldDefinitionByName(fieldName);
|
|
136
|
+
if (!fieldDef) {
|
|
137
|
+
throw new Error(`Field definition not found for name: ${fieldName}`);
|
|
138
|
+
}
|
|
139
|
+
return this.createPersonFieldData(personId, fieldDef.id, value);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Create field data for a person
|
|
143
|
+
*/
|
|
144
|
+
async createPersonFieldData(personId, fieldDefinitionId, value, options = {}) {
|
|
145
|
+
const { handleFileUploads = true } = options;
|
|
146
|
+
// Get field definition to determine type
|
|
147
|
+
const fieldDef = await this.getFieldDefinition(fieldDefinitionId);
|
|
148
|
+
// Check if this is a file field and handle accordingly
|
|
149
|
+
if (fieldDef.attributes && fieldDef.attributes.data_type === 'file' && handleFileUploads) {
|
|
150
|
+
return this.createPersonFileFieldData(personId, fieldDefinitionId, value);
|
|
151
|
+
}
|
|
152
|
+
// For text fields, clean the value if it's a file URL
|
|
153
|
+
const cleanValue = this.isFileUrl(value) ? this.extractFileUrl(value) : value;
|
|
154
|
+
// Check if field data already exists for this person and field
|
|
155
|
+
try {
|
|
156
|
+
const existingFieldData = await this.getPersonFieldData(personId);
|
|
157
|
+
const existingDatum = existingFieldData.data.find(datum => {
|
|
158
|
+
const fieldDefData = datum.relationships?.field_definition?.data;
|
|
159
|
+
return Array.isArray(fieldDefData)
|
|
160
|
+
? fieldDefData.some(fd => fd.id === fieldDefinitionId)
|
|
161
|
+
: fieldDefData?.id === fieldDefinitionId;
|
|
162
|
+
});
|
|
163
|
+
if (existingDatum) {
|
|
164
|
+
// Update existing field data
|
|
165
|
+
return this.updateResource(`/people/${personId}/field_data/${existingDatum.id}`, { value: cleanValue });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
// If we can't get existing field data, continue with creation
|
|
170
|
+
}
|
|
171
|
+
return this.createResource(`/people/${personId}/field_data`, {
|
|
172
|
+
field_definition_id: fieldDefinitionId,
|
|
173
|
+
value: cleanValue,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Delete person's field data
|
|
178
|
+
*/
|
|
179
|
+
async deletePersonFieldData(personId, fieldDataId) {
|
|
180
|
+
return this.deleteResource(`/people/${personId}/field_data/${fieldDataId}`);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get all tabs
|
|
184
|
+
*/
|
|
185
|
+
async getTabs() {
|
|
186
|
+
return this.getList('/tabs');
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Create a tab
|
|
190
|
+
*/
|
|
191
|
+
async createTab(data) {
|
|
192
|
+
return this.createResource('/tabs', data);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Update a tab
|
|
196
|
+
*/
|
|
197
|
+
async updateTab(id, data) {
|
|
198
|
+
return this.updateResource(`/tabs/${id}`, data);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Delete a tab
|
|
202
|
+
*/
|
|
203
|
+
async deleteTab(id) {
|
|
204
|
+
return this.deleteResource(`/tabs/${id}`);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Resolve field definition from options
|
|
208
|
+
*/
|
|
209
|
+
async resolveFieldDefinition(options) {
|
|
210
|
+
if (options.fieldId) {
|
|
211
|
+
return this.getFieldDefinition(options.fieldId);
|
|
212
|
+
}
|
|
213
|
+
if (options.fieldSlug) {
|
|
214
|
+
return this.getFieldDefinitionBySlug(options.fieldSlug);
|
|
215
|
+
}
|
|
216
|
+
if (options.fieldName) {
|
|
217
|
+
return this.getFieldDefinitionByName(options.fieldName);
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Create field data for file uploads
|
|
223
|
+
*/
|
|
224
|
+
async createPersonFileFieldData(personId, fieldDefinitionId, fileUrl) {
|
|
225
|
+
// This would implement the file upload logic from the original implementation
|
|
226
|
+
// For now, return a placeholder
|
|
227
|
+
throw new Error('File upload functionality not yet implemented in v2.0');
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Check if cache is valid
|
|
231
|
+
*/
|
|
232
|
+
isCacheValid() {
|
|
233
|
+
if (!this.fieldDefinitionCache) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
return Date.now() - this.fieldDefinitionCache.lastUpdated < this.cacheTtl;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Ensure cache is loaded
|
|
240
|
+
*/
|
|
241
|
+
async ensureCacheLoaded() {
|
|
242
|
+
if (!this.isCacheValid()) {
|
|
243
|
+
await this.getAllFieldDefinitions(false);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Update field definition cache
|
|
248
|
+
*/
|
|
249
|
+
updateFieldDefinitionCache(fieldDefinitions) {
|
|
250
|
+
this.fieldDefinitionCache = {
|
|
251
|
+
byId: new Map(),
|
|
252
|
+
bySlug: new Map(),
|
|
253
|
+
byName: new Map(),
|
|
254
|
+
lastUpdated: Date.now(),
|
|
255
|
+
};
|
|
256
|
+
for (const fieldDef of fieldDefinitions) {
|
|
257
|
+
if (fieldDef.attributes) {
|
|
258
|
+
this.fieldDefinitionCache.byId.set(fieldDef.id, fieldDef);
|
|
259
|
+
this.fieldDefinitionCache.bySlug.set(fieldDef.attributes.slug, fieldDef);
|
|
260
|
+
this.fieldDefinitionCache.byName.set(fieldDef.attributes.name, fieldDef);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Invalidate cache
|
|
266
|
+
*/
|
|
267
|
+
invalidateCache() {
|
|
268
|
+
this.fieldDefinitionCache = null;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Check if a value is a file URL
|
|
272
|
+
*/
|
|
273
|
+
isFileUrl(value) {
|
|
274
|
+
return value.includes('s3.') || value.includes('amazonaws.com') || value.includes('<a href=');
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Extract file URL from HTML markup
|
|
278
|
+
*/
|
|
279
|
+
extractFileUrl(value) {
|
|
280
|
+
if (value.startsWith('http') && !value.includes('<')) {
|
|
281
|
+
return value;
|
|
282
|
+
}
|
|
283
|
+
const hrefMatch = /href=["']([^"']+)["']/.exec(value);
|
|
284
|
+
if (hrefMatch) {
|
|
285
|
+
return hrefMatch[1];
|
|
286
|
+
}
|
|
287
|
+
const urlMatch = /(https?:\/\/[^\s<>"']+)/.exec(value);
|
|
288
|
+
if (urlMatch) {
|
|
289
|
+
return urlMatch[1];
|
|
290
|
+
}
|
|
291
|
+
return value;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
exports.FieldsModule = FieldsModule;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.0.0 Households Module
|
|
3
|
+
*/
|
|
4
|
+
import { BaseModule } from './base';
|
|
5
|
+
import type { PaginationOptions, PaginationResult } from '../core/pagination';
|
|
6
|
+
import type { HouseholdResource, HouseholdAttributes } from '../types';
|
|
7
|
+
export interface HouseholdListOptions {
|
|
8
|
+
where?: Record<string, any>;
|
|
9
|
+
include?: string[];
|
|
10
|
+
perPage?: number;
|
|
11
|
+
page?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class HouseholdsModule extends BaseModule {
|
|
14
|
+
/**
|
|
15
|
+
* Get all households
|
|
16
|
+
*/
|
|
17
|
+
getAll(options?: HouseholdListOptions): Promise<{
|
|
18
|
+
data: HouseholdResource[];
|
|
19
|
+
meta?: any;
|
|
20
|
+
links?: any;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Get all households across all pages
|
|
24
|
+
*/
|
|
25
|
+
getAllPagesPaginated(options?: HouseholdListOptions, paginationOptions?: PaginationOptions): Promise<PaginationResult<HouseholdResource>>;
|
|
26
|
+
/**
|
|
27
|
+
* Get a single household by ID
|
|
28
|
+
*/
|
|
29
|
+
getById(id: string, include?: string[]): Promise<HouseholdResource>;
|
|
30
|
+
/**
|
|
31
|
+
* Create a household
|
|
32
|
+
*/
|
|
33
|
+
create(data: HouseholdAttributes): Promise<HouseholdResource>;
|
|
34
|
+
/**
|
|
35
|
+
* Update a household
|
|
36
|
+
*/
|
|
37
|
+
update(id: string, data: Partial<HouseholdAttributes>): Promise<HouseholdResource>;
|
|
38
|
+
/**
|
|
39
|
+
* Delete a household
|
|
40
|
+
*/
|
|
41
|
+
delete(id: string): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* v2.0.0 Households Module
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HouseholdsModule = void 0;
|
|
7
|
+
const base_1 = require("./base");
|
|
8
|
+
class HouseholdsModule extends base_1.BaseModule {
|
|
9
|
+
/**
|
|
10
|
+
* Get all households
|
|
11
|
+
*/
|
|
12
|
+
async getAll(options = {}) {
|
|
13
|
+
const params = {};
|
|
14
|
+
if (options.where) {
|
|
15
|
+
Object.entries(options.where).forEach(([key, value]) => {
|
|
16
|
+
params[`where[${key}]`] = value;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
if (options.include) {
|
|
20
|
+
params.include = options.include.join(',');
|
|
21
|
+
}
|
|
22
|
+
if (options.perPage) {
|
|
23
|
+
params.per_page = options.perPage;
|
|
24
|
+
}
|
|
25
|
+
if (options.page) {
|
|
26
|
+
params.page = options.page;
|
|
27
|
+
}
|
|
28
|
+
return this.getList('/households', params);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get all households across all pages
|
|
32
|
+
*/
|
|
33
|
+
async getAllPagesPaginated(options = {}, paginationOptions) {
|
|
34
|
+
const params = {};
|
|
35
|
+
if (options.where) {
|
|
36
|
+
Object.entries(options.where).forEach(([key, value]) => {
|
|
37
|
+
params[`where[${key}]`] = value;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (options.include) {
|
|
41
|
+
params.include = options.include.join(',');
|
|
42
|
+
}
|
|
43
|
+
return this.getAllPages('/households', params, paginationOptions);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get a single household by ID
|
|
47
|
+
*/
|
|
48
|
+
async getById(id, include) {
|
|
49
|
+
const params = {};
|
|
50
|
+
if (include) {
|
|
51
|
+
params.include = include.join(',');
|
|
52
|
+
}
|
|
53
|
+
return this.getSingle(`/households/${id}`, params);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a household
|
|
57
|
+
*/
|
|
58
|
+
async create(data) {
|
|
59
|
+
return this.createResource('/households', data);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Update a household
|
|
63
|
+
*/
|
|
64
|
+
async update(id, data) {
|
|
65
|
+
return this.updateResource(`/households/${id}`, data);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Delete a household
|
|
69
|
+
*/
|
|
70
|
+
async delete(id) {
|
|
71
|
+
return this.deleteResource(`/households/${id}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.HouseholdsModule = HouseholdsModule;
|