doersiq-types 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/src/Bot.d.ts +28 -0
  2. package/dist/src/Bot.js +73 -0
  3. package/dist/src/BotDocument.d.ts +14 -0
  4. package/dist/src/BotDocument.js +38 -0
  5. package/dist/src/Conversation.d.ts +16 -0
  6. package/dist/src/Conversation.js +42 -0
  7. package/dist/src/DoersAPIError.d.ts +4 -0
  8. package/dist/src/DoersAPIError.js +18 -0
  9. package/dist/src/Jurisdiction.d.ts +22 -0
  10. package/dist/src/Jurisdiction.js +53 -0
  11. package/dist/src/JurisdictionDocument.d.ts +15 -0
  12. package/dist/src/JurisdictionDocument.js +44 -0
  13. package/dist/src/Message.d.ts +29 -0
  14. package/dist/src/Message.js +79 -0
  15. package/dist/src/OfficeClass.d.ts +17 -0
  16. package/dist/src/OfficeClass.js +131 -0
  17. package/dist/src/Party.d.ts +10 -0
  18. package/dist/src/Party.js +26 -0
  19. package/dist/src/Sources.d.ts +38 -0
  20. package/dist/src/Sources.js +105 -0
  21. package/dist/src/State.d.ts +10 -0
  22. package/dist/src/State.js +256 -0
  23. package/dist/src/Tweet.d.ts +11 -0
  24. package/dist/src/Tweet.js +32 -0
  25. package/dist/src/User.d.ts +15 -0
  26. package/dist/src/User.js +39 -0
  27. package/dist/src/index.d.ts +13 -0
  28. package/dist/src/index.js +13 -0
  29. package/dist/src/types/Bot.d.ts +29 -0
  30. package/dist/src/types/Bot.js +76 -0
  31. package/dist/src/types/BotDocument.d.ts +14 -0
  32. package/dist/src/types/BotDocument.js +38 -0
  33. package/dist/src/types/Conversation.d.ts +18 -0
  34. package/dist/src/types/Conversation.js +48 -0
  35. package/dist/src/types/DoersAPIError.d.ts +4 -0
  36. package/dist/src/types/DoersAPIError.js +19 -0
  37. package/dist/src/types/Jurisdiction.d.ts +24 -0
  38. package/dist/src/types/Jurisdiction.js +57 -0
  39. package/dist/src/types/JurisdictionDocument.d.ts +15 -0
  40. package/dist/src/types/JurisdictionDocument.js +44 -0
  41. package/dist/src/types/Message.d.ts +31 -0
  42. package/dist/src/types/Message.js +85 -0
  43. package/dist/src/types/OfficeClass.d.ts +17 -0
  44. package/dist/src/types/OfficeClass.js +132 -0
  45. package/dist/src/types/Party.d.ts +10 -0
  46. package/dist/src/types/Party.js +26 -0
  47. package/dist/src/types/Sources.d.ts +38 -0
  48. package/dist/src/types/Sources.js +105 -0
  49. package/dist/src/types/State.d.ts +11 -0
  50. package/dist/src/types/State.js +306 -0
  51. package/dist/src/types/Tweet.d.ts +12 -0
  52. package/dist/src/types/Tweet.js +34 -0
  53. package/dist/src/types/User.d.ts +16 -0
  54. package/dist/src/types/User.js +42 -0
  55. package/eslint.config.ts +13 -0
  56. package/jest.config.js +20 -0
  57. package/package.json +31 -0
  58. package/src/index.ts +13 -0
  59. package/src/types/Bot.ts +87 -0
  60. package/src/types/BotDocument.ts +43 -0
  61. package/src/types/Conversation.ts +59 -0
  62. package/src/types/DoersAPIError.ts +21 -0
  63. package/src/types/Jurisdiction.ts +62 -0
  64. package/src/types/JurisdictionDocument.ts +48 -0
  65. package/src/types/Message.ts +100 -0
  66. package/src/types/OfficeClass.ts +150 -0
  67. package/src/types/Party.ts +36 -0
  68. package/src/types/Sources.ts +125 -0
  69. package/src/types/State.ts +317 -0
  70. package/src/types/Tweet.ts +38 -0
  71. package/src/types/User.ts +53 -0
  72. package/tsconfig.json +34 -0
