@chartcoach/catalog 0.1.6 → 0.2.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/LICENSE +201 -21
- package/README.md +324 -38
- package/dist/duckdb-wasm.d.ts +8 -0
- package/dist/duckdb-wasm.js +22 -0
- package/dist/duckdb.d.ts +8 -0
- package/dist/duckdb.js +9 -0
- package/dist/index-cache-Cx1gIK6N.js +280 -0
- package/dist/index.d.ts +40 -8
- package/dist/index.js +22 -7
- package/dist/json-CBWjz9b4.js +29 -0
- package/dist/model-De0MF-zg.d.ts +255 -0
- package/dist/node.d.ts +15 -0
- package/dist/node.js +218 -0
- package/dist/open-Nnzkr_bE.d.ts +15 -0
- package/dist/open-Uu3-r8kp.js +1244 -0
- package/dist/registration-CgQGMUIH.d.ts +6 -0
- package/dist/registration-DXhS7vgr.js +41 -0
- package/dist/tables-DcgKnXwF.js +389 -0
- package/package.json +48 -19
- package/src/catalog/artifacts.ts +309 -100
- package/src/catalog/description.ts +198 -0
- package/src/catalog/errors.ts +26 -1
- package/src/catalog/identity.ts +69 -0
- package/src/catalog/json.ts +32 -0
- package/src/catalog/labels.ts +8 -6
- package/src/catalog/manifest.ts +81 -20
- package/src/catalog/markdown.ts +2 -2
- package/src/catalog/model.ts +222 -37
- package/src/catalog/open.ts +428 -0
- package/src/catalog/parquet.ts +164 -0
- package/src/catalog/profile-layout.ts +86 -0
- package/src/catalog/profile.ts +345 -0
- package/src/catalog/query.ts +125 -0
- package/src/catalog/read.ts +101 -0
- package/src/catalog/references.ts +336 -0
- package/src/catalog/registration.ts +74 -0
- package/src/catalog/tables.ts +250 -0
- package/src/catalog/wire.ts +38 -65
- package/src/duckdb-wasm.ts +33 -0
- package/src/duckdb.ts +18 -0
- package/src/index.ts +51 -20
- package/src/node/index-cache.ts +432 -0
- package/src/node.ts +347 -0
- package/dist/catalog/artifacts.d.ts +0 -28
- package/dist/catalog/artifacts.d.ts.map +0 -1
- package/dist/catalog/artifacts.js +0 -89
- package/dist/catalog/chartcoach-defaults.d.ts +0 -17
- package/dist/catalog/chartcoach-defaults.d.ts.map +0 -1
- package/dist/catalog/chartcoach-defaults.js +0 -8
- package/dist/catalog/errors.d.ts +0 -4
- package/dist/catalog/errors.d.ts.map +0 -1
- package/dist/catalog/errors.js +0 -6
- package/dist/catalog/labels.d.ts +0 -9
- package/dist/catalog/labels.d.ts.map +0 -1
- package/dist/catalog/labels.js +0 -23
- package/dist/catalog/load-parquet-core.d.ts +0 -15
- package/dist/catalog/load-parquet-core.d.ts.map +0 -1
- package/dist/catalog/load-parquet-core.js +0 -45
- package/dist/catalog/manifest.d.ts +0 -15
- package/dist/catalog/manifest.d.ts.map +0 -1
- package/dist/catalog/manifest.js +0 -143
- package/dist/catalog/markdown.d.ts +0 -3
- package/dist/catalog/markdown.d.ts.map +0 -1
- package/dist/catalog/markdown.js +0 -13
- package/dist/catalog/model.d.ts +0 -33
- package/dist/catalog/model.d.ts.map +0 -1
- package/dist/catalog/model.js +0 -67
- package/dist/catalog/wire.d.ts +0 -18
- package/dist/catalog/wire.d.ts.map +0 -1
- package/dist/catalog/wire.js +0 -78
- package/dist/index.d.ts.map +0 -1
- package/src/catalog/chartcoach-defaults.ts +0 -17
- package/src/catalog/load-parquet-core.ts +0 -78
package/dist/catalog/manifest.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { CatalogError } from "./errors.js";
|
|
2
|
-
import { parseLabel } from "./labels.js";
|
|
3
|
-
export const REQUIRED_MANIFEST_HEADINGS = ["Section Roles", "Label Families"];
|
|
4
|
-
const headingPattern = /^(#{1,6})[ \t]+(.+?)[ \t]*#*[ \t]*$/;
|
|
5
|
-
const codeSpanPattern = /`([^`\n]+)`/g;
|
|
6
|
-
export function parseCatalogManifest(markdown) {
|
|
7
|
-
const requiredSeen = new Set();
|
|
8
|
-
const definitions = {
|
|
9
|
-
"Section Roles": {},
|
|
10
|
-
"Label Families": {},
|
|
11
|
-
};
|
|
12
|
-
let currentHeading;
|
|
13
|
-
let currentName;
|
|
14
|
-
let currentLines = [];
|
|
15
|
-
function flushDefinition() {
|
|
16
|
-
if (currentHeading !== "Section Roles" && currentHeading !== "Label Families") {
|
|
17
|
-
currentLines = [];
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (currentName === undefined) {
|
|
21
|
-
currentLines = [];
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
const description = currentLines.join("\n").trim();
|
|
25
|
-
if (!description) {
|
|
26
|
-
throw new CatalogError(`Manifest definition ${currentHeading}/${currentName} must include prose.`);
|
|
27
|
-
}
|
|
28
|
-
definitions[currentHeading][currentName] = {
|
|
29
|
-
name: currentName,
|
|
30
|
-
description,
|
|
31
|
-
examples: Array.from(description.matchAll(codeSpanPattern), (match) => match[1] ?? ""),
|
|
32
|
-
};
|
|
33
|
-
currentName = undefined;
|
|
34
|
-
currentLines = [];
|
|
35
|
-
}
|
|
36
|
-
for (const line of markdown.split("\n")) {
|
|
37
|
-
const match = headingPattern.exec(line);
|
|
38
|
-
if (!match) {
|
|
39
|
-
if (currentName !== undefined)
|
|
40
|
-
currentLines.push(line);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
const level = match[1].length;
|
|
44
|
-
const title = match[2].trim();
|
|
45
|
-
if (level === 2) {
|
|
46
|
-
flushDefinition();
|
|
47
|
-
currentHeading = title;
|
|
48
|
-
currentName = undefined;
|
|
49
|
-
currentLines = [];
|
|
50
|
-
if (title === "Section Roles" || title === "Label Families") {
|
|
51
|
-
requiredSeen.add(title);
|
|
52
|
-
}
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (level === 3 &&
|
|
56
|
-
(currentHeading === "Section Roles" || currentHeading === "Label Families")) {
|
|
57
|
-
flushDefinition();
|
|
58
|
-
if (!title) {
|
|
59
|
-
throw new CatalogError(`Manifest heading ${currentHeading} contains an empty subheading.`);
|
|
60
|
-
}
|
|
61
|
-
currentName = title;
|
|
62
|
-
currentLines = [];
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (currentName !== undefined)
|
|
66
|
-
currentLines.push(line);
|
|
67
|
-
}
|
|
68
|
-
flushDefinition();
|
|
69
|
-
const missing = REQUIRED_MANIFEST_HEADINGS.filter((heading) => !requiredSeen.has(heading));
|
|
70
|
-
if (missing.length > 0) {
|
|
71
|
-
throw new CatalogError(`MANIFEST.md is missing required heading(s): ${missing.join(", ")}.`);
|
|
72
|
-
}
|
|
73
|
-
for (const heading of REQUIRED_MANIFEST_HEADINGS) {
|
|
74
|
-
if (Object.keys(definitions[heading]).length === 0) {
|
|
75
|
-
throw new CatalogError(`Manifest heading ${heading} must define entries.`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
validateLabelFamilyExamples(Object.values(definitions["Label Families"]));
|
|
79
|
-
return {
|
|
80
|
-
markdown: markdown.endsWith("\n") ? markdown : `${markdown}\n`,
|
|
81
|
-
sectionRoles: definitions["Section Roles"],
|
|
82
|
-
labelFamilies: definitions["Label Families"],
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
export function validateManifestCoverage(guidelines, manifest) {
|
|
86
|
-
const usedRoles = new Set();
|
|
87
|
-
const usedFamilies = new Set();
|
|
88
|
-
for (const guideline of guidelines) {
|
|
89
|
-
for (const section of guideline.sections) {
|
|
90
|
-
const role = section.role.trim();
|
|
91
|
-
if (!role) {
|
|
92
|
-
throw new CatalogError("Section role values must not be empty.");
|
|
93
|
-
}
|
|
94
|
-
usedRoles.add(role);
|
|
95
|
-
}
|
|
96
|
-
for (const label of guideline.labels) {
|
|
97
|
-
usedFamilies.add(parseLabel(label, `label ${JSON.stringify(label)}`).family);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
const missingRoles = Array.from(usedRoles)
|
|
101
|
-
.filter((role) => manifest.sectionRoles[role] === undefined)
|
|
102
|
-
.sort();
|
|
103
|
-
const missingFamilies = Array.from(usedFamilies)
|
|
104
|
-
.filter((family) => manifest.labelFamilies[family] === undefined)
|
|
105
|
-
.sort();
|
|
106
|
-
const errors = [];
|
|
107
|
-
if (missingRoles.length > 0) {
|
|
108
|
-
errors.push(`undefined section role(s): ${missingRoles.join(", ")}`);
|
|
109
|
-
}
|
|
110
|
-
if (missingFamilies.length > 0) {
|
|
111
|
-
errors.push(`undefined label family/families: ${missingFamilies.join(", ")}`);
|
|
112
|
-
}
|
|
113
|
-
if (errors.length > 0) {
|
|
114
|
-
throw new CatalogError(`Catalog manifest validation failed: ${errors.join("; ")}.`);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
function validateLabelFamilyExamples(definitions) {
|
|
118
|
-
for (const definition of definitions) {
|
|
119
|
-
const familyExamples = [];
|
|
120
|
-
const invalidExamples = [];
|
|
121
|
-
for (const example of definition.examples) {
|
|
122
|
-
let parsed;
|
|
123
|
-
try {
|
|
124
|
-
parsed = parseLabel(example, `manifest label example ${JSON.stringify(example)}`);
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
if (parsed.family === definition.name) {
|
|
130
|
-
familyExamples.push(parsed.value);
|
|
131
|
-
}
|
|
132
|
-
else if (example.includes(":")) {
|
|
133
|
-
invalidExamples.push(example);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (invalidExamples.length > 0) {
|
|
137
|
-
throw new CatalogError(`Label family ${definition.name} has example(s) from another family: ${invalidExamples.join(", ")}.`);
|
|
138
|
-
}
|
|
139
|
-
if (familyExamples.length === 0) {
|
|
140
|
-
throw new CatalogError(`Label family ${definition.name} must include at least one label example.`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/catalog/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,wBAAgB,UAAU,CACxB,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,GAAG,cAAc,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC,GAC9F,MAAM,CAYR"}
|
package/dist/catalog/markdown.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { stringify as stringifyYaml } from "yaml";
|
|
2
|
-
export function toMarkdown(guideline) {
|
|
3
|
-
const frontmatter = {
|
|
4
|
-
id: guideline.id,
|
|
5
|
-
title: guideline.title,
|
|
6
|
-
...(guideline.bibliography ? { bibliography: guideline.bibliography } : {}),
|
|
7
|
-
description: guideline.description,
|
|
8
|
-
labels: [...guideline.labels],
|
|
9
|
-
};
|
|
10
|
-
const frontmatterYaml = stringifyYaml(frontmatter, { sortMapEntries: false }).trim();
|
|
11
|
-
const body = guideline.body.trim();
|
|
12
|
-
return ["---", frontmatterYaml, "---", "", body, ""].join("\n");
|
|
13
|
-
}
|
package/dist/catalog/model.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { CatalogManifest } from "./manifest.js";
|
|
2
|
-
export type GuidelineSection = {
|
|
3
|
-
role: string;
|
|
4
|
-
title: string;
|
|
5
|
-
content: string;
|
|
6
|
-
};
|
|
7
|
-
export type Guideline = {
|
|
8
|
-
id: string;
|
|
9
|
-
title: string;
|
|
10
|
-
bibliography?: string;
|
|
11
|
-
description: string;
|
|
12
|
-
labels: readonly string[];
|
|
13
|
-
body: string;
|
|
14
|
-
sections: readonly GuidelineSection[];
|
|
15
|
-
references: readonly string[];
|
|
16
|
-
};
|
|
17
|
-
export type CatalogOptions = {
|
|
18
|
-
manifest?: CatalogManifest;
|
|
19
|
-
};
|
|
20
|
-
export declare class Catalog implements Iterable<Guideline> {
|
|
21
|
-
readonly guidelines: readonly Guideline[];
|
|
22
|
-
readonly manifest?: CatalogManifest;
|
|
23
|
-
private readonly byId;
|
|
24
|
-
constructor(guidelines?: Iterable<Guideline>, options?: CatalogOptions);
|
|
25
|
-
get length(): number;
|
|
26
|
-
get size(): number;
|
|
27
|
-
get(id: string): Guideline | undefined;
|
|
28
|
-
require(id: string): Guideline;
|
|
29
|
-
labels(): string[];
|
|
30
|
-
sectionRoles(): string[];
|
|
31
|
-
[Symbol.iterator](): Iterator<Guideline>;
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=model.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/catalog/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACtC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B,CAAC;AAEF,qBAAa,OAAQ,YAAW,QAAQ,CAAC,SAAS,CAAC;IACjD,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyB;gBAElC,UAAU,GAAE,QAAQ,CAAC,SAAS,CAAM,EAAE,OAAO,GAAE,cAAmB;IAkB9E,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAItC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS;IAQ9B,MAAM,IAAI,MAAM,EAAE;IAIlB,YAAY,IAAI,MAAM,EAAE;IAMxB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC;CAGzC"}
|
package/dist/catalog/model.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { CatalogError } from "./errors.js";
|
|
2
|
-
import { validateManifestCoverage } from "./manifest.js";
|
|
3
|
-
export class Catalog {
|
|
4
|
-
guidelines;
|
|
5
|
-
manifest;
|
|
6
|
-
byId;
|
|
7
|
-
constructor(guidelines = [], options = {}) {
|
|
8
|
-
const records = Array.from(guidelines, copyGuideline);
|
|
9
|
-
const byId = new Map();
|
|
10
|
-
for (const guideline of records) {
|
|
11
|
-
if (byId.has(guideline.id)) {
|
|
12
|
-
throw new CatalogError(`Catalog contains duplicate guideline id: ${guideline.id}.`);
|
|
13
|
-
}
|
|
14
|
-
byId.set(guideline.id, guideline);
|
|
15
|
-
}
|
|
16
|
-
if (options.manifest) {
|
|
17
|
-
validateManifestCoverage(records, options.manifest);
|
|
18
|
-
}
|
|
19
|
-
this.guidelines = records;
|
|
20
|
-
this.manifest = options.manifest;
|
|
21
|
-
this.byId = byId;
|
|
22
|
-
}
|
|
23
|
-
get length() {
|
|
24
|
-
return this.guidelines.length;
|
|
25
|
-
}
|
|
26
|
-
get size() {
|
|
27
|
-
return this.guidelines.length;
|
|
28
|
-
}
|
|
29
|
-
get(id) {
|
|
30
|
-
return this.byId.get(id);
|
|
31
|
-
}
|
|
32
|
-
require(id) {
|
|
33
|
-
const guideline = this.get(id);
|
|
34
|
-
if (!guideline) {
|
|
35
|
-
throw new CatalogError(`Unknown guideline id: ${id}.`);
|
|
36
|
-
}
|
|
37
|
-
return guideline;
|
|
38
|
-
}
|
|
39
|
-
labels() {
|
|
40
|
-
return sortedUnique(this.guidelines.flatMap((guideline) => [...guideline.labels]));
|
|
41
|
-
}
|
|
42
|
-
sectionRoles() {
|
|
43
|
-
return sortedUnique(this.guidelines.flatMap((guideline) => guideline.sections.map((section) => section.role)));
|
|
44
|
-
}
|
|
45
|
-
[Symbol.iterator]() {
|
|
46
|
-
return this.guidelines[Symbol.iterator]();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function copyGuideline(guideline) {
|
|
50
|
-
return {
|
|
51
|
-
id: guideline.id,
|
|
52
|
-
title: guideline.title,
|
|
53
|
-
bibliography: guideline.bibliography,
|
|
54
|
-
description: guideline.description,
|
|
55
|
-
labels: [...guideline.labels],
|
|
56
|
-
body: guideline.body,
|
|
57
|
-
sections: guideline.sections.map((section) => ({
|
|
58
|
-
role: section.role,
|
|
59
|
-
title: section.title,
|
|
60
|
-
content: section.content,
|
|
61
|
-
})),
|
|
62
|
-
references: [...guideline.references],
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function sortedUnique(values) {
|
|
66
|
-
return Array.from(new Set(values)).sort();
|
|
67
|
-
}
|
package/dist/catalog/wire.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Guideline, GuidelineSection } from "./model.js";
|
|
2
|
-
export type CatalogRowWire = {
|
|
3
|
-
id: string;
|
|
4
|
-
guideline: {
|
|
5
|
-
id: string;
|
|
6
|
-
title: string;
|
|
7
|
-
bibliography?: string | null;
|
|
8
|
-
description: string;
|
|
9
|
-
labels: string[];
|
|
10
|
-
body: string;
|
|
11
|
-
sections: GuidelineSection[];
|
|
12
|
-
};
|
|
13
|
-
references: string[];
|
|
14
|
-
};
|
|
15
|
-
export declare function isCatalogRowWire(value: unknown): value is CatalogRowWire;
|
|
16
|
-
export declare function guidelineFromWire(value: unknown): Guideline | null;
|
|
17
|
-
export declare function requireGuidelineFromWire(value: unknown, context?: string): Guideline;
|
|
18
|
-
//# sourceMappingURL=wire.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../src/catalog/wire.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE;QACT,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,gBAAgB,EAAE,CAAC;KAC9B,CAAC;IACF,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAgCF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAYxE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAsBlE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAMpF"}
|
package/dist/catalog/wire.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { CatalogError } from "./errors.js";
|
|
2
|
-
import { normalizeLabel } from "./labels.js";
|
|
3
|
-
function isRecord(value) {
|
|
4
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
5
|
-
}
|
|
6
|
-
function isStringArray(value) {
|
|
7
|
-
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
8
|
-
}
|
|
9
|
-
function isGuidelineSection(value) {
|
|
10
|
-
return (isRecord(value) &&
|
|
11
|
-
typeof value.role === "string" &&
|
|
12
|
-
value.role.trim().length > 0 &&
|
|
13
|
-
typeof value.title === "string" &&
|
|
14
|
-
typeof value.content === "string");
|
|
15
|
-
}
|
|
16
|
-
function isSectionArray(value) {
|
|
17
|
-
return Array.isArray(value) && value.every(isGuidelineSection);
|
|
18
|
-
}
|
|
19
|
-
function sectionsFromWire(value) {
|
|
20
|
-
return value.map((section) => ({
|
|
21
|
-
role: section.role.trim(),
|
|
22
|
-
title: section.title,
|
|
23
|
-
content: section.content,
|
|
24
|
-
}));
|
|
25
|
-
}
|
|
26
|
-
export function isCatalogRowWire(value) {
|
|
27
|
-
if (!isRecord(value))
|
|
28
|
-
return false;
|
|
29
|
-
if (typeof value.id !== "string" || value.id.length === 0)
|
|
30
|
-
return false;
|
|
31
|
-
if (!isRecord(value.guideline))
|
|
32
|
-
return false;
|
|
33
|
-
if (value.guideline.id !== value.id)
|
|
34
|
-
return false;
|
|
35
|
-
if (typeof value.guideline.title !== "string")
|
|
36
|
-
return false;
|
|
37
|
-
if (typeof value.guideline.description !== "string")
|
|
38
|
-
return false;
|
|
39
|
-
if (typeof value.guideline.body !== "string")
|
|
40
|
-
return false;
|
|
41
|
-
if (!isStringArray(value.guideline.labels))
|
|
42
|
-
return false;
|
|
43
|
-
if (!isSectionArray(value.guideline.sections))
|
|
44
|
-
return false;
|
|
45
|
-
if (!isStringArray(value.references))
|
|
46
|
-
return false;
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
export function guidelineFromWire(value) {
|
|
50
|
-
if (!isCatalogRowWire(value))
|
|
51
|
-
return null;
|
|
52
|
-
const { guideline, references } = value;
|
|
53
|
-
const sections = sectionsFromWire(guideline.sections);
|
|
54
|
-
let labels;
|
|
55
|
-
try {
|
|
56
|
-
labels = guideline.labels.map((label) => normalizeLabel(label, "guideline label"));
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
return {
|
|
62
|
-
id: guideline.id,
|
|
63
|
-
title: guideline.title,
|
|
64
|
-
bibliography: typeof guideline.bibliography === "string" ? guideline.bibliography : undefined,
|
|
65
|
-
description: guideline.description,
|
|
66
|
-
labels,
|
|
67
|
-
body: guideline.body,
|
|
68
|
-
sections,
|
|
69
|
-
references: [...references],
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
export function requireGuidelineFromWire(value, context) {
|
|
73
|
-
const guideline = guidelineFromWire(value);
|
|
74
|
-
if (guideline)
|
|
75
|
-
return guideline;
|
|
76
|
-
const suffix = context ? ` (${context})` : "";
|
|
77
|
-
throw new CatalogError(`Invalid catalog row format${suffix}.`);
|
|
78
|
-
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,2BAA2B,EAC3B,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export type ChartCoachDefaults = {
|
|
2
|
-
catalogArtifactBaseUrl: string;
|
|
3
|
-
catalogDigest: string;
|
|
4
|
-
catalogVersion: string;
|
|
5
|
-
guidelineUrlTemplate: string;
|
|
6
|
-
indexTopK: number;
|
|
7
|
-
lanceDocumentTable: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const CHARTCOACH_DEFAULTS = {
|
|
11
|
-
catalogArtifactBaseUrl: "https://artifacts.chartcoach.dev",
|
|
12
|
-
catalogDigest: "7cfd43ee820be252b8ae9058c4c36109a9c8415c6b3a5ff8a9127117b4a10c19",
|
|
13
|
-
catalogVersion: "0.1.6",
|
|
14
|
-
guidelineUrlTemplate: "https://chartcoach.dev/guidelines/{id}",
|
|
15
|
-
indexTopK: 10,
|
|
16
|
-
lanceDocumentTable: "catalog_documents",
|
|
17
|
-
} as const satisfies ChartCoachDefaults;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { parquetReadObjects } from "hyparquet";
|
|
2
|
-
import { compressors } from "hyparquet-compressors";
|
|
3
|
-
import { Catalog, type Guideline } from "./model";
|
|
4
|
-
import { CatalogError } from "./errors";
|
|
5
|
-
import type { CatalogManifest } from "./manifest";
|
|
6
|
-
import { parseCatalogManifest } from "./manifest";
|
|
7
|
-
import { requireGuidelineFromWire } from "./wire";
|
|
8
|
-
|
|
9
|
-
export type AsyncBuffer = {
|
|
10
|
-
byteLength: number;
|
|
11
|
-
slice(start: number, end?: number): ArrayBuffer | Promise<ArrayBuffer>;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export type ParquetBytes = ArrayBuffer | ArrayBufferView;
|
|
15
|
-
export type CatalogBytes = ParquetBytes | AsyncBuffer;
|
|
16
|
-
export type LoadCatalogInput =
|
|
17
|
-
| CatalogBytes
|
|
18
|
-
| {
|
|
19
|
-
entries: CatalogBytes;
|
|
20
|
-
manifest?: CatalogManifest;
|
|
21
|
-
manifestText?: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function normalizeParquetBytes(bytes: ParquetBytes): ArrayBuffer {
|
|
25
|
-
if (bytes instanceof ArrayBuffer) return bytes;
|
|
26
|
-
|
|
27
|
-
// TypedArray/DataView may be a view into a larger ArrayBuffer (or SharedArrayBuffer).
|
|
28
|
-
// Copy to a standalone ArrayBuffer covering exactly the view range.
|
|
29
|
-
const u8 = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
30
|
-
return u8.slice().buffer;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function loadCatalog(input: LoadCatalogInput): Promise<Catalog> {
|
|
34
|
-
const { entries, manifest } = resolveLoadCatalogInput(input);
|
|
35
|
-
const normalizedFile =
|
|
36
|
-
entries instanceof ArrayBuffer || ArrayBuffer.isView(entries)
|
|
37
|
-
? normalizeParquetBytes(entries as ParquetBytes)
|
|
38
|
-
: entries;
|
|
39
|
-
|
|
40
|
-
const rows = (await parquetReadObjects({
|
|
41
|
-
file: normalizedFile,
|
|
42
|
-
compressors,
|
|
43
|
-
})) as Array<Record<string, unknown>>;
|
|
44
|
-
|
|
45
|
-
const guidelines: Guideline[] = rows.map((row, index) =>
|
|
46
|
-
requireGuidelineFromWire(row, `parquet row ${index}`),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
return new Catalog(guidelines, { manifest });
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function resolveLoadCatalogInput(input: LoadCatalogInput): {
|
|
53
|
-
entries: CatalogBytes;
|
|
54
|
-
manifest?: CatalogManifest;
|
|
55
|
-
} {
|
|
56
|
-
if (isCatalogBytes(input)) return { entries: input };
|
|
57
|
-
|
|
58
|
-
if (input.manifest && input.manifestText !== undefined) {
|
|
59
|
-
throw new CatalogError("Pass manifest or manifestText, not both.");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
entries: input.entries,
|
|
64
|
-
manifest:
|
|
65
|
-
input.manifestText === undefined ? input.manifest : parseCatalogManifest(input.manifestText),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function isCatalogBytes(value: LoadCatalogInput): value is CatalogBytes {
|
|
70
|
-
return (
|
|
71
|
-
value instanceof ArrayBuffer ||
|
|
72
|
-
ArrayBuffer.isView(value) ||
|
|
73
|
-
(typeof value === "object" &&
|
|
74
|
-
value !== null &&
|
|
75
|
-
typeof (value as AsyncBuffer).byteLength === "number" &&
|
|
76
|
-
typeof (value as AsyncBuffer).slice === "function")
|
|
77
|
-
);
|
|
78
|
-
}
|