@cyanheads/eur-lex-mcp-server 0.3.0 → 0.4.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/AGENTS.md +2 -2
- package/CLAUDE.md +2 -2
- package/README.md +4 -4
- package/changelog/0.4.x/0.4.0.md +20 -0
- package/changelog/0.4.x/0.4.1.md +14 -0
- package/dist/mcp-server/resources/definitions/eurlex-document-relations.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/eurlex-document-relations.resource.js +17 -51
- package/dist/mcp-server/resources/definitions/eurlex-document-relations.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/eurlex-document.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/eurlex-document.resource.js +3 -3
- package/dist/mcp-server/resources/definitions/eurlex-document.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.js +12 -7
- package/dist/mcp-server/tools/definitions/eurlex-get-document.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-relations.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-get-relations.tool.js +19 -76
- package/dist/mcp-server/tools/definitions/eurlex-get-relations.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-lookup-celex.tool.d.ts +0 -5
- package/dist/mcp-server/tools/definitions/eurlex-lookup-celex.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-lookup-celex.tool.js +6 -10
- package/dist/mcp-server/tools/definitions/eurlex-lookup-celex.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-query-sparql.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurlex-query-sparql.tool.js +5 -3
- package/dist/mcp-server/tools/definitions/eurlex-query-sparql.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +1 -5
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/services/cellar-sparql/cellar-sparql-service.d.ts +25 -2
- package/dist/services/cellar-sparql/cellar-sparql-service.d.ts.map +1 -1
- package/dist/services/cellar-sparql/cellar-sparql-service.js +34 -5
- package/dist/services/cellar-sparql/cellar-sparql-service.js.map +1 -1
- package/dist/services/cellar-sparql/relation-traversal.d.ts +28 -0
- package/dist/services/cellar-sparql/relation-traversal.d.ts.map +1 -0
- package/dist/services/cellar-sparql/relation-traversal.js +103 -0
- package/dist/services/cellar-sparql/relation-traversal.js.map +1 -0
- package/dist/services/eurlex-content/eurlex-content-service.d.ts +5 -1
- package/dist/services/eurlex-content/eurlex-content-service.d.ts.map +1 -1
- package/dist/services/eurlex-content/eurlex-content-service.js +15 -4
- package/dist/services/eurlex-content/eurlex-content-service.js.map +1 -1
- package/dist/services/eurlex-content/html-to-markdown.d.ts +29 -0
- package/dist/services/eurlex-content/html-to-markdown.d.ts.map +1 -0
- package/dist/services/eurlex-content/html-to-markdown.js +172 -0
- package/dist/services/eurlex-content/html-to-markdown.js.map +1 -0
- package/package.json +4 -2
- package/server.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurlex-lookup-celex.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurlex-lookup-celex.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,gBAAgB,GACjB,MAAM,4CAA4C,CAAC;AAGpD,8DAA8D;AAC9D,SAAS,OAAO,CAAC,UAAkB;IACjC,OAAO,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC;AAID,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,IAAI,OAAO,CAAC,UAAU,CAAC;QAAE,OAAO,OAAO,CAAC;IACxC,IAAI,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC,qBAAqB,EAAE;IAC7D,KAAK,EAAE,2BAA2B;IAClC,WAAW,EACT,8FAA8F;QAC9F,gIAAgI;QAChI,uGAAuG;QACvG,qEAAqE;QACrE,4FAA4F;IAC9F,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IAC9E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,CACP,2KAA2K,CAC5K;QACH,eAAe,EAAE,CAAC;aACf,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;aAC9B,OAAO,CAAC,MAAM,CAAC;aACf,QAAQ,CACP,0FAA0F;YACxF,8EAA8E,CACjF;KACJ,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,KAAK,EAAE,CAAC;aACL,OAAO,EAAE;aACT,QAAQ,CACP,
|
|
1
|
+
{"version":3,"file":"eurlex-lookup-celex.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurlex-lookup-celex.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurlex-query-sparql.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurlex-query-sparql.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAsCjE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"eurlex-query-sparql.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurlex-query-sparql.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAsCjE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;cA0I9B,CAAC"}
|
|
@@ -53,6 +53,7 @@ export const eurlex_query_sparql = tool('eurlex_query_sparql', {
|
|
|
53
53
|
'Key predicates: cdm:resource_legal_id_celex (CELEX number), cdm:work_date_document (date), ' +
|
|
54
54
|
'cdm:work_has_resource-type (document type), cdm:work_is_about_concept_eurovoc (EuroVoc subject), ' +
|
|
55
55
|
'cdm:work_cites_work (citation). ' +
|
|
56
|
+
'CELEX is stored as an xsd:string-typed literal, so match it with FILTER(STR(?celex) = "…"); a plain FILTER(?celex = "…") matches nothing. ' +
|
|
56
57
|
'For multi-word phrases, single-quote the term inside bif:contains (e.g. "\'data protection\'") to use the full-text index, or FILTER(CONTAINS(LCASE(?title), "keyword")) to scan.',
|
|
57
58
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
58
59
|
input: z.object({
|
|
@@ -111,10 +112,11 @@ export const eurlex_query_sparql = tool('eurlex_query_sparql', {
|
|
|
111
112
|
: 'Only read-only SELECT queries are accepted; no SELECT keyword was found.', { ...ctx.recoveryFor('not_read_only') });
|
|
112
113
|
}
|
|
113
114
|
const svc = getCellarSparqlService();
|
|
114
|
-
|
|
115
|
+
// queryWithVars exposes the projected SELECT variables (head.vars), so the
|
|
116
|
+
// result columns are reported even when no rows match — Object.keys on an
|
|
117
|
+
// empty bindings array would drop them.
|
|
118
|
+
const { variables, bindings } = await svc.queryWithVars(input.sparql_query, ctx, input.timeout_hint);
|
|
115
119
|
ctx.log.info('Raw SPARQL query executed', { resultCount: bindings.length });
|
|
116
|
-
// Extract variable names from first binding or return empty
|
|
117
|
-
const variables = bindings.length > 0 ? Object.keys(bindings[0]) : [];
|
|
118
120
|
return {
|
|
119
121
|
bindings,
|
|
120
122
|
variables,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurlex-query-sparql.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurlex-query-sparql.tool.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"eurlex-query-sparql.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurlex-query-sparql.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -71,6 +71,7 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
71
71
|
format: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
72
72
|
html: "html";
|
|
73
73
|
xml: "xml";
|
|
74
|
+
markdown: "markdown";
|
|
74
75
|
}>>;
|
|
75
76
|
content_mode: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
76
77
|
full: "full";
|
|
@@ -168,11 +169,6 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
168
169
|
resource_type: import("zod").ZodOptional<import("zod").ZodString>;
|
|
169
170
|
date: import("zod").ZodOptional<import("zod").ZodString>;
|
|
170
171
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
171
|
-
readonly reason: "not_found";
|
|
172
|
-
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
173
|
-
readonly when: "The identifier resolves to no CELLAR work — check the CELEX/ELI format and try again.";
|
|
174
|
-
readonly recovery: "Verify the CELEX or ELI format, or try eurlex_search_documents to find the work by keyword.";
|
|
175
|
-
}, {
|
|
176
172
|
readonly reason: "ambiguous_identifier";
|
|
177
173
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
178
174
|
readonly when: "identifier_type is \"auto\" and the identifier format could not be determined.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQ9B,CAAC"}
|
|
@@ -15,15 +15,38 @@ export declare class CellarSparqlService {
|
|
|
15
15
|
private readonly maxResults;
|
|
16
16
|
constructor(_config: AppConfig, _storage: StorageService, serverConfig: ServerConfig);
|
|
17
17
|
/**
|
|
18
|
-
* Execute a raw SPARQL SELECT query. Prefixes are
|
|
19
|
-
* if not already present. LIMIT is injected/capped at
|
|
18
|
+
* Execute a raw SPARQL SELECT query and return its binding rows. Prefixes are
|
|
19
|
+
* prepended automatically if not already present. LIMIT is injected/capped at
|
|
20
|
+
* `maxResults`.
|
|
20
21
|
*
|
|
21
22
|
* @param timeoutMs - Optional per-call client-side timeout in milliseconds.
|
|
22
23
|
* Falls back to the server-configured `sparqlQueryTimeoutMs` when omitted.
|
|
23
24
|
*/
|
|
24
25
|
query(rawQuery: string, ctx: Context, timeoutMs?: number): Promise<SparqlBinding[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Execute a raw SPARQL SELECT query and return the projected SELECT variables
|
|
28
|
+
* (`head.vars`) alongside the binding rows. Unlike deriving variable names
|
|
29
|
+
* from a binding's keys, the projection is reported even when the result set
|
|
30
|
+
* is empty — SPARQL 1.1 carries `head.vars` independent of binding count.
|
|
31
|
+
*/
|
|
32
|
+
queryWithVars(rawQuery: string, ctx: Context, timeoutMs?: number): Promise<{
|
|
33
|
+
variables: string[];
|
|
34
|
+
bindings: SparqlBinding[];
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* POST a SPARQL query to CELLAR and return the parsed SPARQL-results JSON
|
|
38
|
+
* envelope (`head` + `results`). Shared by `query` and `queryWithVars`.
|
|
39
|
+
*/
|
|
40
|
+
private execute;
|
|
25
41
|
/** Extract a string value from a binding field, returning undefined if absent. */
|
|
26
42
|
static bindingValue(binding: SparqlBinding | undefined, field: string): string | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Interpret a SPARQL `xsd:boolean` lexical value. Virtuoso serializes
|
|
45
|
+
* `xsd:boolean` as the lexicals `"1"` / `"0"` (not `"true"` / `"false"`) in
|
|
46
|
+
* SPARQL-JSON, so accept both forms. Returns `undefined` for an absent or
|
|
47
|
+
* unrecognized value rather than coercing it to a false negative.
|
|
48
|
+
*/
|
|
49
|
+
static parseBoolean(lexical: string | undefined): boolean | undefined;
|
|
27
50
|
}
|
|
28
51
|
export declare function initCellarSparqlService(config: AppConfig, storage: StorageService, serverConfig: ServerConfig): void;
|
|
29
52
|
export declare function getCellarSparqlService(): CellarSparqlService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cellar-sparql-service.d.ts","sourceRoot":"","sources":["../../../src/services/cellar-sparql/cellar-sparql-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AA8BnE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY;IAMpF
|
|
1
|
+
{"version":3,"file":"cellar-sparql-service.d.ts","sourceRoot":"","sources":["../../../src/services/cellar-sparql/cellar-sparql-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AA8BnE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY;IAMpF;;;;;;;OAOG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAIzF;;;;;OAKG;IACG,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,OAAO,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;IAK9D;;;OAGG;YACW,OAAO;IAyErB,kFAAkF;IAClF,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI1F;;;;;OAKG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS;CAKtE;AAMD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,YAAY,GACzB,IAAI,CAEN;AAED,wBAAgB,sBAAsB,IAAI,mBAAmB,CAO5D"}
|
|
@@ -41,13 +41,31 @@ export class CellarSparqlService {
|
|
|
41
41
|
this.maxResults = serverConfig.maxSparqlResults;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Execute a raw SPARQL SELECT query. Prefixes are
|
|
45
|
-
* if not already present. LIMIT is injected/capped at
|
|
44
|
+
* Execute a raw SPARQL SELECT query and return its binding rows. Prefixes are
|
|
45
|
+
* prepended automatically if not already present. LIMIT is injected/capped at
|
|
46
|
+
* `maxResults`.
|
|
46
47
|
*
|
|
47
48
|
* @param timeoutMs - Optional per-call client-side timeout in milliseconds.
|
|
48
49
|
* Falls back to the server-configured `sparqlQueryTimeoutMs` when omitted.
|
|
49
50
|
*/
|
|
50
51
|
async query(rawQuery, ctx, timeoutMs) {
|
|
52
|
+
return (await this.execute(rawQuery, ctx, timeoutMs)).results.bindings;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute a raw SPARQL SELECT query and return the projected SELECT variables
|
|
56
|
+
* (`head.vars`) alongside the binding rows. Unlike deriving variable names
|
|
57
|
+
* from a binding's keys, the projection is reported even when the result set
|
|
58
|
+
* is empty — SPARQL 1.1 carries `head.vars` independent of binding count.
|
|
59
|
+
*/
|
|
60
|
+
async queryWithVars(rawQuery, ctx, timeoutMs) {
|
|
61
|
+
const parsed = await this.execute(rawQuery, ctx, timeoutMs);
|
|
62
|
+
return { variables: parsed.head?.vars ?? [], bindings: parsed.results.bindings };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* POST a SPARQL query to CELLAR and return the parsed SPARQL-results JSON
|
|
66
|
+
* envelope (`head` + `results`). Shared by `query` and `queryWithVars`.
|
|
67
|
+
*/
|
|
68
|
+
async execute(rawQuery, ctx, timeoutMs) {
|
|
51
69
|
const effectiveTimeoutMs = timeoutMs ?? this.timeoutMs;
|
|
52
70
|
const withPrefixes = rawQuery.includes('PREFIX cdm:') ? rawQuery : SPARQL_PREFIXES + rawQuery;
|
|
53
71
|
const cappedQuery = enforceLimitInQuery(withPrefixes, this.maxResults);
|
|
@@ -91,9 +109,8 @@ export class CellarSparqlService {
|
|
|
91
109
|
retryable: false,
|
|
92
110
|
});
|
|
93
111
|
}
|
|
94
|
-
let parsed;
|
|
95
112
|
try {
|
|
96
|
-
|
|
113
|
+
return JSON.parse(text);
|
|
97
114
|
}
|
|
98
115
|
catch {
|
|
99
116
|
if (/^\s*<(!DOCTYPE\s+html|html[\s>])/i.test(text)) {
|
|
@@ -101,7 +118,6 @@ export class CellarSparqlService {
|
|
|
101
118
|
}
|
|
102
119
|
throw serviceUnavailable('Failed to parse CELLAR SPARQL response as JSON');
|
|
103
120
|
}
|
|
104
|
-
return parsed.results.bindings;
|
|
105
121
|
}, {
|
|
106
122
|
operation: 'CellarSparqlService.query',
|
|
107
123
|
baseDelayMs: 1500,
|
|
@@ -112,6 +128,19 @@ export class CellarSparqlService {
|
|
|
112
128
|
static bindingValue(binding, field) {
|
|
113
129
|
return binding?.[field]?.value;
|
|
114
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Interpret a SPARQL `xsd:boolean` lexical value. Virtuoso serializes
|
|
133
|
+
* `xsd:boolean` as the lexicals `"1"` / `"0"` (not `"true"` / `"false"`) in
|
|
134
|
+
* SPARQL-JSON, so accept both forms. Returns `undefined` for an absent or
|
|
135
|
+
* unrecognized value rather than coercing it to a false negative.
|
|
136
|
+
*/
|
|
137
|
+
static parseBoolean(lexical) {
|
|
138
|
+
if (lexical === 'true' || lexical === '1')
|
|
139
|
+
return true;
|
|
140
|
+
if (lexical === 'false' || lexical === '0')
|
|
141
|
+
return false;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
115
144
|
}
|
|
116
145
|
// --- Init/accessor pattern ---
|
|
117
146
|
let _service;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cellar-sparql-service.js","sourceRoot":"","sources":["../../../src/services/cellar-sparql/cellar-sparql-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEpF,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAIzD,oEAAoE;AACpE,MAAM,eAAe,GAAG;;;CAGvB,CAAC;AAEF,qFAAqF;AACrF,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AACpD,qDAAqD;AACrD,MAAM,mBAAmB,GAAG,kCAAkC,CAAC;AAE/D;;;GAGG;AACH,SAAS,mBAAmB,CAAC,KAAa,EAAE,GAAW;IACrD,MAAM,OAAO,GAAG,kBAAkB,CAAC;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,EAAE,CAAC;IAC5C,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,QAAQ,GAAG,GAAG,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,GAAG,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,OAAO,mBAAmB;IACb,QAAQ,CAAS;IACjB,SAAS,CAAS;IAClB,UAAU,CAAS;IAEpC,YAAY,OAAkB,EAAE,QAAwB,EAAE,YAA0B;QAClF,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC,oBAAoB,CAAC;QAClD,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,oBAAoB,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,gBAAgB,CAAC;IAClD,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"cellar-sparql-service.js","sourceRoot":"","sources":["../../../src/services/cellar-sparql/cellar-sparql-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared CELLAR CDM relation traversal, used by the
|
|
3
|
+
* eurlex_get_relations tool and the eurlex://document/{celex}/relations
|
|
4
|
+
* resource. Owns the relation-type → CDM predicate + direction model so both
|
|
5
|
+
* surfaces resolve relations identically.
|
|
6
|
+
* @module services/cellar-sparql/relation-traversal
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
9
|
+
import { CellarSparqlService } from './cellar-sparql-service.js';
|
|
10
|
+
import type { WorkRelation } from './types.js';
|
|
11
|
+
/** The relation types this server exposes over the CDM graph. */
|
|
12
|
+
export declare const RELATION_TYPES: readonly ["cites", "amends", "amended_by", "legal_basis", "consolidated_version"];
|
|
13
|
+
export type RelationType = (typeof RELATION_TYPES)[number];
|
|
14
|
+
/**
|
|
15
|
+
* Default per-type result cap. Each relation type is queried independently with
|
|
16
|
+
* its own LIMIT so a high-volume type (e.g. `cites`) can't starve rarer types
|
|
17
|
+
* under a single shared cap. The service caps further if MAX_SPARQL_RESULTS is
|
|
18
|
+
* lower than this.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_PER_TYPE_LIMIT = 100;
|
|
21
|
+
/**
|
|
22
|
+
* Traverse the requested CDM relation types for a work — one query per type, run
|
|
23
|
+
* concurrently — and return de-duplicated relations tagged with their type and
|
|
24
|
+
* direction. Each type is resolved through its own query (and its own LIMIT) so
|
|
25
|
+
* the per-type caps are independent.
|
|
26
|
+
*/
|
|
27
|
+
export declare function traverseRelations(svc: Pick<CellarSparqlService, 'query'>, workUri: string, types: readonly RelationType[], ctx: Context, perTypeLimit?: number): Promise<WorkRelation[]>;
|
|
28
|
+
//# sourceMappingURL=relation-traversal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-traversal.d.ts","sourceRoot":"","sources":["../../../src/services/cellar-sparql/relation-traversal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,iEAAiE;AACjE,eAAO,MAAM,cAAc,mFAMjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAiC3D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AA6B1C;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,EACvC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,GAAG,EAAE,OAAO,EACZ,YAAY,GAAE,MAA+B,GAC5C,OAAO,CAAC,YAAY,EAAE,CAAC,CA6BzB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared CELLAR CDM relation traversal, used by the
|
|
3
|
+
* eurlex_get_relations tool and the eurlex://document/{celex}/relations
|
|
4
|
+
* resource. Owns the relation-type → CDM predicate + direction model so both
|
|
5
|
+
* surfaces resolve relations identically.
|
|
6
|
+
* @module services/cellar-sparql/relation-traversal
|
|
7
|
+
*/
|
|
8
|
+
import { CellarSparqlService } from './cellar-sparql-service.js';
|
|
9
|
+
/** The relation types this server exposes over the CDM graph. */
|
|
10
|
+
export const RELATION_TYPES = [
|
|
11
|
+
'cites',
|
|
12
|
+
'amends',
|
|
13
|
+
'amended_by',
|
|
14
|
+
'legal_basis',
|
|
15
|
+
'consolidated_version',
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Per-relation-type CDM traversal spec: the predicate to follow and the
|
|
19
|
+
* direction(s) relative to the source work.
|
|
20
|
+
*
|
|
21
|
+
* CELLAR models amendment and consolidation one-directionally, so two types are
|
|
22
|
+
* the INCOMING side of a predicate whose name reads the other way — the
|
|
23
|
+
* dedicated `…amended_by…` and `…has_consolidated_version…` predicates carry
|
|
24
|
+
* zero triples:
|
|
25
|
+
* - `amended_by` is the incoming side of `…amends…` (`?amender amends <work>`).
|
|
26
|
+
* - `consolidated_version` is the incoming side of
|
|
27
|
+
* `…act_consolidated_consolidates…` (the consolidated act points back to the
|
|
28
|
+
* base; there is no forward `…has_consolidated_version…` link).
|
|
29
|
+
*
|
|
30
|
+
* `amends` and `legal_basis` are outgoing-only — their incoming rows describe a
|
|
31
|
+
* different relation (what amends this / what is based on this) and belong under
|
|
32
|
+
* `amended_by` and another work's `legal_basis`, not here. `cites` is symmetric
|
|
33
|
+
* ("citation graph"), so both directions are surfaced and tagged via `?direction`.
|
|
34
|
+
*/
|
|
35
|
+
const RELATION_SPECS = {
|
|
36
|
+
cites: { predicate: 'cdm:work_cites_work', direction: 'both' },
|
|
37
|
+
amends: { predicate: 'cdm:resource_legal_amends_resource_legal', direction: 'outgoing' },
|
|
38
|
+
amended_by: { predicate: 'cdm:resource_legal_amends_resource_legal', direction: 'incoming' },
|
|
39
|
+
legal_basis: { predicate: 'cdm:resource_legal_based_on_resource_legal', direction: 'outgoing' },
|
|
40
|
+
consolidated_version: {
|
|
41
|
+
predicate: 'cdm:act_consolidated_consolidates_resource_legal',
|
|
42
|
+
direction: 'incoming',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Default per-type result cap. Each relation type is queried independently with
|
|
47
|
+
* its own LIMIT so a high-volume type (e.g. `cites`) can't starve rarer types
|
|
48
|
+
* under a single shared cap. The service caps further if MAX_SPARQL_RESULTS is
|
|
49
|
+
* lower than this.
|
|
50
|
+
*/
|
|
51
|
+
export const DEFAULT_PER_TYPE_LIMIT = 100;
|
|
52
|
+
/** Build a single-relation-type SPARQL query for the given predicate + direction. */
|
|
53
|
+
function buildRelationQuery(workUri, spec, limit) {
|
|
54
|
+
const outgoing = `{
|
|
55
|
+
<${workUri}> ${spec.predicate} ?relatedWork .
|
|
56
|
+
OPTIONAL { ?relatedWork cdm:resource_legal_id_celex ?relatedCelex . }
|
|
57
|
+
BIND("outgoing" AS ?direction)
|
|
58
|
+
}`;
|
|
59
|
+
const incoming = `{
|
|
60
|
+
?relatedWork ${spec.predicate} <${workUri}> .
|
|
61
|
+
OPTIONAL { ?relatedWork cdm:resource_legal_id_celex ?relatedCelex . }
|
|
62
|
+
BIND("incoming" AS ?direction)
|
|
63
|
+
}`;
|
|
64
|
+
const body = spec.direction === 'outgoing'
|
|
65
|
+
? outgoing
|
|
66
|
+
: spec.direction === 'incoming'
|
|
67
|
+
? incoming
|
|
68
|
+
: `${outgoing} UNION ${incoming}`;
|
|
69
|
+
return `SELECT ?relatedWork ?relatedCelex ?direction WHERE {
|
|
70
|
+
${body}
|
|
71
|
+
} LIMIT ${limit}`;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Traverse the requested CDM relation types for a work — one query per type, run
|
|
75
|
+
* concurrently — and return de-duplicated relations tagged with their type and
|
|
76
|
+
* direction. Each type is resolved through its own query (and its own LIMIT) so
|
|
77
|
+
* the per-type caps are independent.
|
|
78
|
+
*/
|
|
79
|
+
export async function traverseRelations(svc, workUri, types, ctx, perTypeLimit = DEFAULT_PER_TYPE_LIMIT) {
|
|
80
|
+
const perType = await Promise.all(types.map(async (type) => ({
|
|
81
|
+
type,
|
|
82
|
+
bindings: await svc.query(buildRelationQuery(workUri, RELATION_SPECS[type], perTypeLimit), ctx),
|
|
83
|
+
})));
|
|
84
|
+
const seen = new Set();
|
|
85
|
+
const relations = [];
|
|
86
|
+
for (const { type, bindings } of perType) {
|
|
87
|
+
for (const b of bindings) {
|
|
88
|
+
const relatedWorkUri = CellarSparqlService.bindingValue(b, 'relatedWork') ?? '';
|
|
89
|
+
const direction = CellarSparqlService.bindingValue(b, 'direction') === 'incoming' ? 'incoming' : 'outgoing';
|
|
90
|
+
const key = `${type}|${direction}|${relatedWorkUri}`;
|
|
91
|
+
if (seen.has(key))
|
|
92
|
+
continue;
|
|
93
|
+
seen.add(key);
|
|
94
|
+
const relation = { relationType: type, direction, relatedWorkUri };
|
|
95
|
+
const relatedCelex = CellarSparqlService.bindingValue(b, 'relatedCelex');
|
|
96
|
+
if (relatedCelex)
|
|
97
|
+
relation.relatedCelexNumber = relatedCelex;
|
|
98
|
+
relations.push(relation);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return relations;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=relation-traversal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-traversal.js","sourceRoot":"","sources":["../../../src/services/cellar-sparql/relation-traversal.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,7 +27,11 @@ import type { Context } from '@cyanheads/mcp-ts-core';
|
|
|
27
27
|
import type { AppConfig } from '@cyanheads/mcp-ts-core/config';
|
|
28
28
|
import type { StorageService } from '@cyanheads/mcp-ts-core/storage';
|
|
29
29
|
import type { ServerConfig } from '../../config/server-config.js';
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Output formats a caller can request. `markdown` is not served by EUR-Lex — it is
|
|
32
|
+
* rendered server-side from the HTML body (see {@link WireFormat}).
|
|
33
|
+
*/
|
|
34
|
+
export type ContentFormat = 'html' | 'xml' | 'markdown';
|
|
31
35
|
/** Language codes supported by EUR-Lex (24 official EU languages). */
|
|
32
36
|
export type EurLexLanguage = 'EN' | 'FR' | 'DE' | 'ES' | 'IT' | 'PL' | 'PT' | 'NL' | 'CS' | 'DA' | 'EL' | 'ET' | 'FI' | 'HU' | 'LT' | 'LV' | 'MT' | 'RO' | 'SK' | 'SL' | 'SV' | 'BG' | 'HR' | 'GA';
|
|
33
37
|
export interface FetchContentResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurlex-content-service.d.ts","sourceRoot":"","sources":["../../../src/services/eurlex-content/eurlex-content-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"eurlex-content-service.d.ts","sourceRoot":"","sources":["../../../src/services/eurlex-content/eurlex-content-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG9D;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;AAQxD,sEAAsE;AACtE,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,CAAC;AA0ET,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,cAAc,CAAC;IACzB,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY;IAKpF;;;OAGG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAI5C;;;;;;;OAOG;IACG,YAAY,CAChB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,kBAAkB,CAAC;IA2B9B;;;;;OAKG;YACW,gBAAgB;IAgC9B;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;CA+BrB;AAMD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,YAAY,GACzB,IAAI,CAEN;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAO9D"}
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
27
27
|
import { withRetry } from '@cyanheads/mcp-ts-core/utils';
|
|
28
|
+
import { htmlToMarkdown } from './html-to-markdown.js';
|
|
28
29
|
/**
|
|
29
30
|
* Map EUR-Lex two-letter language codes to the ISO 639-2/T (terminological,
|
|
30
31
|
* three-letter) codes CELLAR's content-negotiation resolver accepts in
|
|
@@ -66,6 +67,13 @@ const ACCEPT_BY_FORMAT = {
|
|
|
66
67
|
html: ['application/xhtml+xml', 'text/html'],
|
|
67
68
|
xml: ['application/xml;type=fmx4'],
|
|
68
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Render a fetched wire body into the requested output format. `html`/`xml` pass
|
|
72
|
+
* through verbatim; `markdown` is converted server-side from the HTML body.
|
|
73
|
+
*/
|
|
74
|
+
function renderContent(body, format) {
|
|
75
|
+
return format === 'markdown' ? htmlToMarkdown(body) : body;
|
|
76
|
+
}
|
|
69
77
|
/**
|
|
70
78
|
* AWS WAF bot-challenge signatures. `awswaf` matches the challenge.js host
|
|
71
79
|
* (`token.awswaf.com`), the cookie-domain list, and the `AwsWafIntegration`
|
|
@@ -104,16 +112,19 @@ export class EurLexContentService {
|
|
|
104
112
|
* stub — a challenge is never reported as available content.
|
|
105
113
|
*/
|
|
106
114
|
async fetchContent(celexNumber, language, format, ctx) {
|
|
107
|
-
|
|
115
|
+
// `markdown` is rendered from the HTML body, so it is fetched as HTML; the
|
|
116
|
+
// returned `format` still reports `markdown` and `renderContent` converts.
|
|
117
|
+
const wireFormat = format === 'markdown' ? 'html' : format;
|
|
118
|
+
const primary = await this.fetchForLanguage(celexNumber, language, wireFormat, ctx);
|
|
108
119
|
if (primary !== null) {
|
|
109
|
-
return { content: primary, language, format, contentAvailable: true };
|
|
120
|
+
return { content: renderContent(primary, format), language, format, contentAvailable: true };
|
|
110
121
|
}
|
|
111
122
|
// Language fallback: try English if primary language failed.
|
|
112
123
|
if (language !== 'EN') {
|
|
113
|
-
const fallback = await this.fetchForLanguage(celexNumber, 'EN',
|
|
124
|
+
const fallback = await this.fetchForLanguage(celexNumber, 'EN', wireFormat, ctx);
|
|
114
125
|
if (fallback !== null) {
|
|
115
126
|
return {
|
|
116
|
-
content: fallback,
|
|
127
|
+
content: renderContent(fallback, format),
|
|
117
128
|
language: 'EN',
|
|
118
129
|
format,
|
|
119
130
|
contentAvailable: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurlex-content-service.js","sourceRoot":"","sources":["../../../src/services/eurlex-content/eurlex-content-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"eurlex-content-service.js","sourceRoot":"","sources":["../../../src/services/eurlex-content/eurlex-content-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-side HTML→Markdown conversion for EU act bodies.
|
|
3
|
+
*
|
|
4
|
+
* EUR-Lex/CELLAR serves acts as CONVEX-generated XHTML in which the numbered
|
|
5
|
+
* structure — recitals, article paragraphs, lettered/roman points — is laid out
|
|
6
|
+
* in two-column tables: a narrow marker column (`(1)`, `(a)`, `1.1.`, `—`) beside
|
|
7
|
+
* a wide ~96% prose column. A naive HTML→Markdown pass turns each of these into an
|
|
8
|
+
* unreadable two-column GFM row (`| (1) | The protection of natural persons… |`).
|
|
9
|
+
*
|
|
10
|
+
* This module pre-processes the parsed DOM before conversion:
|
|
11
|
+
* - strips non-body chrome (`<head>`, inline `<style>`/`<script>`, the OJ
|
|
12
|
+
* masthead table, separators, dead intra-document fragment links);
|
|
13
|
+
* - flattens the numbering layout tables into inline-marked block text
|
|
14
|
+
* (`(1) The protection of natural persons…`), recursing innermost-first so
|
|
15
|
+
* nested points collapse cleanly;
|
|
16
|
+
* - preserves genuine data tables — CONVEX tags them `class="oj-table"` — so
|
|
17
|
+
* node-html-markdown renders them as real GFM tables.
|
|
18
|
+
*
|
|
19
|
+
* The conversion produces the full Markdown body; windowing/pagination is applied
|
|
20
|
+
* downstream by the caller (a paged window may land mid-structure — acceptable).
|
|
21
|
+
* @module services/eurlex-content/html-to-markdown
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Convert an EU act XHTML/HTML body to clean Markdown. Numbering layout tables
|
|
25
|
+
* become inline-marked text; genuine data tables become GFM tables; no raw HTML
|
|
26
|
+
* leaks through. Returns the full converted body.
|
|
27
|
+
*/
|
|
28
|
+
export declare function htmlToMarkdown(html: string): string;
|
|
29
|
+
//# sourceMappingURL=html-to-markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-to-markdown.d.ts","sourceRoot":"","sources":["../../../src/services/eurlex-content/html-to-markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA2BH;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnD"}
|