@goodparty_org/sdk 1.14.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/README.md CHANGED
@@ -70,16 +70,23 @@ const updatedOffice = await client.electedOffices.update('some-uuid', {
70
70
  isActive: true,
71
71
  })
72
72
 
73
- const p2vs = await client.pathsToVictory.list({
74
- userId: 42,
75
- offset: 0,
76
- limit: 20,
77
- })
78
-
79
- const p2v = await client.pathsToVictory.get(1)
80
-
81
- const updatedP2v = await client.pathsToVictory.update(1, {
82
- data: { p2vStatus: 'Complete', winNumber: 5000 },
73
+ const officeWithDistrict = await client.electedOffices.updateDistrict(
74
+ 'some-uuid',
75
+ {
76
+ state: 'CA',
77
+ L2DistrictType: 'CITY',
78
+ L2DistrictName: 'OAKLAND',
79
+ },
80
+ )
81
+
82
+ // Organizations (admin / M2M)
83
+ const org = await client.organizations.get('campaign-123')
84
+
85
+ const orgs = await client.organizations.list({ email: 'owner@example.com' })
86
+
87
+ const patched = await client.organizations.patch('campaign-123', {
88
+ customPositionName: 'Mayor',
89
+ overrideDistrictId: 'district-uuid',
83
90
  })
84
91
 
85
92
  // Ecanvasser
package/dist/index.d.mts CHANGED
@@ -3,7 +3,7 @@ import { ReadCampaignOutput, ListCampaignsPagination, PaginatedList, UpdateCampa
3
3
  export { AiChatMessage, AiContentData, AiContentGenerationStatus, AiContentInputValues, BALLOT_READY_POSITION_LEVEL_VALUES, BallotReadyPositionLevel, CAMPAIGN_CREATED_BY_VALUES, CAMPAIGN_LAUNCH_STATUS_VALUES, CAMPAIGN_STATUS_VALUES, CAMPAIGN_TIER_VALUES, ReadCampaignOutput as Campaign, CampaignAiContent, CampaignCreatedBy, CampaignData, CampaignDetails, CampaignFinance, CampaignLaunchStatus, CampaignPlan, CampaignPlanStatus, CampaignStatus, CreateEcanvasserInput, CustomIssue, CustomVoterFile, ELECTION_LEVEL_VALUES, Ecanvasser, EcanvasserSummary, ElectionLevel, GENERATION_STATUS_VALUES, GenerationStatus, GeoLocation, HubSpotUpdates, ListCampaignsPagination, ListUsersPagination, ONBOARDING_STEP_VALUES, OnboardingStep, Opponent, PaginatedList, PaginationMeta, PaginationOptions, ReadCampaignOutput, ReadUserOutput, SetDistrictOutput, USER_ROLE_VALUES, UpdateCampaignM2MInput as UpdateCampaignInput, UpdatePasswordInput, UpdateUserInput, ReadUserOutput as User, UserMetaData, VoterGoals, WHY_BROWSING_VALUES } from '@goodparty_org/contracts';
4
4
 
5
5
  type ImpersonateUserInput = {
6
- actorClerkId: string;
6
+ actorEmail: string;
7
7
  };
8
8
  type ImpersonateUserOutput = {
9
9
  token: string;
@@ -24,14 +24,38 @@ declare abstract class BaseResource {
24
24
  protected getRequest: <T>(path: string, query?: FetchOptions<"json">["query"]) => Promise<T>;
25
25
  protected postRequest: <T>(path: string, body: OfetchRequestBody) => Promise<T>;
26
26
  protected putRequest: <T>(path: string, body: OfetchRequestBody) => Promise<T>;
27
+ protected patchRequest: <T>(path: string, body: OfetchRequestBody) => Promise<T>;
27
28
  protected deleteRequest: <T>(path: string) => Promise<T>;
28
29
  }
29
30
 
30
31
  declare class AdminResource extends BaseResource {
31
32
  protected readonly resourceBasePath = "/admin";
32
- impersonateUser: (targetUserId: number, actorClerkId: string) => Promise<ImpersonateUserOutput>;
33
+ impersonateUser: (targetUserId: number, actorEmail: string) => Promise<ImpersonateUserOutput>;
33
34
  }
34
35
 
36
+ type RaceTargetMetrics = {
37
+ winNumber: number;
38
+ voterContactGoal: number;
39
+ projectedTurnout: number;
40
+ };
41
+ /**
42
+ * The full single-campaign read shape (e.g. `GET /campaigns/:id`),
43
+ * enriched with both `positionName` and live race-target metrics.
44
+ */
45
+ type CampaignWithLiveContext = ReadCampaignOutput & {
46
+ positionName: string | null;
47
+ raceTargetMetrics: RaceTargetMetrics | null;
48
+ };
49
+ /**
50
+ * The list-campaign read shape (e.g. `GET /campaigns/list`), enriched
51
+ * only with `positionName`. Live race-target metrics are intentionally
52
+ * excluded from list responses to avoid expensive per-row external
53
+ * lookups.
54
+ */
55
+ type CampaignWithPositionName = ReadCampaignOutput & {
56
+ positionName: string | null;
57
+ };
58
+
35
59
  type DistrictTypeItem = {
36
60
  id: string;
37
61
  L2DistrictType: string;
@@ -58,8 +82,8 @@ type UpdateDistrictInput = {
58
82
 
59
83
  declare class CampaignsResource extends BaseResource {
60
84
  protected readonly resourceBasePath = "/campaigns";
61
- get: (id: number) => Promise<ReadCampaignOutput>;
62
- list: (options?: ListCampaignsPagination) => Promise<PaginatedList<ReadCampaignOutput>>;
85
+ get: (id: number) => Promise<CampaignWithLiveContext>;
86
+ list: (options?: ListCampaignsPagination) => Promise<PaginatedList<CampaignWithPositionName>>;
63
87
  update: (id: number, input: UpdateCampaignM2MInput) => Promise<ReadCampaignOutput>;
64
88
  updateDistrict: (id: number, input: UpdateDistrictInput) => Promise<SetDistrictOutput>;
65
89
  }
@@ -96,12 +120,22 @@ type UpdateElectedOfficeInput = {
96
120
  termLengthDays?: number | null;
97
121
  isActive?: boolean;
98
122
  };
123
+ type UpdateElectedOfficeDistrictInput = {
124
+ state: string;
125
+ L2DistrictType: string;
126
+ L2DistrictName: string;
127
+ };
128
+ type SetElectedOfficeDistrictOutput = {
129
+ electedOfficeId: string;
130
+ overrideDistrictId: string | null;
131
+ };
99
132
 
100
133
  declare class ElectedOfficesResource extends BaseResource {
101
134
  protected readonly resourceBasePath = "/elected-office";
102
135
  list: (options?: ListElectedOfficesOptions) => Promise<PaginatedList<ElectedOffice>>;
103
136
  get: (id: string) => Promise<ElectedOffice>;
104
137
  update: (id: string, input: UpdateElectedOfficeInput) => Promise<ElectedOffice>;
138
+ updateDistrict: (id: string, input: UpdateElectedOfficeDistrictInput) => Promise<SetElectedOfficeDistrictOutput>;
105
139
  }
106
140
 
107
141
  declare class ElectionsResource extends BaseResource {
@@ -110,74 +144,61 @@ declare class ElectionsResource extends BaseResource {
110
144
  listDistrictNames: (options: ListDistrictNamesOptions) => Promise<DistrictNameItem[]>;
111
145
  }
112
146
 
113
- declare enum P2VStatus {
114
- complete = "Complete",
115
- waiting = "Waiting",
116
- failed = "Failed",
117
- districtMatched = "DistrictMatched"
118
- }
119
- declare enum P2VSource {
120
- GpApi = "GpApi",
121
- ElectionApi = "ElectionApi"
122
- }
123
- type ViabilityScore = {
124
- level: string;
125
- isPartisan: boolean;
126
- isIncumbent: boolean;
127
- isUncontested: boolean;
128
- candidates: number;
129
- seats: number;
130
- candidatesPerSeat: number;
131
- score: number;
132
- probOfWin: number;
133
- };
134
- type PathToVictoryData = {
135
- p2vStatus?: P2VStatus;
136
- p2vAttempts?: number;
137
- p2vCompleteDate?: string;
138
- completedBy?: number;
139
- electionType?: string;
140
- electionLocation?: string;
141
- voterContactGoal?: number;
142
- winNumber?: number;
143
- p2vNotNeeded?: boolean;
144
- totalRegisteredVoters?: number;
145
- republicans?: number;
146
- democrats?: number;
147
- indies?: number;
148
- women?: number;
149
- men?: number;
150
- white?: number;
151
- asian?: number;
152
- africanAmerican?: number;
153
- hispanic?: number;
154
- averageTurnout?: number;
155
- projectedTurnout?: number;
156
- viability?: ViabilityScore;
157
- source?: P2VSource;
158
- districtId?: string;
159
- districtManuallySet?: boolean;
160
- officeContextFingerprint?: string;
161
- };
162
- type PathToVictory = {
163
- id: number;
164
- createdAt: string;
165
- updatedAt: string;
166
- campaignId: number;
167
- data: PathToVictoryData;
168
- };
169
- type ListPathsToVictoryOptions = PaginationOptions & {
170
- userId?: number;
171
- };
172
- type UpdatePathToVictoryInput = {
173
- data: PathToVictoryData;
147
+ type OrgDistrict = {
148
+ id: string;
149
+ l2Type: string;
150
+ l2Name: string;
174
151
  };
175
-
176
- declare class PathsToVictoryResource extends BaseResource {
177
- protected resourceBasePath: string;
178
- list: (options?: ListPathsToVictoryOptions) => Promise<PaginatedList<PathToVictory>>;
179
- get: (id: number) => Promise<PathToVictory>;
180
- update: (id: number, input: UpdatePathToVictoryInput) => Promise<PathToVictory>;
152
+ type OrgPosition = {
153
+ id: string;
154
+ state: string;
155
+ brPositionId: string;
156
+ };
157
+ type Organization = {
158
+ slug: string;
159
+ name: string | null;
160
+ positionName: string | null;
161
+ position: OrgPosition | null;
162
+ district: OrgDistrict | null;
163
+ electedOfficeId: string | null;
164
+ campaignId: number | null;
165
+ };
166
+ type ListOrganizationsOptions = {
167
+ slug?: string;
168
+ email?: string;
169
+ };
170
+ type OrganizationOwnerSummary = {
171
+ id: number;
172
+ email: string | null;
173
+ firstName: string | null;
174
+ lastName: string | null;
175
+ phone: string | null;
176
+ };
177
+ type OrganizationListItem = Organization & {
178
+ extra: {
179
+ positionName: string | null;
180
+ hasDistrictOverride: boolean;
181
+ owner: OrganizationOwnerSummary;
182
+ campaign: {
183
+ id: number;
184
+ slug: string;
185
+ details: unknown;
186
+ } | null;
187
+ };
188
+ };
189
+ type PatchOrganizationInput = {
190
+ ballotReadyPositionId?: string | null;
191
+ overrideDistrictId?: string | null;
192
+ customPositionName?: string | null;
193
+ };
194
+
195
+ declare class OrganizationsResource extends BaseResource {
196
+ protected readonly resourceBasePath = "/organizations";
197
+ get: (slug: string) => Promise<Organization>;
198
+ list: (options?: ListOrganizationsOptions) => Promise<{
199
+ organizations: OrganizationListItem[];
200
+ }>;
201
+ patch: (slug: string, input: PatchOrganizationInput) => Promise<Organization>;
181
202
  }
182
203
 
183
204
  declare class UsersResource extends BaseResource {
@@ -200,7 +221,7 @@ declare class GoodPartyClient {
200
221
  readonly ecanvasser: EcanvasserResource;
201
222
  readonly electedOffices: ElectedOfficesResource;
202
223
  readonly elections: ElectionsResource;
203
- readonly pathsToVictory: PathsToVictoryResource;
224
+ readonly organizations: OrganizationsResource;
204
225
  private clerkService;
205
226
  private constructor();
206
227
  static create: (config: GoodPartyClientConfig) => Promise<GoodPartyClient>;
@@ -223,4 +244,4 @@ declare const WhyBrowsing: EnumObject<readonly ["considering", "learning", "test
223
244
  type CampaignTier = CampaignTier$1;
224
245
  declare const CampaignTier: EnumObject<readonly ["WIN", "LOSE", "TOSSUP"]>;
225
246
 
226
- export { CampaignTier, type DistrictNameItem, type DistrictTypeItem, type ElectedOffice, GoodPartyClient, type GoodPartyClientConfig, type ImpersonateUserInput, type ImpersonateUserOutput, type ListDistrictNamesOptions, type ListDistrictTypesOptions, type ListElectedOfficesOptions, type ListPathsToVictoryOptions, P2VSource, P2VStatus, type PathToVictory, type PathToVictoryData, SdkError, type UpdateDistrictInput, type UpdateElectedOfficeInput, type UpdatePathToVictoryInput, UserRole, type ViabilityScore, WhyBrowsing };
247
+ export { CampaignTier, type CampaignWithLiveContext, type CampaignWithPositionName, type DistrictNameItem, type DistrictTypeItem, type ElectedOffice, GoodPartyClient, type GoodPartyClientConfig, type ImpersonateUserInput, type ImpersonateUserOutput, type ListDistrictNamesOptions, type ListDistrictTypesOptions, type ListElectedOfficesOptions, type ListOrganizationsOptions, type OrgDistrict, type OrgPosition, type Organization, type OrganizationListItem, type OrganizationOwnerSummary, type PatchOrganizationInput, type RaceTargetMetrics, SdkError, type SetElectedOfficeDistrictOutput, type UpdateDistrictInput, type UpdateElectedOfficeDistrictInput, type UpdateElectedOfficeInput, UserRole, WhyBrowsing };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { ReadCampaignOutput, ListCampaignsPagination, PaginatedList, UpdateCampa
3
3
  export { AiChatMessage, AiContentData, AiContentGenerationStatus, AiContentInputValues, BALLOT_READY_POSITION_LEVEL_VALUES, BallotReadyPositionLevel, CAMPAIGN_CREATED_BY_VALUES, CAMPAIGN_LAUNCH_STATUS_VALUES, CAMPAIGN_STATUS_VALUES, CAMPAIGN_TIER_VALUES, ReadCampaignOutput as Campaign, CampaignAiContent, CampaignCreatedBy, CampaignData, CampaignDetails, CampaignFinance, CampaignLaunchStatus, CampaignPlan, CampaignPlanStatus, CampaignStatus, CreateEcanvasserInput, CustomIssue, CustomVoterFile, ELECTION_LEVEL_VALUES, Ecanvasser, EcanvasserSummary, ElectionLevel, GENERATION_STATUS_VALUES, GenerationStatus, GeoLocation, HubSpotUpdates, ListCampaignsPagination, ListUsersPagination, ONBOARDING_STEP_VALUES, OnboardingStep, Opponent, PaginatedList, PaginationMeta, PaginationOptions, ReadCampaignOutput, ReadUserOutput, SetDistrictOutput, USER_ROLE_VALUES, UpdateCampaignM2MInput as UpdateCampaignInput, UpdatePasswordInput, UpdateUserInput, ReadUserOutput as User, UserMetaData, VoterGoals, WHY_BROWSING_VALUES } from '@goodparty_org/contracts';
4
4
 
5
5
  type ImpersonateUserInput = {
6
- actorClerkId: string;
6
+ actorEmail: string;
7
7
  };
8
8
  type ImpersonateUserOutput = {
9
9
  token: string;
@@ -24,14 +24,38 @@ declare abstract class BaseResource {
24
24
  protected getRequest: <T>(path: string, query?: FetchOptions<"json">["query"]) => Promise<T>;
25
25
  protected postRequest: <T>(path: string, body: OfetchRequestBody) => Promise<T>;
26
26
  protected putRequest: <T>(path: string, body: OfetchRequestBody) => Promise<T>;
27
+ protected patchRequest: <T>(path: string, body: OfetchRequestBody) => Promise<T>;
27
28
  protected deleteRequest: <T>(path: string) => Promise<T>;
28
29
  }
29
30
 
30
31
  declare class AdminResource extends BaseResource {
31
32
  protected readonly resourceBasePath = "/admin";
32
- impersonateUser: (targetUserId: number, actorClerkId: string) => Promise<ImpersonateUserOutput>;
33
+ impersonateUser: (targetUserId: number, actorEmail: string) => Promise<ImpersonateUserOutput>;
33
34
  }
34
35
 
36
+ type RaceTargetMetrics = {
37
+ winNumber: number;
38
+ voterContactGoal: number;
39
+ projectedTurnout: number;
40
+ };
41
+ /**
42
+ * The full single-campaign read shape (e.g. `GET /campaigns/:id`),
43
+ * enriched with both `positionName` and live race-target metrics.
44
+ */
45
+ type CampaignWithLiveContext = ReadCampaignOutput & {
46
+ positionName: string | null;
47
+ raceTargetMetrics: RaceTargetMetrics | null;
48
+ };
49
+ /**
50
+ * The list-campaign read shape (e.g. `GET /campaigns/list`), enriched
51
+ * only with `positionName`. Live race-target metrics are intentionally
52
+ * excluded from list responses to avoid expensive per-row external
53
+ * lookups.
54
+ */
55
+ type CampaignWithPositionName = ReadCampaignOutput & {
56
+ positionName: string | null;
57
+ };
58
+
35
59
  type DistrictTypeItem = {
36
60
  id: string;
37
61
  L2DistrictType: string;
@@ -58,8 +82,8 @@ type UpdateDistrictInput = {
58
82
 
59
83
  declare class CampaignsResource extends BaseResource {
60
84
  protected readonly resourceBasePath = "/campaigns";
61
- get: (id: number) => Promise<ReadCampaignOutput>;
62
- list: (options?: ListCampaignsPagination) => Promise<PaginatedList<ReadCampaignOutput>>;
85
+ get: (id: number) => Promise<CampaignWithLiveContext>;
86
+ list: (options?: ListCampaignsPagination) => Promise<PaginatedList<CampaignWithPositionName>>;
63
87
  update: (id: number, input: UpdateCampaignM2MInput) => Promise<ReadCampaignOutput>;
64
88
  updateDistrict: (id: number, input: UpdateDistrictInput) => Promise<SetDistrictOutput>;
65
89
  }
@@ -96,12 +120,22 @@ type UpdateElectedOfficeInput = {
96
120
  termLengthDays?: number | null;
97
121
  isActive?: boolean;
98
122
  };
123
+ type UpdateElectedOfficeDistrictInput = {
124
+ state: string;
125
+ L2DistrictType: string;
126
+ L2DistrictName: string;
127
+ };
128
+ type SetElectedOfficeDistrictOutput = {
129
+ electedOfficeId: string;
130
+ overrideDistrictId: string | null;
131
+ };
99
132
 
100
133
  declare class ElectedOfficesResource extends BaseResource {
101
134
  protected readonly resourceBasePath = "/elected-office";
102
135
  list: (options?: ListElectedOfficesOptions) => Promise<PaginatedList<ElectedOffice>>;
103
136
  get: (id: string) => Promise<ElectedOffice>;
104
137
  update: (id: string, input: UpdateElectedOfficeInput) => Promise<ElectedOffice>;
138
+ updateDistrict: (id: string, input: UpdateElectedOfficeDistrictInput) => Promise<SetElectedOfficeDistrictOutput>;
105
139
  }
106
140
 
107
141
  declare class ElectionsResource extends BaseResource {
@@ -110,74 +144,61 @@ declare class ElectionsResource extends BaseResource {
110
144
  listDistrictNames: (options: ListDistrictNamesOptions) => Promise<DistrictNameItem[]>;
111
145
  }
112
146
 
113
- declare enum P2VStatus {
114
- complete = "Complete",
115
- waiting = "Waiting",
116
- failed = "Failed",
117
- districtMatched = "DistrictMatched"
118
- }
119
- declare enum P2VSource {
120
- GpApi = "GpApi",
121
- ElectionApi = "ElectionApi"
122
- }
123
- type ViabilityScore = {
124
- level: string;
125
- isPartisan: boolean;
126
- isIncumbent: boolean;
127
- isUncontested: boolean;
128
- candidates: number;
129
- seats: number;
130
- candidatesPerSeat: number;
131
- score: number;
132
- probOfWin: number;
133
- };
134
- type PathToVictoryData = {
135
- p2vStatus?: P2VStatus;
136
- p2vAttempts?: number;
137
- p2vCompleteDate?: string;
138
- completedBy?: number;
139
- electionType?: string;
140
- electionLocation?: string;
141
- voterContactGoal?: number;
142
- winNumber?: number;
143
- p2vNotNeeded?: boolean;
144
- totalRegisteredVoters?: number;
145
- republicans?: number;
146
- democrats?: number;
147
- indies?: number;
148
- women?: number;
149
- men?: number;
150
- white?: number;
151
- asian?: number;
152
- africanAmerican?: number;
153
- hispanic?: number;
154
- averageTurnout?: number;
155
- projectedTurnout?: number;
156
- viability?: ViabilityScore;
157
- source?: P2VSource;
158
- districtId?: string;
159
- districtManuallySet?: boolean;
160
- officeContextFingerprint?: string;
161
- };
162
- type PathToVictory = {
163
- id: number;
164
- createdAt: string;
165
- updatedAt: string;
166
- campaignId: number;
167
- data: PathToVictoryData;
168
- };
169
- type ListPathsToVictoryOptions = PaginationOptions & {
170
- userId?: number;
171
- };
172
- type UpdatePathToVictoryInput = {
173
- data: PathToVictoryData;
147
+ type OrgDistrict = {
148
+ id: string;
149
+ l2Type: string;
150
+ l2Name: string;
174
151
  };
175
-
176
- declare class PathsToVictoryResource extends BaseResource {
177
- protected resourceBasePath: string;
178
- list: (options?: ListPathsToVictoryOptions) => Promise<PaginatedList<PathToVictory>>;
179
- get: (id: number) => Promise<PathToVictory>;
180
- update: (id: number, input: UpdatePathToVictoryInput) => Promise<PathToVictory>;
152
+ type OrgPosition = {
153
+ id: string;
154
+ state: string;
155
+ brPositionId: string;
156
+ };
157
+ type Organization = {
158
+ slug: string;
159
+ name: string | null;
160
+ positionName: string | null;
161
+ position: OrgPosition | null;
162
+ district: OrgDistrict | null;
163
+ electedOfficeId: string | null;
164
+ campaignId: number | null;
165
+ };
166
+ type ListOrganizationsOptions = {
167
+ slug?: string;
168
+ email?: string;
169
+ };
170
+ type OrganizationOwnerSummary = {
171
+ id: number;
172
+ email: string | null;
173
+ firstName: string | null;
174
+ lastName: string | null;
175
+ phone: string | null;
176
+ };
177
+ type OrganizationListItem = Organization & {
178
+ extra: {
179
+ positionName: string | null;
180
+ hasDistrictOverride: boolean;
181
+ owner: OrganizationOwnerSummary;
182
+ campaign: {
183
+ id: number;
184
+ slug: string;
185
+ details: unknown;
186
+ } | null;
187
+ };
188
+ };
189
+ type PatchOrganizationInput = {
190
+ ballotReadyPositionId?: string | null;
191
+ overrideDistrictId?: string | null;
192
+ customPositionName?: string | null;
193
+ };
194
+
195
+ declare class OrganizationsResource extends BaseResource {
196
+ protected readonly resourceBasePath = "/organizations";
197
+ get: (slug: string) => Promise<Organization>;
198
+ list: (options?: ListOrganizationsOptions) => Promise<{
199
+ organizations: OrganizationListItem[];
200
+ }>;
201
+ patch: (slug: string, input: PatchOrganizationInput) => Promise<Organization>;
181
202
  }
182
203
 
183
204
  declare class UsersResource extends BaseResource {
@@ -200,7 +221,7 @@ declare class GoodPartyClient {
200
221
  readonly ecanvasser: EcanvasserResource;
201
222
  readonly electedOffices: ElectedOfficesResource;
202
223
  readonly elections: ElectionsResource;
203
- readonly pathsToVictory: PathsToVictoryResource;
224
+ readonly organizations: OrganizationsResource;
204
225
  private clerkService;
205
226
  private constructor();
206
227
  static create: (config: GoodPartyClientConfig) => Promise<GoodPartyClient>;
@@ -223,4 +244,4 @@ declare const WhyBrowsing: EnumObject<readonly ["considering", "learning", "test
223
244
  type CampaignTier = CampaignTier$1;
224
245
  declare const CampaignTier: EnumObject<readonly ["WIN", "LOSE", "TOSSUP"]>;
225
246
 
226
- export { CampaignTier, type DistrictNameItem, type DistrictTypeItem, type ElectedOffice, GoodPartyClient, type GoodPartyClientConfig, type ImpersonateUserInput, type ImpersonateUserOutput, type ListDistrictNamesOptions, type ListDistrictTypesOptions, type ListElectedOfficesOptions, type ListPathsToVictoryOptions, P2VSource, P2VStatus, type PathToVictory, type PathToVictoryData, SdkError, type UpdateDistrictInput, type UpdateElectedOfficeInput, type UpdatePathToVictoryInput, UserRole, type ViabilityScore, WhyBrowsing };
247
+ export { CampaignTier, type CampaignWithLiveContext, type CampaignWithPositionName, type DistrictNameItem, type DistrictTypeItem, type ElectedOffice, GoodPartyClient, type GoodPartyClientConfig, type ImpersonateUserInput, type ImpersonateUserOutput, type ListDistrictNamesOptions, type ListDistrictTypesOptions, type ListElectedOfficesOptions, type ListOrganizationsOptions, type OrgDistrict, type OrgPosition, type Organization, type OrganizationListItem, type OrganizationOwnerSummary, type PatchOrganizationInput, type RaceTargetMetrics, SdkError, type SetElectedOfficeDistrictOutput, type UpdateDistrictInput, type UpdateElectedOfficeDistrictInput, type UpdateElectedOfficeInput, UserRole, WhyBrowsing };
package/dist/index.js CHANGED
@@ -37,8 +37,6 @@ __export(index_exports, {
37
37
  GoodPartyClient: () => GoodPartyClient,
38
38
  ONBOARDING_STEP_VALUES: () => import_contracts2.ONBOARDING_STEP_VALUES,
39
39
  OnboardingStep: () => import_contracts2.OnboardingStep,
40
- P2VSource: () => P2VSource,
41
- P2VStatus: () => P2VStatus,
42
40
  SdkError: () => SdkError,
43
41
  USER_ROLE_VALUES: () => import_contracts2.USER_ROLE_VALUES,
44
42
  UserRole: () => UserRole,
@@ -99,15 +97,16 @@ var BaseResource = class {
99
97
  getRequest = (path, query) => this.httpClient.request(path, { method: "GET", query });
100
98
  postRequest = (path, body) => this.httpClient.request(path, { method: "POST", body });
101
99
  putRequest = (path, body) => this.httpClient.request(path, { method: "PUT", body });
100
+ patchRequest = (path, body) => this.httpClient.request(path, { method: "PATCH", body });
102
101
  deleteRequest = (path) => this.httpClient.request(path, { method: "DELETE" });
103
102
  };
104
103
 
105
104
  // src/resources/AdminResource.ts
106
105
  var AdminResource = class extends BaseResource {
107
106
  resourceBasePath = "/admin";
108
- impersonateUser = (targetUserId, actorClerkId) => this.postRequest(
107
+ impersonateUser = (targetUserId, actorEmail) => this.postRequest(
109
108
  `${this.resourceBasePath}/users/impersonate/${targetUserId}`,
110
- { actorClerkId }
109
+ { actorEmail }
111
110
  );
112
111
  };
113
112
 
@@ -144,6 +143,10 @@ var ElectedOfficesResource = class extends BaseResource {
144
143
  );
145
144
  get = (id) => this.getRequest(`${this.resourceBasePath}/${id}`);
146
145
  update = (id, input) => this.putRequest(`${this.resourceBasePath}/${id}`, input);
146
+ updateDistrict = (id, input) => this.putRequest(
147
+ `${this.resourceBasePath}/${id}/district`,
148
+ input
149
+ );
147
150
  };
148
151
 
149
152
  // src/resources/ElectionsResource.ts
@@ -159,15 +162,18 @@ var ElectionsResource = class extends BaseResource {
159
162
  );
160
163
  };
161
164
 
162
- // src/resources/PathsToVictoryResource.ts
163
- var PathsToVictoryResource = class extends BaseResource {
164
- resourceBasePath = "/path-to-victory";
165
+ // src/resources/OrganizationsResource.ts
166
+ var OrganizationsResource = class extends BaseResource {
167
+ resourceBasePath = "/organizations";
168
+ get = (slug) => this.getRequest(`${this.resourceBasePath}/admin/${slug}`);
165
169
  list = (options) => this.getRequest(
166
- `${this.resourceBasePath}/list`,
170
+ `${this.resourceBasePath}/admin/list`,
167
171
  options
168
172
  );
169
- get = (id) => this.getRequest(`${this.resourceBasePath}/${id}`);
170
- update = (id, input) => this.putRequest(`${this.resourceBasePath}/${id}`, input);
173
+ patch = (slug, input) => this.patchRequest(
174
+ `${this.resourceBasePath}/admin/${slug}`,
175
+ input
176
+ );
171
177
  };
172
178
 
173
179
  // src/resources/UsersResource.ts
@@ -278,7 +284,7 @@ var GoodPartyClient = class _GoodPartyClient {
278
284
  ecanvasser;
279
285
  electedOffices;
280
286
  elections;
281
- pathsToVictory;
287
+ organizations;
282
288
  clerkService;
283
289
  constructor(clerkService, gpApiRootUrl) {
284
290
  this.clerkService = clerkService;
@@ -289,7 +295,7 @@ var GoodPartyClient = class _GoodPartyClient {
289
295
  this.ecanvasser = new EcanvasserResource(httpClient);
290
296
  this.electedOffices = new ElectedOfficesResource(httpClient);
291
297
  this.elections = new ElectionsResource(httpClient);
292
- this.pathsToVictory = new PathsToVictoryResource(httpClient);
298
+ this.organizations = new OrganizationsResource(httpClient);
293
299
  }
294
300
  static create = async (config) => {
295
301
  const { m2mSecret, gpApiRootUrl } = config;
@@ -311,20 +317,6 @@ var toEnumObject = (values) => Object.fromEntries(values.map((v) => [v, v]));
311
317
  var UserRole = toEnumObject(import_contracts.USER_ROLE_VALUES);
312
318
  var WhyBrowsing = toEnumObject(import_contracts.WHY_BROWSING_VALUES);
313
319
  var CampaignTier = toEnumObject(import_contracts.CAMPAIGN_TIER_VALUES);
314
-
315
- // src/types/pathToVictory.ts
316
- var P2VStatus = /* @__PURE__ */ ((P2VStatus2) => {
317
- P2VStatus2["complete"] = "Complete";
318
- P2VStatus2["waiting"] = "Waiting";
319
- P2VStatus2["failed"] = "Failed";
320
- P2VStatus2["districtMatched"] = "DistrictMatched";
321
- return P2VStatus2;
322
- })(P2VStatus || {});
323
- var P2VSource = /* @__PURE__ */ ((P2VSource2) => {
324
- P2VSource2["GpApi"] = "GpApi";
325
- P2VSource2["ElectionApi"] = "ElectionApi";
326
- return P2VSource2;
327
- })(P2VSource || {});
328
320
  // Annotate the CommonJS export names for ESM import in node:
329
321
  0 && (module.exports = {
330
322
  BALLOT_READY_POSITION_LEVEL_VALUES,
@@ -344,8 +336,6 @@ var P2VSource = /* @__PURE__ */ ((P2VSource2) => {
344
336
  GoodPartyClient,
345
337
  ONBOARDING_STEP_VALUES,
346
338
  OnboardingStep,
347
- P2VSource,
348
- P2VStatus,
349
339
  SdkError,
350
340
  USER_ROLE_VALUES,
351
341
  UserRole,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/AdminResource.ts","../src/resources/CampaignsResource.ts","../src/resources/EcanvasserResource.ts","../src/resources/ElectedOfficesResource.ts","../src/resources/ElectionsResource.ts","../src/resources/PathsToVictoryResource.ts","../src/resources/UsersResource.ts","../src/vendor/clerk/clerk.service.ts","../src/GoodPartyClient.ts","../src/enums.ts","../src/types/pathToVictory.ts"],"sourcesContent":["export { GoodPartyClient } from './GoodPartyClient'\nexport type { GoodPartyClientConfig } from './GoodPartyClient'\n\nexport { SdkError } from './types/result'\n\nexport type {\n PaginationMeta,\n PaginatedList,\n PaginationOptions,\n ReadUserOutput,\n ReadUserOutput as User,\n UpdatePasswordInput,\n UpdateUserInput,\n UserMetaData,\n ListUsersPagination,\n ReadCampaignOutput,\n ReadCampaignOutput as Campaign,\n CampaignDetails,\n CampaignData,\n CampaignAiContent,\n VoterGoals,\n CustomVoterFile,\n AiChatMessage,\n AiContentInputValues,\n AiContentGenerationStatus,\n AiContentData,\n GeoLocation,\n CustomIssue,\n Opponent,\n HubSpotUpdates,\n CampaignFinance,\n CampaignPlan,\n CampaignPlanStatus,\n ListCampaignsPagination,\n SetDistrictOutput,\n UpdateCampaignM2MInput as UpdateCampaignInput,\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\n\nexport {\n USER_ROLE_VALUES,\n WHY_BROWSING_VALUES,\n CAMPAIGN_TIER_VALUES,\n BALLOT_READY_POSITION_LEVEL_VALUES,\n ELECTION_LEVEL_VALUES,\n CAMPAIGN_CREATED_BY_VALUES,\n CAMPAIGN_LAUNCH_STATUS_VALUES,\n CAMPAIGN_STATUS_VALUES,\n ONBOARDING_STEP_VALUES,\n GENERATION_STATUS_VALUES,\n BallotReadyPositionLevel,\n ElectionLevel,\n CampaignCreatedBy,\n CampaignLaunchStatus,\n CampaignStatus,\n OnboardingStep,\n GenerationStatus,\n} from '@goodparty_org/contracts'\n\nexport { UserRole, WhyBrowsing, CampaignTier } from './enums'\n\nexport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n UpdateElectedOfficeInput,\n} from './types/electedOffice'\n\nexport type {\n PathToVictory,\n PathToVictoryData,\n ViabilityScore,\n ListPathsToVictoryOptions,\n UpdatePathToVictoryInput,\n} from './types/pathToVictory'\n\nexport { P2VStatus, P2VSource } from './types/pathToVictory'\n\nexport type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n UpdateDistrictInput,\n} from './types/district'\n\nexport type { ImpersonateUserInput, ImpersonateUserOutput } from './types/admin'\n","import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private getToken: () => Promise<string>\n\n constructor(gpApiRootUrl: string, getToken: () => Promise<string>) {\n this.baseUrl = gpApiRootUrl\n this.getToken = getToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${await this.getToken()}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n protected abstract readonly resourceBasePath: string\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { ImpersonateUserOutput } from '../types/admin'\nimport { BaseResource } from './BaseResource'\n\nexport class AdminResource extends BaseResource {\n protected readonly resourceBasePath = '/admin'\n\n impersonateUser = (\n targetUserId: number,\n actorClerkId: string,\n ): Promise<ImpersonateUserOutput> =>\n this.postRequest<ImpersonateUserOutput>(\n `${this.resourceBasePath}/users/impersonate/${targetUserId}`,\n { actorClerkId },\n )\n}\n","import type {\n ListCampaignsPagination,\n PaginatedList,\n ReadCampaignOutput,\n SetDistrictOutput,\n UpdateCampaignM2MInput,\n} from '@goodparty_org/contracts'\nimport type { UpdateDistrictInput } from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class CampaignsResource extends BaseResource {\n protected readonly resourceBasePath = '/campaigns'\n\n get = (id: number): Promise<ReadCampaignOutput> =>\n this.getRequest<ReadCampaignOutput>(`${this.resourceBasePath}/${id}`)\n\n list = (\n options?: ListCampaignsPagination,\n ): Promise<PaginatedList<ReadCampaignOutput>> =>\n this.getRequest<PaginatedList<ReadCampaignOutput>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n update = (\n id: number,\n input: UpdateCampaignM2MInput,\n ): Promise<ReadCampaignOutput> =>\n this.putRequest<ReadCampaignOutput>(`${this.resourceBasePath}/${id}`, input)\n\n updateDistrict = (\n id: number,\n input: UpdateDistrictInput,\n ): Promise<SetDistrictOutput> =>\n this.putRequest<SetDistrictOutput>(\n `${this.resourceBasePath}/${id}/district`,\n input,\n )\n}\n","import type {\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class EcanvasserResource extends BaseResource {\n protected readonly resourceBasePath = '/ecanvasser'\n\n create = (input: CreateEcanvasserInput): Promise<Ecanvasser> =>\n this.postRequest<Ecanvasser>(this.resourceBasePath, input)\n\n list = (): Promise<EcanvasserSummary[]> =>\n this.getRequest<EcanvasserSummary[]>(`${this.resourceBasePath}/list`)\n\n syncAll = (): Promise<void> =>\n this.getRequest<void>(`${this.resourceBasePath}/sync-all`)\n\n delete = (campaignId: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${campaignId}`)\n}\n","import type { PaginatedList } from '@goodparty_org/contracts'\nimport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n UpdateElectedOfficeInput,\n} from '../types/electedOffice'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectedOfficesResource extends BaseResource {\n protected readonly resourceBasePath = '/elected-office'\n\n list = (\n options?: ListElectedOfficesOptions,\n ): Promise<PaginatedList<ElectedOffice>> =>\n this.getRequest<PaginatedList<ElectedOffice>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n get = (id: string): Promise<ElectedOffice> =>\n this.getRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`)\n\n update = (\n id: string,\n input: UpdateElectedOfficeInput,\n ): Promise<ElectedOffice> =>\n this.putRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`, input)\n}\n","import type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n} from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectionsResource extends BaseResource {\n protected readonly resourceBasePath = '/elections'\n\n listDistrictTypes = (\n options: ListDistrictTypesOptions,\n ): Promise<DistrictTypeItem[]> =>\n this.getRequest<DistrictTypeItem[]>(\n `${this.resourceBasePath}/districts/types`,\n options,\n )\n\n listDistrictNames = (\n options: ListDistrictNamesOptions,\n ): Promise<DistrictNameItem[]> =>\n this.getRequest<DistrictNameItem[]>(\n `${this.resourceBasePath}/districts/names`,\n options,\n )\n}\n","import type { PaginatedList } from '@goodparty_org/contracts'\nimport type {\n ListPathsToVictoryOptions,\n PathToVictory,\n UpdatePathToVictoryInput,\n} from '../types/pathToVictory'\nimport { BaseResource } from './BaseResource'\n\nexport class PathsToVictoryResource extends BaseResource {\n protected resourceBasePath = '/path-to-victory'\n list = (\n options?: ListPathsToVictoryOptions,\n ): Promise<PaginatedList<PathToVictory>> =>\n this.getRequest<PaginatedList<PathToVictory>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n get = (id: number): Promise<PathToVictory> =>\n this.getRequest<PathToVictory>(`${this.resourceBasePath}/${id}`)\n\n update = (\n id: number,\n input: UpdatePathToVictoryInput,\n ): Promise<PathToVictory> =>\n this.putRequest<PathToVictory>(`${this.resourceBasePath}/${id}`, input)\n}\n","import type {\n ListUsersPagination,\n PaginatedList,\n ReadUserOutput,\n UpdatePasswordInput,\n UpdateUserInput,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n protected readonly resourceBasePath = '/users'\n\n list = (\n options?: ListUsersPagination,\n ): Promise<PaginatedList<ReadUserOutput>> =>\n this.getRequest<PaginatedList<ReadUserOutput>>(\n this.resourceBasePath,\n options,\n )\n\n get = (id: number): Promise<ReadUserOutput> =>\n this.getRequest<ReadUserOutput>(`/users/${id}`)\n\n update = (id: number, input: UpdateUserInput): Promise<ReadUserOutput> =>\n this.putRequest<ReadUserOutput>(`${this.resourceBasePath}/${id}`, input)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`${this.resourceBasePath}/${id}/password`, input)\n}\n","import { createClerkClient } from '@clerk/backend'\nimport { SdkError } from '../../types/result'\n\nconst TOKEN_RENEWAL_BUFFER_MS = 30_000\n\nexport class ClerkService {\n private readonly m2mSecret: string\n private readonly clerkClient: ReturnType<typeof createClerkClient>\n private cachedToken: string | null = null\n private tokenExpiration: number | null = null\n private renewalTimer: ReturnType<typeof setTimeout> | null = null\n private pendingTokenPromise: Promise<string> | null = null\n private destroyed = false\n\n constructor(m2mSecret: string) {\n this.m2mSecret = m2mSecret\n this.clerkClient = createClerkClient({})\n }\n\n getToken = async (): Promise<string> => {\n if (this.cachedToken && this.isTokenValid()) {\n return this.cachedToken\n }\n\n if (this.pendingTokenPromise) {\n return this.pendingTokenPromise\n }\n\n const promise = this.createAndCacheToken()\n this.pendingTokenPromise = promise\n\n try {\n return await promise\n } finally {\n if (this.pendingTokenPromise === promise) {\n this.pendingTokenPromise = null\n }\n }\n }\n\n destroy = (): void => {\n this.destroyed = true\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n this.cachedToken = null\n this.tokenExpiration = null\n this.pendingTokenPromise = null\n }\n\n private isTokenValid = (): boolean => {\n if (!this.tokenExpiration) return true\n return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS\n }\n\n private createAndCacheToken = async (): Promise<string> => {\n try {\n const m2mToken = await this.clerkClient.m2m.createToken({\n machineSecretKey: this.m2mSecret,\n })\n\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n\n if (this.destroyed) return m2mToken.token\n\n this.cachedToken = m2mToken.token\n this.tokenExpiration = m2mToken.expiration\n this.scheduleRenewal()\n\n return this.cachedToken\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n }\n\n private scheduleRenewal = (): void => {\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n\n if (!this.tokenExpiration) return\n\n const timeUntilRenewal =\n this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS\n\n if (timeUntilRenewal <= 0) return\n\n this.renewalTimer = setTimeout(() => {\n this.cachedToken = null\n this.getToken().catch((error: unknown) => {\n console.error('Proactive M2M token renewal failed:', error)\n })\n }, timeUntilRenewal)\n }\n}\n","import { HttpClient } from './http/HttpClient'\nimport { AdminResource } from './resources/AdminResource'\nimport { CampaignsResource } from './resources/CampaignsResource'\nimport { EcanvasserResource } from './resources/EcanvasserResource'\nimport { ElectedOfficesResource } from './resources/ElectedOfficesResource'\nimport { ElectionsResource } from './resources/ElectionsResource'\nimport { PathsToVictoryResource } from './resources/PathsToVictoryResource'\nimport { UsersResource } from './resources/UsersResource'\nimport { ClerkService } from './vendor/clerk/clerk.service'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly admin: AdminResource\n readonly users: UsersResource\n readonly campaigns: CampaignsResource\n readonly ecanvasser: EcanvasserResource\n readonly electedOffices: ElectedOfficesResource\n readonly elections: ElectionsResource\n readonly pathsToVictory: PathsToVictoryResource\n private clerkService: ClerkService\n\n private constructor(clerkService: ClerkService, gpApiRootUrl: string) {\n this.clerkService = clerkService\n const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken)\n this.admin = new AdminResource(httpClient)\n this.users = new UsersResource(httpClient)\n this.campaigns = new CampaignsResource(httpClient)\n this.ecanvasser = new EcanvasserResource(httpClient)\n this.electedOffices = new ElectedOfficesResource(httpClient)\n this.elections = new ElectionsResource(httpClient)\n this.pathsToVictory = new PathsToVictoryResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkService = new ClerkService(m2mSecret)\n await clerkService.getToken()\n return new GoodPartyClient(clerkService, gpApiRootUrl)\n }\n\n destroy = (): void => {\n this.clerkService.destroy()\n }\n}\n","import {\n USER_ROLE_VALUES,\n type UserRole as UserRoleType,\n WHY_BROWSING_VALUES,\n type WhyBrowsing as WhyBrowsingType,\n CAMPAIGN_TIER_VALUES,\n type CampaignTier as CampaignTierType,\n} from '@goodparty_org/contracts'\n\ntype EnumObject<T extends readonly string[]> = { [K in T[number]]: K }\n\nconst toEnumObject = <T extends readonly string[]>(values: T): EnumObject<T> =>\n Object.fromEntries(values.map((v) => [v, v])) as EnumObject<T>\n\nexport type UserRole = UserRoleType\nexport const UserRole = toEnumObject(USER_ROLE_VALUES)\n\nexport type WhyBrowsing = WhyBrowsingType\nexport const WhyBrowsing = toEnumObject(WHY_BROWSING_VALUES)\n\nexport type CampaignTier = CampaignTierType\nexport const CampaignTier = toEnumObject(CAMPAIGN_TIER_VALUES)\n","import type { PaginationOptions } from '@goodparty_org/contracts'\n\nexport enum P2VStatus {\n complete = 'Complete',\n waiting = 'Waiting',\n failed = 'Failed',\n districtMatched = 'DistrictMatched',\n}\n\nexport enum P2VSource {\n GpApi = 'GpApi',\n ElectionApi = 'ElectionApi',\n}\n\nexport type ViabilityScore = {\n level: string\n isPartisan: boolean\n isIncumbent: boolean\n isUncontested: boolean\n candidates: number\n seats: number\n candidatesPerSeat: number\n score: number\n probOfWin: number\n}\n\nexport type PathToVictoryData = {\n p2vStatus?: P2VStatus\n p2vAttempts?: number\n p2vCompleteDate?: string\n completedBy?: number\n electionType?: string\n electionLocation?: string\n voterContactGoal?: number\n winNumber?: number\n p2vNotNeeded?: boolean\n totalRegisteredVoters?: number\n republicans?: number\n democrats?: number\n indies?: number\n women?: number\n men?: number\n white?: number\n asian?: number\n africanAmerican?: number\n hispanic?: number\n averageTurnout?: number\n projectedTurnout?: number\n viability?: ViabilityScore\n source?: P2VSource\n districtId?: string\n districtManuallySet?: boolean\n officeContextFingerprint?: string\n}\n\nexport type PathToVictory = {\n id: number\n createdAt: string\n updatedAt: string\n campaignId: number\n data: PathToVictoryData\n}\n\nexport type ListPathsToVictoryOptions = PaginationOptions & {\n userId?: number\n}\n\nexport type UpdatePathToVictoryInput = {\n data: PathToVictoryData\n}\n"],"mappings":"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","names":["import_contracts","P2VStatus","P2VSource"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/AdminResource.ts","../src/resources/CampaignsResource.ts","../src/resources/EcanvasserResource.ts","../src/resources/ElectedOfficesResource.ts","../src/resources/ElectionsResource.ts","../src/resources/OrganizationsResource.ts","../src/resources/UsersResource.ts","../src/vendor/clerk/clerk.service.ts","../src/GoodPartyClient.ts","../src/enums.ts"],"sourcesContent":["export { GoodPartyClient } from './GoodPartyClient'\nexport type { GoodPartyClientConfig } from './GoodPartyClient'\n\nexport { SdkError } from './types/result'\n\nexport type {\n PaginationMeta,\n PaginatedList,\n PaginationOptions,\n ReadUserOutput,\n ReadUserOutput as User,\n UpdatePasswordInput,\n UpdateUserInput,\n UserMetaData,\n ListUsersPagination,\n ReadCampaignOutput,\n ReadCampaignOutput as Campaign,\n CampaignDetails,\n CampaignData,\n CampaignAiContent,\n VoterGoals,\n CustomVoterFile,\n AiChatMessage,\n AiContentInputValues,\n AiContentGenerationStatus,\n AiContentData,\n GeoLocation,\n CustomIssue,\n Opponent,\n HubSpotUpdates,\n CampaignFinance,\n CampaignPlan,\n CampaignPlanStatus,\n ListCampaignsPagination,\n SetDistrictOutput,\n UpdateCampaignM2MInput as UpdateCampaignInput,\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\n\nexport {\n USER_ROLE_VALUES,\n WHY_BROWSING_VALUES,\n CAMPAIGN_TIER_VALUES,\n BALLOT_READY_POSITION_LEVEL_VALUES,\n ELECTION_LEVEL_VALUES,\n CAMPAIGN_CREATED_BY_VALUES,\n CAMPAIGN_LAUNCH_STATUS_VALUES,\n CAMPAIGN_STATUS_VALUES,\n ONBOARDING_STEP_VALUES,\n GENERATION_STATUS_VALUES,\n BallotReadyPositionLevel,\n ElectionLevel,\n CampaignCreatedBy,\n CampaignLaunchStatus,\n CampaignStatus,\n OnboardingStep,\n GenerationStatus,\n} from '@goodparty_org/contracts'\n\nexport { UserRole, WhyBrowsing, CampaignTier } from './enums'\n\nexport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n SetElectedOfficeDistrictOutput,\n UpdateElectedOfficeDistrictInput,\n UpdateElectedOfficeInput,\n} from './types/electedOffice'\n\nexport type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n UpdateDistrictInput,\n} from './types/district'\n\nexport type {\n CampaignWithLiveContext,\n CampaignWithPositionName,\n RaceTargetMetrics,\n} from './types/campaign'\n\nexport type { ImpersonateUserInput, ImpersonateUserOutput } from './types/admin'\n\nexport type {\n Organization,\n OrgDistrict,\n OrgPosition,\n OrganizationListItem,\n OrganizationOwnerSummary,\n ListOrganizationsOptions,\n PatchOrganizationInput,\n} from './types/organization'\n","import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private getToken: () => Promise<string>\n\n constructor(gpApiRootUrl: string, getToken: () => Promise<string>) {\n this.baseUrl = gpApiRootUrl\n this.getToken = getToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${await this.getToken()}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n protected abstract readonly resourceBasePath: string\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected patchRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PATCH', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { ImpersonateUserOutput } from '../types/admin'\nimport { BaseResource } from './BaseResource'\n\nexport class AdminResource extends BaseResource {\n protected readonly resourceBasePath = '/admin'\n\n impersonateUser = (\n targetUserId: number,\n actorEmail: string,\n ): Promise<ImpersonateUserOutput> =>\n this.postRequest<ImpersonateUserOutput>(\n `${this.resourceBasePath}/users/impersonate/${targetUserId}`,\n { actorEmail },\n )\n}\n","import type {\n ListCampaignsPagination,\n PaginatedList,\n ReadCampaignOutput,\n SetDistrictOutput,\n UpdateCampaignM2MInput,\n} from '@goodparty_org/contracts'\nimport type {\n CampaignWithLiveContext,\n CampaignWithPositionName,\n} from '../types/campaign'\nimport type { UpdateDistrictInput } from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class CampaignsResource extends BaseResource {\n protected readonly resourceBasePath = '/campaigns'\n\n get = (id: number): Promise<CampaignWithLiveContext> =>\n this.getRequest<CampaignWithLiveContext>(`${this.resourceBasePath}/${id}`)\n\n list = (\n options?: ListCampaignsPagination,\n ): Promise<PaginatedList<CampaignWithPositionName>> =>\n this.getRequest<PaginatedList<CampaignWithPositionName>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n update = (\n id: number,\n input: UpdateCampaignM2MInput,\n ): Promise<ReadCampaignOutput> =>\n this.putRequest<ReadCampaignOutput>(`${this.resourceBasePath}/${id}`, input)\n\n updateDistrict = (\n id: number,\n input: UpdateDistrictInput,\n ): Promise<SetDistrictOutput> =>\n this.putRequest<SetDistrictOutput>(\n `${this.resourceBasePath}/${id}/district`,\n input,\n )\n}\n","import type {\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class EcanvasserResource extends BaseResource {\n protected readonly resourceBasePath = '/ecanvasser'\n\n create = (input: CreateEcanvasserInput): Promise<Ecanvasser> =>\n this.postRequest<Ecanvasser>(this.resourceBasePath, input)\n\n list = (): Promise<EcanvasserSummary[]> =>\n this.getRequest<EcanvasserSummary[]>(`${this.resourceBasePath}/list`)\n\n syncAll = (): Promise<void> =>\n this.getRequest<void>(`${this.resourceBasePath}/sync-all`)\n\n delete = (campaignId: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${campaignId}`)\n}\n","import type { PaginatedList } from '@goodparty_org/contracts'\nimport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n SetElectedOfficeDistrictOutput,\n UpdateElectedOfficeDistrictInput,\n UpdateElectedOfficeInput,\n} from '../types/electedOffice'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectedOfficesResource extends BaseResource {\n protected readonly resourceBasePath = '/elected-office'\n\n list = (\n options?: ListElectedOfficesOptions,\n ): Promise<PaginatedList<ElectedOffice>> =>\n this.getRequest<PaginatedList<ElectedOffice>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n get = (id: string): Promise<ElectedOffice> =>\n this.getRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`)\n\n update = (\n id: string,\n input: UpdateElectedOfficeInput,\n ): Promise<ElectedOffice> =>\n this.putRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`, input)\n\n updateDistrict = (\n id: string,\n input: UpdateElectedOfficeDistrictInput,\n ): Promise<SetElectedOfficeDistrictOutput> =>\n this.putRequest<SetElectedOfficeDistrictOutput>(\n `${this.resourceBasePath}/${id}/district`,\n input,\n )\n}\n","import type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n} from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectionsResource extends BaseResource {\n protected readonly resourceBasePath = '/elections'\n\n listDistrictTypes = (\n options: ListDistrictTypesOptions,\n ): Promise<DistrictTypeItem[]> =>\n this.getRequest<DistrictTypeItem[]>(\n `${this.resourceBasePath}/districts/types`,\n options,\n )\n\n listDistrictNames = (\n options: ListDistrictNamesOptions,\n ): Promise<DistrictNameItem[]> =>\n this.getRequest<DistrictNameItem[]>(\n `${this.resourceBasePath}/districts/names`,\n options,\n )\n}\n","import type {\n ListOrganizationsOptions,\n Organization,\n OrganizationListItem,\n PatchOrganizationInput,\n} from '../types/organization'\nimport { BaseResource } from './BaseResource'\n\nexport class OrganizationsResource extends BaseResource {\n protected readonly resourceBasePath = '/organizations'\n\n get = (slug: string): Promise<Organization> =>\n this.getRequest<Organization>(`${this.resourceBasePath}/admin/${slug}`)\n\n list = (\n options?: ListOrganizationsOptions,\n ): Promise<{ organizations: OrganizationListItem[] }> =>\n this.getRequest<{ organizations: OrganizationListItem[] }>(\n `${this.resourceBasePath}/admin/list`,\n options,\n )\n\n patch = (\n slug: string,\n input: PatchOrganizationInput,\n ): Promise<Organization> =>\n this.patchRequest<Organization>(\n `${this.resourceBasePath}/admin/${slug}`,\n input,\n )\n}\n","import type {\n ListUsersPagination,\n PaginatedList,\n ReadUserOutput,\n UpdatePasswordInput,\n UpdateUserInput,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n protected readonly resourceBasePath = '/users'\n\n list = (\n options?: ListUsersPagination,\n ): Promise<PaginatedList<ReadUserOutput>> =>\n this.getRequest<PaginatedList<ReadUserOutput>>(\n this.resourceBasePath,\n options,\n )\n\n get = (id: number): Promise<ReadUserOutput> =>\n this.getRequest<ReadUserOutput>(`/users/${id}`)\n\n update = (id: number, input: UpdateUserInput): Promise<ReadUserOutput> =>\n this.putRequest<ReadUserOutput>(`${this.resourceBasePath}/${id}`, input)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`${this.resourceBasePath}/${id}/password`, input)\n}\n","import { createClerkClient } from '@clerk/backend'\nimport { SdkError } from '../../types/result'\n\nconst TOKEN_RENEWAL_BUFFER_MS = 30_000\n\nexport class ClerkService {\n private readonly m2mSecret: string\n private readonly clerkClient: ReturnType<typeof createClerkClient>\n private cachedToken: string | null = null\n private tokenExpiration: number | null = null\n private renewalTimer: ReturnType<typeof setTimeout> | null = null\n private pendingTokenPromise: Promise<string> | null = null\n private destroyed = false\n\n constructor(m2mSecret: string) {\n this.m2mSecret = m2mSecret\n this.clerkClient = createClerkClient({})\n }\n\n getToken = async (): Promise<string> => {\n if (this.cachedToken && this.isTokenValid()) {\n return this.cachedToken\n }\n\n if (this.pendingTokenPromise) {\n return this.pendingTokenPromise\n }\n\n const promise = this.createAndCacheToken()\n this.pendingTokenPromise = promise\n\n try {\n return await promise\n } finally {\n if (this.pendingTokenPromise === promise) {\n this.pendingTokenPromise = null\n }\n }\n }\n\n destroy = (): void => {\n this.destroyed = true\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n this.cachedToken = null\n this.tokenExpiration = null\n this.pendingTokenPromise = null\n }\n\n private isTokenValid = (): boolean => {\n if (!this.tokenExpiration) return true\n return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS\n }\n\n private createAndCacheToken = async (): Promise<string> => {\n try {\n const m2mToken = await this.clerkClient.m2m.createToken({\n machineSecretKey: this.m2mSecret,\n })\n\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n\n if (this.destroyed) return m2mToken.token\n\n this.cachedToken = m2mToken.token\n this.tokenExpiration = m2mToken.expiration\n this.scheduleRenewal()\n\n return this.cachedToken\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n }\n\n private scheduleRenewal = (): void => {\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n\n if (!this.tokenExpiration) return\n\n const timeUntilRenewal =\n this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS\n\n if (timeUntilRenewal <= 0) return\n\n this.renewalTimer = setTimeout(() => {\n this.cachedToken = null\n this.getToken().catch((error: unknown) => {\n console.error('Proactive M2M token renewal failed:', error)\n })\n }, timeUntilRenewal)\n }\n}\n","import { HttpClient } from './http/HttpClient'\nimport { AdminResource } from './resources/AdminResource'\nimport { CampaignsResource } from './resources/CampaignsResource'\nimport { EcanvasserResource } from './resources/EcanvasserResource'\nimport { ElectedOfficesResource } from './resources/ElectedOfficesResource'\nimport { ElectionsResource } from './resources/ElectionsResource'\nimport { OrganizationsResource } from './resources/OrganizationsResource'\nimport { UsersResource } from './resources/UsersResource'\nimport { ClerkService } from './vendor/clerk/clerk.service'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly admin: AdminResource\n readonly users: UsersResource\n readonly campaigns: CampaignsResource\n readonly ecanvasser: EcanvasserResource\n readonly electedOffices: ElectedOfficesResource\n readonly elections: ElectionsResource\n readonly organizations: OrganizationsResource\n private clerkService: ClerkService\n\n private constructor(clerkService: ClerkService, gpApiRootUrl: string) {\n this.clerkService = clerkService\n const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken)\n this.admin = new AdminResource(httpClient)\n this.users = new UsersResource(httpClient)\n this.campaigns = new CampaignsResource(httpClient)\n this.ecanvasser = new EcanvasserResource(httpClient)\n this.electedOffices = new ElectedOfficesResource(httpClient)\n this.elections = new ElectionsResource(httpClient)\n this.organizations = new OrganizationsResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkService = new ClerkService(m2mSecret)\n await clerkService.getToken()\n return new GoodPartyClient(clerkService, gpApiRootUrl)\n }\n\n destroy = (): void => {\n this.clerkService.destroy()\n }\n}\n","import {\n USER_ROLE_VALUES,\n type UserRole as UserRoleType,\n WHY_BROWSING_VALUES,\n type WhyBrowsing as WhyBrowsingType,\n CAMPAIGN_TIER_VALUES,\n type CampaignTier as CampaignTierType,\n} from '@goodparty_org/contracts'\n\ntype EnumObject<T extends readonly string[]> = { [K in T[number]]: K }\n\nconst toEnumObject = <T extends readonly string[]>(values: T): EnumObject<T> =>\n Object.fromEntries(values.map((v) => [v, v])) as EnumObject<T>\n\nexport type UserRole = UserRoleType\nexport const UserRole = toEnumObject(USER_ROLE_VALUES)\n\nexport type WhyBrowsing = WhyBrowsingType\nexport const WhyBrowsing = toEnumObject(WHY_BROWSING_VALUES)\n\nexport type CampaignTier = CampaignTierType\nexport const CampaignTier = toEnumObject(CAMPAIGN_TIER_VALUES)\n"],"mappings":"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","names":["import_contracts"]}
package/dist/index.mjs CHANGED
@@ -50,15 +50,16 @@ var BaseResource = class {
50
50
  getRequest = (path, query) => this.httpClient.request(path, { method: "GET", query });
51
51
  postRequest = (path, body) => this.httpClient.request(path, { method: "POST", body });
52
52
  putRequest = (path, body) => this.httpClient.request(path, { method: "PUT", body });
53
+ patchRequest = (path, body) => this.httpClient.request(path, { method: "PATCH", body });
53
54
  deleteRequest = (path) => this.httpClient.request(path, { method: "DELETE" });
54
55
  };
55
56
 
56
57
  // src/resources/AdminResource.ts
57
58
  var AdminResource = class extends BaseResource {
58
59
  resourceBasePath = "/admin";
59
- impersonateUser = (targetUserId, actorClerkId) => this.postRequest(
60
+ impersonateUser = (targetUserId, actorEmail) => this.postRequest(
60
61
  `${this.resourceBasePath}/users/impersonate/${targetUserId}`,
61
- { actorClerkId }
62
+ { actorEmail }
62
63
  );
63
64
  };
64
65
 
@@ -95,6 +96,10 @@ var ElectedOfficesResource = class extends BaseResource {
95
96
  );
96
97
  get = (id) => this.getRequest(`${this.resourceBasePath}/${id}`);
97
98
  update = (id, input) => this.putRequest(`${this.resourceBasePath}/${id}`, input);
99
+ updateDistrict = (id, input) => this.putRequest(
100
+ `${this.resourceBasePath}/${id}/district`,
101
+ input
102
+ );
98
103
  };
99
104
 
100
105
  // src/resources/ElectionsResource.ts
@@ -110,15 +115,18 @@ var ElectionsResource = class extends BaseResource {
110
115
  );
111
116
  };
112
117
 
113
- // src/resources/PathsToVictoryResource.ts
114
- var PathsToVictoryResource = class extends BaseResource {
115
- resourceBasePath = "/path-to-victory";
118
+ // src/resources/OrganizationsResource.ts
119
+ var OrganizationsResource = class extends BaseResource {
120
+ resourceBasePath = "/organizations";
121
+ get = (slug) => this.getRequest(`${this.resourceBasePath}/admin/${slug}`);
116
122
  list = (options) => this.getRequest(
117
- `${this.resourceBasePath}/list`,
123
+ `${this.resourceBasePath}/admin/list`,
118
124
  options
119
125
  );
120
- get = (id) => this.getRequest(`${this.resourceBasePath}/${id}`);
121
- update = (id, input) => this.putRequest(`${this.resourceBasePath}/${id}`, input);
126
+ patch = (slug, input) => this.patchRequest(
127
+ `${this.resourceBasePath}/admin/${slug}`,
128
+ input
129
+ );
122
130
  };
123
131
 
124
132
  // src/resources/UsersResource.ts
@@ -229,7 +237,7 @@ var GoodPartyClient = class _GoodPartyClient {
229
237
  ecanvasser;
230
238
  electedOffices;
231
239
  elections;
232
- pathsToVictory;
240
+ organizations;
233
241
  clerkService;
234
242
  constructor(clerkService, gpApiRootUrl) {
235
243
  this.clerkService = clerkService;
@@ -240,7 +248,7 @@ var GoodPartyClient = class _GoodPartyClient {
240
248
  this.ecanvasser = new EcanvasserResource(httpClient);
241
249
  this.electedOffices = new ElectedOfficesResource(httpClient);
242
250
  this.elections = new ElectionsResource(httpClient);
243
- this.pathsToVictory = new PathsToVictoryResource(httpClient);
251
+ this.organizations = new OrganizationsResource(httpClient);
244
252
  }
245
253
  static create = async (config) => {
246
254
  const { m2mSecret, gpApiRootUrl } = config;
@@ -284,20 +292,6 @@ var toEnumObject = (values) => Object.fromEntries(values.map((v) => [v, v]));
284
292
  var UserRole = toEnumObject(USER_ROLE_VALUES);
285
293
  var WhyBrowsing = toEnumObject(WHY_BROWSING_VALUES);
286
294
  var CampaignTier = toEnumObject(CAMPAIGN_TIER_VALUES);
287
-
288
- // src/types/pathToVictory.ts
289
- var P2VStatus = /* @__PURE__ */ ((P2VStatus2) => {
290
- P2VStatus2["complete"] = "Complete";
291
- P2VStatus2["waiting"] = "Waiting";
292
- P2VStatus2["failed"] = "Failed";
293
- P2VStatus2["districtMatched"] = "DistrictMatched";
294
- return P2VStatus2;
295
- })(P2VStatus || {});
296
- var P2VSource = /* @__PURE__ */ ((P2VSource2) => {
297
- P2VSource2["GpApi"] = "GpApi";
298
- P2VSource2["ElectionApi"] = "ElectionApi";
299
- return P2VSource2;
300
- })(P2VSource || {});
301
295
  export {
302
296
  BALLOT_READY_POSITION_LEVEL_VALUES,
303
297
  BallotReadyPositionLevel,
@@ -316,8 +310,6 @@ export {
316
310
  GoodPartyClient,
317
311
  ONBOARDING_STEP_VALUES,
318
312
  OnboardingStep,
319
- P2VSource,
320
- P2VStatus,
321
313
  SdkError,
322
314
  USER_ROLE_VALUES2 as USER_ROLE_VALUES,
323
315
  UserRole,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/AdminResource.ts","../src/resources/CampaignsResource.ts","../src/resources/EcanvasserResource.ts","../src/resources/ElectedOfficesResource.ts","../src/resources/ElectionsResource.ts","../src/resources/PathsToVictoryResource.ts","../src/resources/UsersResource.ts","../src/vendor/clerk/clerk.service.ts","../src/GoodPartyClient.ts","../src/index.ts","../src/enums.ts","../src/types/pathToVictory.ts"],"sourcesContent":["import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private getToken: () => Promise<string>\n\n constructor(gpApiRootUrl: string, getToken: () => Promise<string>) {\n this.baseUrl = gpApiRootUrl\n this.getToken = getToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${await this.getToken()}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n protected abstract readonly resourceBasePath: string\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { ImpersonateUserOutput } from '../types/admin'\nimport { BaseResource } from './BaseResource'\n\nexport class AdminResource extends BaseResource {\n protected readonly resourceBasePath = '/admin'\n\n impersonateUser = (\n targetUserId: number,\n actorClerkId: string,\n ): Promise<ImpersonateUserOutput> =>\n this.postRequest<ImpersonateUserOutput>(\n `${this.resourceBasePath}/users/impersonate/${targetUserId}`,\n { actorClerkId },\n )\n}\n","import type {\n ListCampaignsPagination,\n PaginatedList,\n ReadCampaignOutput,\n SetDistrictOutput,\n UpdateCampaignM2MInput,\n} from '@goodparty_org/contracts'\nimport type { UpdateDistrictInput } from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class CampaignsResource extends BaseResource {\n protected readonly resourceBasePath = '/campaigns'\n\n get = (id: number): Promise<ReadCampaignOutput> =>\n this.getRequest<ReadCampaignOutput>(`${this.resourceBasePath}/${id}`)\n\n list = (\n options?: ListCampaignsPagination,\n ): Promise<PaginatedList<ReadCampaignOutput>> =>\n this.getRequest<PaginatedList<ReadCampaignOutput>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n update = (\n id: number,\n input: UpdateCampaignM2MInput,\n ): Promise<ReadCampaignOutput> =>\n this.putRequest<ReadCampaignOutput>(`${this.resourceBasePath}/${id}`, input)\n\n updateDistrict = (\n id: number,\n input: UpdateDistrictInput,\n ): Promise<SetDistrictOutput> =>\n this.putRequest<SetDistrictOutput>(\n `${this.resourceBasePath}/${id}/district`,\n input,\n )\n}\n","import type {\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class EcanvasserResource extends BaseResource {\n protected readonly resourceBasePath = '/ecanvasser'\n\n create = (input: CreateEcanvasserInput): Promise<Ecanvasser> =>\n this.postRequest<Ecanvasser>(this.resourceBasePath, input)\n\n list = (): Promise<EcanvasserSummary[]> =>\n this.getRequest<EcanvasserSummary[]>(`${this.resourceBasePath}/list`)\n\n syncAll = (): Promise<void> =>\n this.getRequest<void>(`${this.resourceBasePath}/sync-all`)\n\n delete = (campaignId: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${campaignId}`)\n}\n","import type { PaginatedList } from '@goodparty_org/contracts'\nimport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n UpdateElectedOfficeInput,\n} from '../types/electedOffice'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectedOfficesResource extends BaseResource {\n protected readonly resourceBasePath = '/elected-office'\n\n list = (\n options?: ListElectedOfficesOptions,\n ): Promise<PaginatedList<ElectedOffice>> =>\n this.getRequest<PaginatedList<ElectedOffice>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n get = (id: string): Promise<ElectedOffice> =>\n this.getRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`)\n\n update = (\n id: string,\n input: UpdateElectedOfficeInput,\n ): Promise<ElectedOffice> =>\n this.putRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`, input)\n}\n","import type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n} from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectionsResource extends BaseResource {\n protected readonly resourceBasePath = '/elections'\n\n listDistrictTypes = (\n options: ListDistrictTypesOptions,\n ): Promise<DistrictTypeItem[]> =>\n this.getRequest<DistrictTypeItem[]>(\n `${this.resourceBasePath}/districts/types`,\n options,\n )\n\n listDistrictNames = (\n options: ListDistrictNamesOptions,\n ): Promise<DistrictNameItem[]> =>\n this.getRequest<DistrictNameItem[]>(\n `${this.resourceBasePath}/districts/names`,\n options,\n )\n}\n","import type { PaginatedList } from '@goodparty_org/contracts'\nimport type {\n ListPathsToVictoryOptions,\n PathToVictory,\n UpdatePathToVictoryInput,\n} from '../types/pathToVictory'\nimport { BaseResource } from './BaseResource'\n\nexport class PathsToVictoryResource extends BaseResource {\n protected resourceBasePath = '/path-to-victory'\n list = (\n options?: ListPathsToVictoryOptions,\n ): Promise<PaginatedList<PathToVictory>> =>\n this.getRequest<PaginatedList<PathToVictory>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n get = (id: number): Promise<PathToVictory> =>\n this.getRequest<PathToVictory>(`${this.resourceBasePath}/${id}`)\n\n update = (\n id: number,\n input: UpdatePathToVictoryInput,\n ): Promise<PathToVictory> =>\n this.putRequest<PathToVictory>(`${this.resourceBasePath}/${id}`, input)\n}\n","import type {\n ListUsersPagination,\n PaginatedList,\n ReadUserOutput,\n UpdatePasswordInput,\n UpdateUserInput,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n protected readonly resourceBasePath = '/users'\n\n list = (\n options?: ListUsersPagination,\n ): Promise<PaginatedList<ReadUserOutput>> =>\n this.getRequest<PaginatedList<ReadUserOutput>>(\n this.resourceBasePath,\n options,\n )\n\n get = (id: number): Promise<ReadUserOutput> =>\n this.getRequest<ReadUserOutput>(`/users/${id}`)\n\n update = (id: number, input: UpdateUserInput): Promise<ReadUserOutput> =>\n this.putRequest<ReadUserOutput>(`${this.resourceBasePath}/${id}`, input)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`${this.resourceBasePath}/${id}/password`, input)\n}\n","import { createClerkClient } from '@clerk/backend'\nimport { SdkError } from '../../types/result'\n\nconst TOKEN_RENEWAL_BUFFER_MS = 30_000\n\nexport class ClerkService {\n private readonly m2mSecret: string\n private readonly clerkClient: ReturnType<typeof createClerkClient>\n private cachedToken: string | null = null\n private tokenExpiration: number | null = null\n private renewalTimer: ReturnType<typeof setTimeout> | null = null\n private pendingTokenPromise: Promise<string> | null = null\n private destroyed = false\n\n constructor(m2mSecret: string) {\n this.m2mSecret = m2mSecret\n this.clerkClient = createClerkClient({})\n }\n\n getToken = async (): Promise<string> => {\n if (this.cachedToken && this.isTokenValid()) {\n return this.cachedToken\n }\n\n if (this.pendingTokenPromise) {\n return this.pendingTokenPromise\n }\n\n const promise = this.createAndCacheToken()\n this.pendingTokenPromise = promise\n\n try {\n return await promise\n } finally {\n if (this.pendingTokenPromise === promise) {\n this.pendingTokenPromise = null\n }\n }\n }\n\n destroy = (): void => {\n this.destroyed = true\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n this.cachedToken = null\n this.tokenExpiration = null\n this.pendingTokenPromise = null\n }\n\n private isTokenValid = (): boolean => {\n if (!this.tokenExpiration) return true\n return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS\n }\n\n private createAndCacheToken = async (): Promise<string> => {\n try {\n const m2mToken = await this.clerkClient.m2m.createToken({\n machineSecretKey: this.m2mSecret,\n })\n\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n\n if (this.destroyed) return m2mToken.token\n\n this.cachedToken = m2mToken.token\n this.tokenExpiration = m2mToken.expiration\n this.scheduleRenewal()\n\n return this.cachedToken\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n }\n\n private scheduleRenewal = (): void => {\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n\n if (!this.tokenExpiration) return\n\n const timeUntilRenewal =\n this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS\n\n if (timeUntilRenewal <= 0) return\n\n this.renewalTimer = setTimeout(() => {\n this.cachedToken = null\n this.getToken().catch((error: unknown) => {\n console.error('Proactive M2M token renewal failed:', error)\n })\n }, timeUntilRenewal)\n }\n}\n","import { HttpClient } from './http/HttpClient'\nimport { AdminResource } from './resources/AdminResource'\nimport { CampaignsResource } from './resources/CampaignsResource'\nimport { EcanvasserResource } from './resources/EcanvasserResource'\nimport { ElectedOfficesResource } from './resources/ElectedOfficesResource'\nimport { ElectionsResource } from './resources/ElectionsResource'\nimport { PathsToVictoryResource } from './resources/PathsToVictoryResource'\nimport { UsersResource } from './resources/UsersResource'\nimport { ClerkService } from './vendor/clerk/clerk.service'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly admin: AdminResource\n readonly users: UsersResource\n readonly campaigns: CampaignsResource\n readonly ecanvasser: EcanvasserResource\n readonly electedOffices: ElectedOfficesResource\n readonly elections: ElectionsResource\n readonly pathsToVictory: PathsToVictoryResource\n private clerkService: ClerkService\n\n private constructor(clerkService: ClerkService, gpApiRootUrl: string) {\n this.clerkService = clerkService\n const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken)\n this.admin = new AdminResource(httpClient)\n this.users = new UsersResource(httpClient)\n this.campaigns = new CampaignsResource(httpClient)\n this.ecanvasser = new EcanvasserResource(httpClient)\n this.electedOffices = new ElectedOfficesResource(httpClient)\n this.elections = new ElectionsResource(httpClient)\n this.pathsToVictory = new PathsToVictoryResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkService = new ClerkService(m2mSecret)\n await clerkService.getToken()\n return new GoodPartyClient(clerkService, gpApiRootUrl)\n }\n\n destroy = (): void => {\n this.clerkService.destroy()\n }\n}\n","export { GoodPartyClient } from './GoodPartyClient'\nexport type { GoodPartyClientConfig } from './GoodPartyClient'\n\nexport { SdkError } from './types/result'\n\nexport type {\n PaginationMeta,\n PaginatedList,\n PaginationOptions,\n ReadUserOutput,\n ReadUserOutput as User,\n UpdatePasswordInput,\n UpdateUserInput,\n UserMetaData,\n ListUsersPagination,\n ReadCampaignOutput,\n ReadCampaignOutput as Campaign,\n CampaignDetails,\n CampaignData,\n CampaignAiContent,\n VoterGoals,\n CustomVoterFile,\n AiChatMessage,\n AiContentInputValues,\n AiContentGenerationStatus,\n AiContentData,\n GeoLocation,\n CustomIssue,\n Opponent,\n HubSpotUpdates,\n CampaignFinance,\n CampaignPlan,\n CampaignPlanStatus,\n ListCampaignsPagination,\n SetDistrictOutput,\n UpdateCampaignM2MInput as UpdateCampaignInput,\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\n\nexport {\n USER_ROLE_VALUES,\n WHY_BROWSING_VALUES,\n CAMPAIGN_TIER_VALUES,\n BALLOT_READY_POSITION_LEVEL_VALUES,\n ELECTION_LEVEL_VALUES,\n CAMPAIGN_CREATED_BY_VALUES,\n CAMPAIGN_LAUNCH_STATUS_VALUES,\n CAMPAIGN_STATUS_VALUES,\n ONBOARDING_STEP_VALUES,\n GENERATION_STATUS_VALUES,\n BallotReadyPositionLevel,\n ElectionLevel,\n CampaignCreatedBy,\n CampaignLaunchStatus,\n CampaignStatus,\n OnboardingStep,\n GenerationStatus,\n} from '@goodparty_org/contracts'\n\nexport { UserRole, WhyBrowsing, CampaignTier } from './enums'\n\nexport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n UpdateElectedOfficeInput,\n} from './types/electedOffice'\n\nexport type {\n PathToVictory,\n PathToVictoryData,\n ViabilityScore,\n ListPathsToVictoryOptions,\n UpdatePathToVictoryInput,\n} from './types/pathToVictory'\n\nexport { P2VStatus, P2VSource } from './types/pathToVictory'\n\nexport type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n UpdateDistrictInput,\n} from './types/district'\n\nexport type { ImpersonateUserInput, ImpersonateUserOutput } from './types/admin'\n","import {\n USER_ROLE_VALUES,\n type UserRole as UserRoleType,\n WHY_BROWSING_VALUES,\n type WhyBrowsing as WhyBrowsingType,\n CAMPAIGN_TIER_VALUES,\n type CampaignTier as CampaignTierType,\n} from '@goodparty_org/contracts'\n\ntype EnumObject<T extends readonly string[]> = { [K in T[number]]: K }\n\nconst toEnumObject = <T extends readonly string[]>(values: T): EnumObject<T> =>\n Object.fromEntries(values.map((v) => [v, v])) as EnumObject<T>\n\nexport type UserRole = UserRoleType\nexport const UserRole = toEnumObject(USER_ROLE_VALUES)\n\nexport type WhyBrowsing = WhyBrowsingType\nexport const WhyBrowsing = toEnumObject(WHY_BROWSING_VALUES)\n\nexport type CampaignTier = CampaignTierType\nexport const CampaignTier = toEnumObject(CAMPAIGN_TIER_VALUES)\n","import type { PaginationOptions } from '@goodparty_org/contracts'\n\nexport enum P2VStatus {\n complete = 'Complete',\n waiting = 'Waiting',\n failed = 'Failed',\n districtMatched = 'DistrictMatched',\n}\n\nexport enum P2VSource {\n GpApi = 'GpApi',\n ElectionApi = 'ElectionApi',\n}\n\nexport type ViabilityScore = {\n level: string\n isPartisan: boolean\n isIncumbent: boolean\n isUncontested: boolean\n candidates: number\n seats: number\n candidatesPerSeat: number\n score: number\n probOfWin: number\n}\n\nexport type PathToVictoryData = {\n p2vStatus?: P2VStatus\n p2vAttempts?: number\n p2vCompleteDate?: string\n completedBy?: number\n electionType?: string\n electionLocation?: string\n voterContactGoal?: number\n winNumber?: number\n p2vNotNeeded?: boolean\n totalRegisteredVoters?: number\n republicans?: number\n democrats?: number\n indies?: number\n women?: number\n men?: number\n white?: number\n asian?: number\n africanAmerican?: number\n hispanic?: number\n averageTurnout?: number\n projectedTurnout?: number\n viability?: ViabilityScore\n source?: P2VSource\n districtId?: string\n districtManuallySet?: boolean\n officeContextFingerprint?: string\n}\n\nexport type PathToVictory = {\n id: number\n createdAt: string\n updatedAt: string\n campaignId: number\n data: PathToVictoryData\n}\n\nexport type ListPathsToVictoryOptions = PaginationOptions & {\n userId?: number\n}\n\nexport type UpdatePathToVictoryInput = {\n data: PathToVictoryData\n}\n"],"mappings":"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","names":["USER_ROLE_VALUES","WHY_BROWSING_VALUES","CAMPAIGN_TIER_VALUES","P2VStatus","P2VSource"]}
1
+ {"version":3,"sources":["../src/http/HttpClient.ts","../src/types/result.ts","../src/resources/BaseResource.ts","../src/resources/AdminResource.ts","../src/resources/CampaignsResource.ts","../src/resources/EcanvasserResource.ts","../src/resources/ElectedOfficesResource.ts","../src/resources/ElectionsResource.ts","../src/resources/OrganizationsResource.ts","../src/resources/UsersResource.ts","../src/vendor/clerk/clerk.service.ts","../src/GoodPartyClient.ts","../src/index.ts","../src/enums.ts"],"sourcesContent":["import { ofetch, FetchError, FetchOptions } from 'ofetch'\nimport { SdkError } from '../types/result'\n\nexport type OfetchRequestBody = FetchOptions<'json'>['body']\n\nexport class HttpClient {\n private baseUrl: string\n private getToken: () => Promise<string>\n\n constructor(gpApiRootUrl: string, getToken: () => Promise<string>) {\n this.baseUrl = gpApiRootUrl\n this.getToken = getToken\n }\n\n request = async <T>(\n path: string,\n init?: FetchOptions<'json'>,\n ): Promise<T> => {\n try {\n return await ofetch<T>(path, {\n baseURL: this.baseUrl,\n headers: {\n Authorization: `Bearer ${await this.getToken()}`,\n ...(init?.headers ?? {}),\n },\n ...init,\n })\n } catch (error: unknown) {\n if (error instanceof FetchError) {\n throw new SdkError(error.statusCode ?? 0, error.message, error.response)\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, message)\n }\n }\n}\n","export class SdkError extends Error {\n readonly status: number\n readonly response?: Response\n\n constructor(status: number, message: string, response?: Response) {\n super(message)\n this.name = 'SdkError'\n this.status = status\n this.response = response\n }\n}\n","import type { FetchOptions } from 'ofetch'\nimport type { HttpClient, OfetchRequestBody } from '../http/HttpClient'\n\nexport abstract class BaseResource {\n protected httpClient: HttpClient\n protected abstract readonly resourceBasePath: string\n\n constructor(httpClient: HttpClient) {\n this.httpClient = httpClient\n }\n\n protected getRequest = <T>(\n path: string,\n query?: FetchOptions<'json'>['query'],\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'GET', query })\n\n protected postRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'POST', body })\n\n protected putRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PUT', body })\n\n protected patchRequest = <T>(\n path: string,\n body: OfetchRequestBody,\n ): Promise<T> => this.httpClient.request<T>(path, { method: 'PATCH', body })\n\n protected deleteRequest = <T>(path: string): Promise<T> =>\n this.httpClient.request<T>(path, { method: 'DELETE' })\n}\n","import type { ImpersonateUserOutput } from '../types/admin'\nimport { BaseResource } from './BaseResource'\n\nexport class AdminResource extends BaseResource {\n protected readonly resourceBasePath = '/admin'\n\n impersonateUser = (\n targetUserId: number,\n actorEmail: string,\n ): Promise<ImpersonateUserOutput> =>\n this.postRequest<ImpersonateUserOutput>(\n `${this.resourceBasePath}/users/impersonate/${targetUserId}`,\n { actorEmail },\n )\n}\n","import type {\n ListCampaignsPagination,\n PaginatedList,\n ReadCampaignOutput,\n SetDistrictOutput,\n UpdateCampaignM2MInput,\n} from '@goodparty_org/contracts'\nimport type {\n CampaignWithLiveContext,\n CampaignWithPositionName,\n} from '../types/campaign'\nimport type { UpdateDistrictInput } from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class CampaignsResource extends BaseResource {\n protected readonly resourceBasePath = '/campaigns'\n\n get = (id: number): Promise<CampaignWithLiveContext> =>\n this.getRequest<CampaignWithLiveContext>(`${this.resourceBasePath}/${id}`)\n\n list = (\n options?: ListCampaignsPagination,\n ): Promise<PaginatedList<CampaignWithPositionName>> =>\n this.getRequest<PaginatedList<CampaignWithPositionName>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n update = (\n id: number,\n input: UpdateCampaignM2MInput,\n ): Promise<ReadCampaignOutput> =>\n this.putRequest<ReadCampaignOutput>(`${this.resourceBasePath}/${id}`, input)\n\n updateDistrict = (\n id: number,\n input: UpdateDistrictInput,\n ): Promise<SetDistrictOutput> =>\n this.putRequest<SetDistrictOutput>(\n `${this.resourceBasePath}/${id}/district`,\n input,\n )\n}\n","import type {\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class EcanvasserResource extends BaseResource {\n protected readonly resourceBasePath = '/ecanvasser'\n\n create = (input: CreateEcanvasserInput): Promise<Ecanvasser> =>\n this.postRequest<Ecanvasser>(this.resourceBasePath, input)\n\n list = (): Promise<EcanvasserSummary[]> =>\n this.getRequest<EcanvasserSummary[]>(`${this.resourceBasePath}/list`)\n\n syncAll = (): Promise<void> =>\n this.getRequest<void>(`${this.resourceBasePath}/sync-all`)\n\n delete = (campaignId: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${campaignId}`)\n}\n","import type { PaginatedList } from '@goodparty_org/contracts'\nimport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n SetElectedOfficeDistrictOutput,\n UpdateElectedOfficeDistrictInput,\n UpdateElectedOfficeInput,\n} from '../types/electedOffice'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectedOfficesResource extends BaseResource {\n protected readonly resourceBasePath = '/elected-office'\n\n list = (\n options?: ListElectedOfficesOptions,\n ): Promise<PaginatedList<ElectedOffice>> =>\n this.getRequest<PaginatedList<ElectedOffice>>(\n `${this.resourceBasePath}/list`,\n options,\n )\n\n get = (id: string): Promise<ElectedOffice> =>\n this.getRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`)\n\n update = (\n id: string,\n input: UpdateElectedOfficeInput,\n ): Promise<ElectedOffice> =>\n this.putRequest<ElectedOffice>(`${this.resourceBasePath}/${id}`, input)\n\n updateDistrict = (\n id: string,\n input: UpdateElectedOfficeDistrictInput,\n ): Promise<SetElectedOfficeDistrictOutput> =>\n this.putRequest<SetElectedOfficeDistrictOutput>(\n `${this.resourceBasePath}/${id}/district`,\n input,\n )\n}\n","import type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n} from '../types/district'\nimport { BaseResource } from './BaseResource'\n\nexport class ElectionsResource extends BaseResource {\n protected readonly resourceBasePath = '/elections'\n\n listDistrictTypes = (\n options: ListDistrictTypesOptions,\n ): Promise<DistrictTypeItem[]> =>\n this.getRequest<DistrictTypeItem[]>(\n `${this.resourceBasePath}/districts/types`,\n options,\n )\n\n listDistrictNames = (\n options: ListDistrictNamesOptions,\n ): Promise<DistrictNameItem[]> =>\n this.getRequest<DistrictNameItem[]>(\n `${this.resourceBasePath}/districts/names`,\n options,\n )\n}\n","import type {\n ListOrganizationsOptions,\n Organization,\n OrganizationListItem,\n PatchOrganizationInput,\n} from '../types/organization'\nimport { BaseResource } from './BaseResource'\n\nexport class OrganizationsResource extends BaseResource {\n protected readonly resourceBasePath = '/organizations'\n\n get = (slug: string): Promise<Organization> =>\n this.getRequest<Organization>(`${this.resourceBasePath}/admin/${slug}`)\n\n list = (\n options?: ListOrganizationsOptions,\n ): Promise<{ organizations: OrganizationListItem[] }> =>\n this.getRequest<{ organizations: OrganizationListItem[] }>(\n `${this.resourceBasePath}/admin/list`,\n options,\n )\n\n patch = (\n slug: string,\n input: PatchOrganizationInput,\n ): Promise<Organization> =>\n this.patchRequest<Organization>(\n `${this.resourceBasePath}/admin/${slug}`,\n input,\n )\n}\n","import type {\n ListUsersPagination,\n PaginatedList,\n ReadUserOutput,\n UpdatePasswordInput,\n UpdateUserInput,\n} from '@goodparty_org/contracts'\nimport { BaseResource } from './BaseResource'\n\nexport class UsersResource extends BaseResource {\n protected readonly resourceBasePath = '/users'\n\n list = (\n options?: ListUsersPagination,\n ): Promise<PaginatedList<ReadUserOutput>> =>\n this.getRequest<PaginatedList<ReadUserOutput>>(\n this.resourceBasePath,\n options,\n )\n\n get = (id: number): Promise<ReadUserOutput> =>\n this.getRequest<ReadUserOutput>(`/users/${id}`)\n\n update = (id: number, input: UpdateUserInput): Promise<ReadUserOutput> =>\n this.putRequest<ReadUserOutput>(`${this.resourceBasePath}/${id}`, input)\n\n delete = (id: number): Promise<void> =>\n this.deleteRequest<void>(`${this.resourceBasePath}/${id}`)\n\n updatePassword = (id: number, input: UpdatePasswordInput): Promise<void> =>\n this.putRequest<void>(`${this.resourceBasePath}/${id}/password`, input)\n}\n","import { createClerkClient } from '@clerk/backend'\nimport { SdkError } from '../../types/result'\n\nconst TOKEN_RENEWAL_BUFFER_MS = 30_000\n\nexport class ClerkService {\n private readonly m2mSecret: string\n private readonly clerkClient: ReturnType<typeof createClerkClient>\n private cachedToken: string | null = null\n private tokenExpiration: number | null = null\n private renewalTimer: ReturnType<typeof setTimeout> | null = null\n private pendingTokenPromise: Promise<string> | null = null\n private destroyed = false\n\n constructor(m2mSecret: string) {\n this.m2mSecret = m2mSecret\n this.clerkClient = createClerkClient({})\n }\n\n getToken = async (): Promise<string> => {\n if (this.cachedToken && this.isTokenValid()) {\n return this.cachedToken\n }\n\n if (this.pendingTokenPromise) {\n return this.pendingTokenPromise\n }\n\n const promise = this.createAndCacheToken()\n this.pendingTokenPromise = promise\n\n try {\n return await promise\n } finally {\n if (this.pendingTokenPromise === promise) {\n this.pendingTokenPromise = null\n }\n }\n }\n\n destroy = (): void => {\n this.destroyed = true\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n this.cachedToken = null\n this.tokenExpiration = null\n this.pendingTokenPromise = null\n }\n\n private isTokenValid = (): boolean => {\n if (!this.tokenExpiration) return true\n return Date.now() < this.tokenExpiration - TOKEN_RENEWAL_BUFFER_MS\n }\n\n private createAndCacheToken = async (): Promise<string> => {\n try {\n const m2mToken = await this.clerkClient.m2m.createToken({\n machineSecretKey: this.m2mSecret,\n })\n\n if (!m2mToken.token) {\n throw new SdkError(\n 0,\n 'Clerk M2M token creation succeeded but returned no token string',\n )\n }\n\n if (this.destroyed) return m2mToken.token\n\n this.cachedToken = m2mToken.token\n this.tokenExpiration = m2mToken.expiration\n this.scheduleRenewal()\n\n return this.cachedToken\n } catch (error: unknown) {\n if (error instanceof SdkError) {\n throw error\n }\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new SdkError(0, `Failed to create Clerk M2M token: ${message}`)\n }\n }\n\n private scheduleRenewal = (): void => {\n if (this.renewalTimer) {\n clearTimeout(this.renewalTimer)\n this.renewalTimer = null\n }\n\n if (!this.tokenExpiration) return\n\n const timeUntilRenewal =\n this.tokenExpiration - Date.now() - TOKEN_RENEWAL_BUFFER_MS\n\n if (timeUntilRenewal <= 0) return\n\n this.renewalTimer = setTimeout(() => {\n this.cachedToken = null\n this.getToken().catch((error: unknown) => {\n console.error('Proactive M2M token renewal failed:', error)\n })\n }, timeUntilRenewal)\n }\n}\n","import { HttpClient } from './http/HttpClient'\nimport { AdminResource } from './resources/AdminResource'\nimport { CampaignsResource } from './resources/CampaignsResource'\nimport { EcanvasserResource } from './resources/EcanvasserResource'\nimport { ElectedOfficesResource } from './resources/ElectedOfficesResource'\nimport { ElectionsResource } from './resources/ElectionsResource'\nimport { OrganizationsResource } from './resources/OrganizationsResource'\nimport { UsersResource } from './resources/UsersResource'\nimport { ClerkService } from './vendor/clerk/clerk.service'\n\nexport type GoodPartyClientConfig = {\n m2mSecret: string\n gpApiRootUrl: string\n}\n\nexport class GoodPartyClient {\n readonly admin: AdminResource\n readonly users: UsersResource\n readonly campaigns: CampaignsResource\n readonly ecanvasser: EcanvasserResource\n readonly electedOffices: ElectedOfficesResource\n readonly elections: ElectionsResource\n readonly organizations: OrganizationsResource\n private clerkService: ClerkService\n\n private constructor(clerkService: ClerkService, gpApiRootUrl: string) {\n this.clerkService = clerkService\n const httpClient = new HttpClient(gpApiRootUrl, clerkService.getToken)\n this.admin = new AdminResource(httpClient)\n this.users = new UsersResource(httpClient)\n this.campaigns = new CampaignsResource(httpClient)\n this.ecanvasser = new EcanvasserResource(httpClient)\n this.electedOffices = new ElectedOfficesResource(httpClient)\n this.elections = new ElectionsResource(httpClient)\n this.organizations = new OrganizationsResource(httpClient)\n }\n\n static create = async (\n config: GoodPartyClientConfig,\n ): Promise<GoodPartyClient> => {\n const { m2mSecret, gpApiRootUrl } = config\n const clerkService = new ClerkService(m2mSecret)\n await clerkService.getToken()\n return new GoodPartyClient(clerkService, gpApiRootUrl)\n }\n\n destroy = (): void => {\n this.clerkService.destroy()\n }\n}\n","export { GoodPartyClient } from './GoodPartyClient'\nexport type { GoodPartyClientConfig } from './GoodPartyClient'\n\nexport { SdkError } from './types/result'\n\nexport type {\n PaginationMeta,\n PaginatedList,\n PaginationOptions,\n ReadUserOutput,\n ReadUserOutput as User,\n UpdatePasswordInput,\n UpdateUserInput,\n UserMetaData,\n ListUsersPagination,\n ReadCampaignOutput,\n ReadCampaignOutput as Campaign,\n CampaignDetails,\n CampaignData,\n CampaignAiContent,\n VoterGoals,\n CustomVoterFile,\n AiChatMessage,\n AiContentInputValues,\n AiContentGenerationStatus,\n AiContentData,\n GeoLocation,\n CustomIssue,\n Opponent,\n HubSpotUpdates,\n CampaignFinance,\n CampaignPlan,\n CampaignPlanStatus,\n ListCampaignsPagination,\n SetDistrictOutput,\n UpdateCampaignM2MInput as UpdateCampaignInput,\n CreateEcanvasserInput,\n Ecanvasser,\n EcanvasserSummary,\n} from '@goodparty_org/contracts'\n\nexport {\n USER_ROLE_VALUES,\n WHY_BROWSING_VALUES,\n CAMPAIGN_TIER_VALUES,\n BALLOT_READY_POSITION_LEVEL_VALUES,\n ELECTION_LEVEL_VALUES,\n CAMPAIGN_CREATED_BY_VALUES,\n CAMPAIGN_LAUNCH_STATUS_VALUES,\n CAMPAIGN_STATUS_VALUES,\n ONBOARDING_STEP_VALUES,\n GENERATION_STATUS_VALUES,\n BallotReadyPositionLevel,\n ElectionLevel,\n CampaignCreatedBy,\n CampaignLaunchStatus,\n CampaignStatus,\n OnboardingStep,\n GenerationStatus,\n} from '@goodparty_org/contracts'\n\nexport { UserRole, WhyBrowsing, CampaignTier } from './enums'\n\nexport type {\n ElectedOffice,\n ListElectedOfficesOptions,\n SetElectedOfficeDistrictOutput,\n UpdateElectedOfficeDistrictInput,\n UpdateElectedOfficeInput,\n} from './types/electedOffice'\n\nexport type {\n DistrictTypeItem,\n DistrictNameItem,\n ListDistrictTypesOptions,\n ListDistrictNamesOptions,\n UpdateDistrictInput,\n} from './types/district'\n\nexport type {\n CampaignWithLiveContext,\n CampaignWithPositionName,\n RaceTargetMetrics,\n} from './types/campaign'\n\nexport type { ImpersonateUserInput, ImpersonateUserOutput } from './types/admin'\n\nexport type {\n Organization,\n OrgDistrict,\n OrgPosition,\n OrganizationListItem,\n OrganizationOwnerSummary,\n ListOrganizationsOptions,\n PatchOrganizationInput,\n} from './types/organization'\n","import {\n USER_ROLE_VALUES,\n type UserRole as UserRoleType,\n WHY_BROWSING_VALUES,\n type WhyBrowsing as WhyBrowsingType,\n CAMPAIGN_TIER_VALUES,\n type CampaignTier as CampaignTierType,\n} from '@goodparty_org/contracts'\n\ntype EnumObject<T extends readonly string[]> = { [K in T[number]]: K }\n\nconst toEnumObject = <T extends readonly string[]>(values: T): EnumObject<T> =>\n Object.fromEntries(values.map((v) => [v, v])) as EnumObject<T>\n\nexport type UserRole = UserRoleType\nexport const UserRole = toEnumObject(USER_ROLE_VALUES)\n\nexport type WhyBrowsing = WhyBrowsingType\nexport const WhyBrowsing = toEnumObject(WHY_BROWSING_VALUES)\n\nexport type CampaignTier = CampaignTierType\nexport const CampaignTier = toEnumObject(CAMPAIGN_TIER_VALUES)\n"],"mappings":"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","names":["USER_ROLE_VALUES","WHY_BROWSING_VALUES","CAMPAIGN_TIER_VALUES"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodparty_org/sdk",
3
- "version": "1.14.0",
3
+ "version": "2.1.0",
4
4
  "description": "TypeScript SDK for interacting with the GoodParty API",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",