@ansvar/us-regulations-mcp 1.0.0 → 1.2.1
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 +422 -79
- package/data/regulations.db +0 -0
- package/data/seed/colorado-cpa.json +97 -0
- package/data/seed/ffiec.json +103 -0
- package/data/seed/mappings/ccpa-nist-csf.json +11 -1
- package/data/seed/mappings/hipaa-nist-800-53.json +10 -1
- package/data/seed/nydfs.json +122 -0
- package/data/seed/sox.json +109 -0
- package/dist/index.js +1 -1
- package/dist/ingest/adapters/colorado-public.d.ts +25 -0
- package/dist/ingest/adapters/colorado-public.d.ts.map +1 -0
- package/dist/ingest/adapters/colorado-public.js +76 -0
- package/dist/ingest/adapters/colorado-public.js.map +1 -0
- package/dist/ingest/adapters/connecticut-cga.d.ts +22 -0
- package/dist/ingest/adapters/connecticut-cga.d.ts.map +1 -0
- package/dist/ingest/adapters/connecticut-cga.js +116 -0
- package/dist/ingest/adapters/connecticut-cga.js.map +1 -0
- package/dist/ingest/adapters/ecfr.d.ts +46 -4
- package/dist/ingest/adapters/ecfr.d.ts.map +1 -1
- package/dist/ingest/adapters/ecfr.js +131 -16
- package/dist/ingest/adapters/ecfr.js.map +1 -1
- package/dist/ingest/adapters/ffiec.d.ts +42 -0
- package/dist/ingest/adapters/ffiec.d.ts.map +1 -0
- package/dist/ingest/adapters/ffiec.js +68 -0
- package/dist/ingest/adapters/ffiec.js.map +1 -0
- package/dist/ingest/adapters/nydfs.d.ts +42 -0
- package/dist/ingest/adapters/nydfs.d.ts.map +1 -0
- package/dist/ingest/adapters/nydfs.js +68 -0
- package/dist/ingest/adapters/nydfs.js.map +1 -0
- package/dist/ingest/adapters/regulations-gov.d.ts +11 -12
- package/dist/ingest/adapters/regulations-gov.d.ts.map +1 -1
- package/dist/ingest/adapters/regulations-gov.js +46 -43
- package/dist/ingest/adapters/regulations-gov.js.map +1 -1
- package/dist/ingest/adapters/utah-xcode.d.ts +19 -0
- package/dist/ingest/adapters/utah-xcode.d.ts.map +1 -0
- package/dist/ingest/adapters/utah-xcode.js +112 -0
- package/dist/ingest/adapters/utah-xcode.js.map +1 -0
- package/dist/ingest/adapters/virginia-law.d.ts +21 -0
- package/dist/ingest/adapters/virginia-law.d.ts.map +1 -0
- package/dist/ingest/adapters/virginia-law.js +111 -0
- package/dist/ingest/adapters/virginia-law.js.map +1 -0
- package/package.json +26 -4
- package/scripts/build-db.ts +50 -32
- package/scripts/check-updates.ts +184 -0
- package/scripts/ingest.ts +72 -25
- package/src/index.ts +1 -1
- package/src/ingest/adapters/colorado-public.ts +96 -0
- package/src/ingest/adapters/connecticut-cga.ts +150 -0
- package/src/ingest/adapters/ecfr.ts +158 -17
- package/src/ingest/adapters/ffiec.ts +77 -0
- package/src/ingest/adapters/nydfs.ts +77 -0
- package/src/ingest/adapters/regulations-gov.ts +48 -47
- package/src/ingest/adapters/utah-xcode.ts +143 -0
- package/src/ingest/adapters/virginia-law.ts +140 -0
- package/scripts/quality-test.ts +0 -346
- package/scripts/test-mcp-tools.ts +0 -187
- package/scripts/test-remaining-tools.ts +0 -107
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ffiec.js","sourceRoot":"","sources":["../../../src/ingest/adapters/ffiec.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IACf,QAAQ,CAAS;IAEzB;QACE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAC9D,OAAO;YACL,GAAG,IAAI,CAAC,UAAU;YAClB,UAAU,EAAE,uCAAuC;YACnD,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc;SAC7C,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,aAAa;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,WAAiB;QACrC,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI,IAAI,EAAE;YACxB,OAAO,EAAE,EAAE;SACZ,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,YAAY,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NYDFS Adapter - Seed-based for v1.1
|
|
3
|
+
* TODO: Implement HTML scraping for automated updates
|
|
4
|
+
*
|
|
5
|
+
* Source: NY DFS Cybersecurity Regulation (23 NYCRR 500)
|
|
6
|
+
* URL: https://www.dfs.ny.gov/industry_guidance/cybersecurity
|
|
7
|
+
*/
|
|
8
|
+
import { SourceAdapter, RegulationMetadata, Section, Definition, UpdateStatus } from '../framework.js';
|
|
9
|
+
/**
|
|
10
|
+
* Seed-based adapter for NYDFS 23 NYCRR 500
|
|
11
|
+
*
|
|
12
|
+
* Future enhancement: Implement HTML scraping from NY DFS website
|
|
13
|
+
* The regulation is published online at dfs.ny.gov
|
|
14
|
+
*/
|
|
15
|
+
export declare class NydfsAdapter implements SourceAdapter {
|
|
16
|
+
private seedPath;
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Fetch regulation metadata from seed file
|
|
20
|
+
*/
|
|
21
|
+
fetchMetadata(): Promise<RegulationMetadata>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetch sections from seed file
|
|
24
|
+
* Returns all sections in a single batch
|
|
25
|
+
*/
|
|
26
|
+
fetchSections(): AsyncGenerator<Section[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Extract definitions (not implemented for seed-based adapter)
|
|
29
|
+
* Future: Extract from 500.01 Definitions section
|
|
30
|
+
*/
|
|
31
|
+
extractDefinitions(): Promise<Definition[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Check for updates (not implemented for seed-based adapter)
|
|
34
|
+
* Future: Check last-modified headers from NY DFS website
|
|
35
|
+
*/
|
|
36
|
+
checkForUpdates(lastFetched: Date): Promise<UpdateStatus>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Factory function to create NYDFS adapter
|
|
40
|
+
*/
|
|
41
|
+
export declare function createNydfsAdapter(): NydfsAdapter;
|
|
42
|
+
//# sourceMappingURL=nydfs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nydfs.d.ts","sourceRoot":"","sources":["../../../src/ingest/adapters/nydfs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQvG;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAS;;IAMzB;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IASlD;;;OAGG;IACI,aAAa,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;IAKjD;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAIjD;;;OAGG;IACG,eAAe,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;CAOhE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NYDFS Adapter - Seed-based for v1.1
|
|
3
|
+
* TODO: Implement HTML scraping for automated updates
|
|
4
|
+
*
|
|
5
|
+
* Source: NY DFS Cybersecurity Regulation (23 NYCRR 500)
|
|
6
|
+
* URL: https://www.dfs.ny.gov/industry_guidance/cybersecurity
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
/**
|
|
14
|
+
* Seed-based adapter for NYDFS 23 NYCRR 500
|
|
15
|
+
*
|
|
16
|
+
* Future enhancement: Implement HTML scraping from NY DFS website
|
|
17
|
+
* The regulation is published online at dfs.ny.gov
|
|
18
|
+
*/
|
|
19
|
+
export class NydfsAdapter {
|
|
20
|
+
seedPath;
|
|
21
|
+
constructor() {
|
|
22
|
+
this.seedPath = join(__dirname, '../../../data/seed/nydfs.json');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Fetch regulation metadata from seed file
|
|
26
|
+
*/
|
|
27
|
+
async fetchMetadata() {
|
|
28
|
+
const seed = JSON.parse(readFileSync(this.seedPath, 'utf-8'));
|
|
29
|
+
return {
|
|
30
|
+
...seed.regulation,
|
|
31
|
+
source_url: 'https://www.dfs.ny.gov/industry_guidance/cybersecurity',
|
|
32
|
+
last_amended: seed.regulation.effective_date
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Fetch sections from seed file
|
|
37
|
+
* Returns all sections in a single batch
|
|
38
|
+
*/
|
|
39
|
+
async *fetchSections() {
|
|
40
|
+
const seed = JSON.parse(readFileSync(this.seedPath, 'utf-8'));
|
|
41
|
+
yield seed.sections;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract definitions (not implemented for seed-based adapter)
|
|
45
|
+
* Future: Extract from 500.01 Definitions section
|
|
46
|
+
*/
|
|
47
|
+
async extractDefinitions() {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check for updates (not implemented for seed-based adapter)
|
|
52
|
+
* Future: Check last-modified headers from NY DFS website
|
|
53
|
+
*/
|
|
54
|
+
async checkForUpdates(lastFetched) {
|
|
55
|
+
return {
|
|
56
|
+
hasChanges: false,
|
|
57
|
+
lastModified: new Date(),
|
|
58
|
+
changes: []
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Factory function to create NYDFS adapter
|
|
64
|
+
*/
|
|
65
|
+
export function createNydfsAdapter() {
|
|
66
|
+
return new NydfsAdapter();
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=nydfs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nydfs.js","sourceRoot":"","sources":["../../../src/ingest/adapters/nydfs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IACf,QAAQ,CAAS;IAEzB;QACE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAC9D,OAAO;YACL,GAAG,IAAI,CAAC,UAAU;YAClB,UAAU,EAAE,wDAAwD;YACpE,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc;SAC7C,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,aAAa;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,WAAiB;QACrC,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI,IAAI,EAAE;YACxB,OAAO,EAAE,EAAE;SACZ,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,YAAY,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -1,42 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SOX Adapter
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Provides Sarbanes-Oxley Act compliance content including:
|
|
5
|
+
* - SOX statute sections (15 U.S.C., 18 U.S.C.)
|
|
6
|
+
* - SEC implementing regulations (17 CFR)
|
|
7
|
+
* - PCAOB auditing standards
|
|
8
|
+
* - IT General Controls guidance
|
|
6
9
|
*
|
|
7
10
|
* PRODUCTION IMPLEMENTATION
|
|
8
|
-
* Uses
|
|
11
|
+
* Uses comprehensive seed data verified against official sources
|
|
9
12
|
*/
|
|
10
13
|
import { SourceAdapter, RegulationMetadata, Section, Definition, UpdateStatus } from '../framework.js';
|
|
11
14
|
/**
|
|
12
|
-
* Adapter for
|
|
15
|
+
* Adapter for SOX compliance content
|
|
13
16
|
*
|
|
14
|
-
*
|
|
17
|
+
* Provides comprehensive SOX coverage including statute, SEC rules, and PCAOB standards
|
|
15
18
|
*/
|
|
16
19
|
export declare class SoxAdapter implements SourceAdapter {
|
|
17
20
|
private readonly regulationId;
|
|
18
|
-
private readonly
|
|
21
|
+
private readonly seedPath;
|
|
19
22
|
constructor(regulationId: string);
|
|
20
23
|
/**
|
|
21
24
|
* Fetch SOX metadata
|
|
22
25
|
*/
|
|
23
26
|
fetchMetadata(): Promise<RegulationMetadata>;
|
|
24
27
|
/**
|
|
25
|
-
* Fetch all SOX
|
|
28
|
+
* Fetch all SOX sections from seed data
|
|
26
29
|
*
|
|
27
|
-
*
|
|
30
|
+
* Includes statute sections, SEC implementing rules, and PCAOB standards
|
|
28
31
|
*/
|
|
29
32
|
fetchSections(): AsyncGenerator<Section[]>;
|
|
30
33
|
/**
|
|
31
34
|
* Check for updates since last fetch
|
|
32
|
-
*
|
|
33
|
-
* Delegates to eCFR adapter for update checking
|
|
34
35
|
*/
|
|
35
36
|
checkForUpdates(lastFetched: Date): Promise<UpdateStatus>;
|
|
36
37
|
/**
|
|
37
38
|
* Extract definitions from SOX sections
|
|
38
|
-
*
|
|
39
|
-
* Future enhancement: Parse definitions from SEC regulations
|
|
40
39
|
*/
|
|
41
40
|
extractDefinitions(): Promise<Definition[]>;
|
|
42
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regulations-gov.d.ts","sourceRoot":"","sources":["../../../src/ingest/adapters/regulations-gov.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"regulations-gov.d.ts","sourceRoot":"","sources":["../../../src/ingest/adapters/regulations-gov.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,OAAO,EACP,UAAU,EACV,YAAY,EACb,MAAM,iBAAiB,CAAC;AAQzB;;;;GAIG;AACH,qBAAa,UAAW,YAAW,aAAa;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,YAAY,EAAE,MAAM;IAKhC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAalD;;;;OAIG;IACI,aAAa,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;IA0BjD;;OAEG;IACG,eAAe,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ/D;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;CAGlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAE7C"}
|
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SOX Adapter
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Provides Sarbanes-Oxley Act compliance content including:
|
|
5
|
+
* - SOX statute sections (15 U.S.C., 18 U.S.C.)
|
|
6
|
+
* - SEC implementing regulations (17 CFR)
|
|
7
|
+
* - PCAOB auditing standards
|
|
8
|
+
* - IT General Controls guidance
|
|
6
9
|
*
|
|
7
10
|
* PRODUCTION IMPLEMENTATION
|
|
8
|
-
* Uses
|
|
11
|
+
* Uses comprehensive seed data verified against official sources
|
|
9
12
|
*/
|
|
10
|
-
import
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = path.dirname(__filename);
|
|
11
18
|
/**
|
|
12
|
-
* Adapter for
|
|
19
|
+
* Adapter for SOX compliance content
|
|
13
20
|
*
|
|
14
|
-
*
|
|
21
|
+
* Provides comprehensive SOX coverage including statute, SEC rules, and PCAOB standards
|
|
15
22
|
*/
|
|
16
23
|
export class SoxAdapter {
|
|
17
24
|
regulationId;
|
|
18
|
-
|
|
25
|
+
seedPath;
|
|
19
26
|
constructor(regulationId) {
|
|
20
27
|
this.regulationId = regulationId;
|
|
21
|
-
|
|
22
|
-
this.ecfrAdapter = new EcfrAdapter('SOX-SEC', 17, [229, 240]);
|
|
28
|
+
this.seedPath = path.join(__dirname, '../../../data/seed/sox.json');
|
|
23
29
|
}
|
|
24
30
|
/**
|
|
25
31
|
* Fetch SOX metadata
|
|
@@ -27,59 +33,56 @@ export class SoxAdapter {
|
|
|
27
33
|
async fetchMetadata() {
|
|
28
34
|
return {
|
|
29
35
|
id: this.regulationId,
|
|
30
|
-
full_name: 'Sarbanes-Oxley Act
|
|
31
|
-
citation: '
|
|
32
|
-
effective_date: '
|
|
33
|
-
last_amended:
|
|
34
|
-
source_url: 'https://www.
|
|
36
|
+
full_name: 'Sarbanes-Oxley Act of 2002',
|
|
37
|
+
citation: 'Pub.L. 107-204, 15 U.S.C. §§ 7201-7266, 17 CFR Parts 229, 240',
|
|
38
|
+
effective_date: '2002-07-30',
|
|
39
|
+
last_amended: '2023-01-01',
|
|
40
|
+
source_url: 'https://www.sec.gov/spotlight/sarbanes-oxley.htm',
|
|
35
41
|
jurisdiction: 'federal',
|
|
36
|
-
regulation_type: '
|
|
42
|
+
regulation_type: 'statute',
|
|
37
43
|
};
|
|
38
44
|
}
|
|
39
45
|
/**
|
|
40
|
-
* Fetch all SOX
|
|
46
|
+
* Fetch all SOX sections from seed data
|
|
41
47
|
*
|
|
42
|
-
*
|
|
48
|
+
* Includes statute sections, SEC implementing rules, and PCAOB standards
|
|
43
49
|
*/
|
|
44
50
|
async *fetchSections() {
|
|
45
|
-
console.log('
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// - 17 CFR 240.13a-14 (Certifications)
|
|
51
|
-
// - 17 CFR 240.15d-14 (Certifications)
|
|
52
|
-
const relevantSections = [
|
|
53
|
-
'229.308',
|
|
54
|
-
'240.13a-15',
|
|
55
|
-
'240.15d-15',
|
|
56
|
-
'240.13a-14',
|
|
57
|
-
'240.15d-14',
|
|
58
|
-
];
|
|
59
|
-
// Fetch from eCFR adapter
|
|
60
|
-
for await (const sectionBatch of this.ecfrAdapter.fetchSections()) {
|
|
61
|
-
// Filter to SOX-relevant sections
|
|
62
|
-
const filtered = sectionBatch.filter(section => relevantSections.some(relevant => section.sectionNumber.includes(relevant)));
|
|
63
|
-
if (filtered.length > 0) {
|
|
64
|
-
yield filtered;
|
|
51
|
+
console.log('Loading SOX sections from seed data...');
|
|
52
|
+
try {
|
|
53
|
+
const seedData = JSON.parse(fs.readFileSync(this.seedPath, 'utf-8'));
|
|
54
|
+
if (!seedData.sections || !Array.isArray(seedData.sections)) {
|
|
55
|
+
throw new Error('Invalid seed data format');
|
|
65
56
|
}
|
|
57
|
+
const sections = seedData.sections.map((s) => ({
|
|
58
|
+
sectionNumber: s.sectionNumber,
|
|
59
|
+
title: s.title,
|
|
60
|
+
text: s.text,
|
|
61
|
+
chapter: s.chapter || 'Sarbanes-Oxley Act',
|
|
62
|
+
}));
|
|
63
|
+
console.log(` Loaded ${sections.length} SOX sections from seed data`);
|
|
64
|
+
yield sections;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error('Failed to load SOX seed data:', error);
|
|
68
|
+
throw error;
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
/**
|
|
69
72
|
* Check for updates since last fetch
|
|
70
|
-
*
|
|
71
|
-
* Delegates to eCFR adapter for update checking
|
|
72
73
|
*/
|
|
73
74
|
async checkForUpdates(lastFetched) {
|
|
74
|
-
|
|
75
|
+
// SOX statute is stable; SEC rules update periodically
|
|
76
|
+
return {
|
|
77
|
+
hasChanges: false,
|
|
78
|
+
changes: ['SOX uses verified seed data. Check SEC.gov for regulatory updates.']
|
|
79
|
+
};
|
|
75
80
|
}
|
|
76
81
|
/**
|
|
77
82
|
* Extract definitions from SOX sections
|
|
78
|
-
*
|
|
79
|
-
* Future enhancement: Parse definitions from SEC regulations
|
|
80
83
|
*/
|
|
81
84
|
async extractDefinitions() {
|
|
82
|
-
return
|
|
85
|
+
return [];
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
88
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regulations-gov.js","sourceRoot":"","sources":["../../../src/ingest/adapters/regulations-gov.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"regulations-gov.js","sourceRoot":"","sources":["../../../src/ingest/adapters/regulations-gov.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C;;;;GAIG;AACH,MAAM,OAAO,UAAU;IACJ,YAAY,CAAS;IACrB,QAAQ,CAAS;IAElC,YAAY,YAAoB;QAC9B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,YAAY;YACrB,SAAS,EAAE,4BAA4B;YACvC,QAAQ,EAAE,+DAA+D;YACzE,cAAc,EAAE,YAAY;YAC5B,YAAY,EAAE,YAAY;YAC1B,UAAU,EAAE,kDAAkD;YAC9D,YAAY,EAAE,SAAS;YACvB,eAAe,EAAE,SAAS;SAC3B,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,CAAC,aAAa;QAClB,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QAEtD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YAErE,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,CAAC;YAED,MAAM,QAAQ,GAAc,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;gBAC7D,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,oBAAoB;aAC3C,CAAC,CAAC,CAAC;YAEJ,OAAO,CAAC,GAAG,CAAC,YAAY,QAAQ,CAAC,MAAM,8BAA8B,CAAC,CAAC;YAEvE,MAAM,QAAQ,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,WAAiB;QACrC,uDAAuD;QACvD,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,CAAC,oEAAoE,CAAC;SAChF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utah XCode Adapter
|
|
3
|
+
*
|
|
4
|
+
* Fetches Utah UCPA from le.utah.gov with version resolution.
|
|
5
|
+
* Source: Utah Code Ann. § 13-61-101 to 13-61-404
|
|
6
|
+
*/
|
|
7
|
+
import { SourceAdapter, RegulationMetadata, Section, Definition, UpdateStatus } from '../framework.js';
|
|
8
|
+
export declare class UtahXcodeAdapter implements SourceAdapter {
|
|
9
|
+
private readonly regulationId;
|
|
10
|
+
private readonly sections;
|
|
11
|
+
fetchMetadata(): Promise<RegulationMetadata>;
|
|
12
|
+
fetchSections(): AsyncGenerator<Section[]>;
|
|
13
|
+
private parseSection;
|
|
14
|
+
private sleep;
|
|
15
|
+
extractDefinitions(): Promise<Definition[]>;
|
|
16
|
+
checkForUpdates(lastFetched: Date): Promise<UpdateStatus>;
|
|
17
|
+
}
|
|
18
|
+
export declare function createUtahAdapter(): SourceAdapter;
|
|
19
|
+
//# sourceMappingURL=utah-xcode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utah-xcode.d.ts","sourceRoot":"","sources":["../../../src/ingest/adapters/utah-xcode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,OAAO,EACP,UAAU,EACV,YAAY,EACb,MAAM,iBAAiB,CAAC;AAUzB,qBAAa,gBAAiB,YAAW,aAAa;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAEvB;IAEI,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAa3C,aAAa,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;IAkEjD,OAAO,CAAC,YAAY;YAmBN,KAAK;IAIb,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAI3C,eAAe,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;CAGhE;AAED,wBAAgB,iBAAiB,IAAI,aAAa,CAEjD"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utah XCode Adapter
|
|
3
|
+
*
|
|
4
|
+
* Fetches Utah UCPA from le.utah.gov with version resolution.
|
|
5
|
+
* Source: Utah Code Ann. § 13-61-101 to 13-61-404
|
|
6
|
+
*/
|
|
7
|
+
import * as cheerio from 'cheerio';
|
|
8
|
+
class ScrapingError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'ScrapingError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class UtahXcodeAdapter {
|
|
15
|
+
regulationId = 'UTAH_UCPA';
|
|
16
|
+
sections = [
|
|
17
|
+
'101', '102', '103', '104', '201', '202', '203', '301', '302', '303', '304', '401', '402', '403', '404'
|
|
18
|
+
];
|
|
19
|
+
async fetchMetadata() {
|
|
20
|
+
return {
|
|
21
|
+
id: 'UTAH_UCPA',
|
|
22
|
+
full_name: 'Utah Consumer Privacy Act',
|
|
23
|
+
citation: 'Utah Code Ann. §13-61-101 to 13-61-404',
|
|
24
|
+
effective_date: '2023-12-31',
|
|
25
|
+
last_amended: '2024-05-01',
|
|
26
|
+
source_url: 'https://le.utah.gov/xcode/Title13/Chapter61/',
|
|
27
|
+
jurisdiction: 'utah',
|
|
28
|
+
regulation_type: 'statute',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async *fetchSections() {
|
|
32
|
+
const sections = [];
|
|
33
|
+
let totalCount = 0;
|
|
34
|
+
console.log(`Fetching Utah UCPA sections (two-step version resolution)...`);
|
|
35
|
+
for (const sectionNum of this.sections) {
|
|
36
|
+
try {
|
|
37
|
+
// Step 1: Get version reference
|
|
38
|
+
const indexUrl = `https://le.utah.gov/xcode/Title13/Chapter61/13-61-S${sectionNum}.html`;
|
|
39
|
+
await this.sleep(500);
|
|
40
|
+
const indexResponse = await fetch(indexUrl);
|
|
41
|
+
if (!indexResponse.ok) {
|
|
42
|
+
console.warn(` Skipping § 13-61-${sectionNum} (HTTP ${indexResponse.status})`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const indexHtml = await indexResponse.text();
|
|
46
|
+
// Extract version filename from JavaScript
|
|
47
|
+
const versionMatch = indexHtml.match(/versionArr\s*=\s*\[\s*\['([^']+)'/);
|
|
48
|
+
if (!versionMatch) {
|
|
49
|
+
console.warn(` Skipping § 13-61-${sectionNum} (no version found)`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const versionFile = versionMatch[1];
|
|
53
|
+
// Step 2: Fetch versioned HTML
|
|
54
|
+
const versionUrl = `https://le.utah.gov/xcode/Title13/Chapter61/${versionFile}`;
|
|
55
|
+
await this.sleep(500);
|
|
56
|
+
const versionResponse = await fetch(versionUrl);
|
|
57
|
+
if (!versionResponse.ok) {
|
|
58
|
+
console.warn(` Skipping § 13-61-${sectionNum} versioned file (HTTP ${versionResponse.status})`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const versionHtml = await versionResponse.text();
|
|
62
|
+
const $ = cheerio.load(versionHtml);
|
|
63
|
+
const section = this.parseSection($, sectionNum);
|
|
64
|
+
if (section) {
|
|
65
|
+
sections.push(section);
|
|
66
|
+
totalCount++;
|
|
67
|
+
console.log(` Fetched § 13-61-${sectionNum}`);
|
|
68
|
+
}
|
|
69
|
+
if (sections.length >= 10) {
|
|
70
|
+
yield sections.splice(0, 10);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.warn(` Failed to fetch § 13-61-${sectionNum}, continuing...`, error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (sections.length > 0) {
|
|
78
|
+
yield sections;
|
|
79
|
+
}
|
|
80
|
+
if (totalCount < 10) {
|
|
81
|
+
throw new ScrapingError(`Expected at least 10 sections, got ${totalCount}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
parseSection($, sectionNum) {
|
|
85
|
+
// Utah uses a main content area
|
|
86
|
+
const content = $('body').text().trim();
|
|
87
|
+
if (!content || content.length < 200) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
// Extract title - format: "13-61-101 Definitions."
|
|
91
|
+
const titleMatch = content.match(/13-61-\d+\s+(.+?)\.(?:\n|$)/);
|
|
92
|
+
const title = titleMatch ? titleMatch[1].trim() : `Section 13-61-${sectionNum}`;
|
|
93
|
+
return {
|
|
94
|
+
sectionNumber: `13-61-${sectionNum}`,
|
|
95
|
+
title: title,
|
|
96
|
+
text: content,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
async sleep(ms) {
|
|
100
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
101
|
+
}
|
|
102
|
+
async extractDefinitions() {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
async checkForUpdates(lastFetched) {
|
|
106
|
+
return { hasChanges: false };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function createUtahAdapter() {
|
|
110
|
+
return new UtahXcodeAdapter();
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=utah-xcode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utah-xcode.js","sourceRoot":"","sources":["../../../src/ingest/adapters/utah-xcode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virginia Legislative Information System Adapter
|
|
3
|
+
*
|
|
4
|
+
* Fetches Virginia CDPA from Virginia LIS.
|
|
5
|
+
* Source: Va. Code Ann. § 59.1-575 to 59.1-585
|
|
6
|
+
*/
|
|
7
|
+
import { SourceAdapter, RegulationMetadata, Section, Definition, UpdateStatus } from '../framework.js';
|
|
8
|
+
export declare class VirginiaLawAdapter implements SourceAdapter {
|
|
9
|
+
private readonly regulationId;
|
|
10
|
+
private readonly sectionStart;
|
|
11
|
+
private readonly sectionEnd;
|
|
12
|
+
fetchMetadata(): Promise<RegulationMetadata>;
|
|
13
|
+
fetchSections(): AsyncGenerator<Section[]>;
|
|
14
|
+
private validateDOM;
|
|
15
|
+
private parseSection;
|
|
16
|
+
private sleep;
|
|
17
|
+
extractDefinitions(): Promise<Definition[]>;
|
|
18
|
+
checkForUpdates(lastFetched: Date): Promise<UpdateStatus>;
|
|
19
|
+
}
|
|
20
|
+
export declare function createVirginiaAdapter(): SourceAdapter;
|
|
21
|
+
//# sourceMappingURL=virginia-law.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virginia-law.d.ts","sourceRoot":"","sources":["../../../src/ingest/adapters/virginia-law.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,OAAO,EACP,UAAU,EACV,YAAY,EACb,MAAM,iBAAiB,CAAC;AAUzB,qBAAa,kBAAmB,YAAW,aAAa;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmB;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAO;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;IAE5B,aAAa,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAa3C,aAAa,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;IAkDjD,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,YAAY;YAyBN,KAAK;IAIb,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAK3C,eAAe,CAAC,WAAW,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;CAGhE;AAED,wBAAgB,qBAAqB,IAAI,aAAa,CAErD"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virginia Legislative Information System Adapter
|
|
3
|
+
*
|
|
4
|
+
* Fetches Virginia CDPA from Virginia LIS.
|
|
5
|
+
* Source: Va. Code Ann. § 59.1-575 to 59.1-585
|
|
6
|
+
*/
|
|
7
|
+
import * as cheerio from 'cheerio';
|
|
8
|
+
class ScrapingError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'ScrapingError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class VirginiaLawAdapter {
|
|
15
|
+
regulationId = 'VIRGINIA_CDPA';
|
|
16
|
+
sectionStart = 575;
|
|
17
|
+
sectionEnd = 585;
|
|
18
|
+
async fetchMetadata() {
|
|
19
|
+
return {
|
|
20
|
+
id: 'VIRGINIA_CDPA',
|
|
21
|
+
full_name: 'Virginia Consumer Data Protection Act',
|
|
22
|
+
citation: 'Va. Code Ann. §59.1-575 to 59.1-585',
|
|
23
|
+
effective_date: '2023-01-01',
|
|
24
|
+
last_amended: '2026-01-01',
|
|
25
|
+
source_url: 'https://law.lis.virginia.gov/vacode/title59.1/chapter53/',
|
|
26
|
+
jurisdiction: 'virginia',
|
|
27
|
+
regulation_type: 'statute',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async *fetchSections() {
|
|
31
|
+
const sections = [];
|
|
32
|
+
let totalCount = 0;
|
|
33
|
+
console.log(`Fetching Virginia CDPA sections ${this.sectionStart}-${this.sectionEnd}...`);
|
|
34
|
+
for (let num = this.sectionStart; num <= this.sectionEnd; num++) {
|
|
35
|
+
try {
|
|
36
|
+
const url = `https://law.lis.virginia.gov/vacode/title59.1/chapter53/section59.1-${num}/`;
|
|
37
|
+
await this.sleep(500); // Polite delay
|
|
38
|
+
const response = await fetch(url);
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
console.warn(` Skipping § 59.1-${num} (HTTP ${response.status})`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const html = await response.text();
|
|
44
|
+
const $ = cheerio.load(html);
|
|
45
|
+
this.validateDOM($);
|
|
46
|
+
const section = this.parseSection($, num);
|
|
47
|
+
if (section) {
|
|
48
|
+
sections.push(section);
|
|
49
|
+
totalCount++;
|
|
50
|
+
console.log(` Fetched § 59.1-${num}`);
|
|
51
|
+
}
|
|
52
|
+
if (sections.length >= 10) {
|
|
53
|
+
yield sections.splice(0, 10);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error instanceof ScrapingError) {
|
|
58
|
+
throw error; // Fail fast on DOM issues
|
|
59
|
+
}
|
|
60
|
+
console.warn(` Failed to fetch § 59.1-${num}, continuing...`, error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (sections.length > 0) {
|
|
64
|
+
yield sections;
|
|
65
|
+
}
|
|
66
|
+
// Validation
|
|
67
|
+
if (totalCount < 10) {
|
|
68
|
+
throw new ScrapingError(`Expected at least 10 sections, got ${totalCount}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
validateDOM($) {
|
|
72
|
+
const codeContent = $('#va_code');
|
|
73
|
+
if (codeContent.length === 0) {
|
|
74
|
+
throw new ScrapingError('DOM structure changed: no #va_code element found');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
parseSection($, num) {
|
|
78
|
+
// Extract section text from #va_code
|
|
79
|
+
const textEl = $('#va_code');
|
|
80
|
+
const text = textEl.text().trim();
|
|
81
|
+
if (!text || text.length < 100) {
|
|
82
|
+
return null; // Skip sections with insufficient content
|
|
83
|
+
}
|
|
84
|
+
// Extract title from h2 within #va_code
|
|
85
|
+
const titleEl = textEl.find('h2').first();
|
|
86
|
+
const titleRaw = titleEl.text().trim();
|
|
87
|
+
// Parse title to extract just the description
|
|
88
|
+
// Format: "§ 59.1-575. (Effective January 1, 2026) Definitions."
|
|
89
|
+
const titleMatch = titleRaw.match(/§\s*59\.1-\d+\.?\s*(?:\([^)]+\))?\s*(.+?)\.?\s*$/);
|
|
90
|
+
const title = titleMatch ? titleMatch[1].trim() : titleRaw;
|
|
91
|
+
return {
|
|
92
|
+
sectionNumber: `59.1-${num}`,
|
|
93
|
+
title: title,
|
|
94
|
+
text: text,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async sleep(ms) {
|
|
98
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
99
|
+
}
|
|
100
|
+
async extractDefinitions() {
|
|
101
|
+
// No separate definitions for Virginia CDPA
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
async checkForUpdates(lastFetched) {
|
|
105
|
+
return { hasChanges: false };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export function createVirginiaAdapter() {
|
|
109
|
+
return new VirginiaLawAdapter();
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=virginia-law.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virginia-law.js","sourceRoot":"","sources":["../../../src/ingest/adapters/virginia-law.ts"],"names":[],"mappings":"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"}
|