elections-types 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.ts +13 -0
- package/jest.config.js +20 -0
- package/package.json +30 -0
- package/src/index.ts +3 -0
- package/src/types/APIError.ts +21 -0
- package/src/types/Candidate.ts +52 -0
- package/src/types/Committee.ts +62 -0
- package/src/types/Election.ts +62 -0
- package/src/types/ElectionsConfig.ts +23 -0
- package/src/types/FormTypeID.ts +20 -0
- package/src/types/State.ts +215 -0
- package/src/types/Tweet.ts +38 -0
- package/src/types/User.ts +34 -0
- package/tsconfig.json +34 -0
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import globals from "globals";
|
|
3
|
+
import tseslint from "typescript-eslint";
|
|
4
|
+
import { defineConfig } from "eslint/config";
|
|
5
|
+
|
|
6
|
+
export default defineConfig([
|
|
7
|
+
{ files: ["**/*.{js,mjs,cjs,ts,mts,cts}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: globals.browser } },
|
|
8
|
+
{
|
|
9
|
+
rules: {
|
|
10
|
+
"@typescript-eslint/explicit-function-return-type": "error"
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
]);
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createDefaultPreset } from "ts-jest"
|
|
2
|
+
|
|
3
|
+
const tsJestTransformCfg = createDefaultPreset().transform;
|
|
4
|
+
|
|
5
|
+
/** @type {import("jest").Config} **/
|
|
6
|
+
export default {
|
|
7
|
+
testEnvironment: "node",
|
|
8
|
+
transform: {
|
|
9
|
+
...tsJestTransformCfg,
|
|
10
|
+
},
|
|
11
|
+
transformIgnorePatterns: ["/node_modules/(?!@smithy|@aws-sdk).+\\.js$"],
|
|
12
|
+
globals : {
|
|
13
|
+
"ts-jest" : {
|
|
14
|
+
useESM : true
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
extensionsToTreatAsEsm : [".ts"],
|
|
18
|
+
testTimeout : 30000,
|
|
19
|
+
testPathIgnorePatterns: ['dist/']
|
|
20
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "elections-types",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/src/index.js",
|
|
5
|
+
"types": "dist/src/index.d.ts",
|
|
6
|
+
"directories": {
|
|
7
|
+
"test": "test"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
11
|
+
"build": "tsc && tsc-alias"
|
|
12
|
+
},
|
|
13
|
+
"author": "",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"description": "",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@eslint/js": "^9.39.2",
|
|
19
|
+
"@types/jest": "^30.0.0",
|
|
20
|
+
"eslint": "^9.39.2",
|
|
21
|
+
"globals": "^17.3.0",
|
|
22
|
+
"jest": "^30.2.0",
|
|
23
|
+
"jiti": "^2.6.1",
|
|
24
|
+
"ts-jest": "^29.4.6",
|
|
25
|
+
"tsc-alias": "^1.8.16",
|
|
26
|
+
"tsx": "^4.21.0",
|
|
27
|
+
"typescript": "^5.9.3",
|
|
28
|
+
"typescript-eslint": "^8.55.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/index.ts
ADDED
|
@@ -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 APIError 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 = "APIError"
|
|
19
|
+
this.status = status
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// import { ElectionID, OfficeID } from "./Election"
|
|
2
|
+
// import { StateID } from "./State"
|
|
3
|
+
|
|
4
|
+
// export class Candidate {
|
|
5
|
+
// readonly candidate_id : string
|
|
6
|
+
// readonly fec_name : string
|
|
7
|
+
// readonly office_id : OfficeID
|
|
8
|
+
// readonly state_id : StateID
|
|
9
|
+
// readonly election_id : ElectionID
|
|
10
|
+
// readonly party_id : string
|
|
11
|
+
// readonly active : boolean
|
|
12
|
+
// readonly status : boolean
|
|
13
|
+
|
|
14
|
+
// constructor(candidate : any) {
|
|
15
|
+
// if (!Candidate.is(candidate)) {
|
|
16
|
+
// throw Error("Invalid input.")
|
|
17
|
+
// }
|
|
18
|
+
// this.office_id = candidate.office_id
|
|
19
|
+
// this.number = candidate.number
|
|
20
|
+
// this.scout_id = candidate.scout_id
|
|
21
|
+
// this.name = candidate.name
|
|
22
|
+
// this.active = candidate.active
|
|
23
|
+
// this.state_id = candidate.state_id
|
|
24
|
+
// this.district = candidate.district
|
|
25
|
+
// this.party_id = candidate.party_id
|
|
26
|
+
// this.tone_description_refresh = candidate.tone_description_refresh
|
|
27
|
+
// this.jurisdiction_ids = candidate.jurisdiction_ids
|
|
28
|
+
// this.sub_scout_ids = candidate.sub_scout_ids
|
|
29
|
+
// this.office_class_id = candidate.office_class_id
|
|
30
|
+
// this.office_name = candidate.office_name
|
|
31
|
+
// }
|
|
32
|
+
|
|
33
|
+
// static is(candidate : any) : candidate is Candidate {
|
|
34
|
+
// return (
|
|
35
|
+
// candidate !== undefined &&
|
|
36
|
+
// typeof candidate.office_id === "string" &&
|
|
37
|
+
// typeof candidate.number === "string" &&
|
|
38
|
+
// typeof candidate.scout_id === "string" &&
|
|
39
|
+
// typeof candidate.name === "string" &&
|
|
40
|
+
// typeof candidate.active === "boolean" &&
|
|
41
|
+
// (candidate.state_id === undefined || is_state_id(candidate.state_id)) &&
|
|
42
|
+
// (candidate.district === undefined || typeof candidate.district === "number") &&
|
|
43
|
+
// is_party_id(candidate.party_id) &&
|
|
44
|
+
// typeof candidate.tone_description_refresh === "boolean" &&
|
|
45
|
+
// Array.isArray(candidate.jurisdiction_ids) &&
|
|
46
|
+
// candidate.jurisdiction_ids.every((jurisdiction_id : any) => typeof jurisdiction_id === "number") &&
|
|
47
|
+
// (candidate.sub_scout_ids === undefined || Array.isArray(candidate.sub_scout_ids) && candidate.sub_scout_ids.every((sub_scout_id : any) => typeof sub_scout_id === "string")) &&
|
|
48
|
+
// is_office_class_id(candidate.office_class_id) &&
|
|
49
|
+
// (candidate.office_name === undefined || typeof candidate.office_name === "string")
|
|
50
|
+
// )
|
|
51
|
+
// }
|
|
52
|
+
// }
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const designations = ["F1", "F2", "F3", "F24"] as const
|
|
2
|
+
|
|
3
|
+
export type CommitteeDesignation = typeof designations[number]
|
|
4
|
+
|
|
5
|
+
export function is_committee_designation(designation : any) : designation is CommitteeDesignation {
|
|
6
|
+
return designations.includes(designation)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class Committee {
|
|
10
|
+
readonly committee_id : string
|
|
11
|
+
readonly name : string
|
|
12
|
+
readonly url : string
|
|
13
|
+
readonly designation : CommitteeDesignation
|
|
14
|
+
readonly file_number : number
|
|
15
|
+
readonly principal_committee_ids? : string[]
|
|
16
|
+
readonly authorized_committee_ids? : string[]
|
|
17
|
+
readonly sponsor_committee_ids? : string[]
|
|
18
|
+
readonly jfp_committee_ids? : string[]
|
|
19
|
+
readonly jfr_committee_ids? : string[]
|
|
20
|
+
readonly aff_committee_ids? : string[]
|
|
21
|
+
readonly candidate_ids? : string[]
|
|
22
|
+
readonly election_ids? : string[]
|
|
23
|
+
readonly [x : string] : any
|
|
24
|
+
|
|
25
|
+
constructor(committee : any) {
|
|
26
|
+
if (!Committee.is(committee)) {
|
|
27
|
+
throw Error("Invalid input.")
|
|
28
|
+
}
|
|
29
|
+
this.committee_id = committee.committee_id
|
|
30
|
+
this.name = committee.name
|
|
31
|
+
this.url = committee.url
|
|
32
|
+
this.designation = committee.designation
|
|
33
|
+
this.file_number = committee.file_number
|
|
34
|
+
this.principal_committee_ids = committee.principal_committee_ids
|
|
35
|
+
this.authorized_committee_ids = committee.authorized_committee_ids
|
|
36
|
+
this.sponsor_committee_ids = committee.sponsor_committee_ids
|
|
37
|
+
this.jfp_committee_ids = committee.jfp_committee_ids
|
|
38
|
+
this.jfr_committee_ids = committee.jfr_committee_ids
|
|
39
|
+
this.aff_committee_ids = committee.aff_committee_ids
|
|
40
|
+
this.candidate_ids = committee.candidate_ids
|
|
41
|
+
this.election_ids = committee.election_ids
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static is(committee : any) : committee is Committee {
|
|
45
|
+
return (
|
|
46
|
+
committee !== undefined &&
|
|
47
|
+
typeof committee.committee_id === "string" &&
|
|
48
|
+
typeof committee.name === "string" &&
|
|
49
|
+
typeof committee.url === "string" &&
|
|
50
|
+
is_committee_designation(committee.designation) &&
|
|
51
|
+
typeof committee.file_number === "number" &&
|
|
52
|
+
(committee.principal_committee_ids === undefined || Array.isArray(committee.principal_committee_ids) && committee.principal_committee_ids.every((committee_id : any) => typeof committee_id === "string")) &&
|
|
53
|
+
(committee.authorized_committee_ids === undefined || Array.isArray(committee.authorized_committee_ids) && committee.authorized_committee_ids.every((committee_id : any) => typeof committee_id === "string")) &&
|
|
54
|
+
(committee.sponsor_committee_ids === undefined || Array.isArray(committee.sponsor_committee_ids) && committee.sponsor_committee_ids.every((committee_id : any) => typeof committee_id === "string")) &&
|
|
55
|
+
(committee.jfp_committee_ids === undefined || Array.isArray(committee.jfp_committee_ids) && committee.jfp_committee_ids.every((committee_id : any) => typeof committee_id === "string")) &&
|
|
56
|
+
(committee.jfr_committee_ids === undefined || Array.isArray(committee.jfr_committee_ids) && committee.jfr_committee_ids.every((committee_id : any) => typeof committee_id === "string")) &&
|
|
57
|
+
(committee.aff_committee_ids === undefined || Array.isArray(committee.aff_committee_ids) && committee.aff_committee_ids.every((committee_id : any) => typeof committee_id === "string")) &&
|
|
58
|
+
(committee.candidate_ids === undefined || Array.isArray(committee.candidate_ids) && committee.candidate_ids.every((committee_id : any) => typeof committee_id === "string")) &&
|
|
59
|
+
(committee.election_ids === undefined || Array.isArray(committee.election_ids) && committee.election_ids.every((committee_id : any) => typeof committee_id === "string"))
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { is_state_id, state_ids, StateID } from "./State"
|
|
2
|
+
|
|
3
|
+
const office_ids = ["H", "S"] as const
|
|
4
|
+
|
|
5
|
+
export type OfficeID = typeof office_ids[number]
|
|
6
|
+
|
|
7
|
+
export function is_office_id(office_id : any) : office_id is OfficeID {
|
|
8
|
+
return office_ids.includes(office_id)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type ElectionID = string
|
|
12
|
+
|
|
13
|
+
export function is_election_id(election_id : any) : election_id is ElectionID {
|
|
14
|
+
const parts = election_id.split("-")
|
|
15
|
+
const year = Number(parts[0])
|
|
16
|
+
const office_id = parts[1]
|
|
17
|
+
const state_id = parts[2]
|
|
18
|
+
const district = Number(parts[3])
|
|
19
|
+
return (
|
|
20
|
+
(parts.length === 4 && office_id === "H" || parts.length === 3) &&
|
|
21
|
+
Number.isInteger(year) && year > 1700 && year < 3000 &&
|
|
22
|
+
is_office_id(office_id) &&
|
|
23
|
+
is_state_id(state_id) &&
|
|
24
|
+
(office_id === "S" || Number.isInteger(district) && district < 100)
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class Election {
|
|
29
|
+
readonly election_id : ElectionID
|
|
30
|
+
readonly name : string
|
|
31
|
+
readonly office_id : OfficeID
|
|
32
|
+
readonly state_id : StateID
|
|
33
|
+
readonly district? : string
|
|
34
|
+
readonly candidate_ids? : string[]
|
|
35
|
+
readonly committee_ids? : string[]
|
|
36
|
+
|
|
37
|
+
constructor(election : any) {
|
|
38
|
+
if (!Election.is(election)) {
|
|
39
|
+
throw Error("Invalid input.")
|
|
40
|
+
}
|
|
41
|
+
this.election_id = election.election_id
|
|
42
|
+
this.name = election.name
|
|
43
|
+
this.office_id = election.office_id
|
|
44
|
+
this.state_id = election.state_id
|
|
45
|
+
this.district = election.district
|
|
46
|
+
this.candidate_ids = election.candidate_ids
|
|
47
|
+
this.committee_ids = election.committee_ids
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static is(election : any) : election is Election {
|
|
51
|
+
return (
|
|
52
|
+
election !== undefined &&
|
|
53
|
+
is_election_id(election.election_id) &&
|
|
54
|
+
typeof election.name === "string" &&
|
|
55
|
+
is_office_id(election.office_id) &&
|
|
56
|
+
is_state_id(election.state_id) &&
|
|
57
|
+
(election.district === undefined && typeof election.district === "string") &&
|
|
58
|
+
(election.candidate_ids === undefined || Array.isArray(election.candidate_ids) && election.candidate_ids.every((candidate_id : any) => typeof candidate_id === "string")) &&
|
|
59
|
+
(election.committee_ids === undefined || Array.isArray(election.committee_ids) && election.committee_ids.every((committee_id : any) => typeof committee_id === "string"))
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface ElectionsUtilsConfig {
|
|
2
|
+
region : string,
|
|
3
|
+
scraping_bee_api_key? : string,
|
|
4
|
+
xai_api_key? : string,
|
|
5
|
+
citizenportal_api_key? : string,
|
|
6
|
+
youtube_api_key? : string
|
|
7
|
+
[key : string]: any
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ElectionsConfig extends ElectionsUtilsConfig {
|
|
11
|
+
port : number,
|
|
12
|
+
api_url : string,
|
|
13
|
+
client_url : string,
|
|
14
|
+
auth_url : string,
|
|
15
|
+
cognito_user_pool_id : string,
|
|
16
|
+
cognito_client_id : string,
|
|
17
|
+
cognito_client_secret : string,
|
|
18
|
+
secret_key : string,
|
|
19
|
+
// admin_key : string,
|
|
20
|
+
dynamodb_donations : string,
|
|
21
|
+
s3_bucket : string,
|
|
22
|
+
s3vectors_bucket : string
|
|
23
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const form_type_ids = ["F1", "F2", "F3", "F24"] as const
|
|
2
|
+
|
|
3
|
+
export type FormTypeID = typeof form_type_ids[number]
|
|
4
|
+
|
|
5
|
+
export function is_form_type_id(form_type_id : any) : form_type_id is FormTypeID {
|
|
6
|
+
return form_type_ids.includes(form_type_id)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const long_form_type_ids = [
|
|
10
|
+
"F1N", "F1A", "F1T",
|
|
11
|
+
"F2N", "F2A", "F2T",
|
|
12
|
+
"F3N", "F3A", "F3T",
|
|
13
|
+
"F24N", "F24A"
|
|
14
|
+
] as const
|
|
15
|
+
|
|
16
|
+
export type LongFormTypeID = typeof long_form_type_ids[number]
|
|
17
|
+
|
|
18
|
+
export function is_long_form_type_id(long_form_type_id : any) : long_form_type_id is LongFormTypeID {
|
|
19
|
+
return long_form_type_ids.includes(long_form_type_id)
|
|
20
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
export const state_ids = ["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"] as const
|
|
2
|
+
|
|
3
|
+
export type StateID = typeof state_ids[number]
|
|
4
|
+
|
|
5
|
+
export function is_state_id(state_id : any) : state_id is StateID {
|
|
6
|
+
return state_ids.includes(state_id)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface State {
|
|
10
|
+
state_id : StateID,
|
|
11
|
+
name : string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const states_by_state_id : Record<StateID, State> = {
|
|
15
|
+
AL : {
|
|
16
|
+
state_id : "AL",
|
|
17
|
+
name : "Alabama"
|
|
18
|
+
},
|
|
19
|
+
AK : {
|
|
20
|
+
state_id : "AK",
|
|
21
|
+
name : "Alaska"
|
|
22
|
+
},
|
|
23
|
+
AZ : {
|
|
24
|
+
state_id : "AZ",
|
|
25
|
+
name : "Arizona"
|
|
26
|
+
},
|
|
27
|
+
AR : {
|
|
28
|
+
state_id : "AR",
|
|
29
|
+
name : "Arkansas"
|
|
30
|
+
},
|
|
31
|
+
CA : {
|
|
32
|
+
state_id : "CA",
|
|
33
|
+
name : "California"
|
|
34
|
+
},
|
|
35
|
+
CO : {
|
|
36
|
+
state_id : "CO",
|
|
37
|
+
name : "Colorado"
|
|
38
|
+
},
|
|
39
|
+
CT : {
|
|
40
|
+
state_id : "CT",
|
|
41
|
+
name : "Connecticut"
|
|
42
|
+
},
|
|
43
|
+
DE : {
|
|
44
|
+
state_id : "DE",
|
|
45
|
+
name : "Delaware"
|
|
46
|
+
},
|
|
47
|
+
FL : {
|
|
48
|
+
state_id : "FL",
|
|
49
|
+
name : "Florida"
|
|
50
|
+
},
|
|
51
|
+
GA : {
|
|
52
|
+
state_id : "GA",
|
|
53
|
+
name : "Georgia"
|
|
54
|
+
},
|
|
55
|
+
HI : {
|
|
56
|
+
state_id : "HI",
|
|
57
|
+
name : "Hawaii"
|
|
58
|
+
},
|
|
59
|
+
ID : {
|
|
60
|
+
state_id : "ID",
|
|
61
|
+
name : "Idaho"
|
|
62
|
+
},
|
|
63
|
+
IL : {
|
|
64
|
+
state_id : "IL",
|
|
65
|
+
name : "Illinois"
|
|
66
|
+
},
|
|
67
|
+
IN : {
|
|
68
|
+
state_id : "IN",
|
|
69
|
+
name : "Indiana"
|
|
70
|
+
},
|
|
71
|
+
IA : {
|
|
72
|
+
state_id : "IA",
|
|
73
|
+
name : "Iowa"
|
|
74
|
+
},
|
|
75
|
+
KS : {
|
|
76
|
+
state_id : "KS",
|
|
77
|
+
name : "Kansas"
|
|
78
|
+
},
|
|
79
|
+
KY : {
|
|
80
|
+
state_id : "KY",
|
|
81
|
+
name : "Kentucky"
|
|
82
|
+
},
|
|
83
|
+
LA : {
|
|
84
|
+
state_id : "LA",
|
|
85
|
+
name : "Louisiana"
|
|
86
|
+
},
|
|
87
|
+
ME : {
|
|
88
|
+
state_id : "ME",
|
|
89
|
+
name : "Maine"
|
|
90
|
+
},
|
|
91
|
+
MD : {
|
|
92
|
+
state_id : "MD",
|
|
93
|
+
name : "Maryland"
|
|
94
|
+
},
|
|
95
|
+
MA : {
|
|
96
|
+
state_id : "MA",
|
|
97
|
+
name : "Massachusetts"
|
|
98
|
+
},
|
|
99
|
+
MI : {
|
|
100
|
+
state_id : "MI",
|
|
101
|
+
name : "Michigan"
|
|
102
|
+
},
|
|
103
|
+
MN : {
|
|
104
|
+
state_id : "MN",
|
|
105
|
+
name : "Minnesota"
|
|
106
|
+
},
|
|
107
|
+
MS : {
|
|
108
|
+
state_id : "MS",
|
|
109
|
+
name : "Mississippi"
|
|
110
|
+
},
|
|
111
|
+
MO : {
|
|
112
|
+
state_id : "MO",
|
|
113
|
+
name : "Missouri"
|
|
114
|
+
},
|
|
115
|
+
MT : {
|
|
116
|
+
state_id : "MT",
|
|
117
|
+
name : "Montana"
|
|
118
|
+
},
|
|
119
|
+
NE : {
|
|
120
|
+
state_id : "NE",
|
|
121
|
+
name : "Nebraska"
|
|
122
|
+
},
|
|
123
|
+
NV : {
|
|
124
|
+
state_id : "NV",
|
|
125
|
+
name : "Nevada"
|
|
126
|
+
},
|
|
127
|
+
NH : {
|
|
128
|
+
state_id : "NH",
|
|
129
|
+
name : "New Hampshire"
|
|
130
|
+
},
|
|
131
|
+
NJ : {
|
|
132
|
+
state_id : "NJ",
|
|
133
|
+
name : "New Jersey"
|
|
134
|
+
},
|
|
135
|
+
NM : {
|
|
136
|
+
state_id : "NM",
|
|
137
|
+
name : "New Mexico"
|
|
138
|
+
},
|
|
139
|
+
NY : {
|
|
140
|
+
state_id : "NY",
|
|
141
|
+
name : "New York"
|
|
142
|
+
},
|
|
143
|
+
NC : {
|
|
144
|
+
state_id : "NC",
|
|
145
|
+
name : "North Carolina"
|
|
146
|
+
},
|
|
147
|
+
ND : {
|
|
148
|
+
state_id : "ND",
|
|
149
|
+
name : "North Dakota"
|
|
150
|
+
},
|
|
151
|
+
OH : {
|
|
152
|
+
state_id : "OH",
|
|
153
|
+
name : "Ohio"
|
|
154
|
+
},
|
|
155
|
+
OK : {
|
|
156
|
+
state_id : "OK",
|
|
157
|
+
name : "Oklahoma"
|
|
158
|
+
},
|
|
159
|
+
OR : {
|
|
160
|
+
state_id : "OR",
|
|
161
|
+
name : "Oregon"
|
|
162
|
+
},
|
|
163
|
+
PA : {
|
|
164
|
+
state_id : "PA",
|
|
165
|
+
name : "Pennsylvania"
|
|
166
|
+
},
|
|
167
|
+
RI : {
|
|
168
|
+
state_id : "RI",
|
|
169
|
+
name : "Rhode Island"
|
|
170
|
+
},
|
|
171
|
+
SC : {
|
|
172
|
+
state_id : "SC",
|
|
173
|
+
name : "South Carolina"
|
|
174
|
+
},
|
|
175
|
+
SD : {
|
|
176
|
+
state_id : "SD",
|
|
177
|
+
name : "South Dakota"
|
|
178
|
+
},
|
|
179
|
+
TN : {
|
|
180
|
+
state_id : "TN",
|
|
181
|
+
name : "Tennessee"
|
|
182
|
+
},
|
|
183
|
+
TX : {
|
|
184
|
+
state_id : "TX",
|
|
185
|
+
name : "Texas"
|
|
186
|
+
},
|
|
187
|
+
UT : {
|
|
188
|
+
state_id : "UT",
|
|
189
|
+
name : "Utah"
|
|
190
|
+
},
|
|
191
|
+
VT : {
|
|
192
|
+
state_id : "VT",
|
|
193
|
+
name : "Vermont"
|
|
194
|
+
},
|
|
195
|
+
VA : {
|
|
196
|
+
state_id : "VA",
|
|
197
|
+
name : "Virginia"
|
|
198
|
+
},
|
|
199
|
+
WA : {
|
|
200
|
+
state_id : "WA",
|
|
201
|
+
name : "Washington"
|
|
202
|
+
},
|
|
203
|
+
WV : {
|
|
204
|
+
state_id : "WV",
|
|
205
|
+
name : "West Virginia"
|
|
206
|
+
},
|
|
207
|
+
WI : {
|
|
208
|
+
state_id : "WI",
|
|
209
|
+
name : "Wisconsin"
|
|
210
|
+
},
|
|
211
|
+
WY : {
|
|
212
|
+
state_id : "WY",
|
|
213
|
+
name : "Wyoming"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export class Tweet {
|
|
2
|
+
readonly tweet_id : string
|
|
3
|
+
readonly username : string
|
|
4
|
+
readonly url : string
|
|
5
|
+
readonly tweet_time : string
|
|
6
|
+
readonly tweet_content : string
|
|
7
|
+
readonly quote? : string
|
|
8
|
+
readonly html : string
|
|
9
|
+
readonly text : string
|
|
10
|
+
|
|
11
|
+
constructor(tweet : any) {
|
|
12
|
+
if (!Tweet.is(tweet)) {
|
|
13
|
+
throw Error("Invalid input.")
|
|
14
|
+
}
|
|
15
|
+
this.tweet_id = tweet.tweet_id
|
|
16
|
+
this.username = tweet.username
|
|
17
|
+
this.url = tweet.url
|
|
18
|
+
this.tweet_time = tweet.tweet_time
|
|
19
|
+
this.tweet_content = tweet.tweet_content
|
|
20
|
+
this.quote = tweet.quote
|
|
21
|
+
this.html = tweet.html
|
|
22
|
+
this.text = tweet.text
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static is(tweet : any) : tweet is Tweet {
|
|
26
|
+
return (
|
|
27
|
+
tweet !== undefined &&
|
|
28
|
+
typeof tweet.tweet_id === "string" &&
|
|
29
|
+
typeof tweet.username === "string" &&
|
|
30
|
+
typeof tweet.url === "string" &&
|
|
31
|
+
typeof tweet.tweet_time === "string" &&
|
|
32
|
+
typeof tweet.tweet_content === "string" &&
|
|
33
|
+
(tweet.quote === undefined || typeof tweet.quote === "string") &&
|
|
34
|
+
(typeof tweet.html === "string") &&
|
|
35
|
+
(typeof tweet.text === "string")
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { is_long_form_type_id, LongFormTypeID } from "./FormTypeID"
|
|
2
|
+
|
|
3
|
+
export class User {
|
|
4
|
+
readonly user_id : string
|
|
5
|
+
readonly admin : boolean
|
|
6
|
+
readonly premium : boolean
|
|
7
|
+
readonly email : string
|
|
8
|
+
readonly email_settings : Record<LongFormTypeID, boolean>
|
|
9
|
+
// readonly [x : string] : any
|
|
10
|
+
|
|
11
|
+
constructor(user : any) {
|
|
12
|
+
if (!User.is(user)) {
|
|
13
|
+
throw Error("Invalid Input.")
|
|
14
|
+
}
|
|
15
|
+
this.user_id = user.user_id
|
|
16
|
+
this.admin = user.admin
|
|
17
|
+
this.premium = user.premium
|
|
18
|
+
this.email = user.email
|
|
19
|
+
this.email_settings = user.email_settings
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static is(user : any) : user is User {
|
|
23
|
+
return (
|
|
24
|
+
user !== undefined &&
|
|
25
|
+
typeof user.user_id === "string" &&
|
|
26
|
+
typeof user.admin === "boolean" &&
|
|
27
|
+
typeof user.premium === "boolean" &&
|
|
28
|
+
typeof user.email === "string" &&
|
|
29
|
+
Array.isArray(user.scout_ids) &&
|
|
30
|
+
typeof user.email_settings === "object" &&
|
|
31
|
+
Object.entries(user.email_settings).every(([key, value]) => is_long_form_type_id(key) && typeof value === "boolean")
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"outDir": "./dist",
|
|
4
|
+
|
|
5
|
+
// Treat files as modules even if it doesn't use import/export
|
|
6
|
+
"moduleDetection": "force",
|
|
7
|
+
|
|
8
|
+
// Ignore module structure
|
|
9
|
+
"module" : "esnext",
|
|
10
|
+
"target" : "es2022",
|
|
11
|
+
"noImplicitAny" : true,
|
|
12
|
+
"noImplicitReturns" : true,
|
|
13
|
+
"moduleResolution": "bundler",
|
|
14
|
+
"declaration": true,
|
|
15
|
+
// Allow JS files to be imported from TS and vice versa
|
|
16
|
+
"allowJs": true,
|
|
17
|
+
"strict" : true,
|
|
18
|
+
// Use correct ESM import behavior
|
|
19
|
+
"esModuleInterop": true,
|
|
20
|
+
"resolveJsonModule": true,
|
|
21
|
+
// Disallow features that require cross-file awareness
|
|
22
|
+
"isolatedModules": true,
|
|
23
|
+
"lib": ["es2022"],
|
|
24
|
+
"rootDir": "./",
|
|
25
|
+
"skipLibCheck": true,
|
|
26
|
+
"maxNodeModuleJsDepth": 0,
|
|
27
|
+
"types": ["jest", "node"]
|
|
28
|
+
},
|
|
29
|
+
"tsc-alias": {
|
|
30
|
+
"resolveFullPaths": true,
|
|
31
|
+
"verbose": false
|
|
32
|
+
},
|
|
33
|
+
"include" : ["src/**/*", "test/**/*"]
|
|
34
|
+
}
|