Skip to content

Commit 56bf3e5

Browse files
committed
[refactor] Chore to update to v1 of TypeBox
1 parent 3cd386f commit 56bf3e5

51 files changed

Lines changed: 689 additions & 117 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bun.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
"@podley/task-graph": "0.0.43",
2626
"@podley/tasks": "0.0.43",
2727
"@podley/util": "0.0.43",
28-
"@sinclair/typebox": "^0.34.41",
2928
"@sroussey/parse-address": "^2.4.2",
3029
"@sroussey/parse-full-name": "^2.0.0",
3130
"awesome-phonenumber": "^7.6.0",
@@ -38,6 +37,7 @@
3837
"fast-xml-parser": "^5.3.2",
3938
"html-entities": "^2.6.0",
4039
"pdf2json": "^3.2.2",
40+
"typebox": "1.0.55",
4141
"words-to-numbers": "^1.5.1",
4242
"xml2js": "^0.6.2"
4343
},

src/sec/facts/CompanyFacts.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
// data.sec.gov/api/xbrl/companyfacts/CIK{cik}.json
88

9-
import { Static, Type } from "@sinclair/typebox";
10-
import { TypeDate, TypeNullable } from "../../util/TypeBoxUtil";
11-
import { YYYYdMMdDD } from "../../util/parseDate";
9+
import { Static, Type } from "typebox";
1210
import { Frame } from "../../util/BaseTypes";
13-
import { TypeSECForm } from "../submissions/EnititySubmissionSchema";
11+
import { TypeDate, TypeNullable, TypeStringEnum } from "../../util/TypeBoxUtil";
12+
import { YYYYdMMdDD } from "../../util/parseDate";
1413
import { AllForms } from "../forms/all-forms";
14+
import { TypeSECForm } from "../submissions/EnititySubmissionSchema";
1515