@@ -0,0 +1,87 @@
1
+ import { is_office_class_id, OfficeClassID } from "./OfficeClass"
2
+ import { Jurisdiction } from "./Jurisdiction"
3
+ import { is_state_id, StateID } from "./State"
4
+ import { is_party_id, PartyID } from "./Party"
5
+
6
+ export class Bot {
7
+ readonly office_id : string
8
+ readonly number : string
9
+ readonly bot_id : string
10
+ readonly name : string
11
+ readonly active : boolean
12
+ readonly state_id : StateID
13
+ readonly district? : number
14
+ readonly party_id : PartyID
15
+ readonly tone_description_refresh : boolean
16
+ readonly topics : string[]
17
+ readonly jurisdiction_ids : number[]
18
+ readonly office_class_id : OfficeClassID
19
+ readonly office_name? : string
20
+ readonly [x : string] : any
21
+
22
+ constructor(bot : any) {
23
+ if (!Bot.is(bot)) {
24
+ throw Error("Invalid input.")
25
+ }
26
+ this.office_id = bot.office_id
27
+ this.number = bot.number
28
+ this.bot_id = bot.bot_id
29
+ this.name = bot.name
30
+ this.active = bot.active
31
+ this.state_id = bot.state_id
32
+ this.district = bot.district
33
+ this.party_id = bot.party_id
34
+ this.tone_description_refresh = bot.tone_description_refresh
35
+ this.topics = bot.topics
36
+ this.jurisdiction_ids = bot.jurisdiction_ids
37
+ this.office_class_id = bot.office_class_id
38
+ this.office_name = bot.office_name
39
+ }
40
+
41
+ static is(bot : any) : bot is Bot {
42
+ return (
43
+ bot !== undefined &&
44
+ typeof bot.office_id === "string" &&
45
+ typeof bot.number === "string" &&
46
+ typeof bot.bot_id === "string" &&
47
+ typeof bot.name === "string" &&
48
+ typeof bot.active === "boolean" &&
49
+ is_state_id(bot.state_id) &&
50
+ (bot.district === undefined || typeof bot.district === "number") &&
51
+ is_party_id(bot.party_id) &&
52
+ typeof bot.tone_description_refresh === "boolean" &&
53
+ Array.isArray(bot.topics) &&
54
+ bot.topics.every((topic : any) => typeof topic === "string") &&
55
+ Array.isArray(bot.jurisdiction_ids) &&
56
+ bot.jurisdiction_ids.every((jurisdiction_id : any) => typeof jurisdiction_id === "number") &&
57
+ is_office_class_id(bot.office_class_id) &&
58
+ (bot.office_name === undefined || typeof bot.office_name === "string")
59
+ )
60
+ }
61
+ }
62
+
63
+ export class BotAux extends Bot {
64
+ readonly jurisdictions : Jurisdiction[]
65
+ readonly photo_download_url? : string
66
+ readonly tone_description? : string
67
+
68
+ constructor(bot : any) {
69
+ if (!BotAux.is(bot)) {
70
+ throw Error("Invalid input.")
71
+ }
72
+ super(bot)
73
+ this.jurisdictions = bot.jurisdictions
74
+ this.photo_download_url = bot.photo_download_url
75
+ this.tone_description = bot.tone_description
76
+ }
77
+
78
+ static is(bot : any) : bot is BotAux {
79
+ return (
80
+ Bot.is(bot) &&
81
+ Array.isArray(bot.jurisdictions) &&
82
+ bot.jurisdictions.every(Jurisdiction.is) &&
83
+ (bot.photo_download_url === undefined || typeof bot.photo_download_url === "string") &&
84
+ (bot.tone_description === undefined || typeof bot.tone_description === "string")
85
+ )
86
+ }
87
+ }
@@ -0,0 +1,43 @@
1
+ import { Tweet } from "./Tweet"
2
+
3
+ export class BotDocument {
4
+ readonly bot_id : string
5
+ readonly document_id : string
6
+ readonly type : "URL" | "TWEET" | "TWITTER"
7
+ readonly s3_filename? : string
8
+ readonly url? : string
9
+ readonly username? : string
10
+ readonly vector_keys? : string[]
11
+ readonly tweet? : Tweet
12
+ readonly text? : string
13
+
14
+ constructor(bot_document : any) {
15
+ if (!BotDocument.is(bot_document)) {
16
+ throw Error("Invalid input.")
17
+ }
18
+ this.bot_id = bot_document.bot_id
19
+ this.document_id = bot_document.document_id
20
+ this.type = bot_document.type
21
+ this.s3_filename = bot_document.s3_filename
22
+ this.url = bot_document.url
23
+ this.username = bot_document.username
24
+ this.vector_keys = bot_document.vector_keys
25
+ this.tweet = bot_document.tweet
26
+ this.text = bot_document.text
27
+ }
28
+
29
+ static is(bot_document : any) : bot_document is BotDocument {
30
+ return (
31
+ bot_document !== undefined &&
32
+ typeof bot_document.bot_id === "string" &&
33
+ typeof bot_document.document_id === "string" &&
34
+ typeof bot_document.type === "string" &&
35
+ (bot_document.s3_filename === undefined || typeof bot_document.s3_filename === "string") &&
36
+ (bot_document.url === undefined || typeof bot_document.url === "string") &&
37
+ (bot_document.username === undefined || typeof bot_document.username === "string") &&
38
+ (bot_document.vector_keys === undefined || Array.isArray(bot_document.vector_keys) && bot_document.vector_keys.every((vector_key : any) => typeof vector_key === "string")) &&
39
+ (bot_document.tweet === undefined || Tweet.is(bot_document.tweet)) &&
40
+ (bot_document.text === undefined || typeof bot_document.text === "string")
41
+ )
42
+ }
43
+ }
@@ -0,0 +1,59 @@
1
+ import { Message } from "./Message"
2
+
3
+ export class Conversation {
4
+ readonly user_id : string
5
+ readonly conversation_id : string
6
+ readonly bot_id : string
7
+ readonly time : string
8
+ readonly mode : "email" | "general"
9
+ readonly topics? : string[]
10
+ readonly [x : string] : any
11
+
12
+ constructor(conversation : any) {
13
+ if (!Conversation.is(conversation)) {
14
+ throw Error("Invalid input.")
15
+ }
16
+ this.user_id = conversation.user_id
17
+ this.conversation_id = conversation.conversation_id
18
+ this.bot_id = conversation.bot_id
19
+ this.time = conversation.time
20
+ this.mode = conversation.mode
21
+ this.topics = conversation.topics
22
+ }
23
+
24
+ static is(conversation : any) : conversation is Conversation {
25
+ return (
26
+ conversation !== undefined &&
27
+ typeof conversation.user_id === "string" &&
28
+ typeof conversation.conversation_id === "string" &&
29
+ typeof conversation.bot_id === "string" &&
30
+ typeof conversation.time === "string" &&
31
+ ["email", "general"].includes(conversation.mode) &&
32
+ (conversation.topics === undefined || Array.isArray(conversation.topics) &&
33
+ conversation.topics.every((topic : any) => typeof topic === "string"))
34
+ )
35
+ }
36
+ }
37
+
38
+ export class ConversationAux extends Conversation {
39
+ readonly messages : Message[]
40
+ readonly max_action_time : string
41
+
42
+ constructor(conversation : any) {
43
+ if (!ConversationAux.is(conversation)) {
44
+ throw Error("Invalid input.")
45
+ }
46
+ super(conversation)
47
+ this.messages = conversation.messages
48
+ this.max_action_time = conversation.max_action_time
49
+ }
50
+
51
+ static is(conversation : any) : conversation is ConversationAux {
52
+ return (
53
+ Conversation.is(conversation) &&
54
+ Array.isArray(conversation.messages) &&
55
+ conversation.messages.every(Message.is) &&
56
+ typeof conversation.max_action_time === "string"
57
+ )
58
+ }
59
+ }
@@ -0,0 +1,21 @@
1
+ const default_messages_by_status : Record<number, string> = {
2
+ 400 : "Bad Request",
3
+ 401 : "Unauthorized",
4
+ 403 : "Forbidden",
5
+ 404 : "Not Found",
6
+ 405 : "Method Not Allowed",
7
+ 500 : "Internal Server Error",
8
+ 504 : "Gateway Timeout",
9
+ 600 : "Failed to Parse Output"
10
+ }
11
+
12
+
13
+ export class DoersAPIError extends Error {
14
+ status : number
15
+ constructor(status : number, message?: string) {
16
+ const default_message = default_messages_by_status[status]
17
+ super(message !== undefined ? message : default_message !== undefined ? default_message : "Error")
18
+ this.name = "DoersAPIError"
19
+ this.status = status
20
+ }
21
+ }
@@ -0,0 +1,62 @@
1
+ export enum JurisdictionLevel {
2
+ OTHER = 0,
3
+ NATION = 1,
4
+ STATE = 2,
5
+ COUNTY = 3,
6
+ CITY = 4,
7
+ SCHOOL = 5
8
+ }
9
+
10
+ export function is_jurisdiction_level(jurisdiction_level : any) : jurisdiction_level is JurisdictionLevel {
11
+ return [0, 1, 2, 3, 4, 5].includes(jurisdiction_level)
12
+ }
13
+
14
+ export class Jurisdiction {
15
+ readonly jurisdiction_id : number
16
+ readonly name : string
17
+ readonly path : number[]
18
+ readonly sub_jurisdiction_ids : number[]
19
+ readonly super_jurisdiction_id? : number
20
+ readonly level : JurisdictionLevel
21
+ readonly state_jurisdiction_id? : number
22
+ readonly county_jurisdiction_id? : number
23
+ readonly city_jurisdiction_id? : number
24
+ readonly school_jurisdiction_id? : number
25
+ readonly geographic : boolean
26
+
27
+ constructor(jurisdiction : any) {
28
+ if (!Jurisdiction.is(jurisdiction)) {
29
+ throw Error("Invalid input.")
30
+ }
31
+ this.jurisdiction_id = jurisdiction.jurisdiction_id
32
+ this.name = jurisdiction.name
33
+ this.path = jurisdiction.path
34
+ this.sub_jurisdiction_ids = jurisdiction.sub_jurisdiction_ids
35
+ this.super_jurisdiction_id = jurisdiction.super_jurisdiction_id
36
+ this.level = jurisdiction.level
37
+ this.state_jurisdiction_id = jurisdiction.state_jurisdiction_id
38
+ this.county_jurisdiction_id = jurisdiction.county_jurisdiction_id
39
+ this.city_jurisdiction_id = jurisdiction.city_jurisdiction_id
40
+ this.school_jurisdiction_id = jurisdiction.school_jurisdiction_id
41
+ this.geographic = jurisdiction.geographic
42
+ }
43
+
44
+ static is(jurisdiction : any) : jurisdiction is Jurisdiction {
45
+ return (
46
+ jurisdiction !== undefined &&
47
+ typeof jurisdiction.jurisdiction_id === "number" &&
48
+ typeof jurisdiction.name === "string" &&
49
+ Array.isArray(jurisdiction.path) &&
50
+ jurisdiction.path.every((jurisdiction_id : any) => typeof jurisdiction_id === "number") &&
51
+ Array.isArray(jurisdiction.sub_jurisdiction_ids) &&
52
+ jurisdiction.sub_jurisdiction_ids.every((jurisdiction_id : any) => typeof jurisdiction_id === "number") &&
53
+ is_jurisdiction_level(jurisdiction.level) &&
54
+ typeof jurisdiction.geographic === "boolean" &&
55
+ (jurisdiction.super_jurisdiction_id === undefined || typeof jurisdiction.super_jurisdiction_id === "number") &&
56
+ (jurisdiction.state_jurisdiction_id === undefined || typeof jurisdiction.state_jurisdiction_id === "number") &&
57
+ (jurisdiction.county_jurisdiction_id === undefined || typeof jurisdiction.county_jurisdiction_id === "number") &&
58
+ (jurisdiction.city_jurisdiction_id === undefined || typeof jurisdiction.city_jurisdiction_id === "number") &&
59
+ (jurisdiction.school_jurisdiction_id === undefined || typeof jurisdiction.school_jurisdiction_id === "number")
60
+ )
61
+ }
62
+ }
@@ -0,0 +1,48 @@
1
+ export class JurisdictionDocument {
2
+ readonly jurisdiction_id : number
3
+ readonly document_id : string
4
+ readonly media_id : string
5
+ readonly origin : string
6
+ readonly s3_filename? : string
7
+ readonly time? : string
8
+ readonly title : string
9
+ readonly type : string
10
+ readonly url : string
11
+ readonly vector_keys? : string[]
12
+ readonly location? : string
13
+
14
+ constructor(jurisdiction_document : any) {
15
+ if (!JurisdictionDocument.is(jurisdiction_document)) {
16
+ throw Error("Invalid input.")
17
+ }
18
+ this.jurisdiction_id = jurisdiction_document.jurisdiction_id
19
+ this.document_id = jurisdiction_document.document_id
20
+ this.media_id = jurisdiction_document.media_id
21
+ this.origin = jurisdiction_document.origin
22
+ this.s3_filename = jurisdiction_document.s3_filename
23
+ this.time = jurisdiction_document.time
24
+ this.title = jurisdiction_document.title
25
+ this.type = jurisdiction_document.type
26
+ this.url = jurisdiction_document.url
27
+ this.vector_keys = jurisdiction_document.vector_keys
28
+ this.location = jurisdiction_document.location
29
+ }
30
+
31
+ static is(jurisdiction_document : any) : jurisdiction_document is JurisdictionDocument {
32
+ return (
33
+ jurisdiction_document !== undefined &&
34
+ typeof jurisdiction_document.jurisdiction_id === "number" &&
35
+ typeof jurisdiction_document.document_id === "string" &&
36
+ typeof jurisdiction_document.media_id === "string" &&
37
+ typeof jurisdiction_document.origin === "string" &&
38
+ (jurisdiction_document.s3_filename === undefined || typeof jurisdiction_document.s3_filename === "string") &&
39
+ (jurisdiction_document.time === undefined || typeof jurisdiction_document.time === "string") &&
40
+ typeof jurisdiction_document.title === "string" &&
41
+ typeof jurisdiction_document.type === "string" &&
42
+ typeof jurisdiction_document.url === "string" &&
43
+ (jurisdiction_document.vector_keys === undefined || Array.isArray(jurisdiction_document.vector_keys) &&
44
+ jurisdiction_document.vector_keys.every((vector_key : any) => typeof vector_key === "string")) &&
45
+ (jurisdiction_document.location === undefined || typeof jurisdiction_document.location === "string")
46
+ )
47
+ }
48
+ }
@@ -0,0 +1,100 @@
1
+ import { Sources } from "./Sources"
2
+
3
+ export class Fragment {
4
+ readonly text : string
5
+ readonly sources : Sources
6
+
7
+ constructor(fragment : any) {
8
+ if (!Fragment.is(fragment)) {
9
+ throw Error("Invalid input.")
10
+ }
11
+ this.text = fragment.text
12
+ this.sources = fragment.sources
13
+ }
14
+
15
+ static is(fragment : any) : fragment is Fragment {
16
+ return (
17
+ fragment !== undefined &&
18
+ typeof fragment.text === "string" &&
19
+ Sources.is(fragment.sources)
20
+ )
21
+ }
22
+ }
23
+
24
+ export class Post {
25
+ text : string
26
+ s3_image_filename? : string
27
+ s3_image_url? : string
28
+
29
+ constructor(post : any) {
30
+ if (!Post.is(post)) {
31
+ throw Error("Invalid input.")
32
+ }
33
+ this.text = post.text
34
+ this.s3_image_filename = post.s3_image_filename
35
+ this.s3_image_url = post.s3_image_url
36
+ }
37
+
38
+ static is(post : any) : post is Post {
39
+ return (
40
+ post !== undefined &&
41
+ typeof post.text === "string" &&
42
+ (post.s3_image_filename === undefined || typeof post.s3_image_filename === "string") &&
43
+ (post.s3_image_url === undefined || typeof post.s3_image_url === "string")
44
+ )
45
+ }
46
+ }
47
+
48
+ export class Message {
49
+ readonly user_id : string
50
+ readonly message_id : string
51
+ readonly bot_id : string
52
+ readonly conversation_id : string
53
+ readonly time : string
54
+ readonly mode : "email" | "general"
55
+ readonly role : "user" | "bot"
56
+ readonly system_prompt? : string
57
+ readonly grok_text? : string
58
+ readonly fragments? : Fragment[]
59
+ readonly sources? : Sources
60
+ readonly text : string
61
+ readonly posts? : Post[]
62
+
63
+ constructor(message : any) {
64
+ if (!Message.is(message)) {
65
+ throw Error("Invalid input.")
66
+ }
67
+ this.user_id = message.user_id
68
+ this.message_id = message.message_id
69
+ this.bot_id = message.bot_id
70
+ this.conversation_id = message.conversation_id
71
+ this.time = message.time
72
+ this.mode = message.mode
73
+ this.role = message.role
74
+ this.system_prompt = message.system_prompt
75
+ this.grok_text = message.grok_text
76
+ this.fragments = message.fragments
77
+ this.sources = message.sources
78
+ this.text = message.text
79
+ this.posts = message.posts
80
+ }
81
+
82
+ static is(message : any) : message is Message {
83
+ return (
84
+ message !== undefined &&
85
+ typeof message.user_id === "string" &&
86
+ typeof message.message_id === "string" &&
87
+ typeof message.bot_id === "string" &&
88
+ typeof message.conversation_id === "string" &&
89
+ typeof message.time === "string" &&
90
+ ["email", "general"].includes(message.mode) &&
91
+ ["user", "bot"].includes(message.role) &&
92
+ (message.system_prompt === undefined || typeof message.system_prompt === "string") &&
93
+ (message.grok_text === undefined || typeof message.grok_text === "string") &&
94
+ (message.fragments === undefined || Array.isArray(message.fragments) && message.fragments.every(Fragment.is)) &&
95
+ (message.sources === undefined || Sources.is(message.sources)) &&
96
+ typeof message.text === "string" &&
97
+ (message.posts === undefined || Array.isArray(message.posts) && message.posts.every(Post.is))
98
+ )
99
+ }
100
+ }
@@ -0,0 +1,150 @@
1
+ import { JurisdictionLevel } from "./Jurisdiction"
2
+
3
+ const office_class_ids = ["ORG", "USH", "USS", "STG", "STH", "STS", "STB", "COG", "CIG", "LOB"] as const
4
+
5
+ export type OfficeClassID = typeof office_class_ids[number]
6
+
7
+ export function is_office_class_id(office_class_id : any) : office_class_id is OfficeClassID {
8
+ return office_class_ids.includes(office_class_id)
9
+ }
10
+
11
+ export interface OfficeClass {
12
+ office_class_id : OfficeClassID,
13
+ name : string,
14
+ type : "candidate" | "organization",
15
+ office_id_template : string,
16
+ jurisdiction_level? : JurisdictionLevel,
17
+ jurisdictions_mutable : Boolean,
18
+ require_district : Boolean,
19
+ require_initial_jurisdiction : Boolean,
20
+ office_names? : string[]
21
+
22
+ }
23
+
24
+ export const office_classes_by_office_class_id : Record<OfficeClassID, OfficeClass> = {
25
+ "ORG" : {
26
+ office_class_id : "ORG",
27
+ name : "Organization",
28
+ type : "organization",
29
+ office_id_template : "O-[state_id]",
30
+ jurisdictions_mutable : true,
31
+ require_district : false,
32
+ require_initial_jurisdiction : false
33
+ },
34
+ "USH" : {
35
+ office_class_id : "USH",
36
+ name : "U.S. House",
37
+ type : "candidate",
38
+ office_id_template : "H-[state_id]",
39
+ jurisdictions_mutable : true,
40
+ require_district : true,
41
+ require_initial_jurisdiction : false
42
+ },
43
+ "USS" : {
44
+ office_class_id : "USS",
45
+ name : "U.S. Senate",
46
+ type : "candidate",
47
+ office_id_template : "S-[state_id]",
48
+ jurisdiction_level : JurisdictionLevel.STATE,
49
+ jurisdictions_mutable : false,
50
+ require_district : false,
51
+ require_initial_jurisdiction : false
52
+ },
53
+ "STG" : {
54
+ office_class_id : "STG",
55
+ name : "State (Executive) Government",
56
+ type : "candidate",
57
+ office_id_template : "[state_id]-G",
58
+ jurisdiction_level : JurisdictionLevel.STATE,
59
+ jurisdictions_mutable : false,
60
+ require_district : false,
61
+ require_initial_jurisdiction : false,
62
+ office_names : [
63
+ "Governor",
64
+ "Lieutenant Governor",
65
+ "Secretary of State",
66
+ "Treasurer",
67
+ "Auditor",
68
+ "Attorney General"
69
+ ]
70
+ },
71
+ "STH" : {
72
+ office_class_id : "STH",
73
+ name : "State House",
74
+ type : "candidate",
75
+ office_id_template : "[state_id]-H",
76
+ jurisdictions_mutable : true,
77
+ require_district : true,
78
+ require_initial_jurisdiction : false
79
+ },
80
+ "STS" : {
81
+ office_class_id : "STS",
82
+ name : "State Senate",
83
+ type : "candidate",
84
+ office_id_template : "[state_id]-S",
85
+ jurisdictions_mutable : true,
86
+ require_district : true,
87
+ require_initial_jurisdiction : false
88
+ },
89
+ "STB" : {
90
+ office_class_id : "STB",
91
+ name : "State School Board",
92
+ type : "candidate",
93
+ office_id_template : "[state_id]-B",
94
+ jurisdiction_level : JurisdictionLevel.SCHOOL,
95
+ jurisdictions_mutable : true,
96
+ require_district : true,
97
+ require_initial_jurisdiction : true,
98
+ office_names : [
99
+ "Board Member"
100
+ ]
101
+ },
102
+ "COG" : {
103
+ office_class_id : "COG",
104
+ name : "County Government",
105
+ type : "candidate",
106
+ office_id_template : "[state_id]-C",
107
+ jurisdiction_level : JurisdictionLevel.COUNTY,
108
+ jurisdictions_mutable : true,
109
+ require_district : false,
110
+ require_initial_jurisdiction : true,
111
+ office_names : [
112
+ "Mayor",
113
+ "Councillor",
114
+ "Commissioner",
115
+ "Clerk",
116
+ "Recorder",
117
+ "Auditor",
118
+ "Surveyor",
119
+ "District Attorney",
120
+ "Sheriff"
121
+ ]
122
+ },
123
+ "CIG" : {
124
+ office_class_id : "CIG",
125
+ name : "City Government",
126
+ type : "candidate",
127
+ office_id_template : "[state_id]-M",
128
+ jurisdiction_level : JurisdictionLevel.CITY,
129
+ jurisdictions_mutable : true,
130
+ require_district : false,
131
+ require_initial_jurisdiction : true,
132
+ office_names : [
133
+ "Mayor",
134
+ "Councillor"
135
+ ]
136
+ },
137
+ "LOB" : {
138
+ office_class_id : "LOB",
139
+ name : "Local School Board",
140
+ type : "candidate",
141
+ office_id_template : "[state_id]-E",
142
+ jurisdiction_level : JurisdictionLevel.SCHOOL,
143
+ jurisdictions_mutable : true,
144
+ require_district : false,
145
+ require_initial_jurisdiction : true,
146
+ office_names : [
147
+ "Board Member"
148
+ ]
149
+ }
150
+ }
@@ -0,0 +1,36 @@
1
+ const party_ids = ["DEM", "REP", "NON", "ETC"] as const
2
+
3
+ export type PartyID = typeof party_ids[number]
4
+
5
+ export function is_party_id(party_id : any) : party_id is PartyID {
6
+ return party_ids.includes(party_id)
7
+ }
8
+
9
+ export interface Party {
10
+ party_id : PartyID,
11
+ name : string,
12
+ adjective : string
13
+ }
14
+
15
+ export const parties_by_party_id : Record<PartyID, Party> = {
16
+ DEM : {
17
+ party_id : "DEM",
18
+ name : "Democratic Party",
19
+ adjective : "Democratic"
20
+ },
21
+ REP : {
22
+ party_id : "REP",
23
+ name : "Republican Party",
24
+ adjective : "Republican"
25
+ },
26
+ ETC : {
27
+ party_id : "ETC",
28
+ name : "Other Party",
29
+ adjective : "Third-Party"
30
+ },
31
+ NON : {
32
+ party_id : "NON",
33
+ name : "Nonpartisan",
34
+ adjective : "Nonpartisan"
35
+ }
36
+ }