1616
export interface CompanyFacts {
1717
cik: number;
@@ -59,7 +59,7 @@ export const FactoidSchema = Type.Object({
5959
start_date: TypeNullable(TypeDate()),
6060
end_date: TypeDate(),
6161
fy: Type.Number({ format: "year" }),
62-
fp: Type.Union(FP.map((fp) => Type.Literal(fp))),
62+
fp: TypeStringEnum(FP),
6363
});
6464

6565
export type Factoid = Static<typeof FactoidSchema>;

src/sec/forms/Form.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// See https://www.sec.gov/files/edgar/filermanual/edgarfilermmanual-vol2-c3.pdf
88

9-
import type { TObject } from "@sinclair/typebox";
9+
import type { TObject } from "typebox";
1010
import { Readable } from "node:stream";
1111
import { extractArrayPaths } from "./parse_util";
1212
import { X2jOptions } from "fast-xml-parser";

src/sec/forms/FormSchemaUtil.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import { Type } from "@sinclair/typebox";
7+
import { Type } from "typebox";
88

99
export const STRING_50_TYPE = Type.String({ minLength: 0, maxLength: 50 });
1010
export const STRING_150_TYPE = Type.String({ minLength: 1, maxLength: 150 });

src/sec/forms/exempt-offerings/Form_D.schema.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import { Type, Static } from "@sinclair/typebox";
7+
import { Type, Static } from "typebox";
88
import {
99
TRUE_FALSE_LIST,
1010
RELATIONSHIP_LIST,
@@ -304,22 +304,24 @@ const NAMES_LIST_TYPE = Type.Union([
304304
Type.Object({ previousName: Type.Optional(Type.Array(ENTITY_NAME_TYPE, { maxItems: 3 })) }),
305305
]);
306306

307-
const YEAR_INC_TYPE = Type.Object({
308-
...Type.Union([
307+
const YEAR_INC_TYPE = Type.Intersect([
308+
Type.Union([
309309
Type.Object({ withinFiveYears: IS_TRUE_TYPE }),
310310
Type.Object({ yetToBeFormed: IS_TRUE_TYPE }),
311311
Type.Object({ overFiveYears: IS_TRUE_TYPE }),
312-
]).properties!,
313-
value: Type.Optional(YEAR_VALUE_TYPE),
314-
});
312+
]),
313+
Type.Object({
314+
value: Type.Optional(YEAR_VALUE_TYPE),
315+
}),
316+
]);
315317

316318
const FILED_BY_COMPANY_FORMD_TYPE = Type.Object({
317319
cik: CIK_TYPE,
318320
ccc: Type.Optional(Type.String({ minLength: 8, maxLength: 8 })),
319321
entityName: Type.Optional(ENTITY_NAME_TYPE),
320322
});
321323

322-
const ISSUER_TYPE = Type.Composite([
324+
const ISSUER_TYPE = Type.Intersect([
323325
FILED_BY_COMPANY_FORMD_TYPE,
324326
Type.Object({
325327
issuerAddress: FORMD_ADDRESS_TYPE,

src/sec/forms/exempt-offerings/Form_D.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import { Value } from "@sinclair/typebox/value";
7+
import { Value } from "typebox/value";
88
import { Form } from "../Form";
99
import { FormD, FormDSchema, FormDSubmission, FormDSubmissionSchema } from "./Form_D.schema";
1010

src/sec/forms/parse_util.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import { TSchema, Kind } from "@sinclair/typebox";
7+
import { TSchema, Type } from "typebox";
88
import { Readable } from "node:stream";
99

1010
/** Read a Node.js Readable stream completely into a UTF-8 string */
@@ -20,30 +20,25 @@ export function extractArrayPaths(schema: TSchema, basePath: string = ""): strin
2020
const arrayPaths: string[] = [];
2121

2222
function walk(currentSchema: TSchema, currentPath: string) {
23-
if (currentSchema[Kind] === "Array") {
23+
if (Type.IsArray(currentSchema)) {
2424
arrayPaths.push(currentPath);
2525
// Also walk the array items to find nested arrays
26-
if (currentSchema.items) {
27-
walk(currentSchema.items as TSchema, currentPath);
28-
}
29-
} else if (currentSchema[Kind] === "Object" && currentSchema.properties) {
26+
walk(currentSchema.items, currentPath);
27+
} else if (Type.IsObject(currentSchema)) {
3028
for (const [key, value] of Object.entries(currentSchema.properties)) {
3129
const newPath = currentPath ? `${currentPath}.${key}` : key;
32-
walk(value as TSchema, newPath);
30+
walk(value, newPath);
3331
}
34-
} else if (currentSchema[Kind] === "Union" && currentSchema.anyOf) {
32+
} else if (Type.IsUnion(currentSchema)) {
3533
// Handle unions by checking each variant
3634
for (const variant of currentSchema.anyOf) {
37-
walk(variant as TSchema, currentPath);
35+
walk(variant, currentPath);
3836
}
39-
} else if (currentSchema[Kind] === "Composite" && currentSchema.allOf) {
37+
} else if (Type.IsIntersect(currentSchema)) {
4038
// Handle composite types
4139
for (const part of currentSchema.allOf) {
42-
walk(part as TSchema, currentPath);
40+
walk(part, currentPath);
4341
}
44-
} else if (currentSchema[Kind] === "Optional" && currentSchema.type) {
45-
// Handle optional types
46-
walk(currentSchema.type as TSchema, currentPath);
4742
}
4843
}
4944

src/sec/submissions/EnititySubmissionSchema.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,22 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import { Static, Type, FormatRegistry } from "@sinclair/typebox";
7+
import { Static, Type } from "typebox";
8+
import { Format } from "typebox/format";
89
import { ArrayToObject } from "@podley/util";
910
import { TypeNullable } from "../../util/TypeBoxUtil";
1011
import { ALL_FORM_NAMES } from "../forms/all-forms";
1112

1213
// const TypeSECForm = () => Type.Union(ALL_FORM_NAMES.map((f) => Type.Literal(f)));
1314

14-
FormatRegistry.Set("sec-form", (value: string) => {
15+
Format.Set("sec-form", (value: string) => {
1516
if (!ALL_FORM_NAMES.includes(value as any)) console.warn(`Unknown SEC form: ${value}`);
1617
return true;
1718
});
1819
export const TypeSECForm = (annotations: Record<string, unknown> = {}) =>
1920
Type.String({ format: "sec-form", maxLength: 20, ...annotations });
2021
export const TypeSECBoolean = (annotations: Record<string, unknown> = {}) =>
21-
Type.Transform(Type.Boolean(annotations))
22+
Type.Codec(Type.Boolean(annotations))
2223
.Decode((value) => (value ? "1" : "0"))
2324
.Encode((value) => value === "1");
2425
export const TypeAddress = (annotations: Record<string, unknown> = {}) =>
@@ -38,7 +39,7 @@ export const TypeAddress = (annotations: Record<string, unknown> = {}) =>
3839
annotations
3940
);
4041
export const TypeSecCik = (annotations: Record<string, unknown> = {}) =>
41-
Type.Transform(
42+
Type.Codec(
4243
Type.Number({ format: "cik", minimum: 0, maximum: 9999999999, title: "CIK", ...annotations })
4344
)
4445
.Decode((value) => value.toString())

src/storage/address/AddressNormalization.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@
55
*/
66

77
import { AddressParser } from "@sroussey/parse-address";
8-
import { Address } from "./AddressSchema";
9-
import { COUNTRY_STATE_CODE_ARRAY, KEYWORD_STATE_OR_COUNTRY_MAP } from "./AddressSchemaCodes";
108
import { hasCompanyEnding } from "../company/CompanyNormalization";
9+
import { Address, type CountryCode, type StateOrCountryCode } from "./AddressSchema";
10+
import { COUNTRY_STATE_CODE_ARRAY, KEYWORD_STATE_OR_COUNTRY_MAP } from "./AddressSchemaCodes";
1111

1212
export type AddressImport = {
1313
// required fields
1414
city?: string | null;
15-
stateOrCountry?: string | null;
15+
stateOrCountry?: StateOrCountryCode | string | null;
16+
countryCode?: CountryCode | string | null;
1617
// optional fields
1718
stateOrCountryDescription?: string | null;
1819
street1?: string | null; // if street 1 is null, street 2 or 3 must have a value
1920
street2?: string | null;
2021
street3?: string | null;
2122
country?: string | null;
22-
countryCode?: string | null;
2323
zipCode?: string | null;
2424
isForeignLocation?: boolean | null;
2525
foreignStateTerritory?: string | null;
@@ -245,18 +245,26 @@ export function normalizeAddress(importAddress: AddressImport | null): Address |
245245
let street3 = cleanStreet(importAddress.street3);
246246
let zip = importAddress.zipCode?.trim() || null;
247247
let city = importAddress.city?.trim() || null;
248-
let state_or_country = importAddress.stateOrCountry?.trim() || null;
248+
let state_or_country: StateOrCountryCode | null =
249+
(importAddress.stateOrCountry?.trim() as StateOrCountryCode | null) || null;
249250

250251
[street1, street2, street3] = consolidateStreetAddresses(street1, street2, street3);
251252

252253
state_or_country =
253-
state_or_country || findCountryByKeyword([street1, street2, street3, city, state_or_country]);
254+
state_or_country ||
255+
(findCountryByKeyword([
256+
street1,
257+
street2,
258+
street3,
259+
city,
260+
state_or_country,
261+
]) as StateOrCountryCode | null);
254262

255263
let country_code = findCountryCode(
256264
state_or_country,
257265
importAddress.country,
258266
importAddress.countryCode
259-
);
267+
) as CountryCode | null;
260268

261269
city = normalizeCity(city ?? "");
262270

@@ -278,8 +286,9 @@ export function normalizeAddress(importAddress: AddressImport | null): Address |
278286
street2 = importAddress.street2 || null;
279287
street3 = importAddress.street3 || null;
280288
city = city || importAddress.city || null;
281-
state_or_country = state_or_country || importAddress.stateOrCountry || null;
282-
country_code = country_code || importAddress.countryCode || null;
289+
state_or_country =
290+
state_or_country || (importAddress.stateOrCountry as StateOrCountryCode) || null;
291+
country_code = country_code || (importAddress.countryCode as CountryCode) || null;
283292
zip = zip || importAddress.zipCode || null;
284293
}
285294

0 commit comments

Comments
 (0)