@nshiab/setup-data-project 2.0.1 → 2.0.3
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 +15 -7
- package/esm/helpers/combinePlotDocs.d.ts +2 -0
- package/esm/helpers/combinePlotDocs.d.ts.map +1 -0
- package/esm/helpers/combinePlotDocs.js +111 -0
- package/esm/helpers/ensureAgents.d.ts.map +1 -1
- package/esm/helpers/ensureAgents.js +11 -1
- package/esm/helpers/fetchPackageDocs.d.ts +4 -0
- package/esm/helpers/fetchPackageDocs.d.ts.map +1 -1
- package/esm/helpers/fetchPlotDocs.d.ts +5 -0
- package/esm/helpers/fetchPlotDocs.d.ts.map +1 -0
- package/esm/helpers/fetchPlotDocs.js +103 -0
- package/esm/helpers/getInstalledPackageVersions.d.ts.map +1 -1
- package/esm/helpers/getInstalledPackageVersions.js +8 -5
- package/esm/helpers/installPackages.d.ts.map +1 -1
- package/esm/helpers/installPackages.js +1 -11
- package/esm/helpers/packageRegistry.d.ts +1 -0
- package/esm/helpers/packageRegistry.d.ts.map +1 -1
- package/esm/helpers/packageRegistry.js +12 -7
- package/esm/helpers/parseArguments.d.ts +7 -0
- package/esm/helpers/parseArguments.d.ts.map +1 -0
- package/esm/helpers/parseArguments.js +30 -0
- package/esm/helpers/plotDocPages.d.ts +2 -0
- package/esm/helpers/plotDocPages.d.ts.map +1 -0
- package/esm/helpers/plotDocPages.js +46 -0
- package/esm/helpers/syncPackageDocs.d.ts.map +1 -1
- package/esm/helpers/syncPackageDocs.js +9 -5
- package/esm/main.js +15 -5
- package/package.json +1 -1
- package/script/helpers/combinePlotDocs.d.ts +2 -0
- package/script/helpers/combinePlotDocs.d.ts.map +1 -0
- package/script/helpers/combinePlotDocs.js +114 -0
- package/script/helpers/ensureAgents.d.ts.map +1 -1
- package/script/helpers/ensureAgents.js +11 -1
- package/script/helpers/fetchPackageDocs.d.ts +4 -0
- package/script/helpers/fetchPackageDocs.d.ts.map +1 -1
- package/script/helpers/fetchPlotDocs.d.ts +5 -0
- package/script/helpers/fetchPlotDocs.d.ts.map +1 -0
- package/script/helpers/fetchPlotDocs.js +106 -0
- package/script/helpers/getInstalledPackageVersions.d.ts.map +1 -1
- package/script/helpers/getInstalledPackageVersions.js +8 -5
- package/script/helpers/installPackages.d.ts.map +1 -1
- package/script/helpers/installPackages.js +1 -11
- package/script/helpers/packageRegistry.d.ts +1 -0
- package/script/helpers/packageRegistry.d.ts.map +1 -1
- package/script/helpers/packageRegistry.js +13 -8
- package/script/helpers/parseArguments.d.ts +7 -0
- package/script/helpers/parseArguments.d.ts.map +1 -0
- package/script/helpers/parseArguments.js +34 -0
- package/script/helpers/plotDocPages.d.ts +2 -0
- package/script/helpers/plotDocPages.d.ts.map +1 -0
- package/script/helpers/plotDocPages.js +49 -0
- package/script/helpers/syncPackageDocs.d.ts.map +1 -1
- package/script/helpers/syncPackageDocs.js +8 -4
- package/script/main.js +15 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combinePlotDocs.d.ts","sourceRoot":"","sources":["../../src/helpers/combinePlotDocs.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CA4GR"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.combinePlotDocs = combinePlotDocs;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
// The Plot source uses ATX headings, explicit VitePress IDs, and Markdown fences.
|
|
6
|
+
// Keep code verbatim; rewrite only prose links and anchors while joining pages.
|
|
7
|
+
function combinePlotDocs(version, documents) {
|
|
8
|
+
const pages = [...documents.keys()].sort();
|
|
9
|
+
const source = `https://github.com/observablehq/plot/tree/v${version}/docs`;
|
|
10
|
+
const anchors = new Map();
|
|
11
|
+
const sections = new Map();
|
|
12
|
+
const pageId = (page) => `plot-${page.replace(/\.md$/, "").replaceAll("/", "--")}`;
|
|
13
|
+
for (const page of pages) {
|
|
14
|
+
const ids = new Map();
|
|
15
|
+
const headings = [];
|
|
16
|
+
const counts = new Map();
|
|
17
|
+
proseLines(documents.get(page), (line, number) => {
|
|
18
|
+
for (const match of line.matchAll(/\bid=["']([^"']+)["']/g)) {
|
|
19
|
+
ids.set(match[1], `${pageId(page)}--${match[1]}`);
|
|
20
|
+
}
|
|
21
|
+
const heading = line.match(/^ {0,3}#{1,6}\s+(.+?)\s*#*\s*$/);
|
|
22
|
+
if (!heading)
|
|
23
|
+
return line;
|
|
24
|
+
const explicit = heading[1].match(/\{#([^}]+)\}/)?.[1];
|
|
25
|
+
const title = heading[1].replace(/\s*\{#[^}]+\}/g, "");
|
|
26
|
+
const slug = explicit ?? title.replace(/<[^>]*>/g, "")
|
|
27
|
+
.toLowerCase().replace(/[^\p{L}\p{N}_\s-]/gu, "")
|
|
28
|
+
.trim().replace(/\s+/g, "-");
|
|
29
|
+
const count = counts.get(slug) ?? 0;
|
|
30
|
+
counts.set(slug, count + 1);
|
|
31
|
+
const localId = `${slug}${count ? `-${count}` : ""}`;
|
|
32
|
+
const id = `${pageId(page)}--${localId}`;
|
|
33
|
+
ids.set(localId, id);
|
|
34
|
+
headings.push({ line: number, title, id });
|
|
35
|
+
return line;
|
|
36
|
+
});
|
|
37
|
+
anchors.set(page, ids);
|
|
38
|
+
sections.set(page, headings);
|
|
39
|
+
}
|
|
40
|
+
function link(target, page) {
|
|
41
|
+
if (/^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(target))
|
|
42
|
+
return target;
|
|
43
|
+
const [pathAndQuery, fragment] = target.split("#", 2);
|
|
44
|
+
const path = pathAndQuery.split("?", 1)[0];
|
|
45
|
+
const resolved = path === "" ? page : node_path_1.posix.normalize(path.startsWith("/")
|
|
46
|
+
? path.slice(1)
|
|
47
|
+
: node_path_1.posix.join(node_path_1.posix.dirname(page), path));
|
|
48
|
+
const markdown = [resolved, `${resolved}.md`, `${resolved}/index.md`]
|
|
49
|
+
.find((candidate) => documents.has(candidate));
|
|
50
|
+
if (markdown) {
|
|
51
|
+
const id = fragment
|
|
52
|
+
? anchors.get(markdown)?.get(decodeURIComponent(fragment))
|
|
53
|
+
: pageId(markdown);
|
|
54
|
+
if (id)
|
|
55
|
+
return `#${id}`;
|
|
56
|
+
// Preserve an upstream target when a fragment is not a known heading/ID.
|
|
57
|
+
return `${source}/${markdown}${fragment ? `#${fragment}` : ""}`;
|
|
58
|
+
}
|
|
59
|
+
if (resolved.endsWith(".md")) {
|
|
60
|
+
return `${source}/${resolved}${fragment ? `#${fragment}` : ""}`;
|
|
61
|
+
}
|
|
62
|
+
const base = "https://raw.githubusercontent.com/observablehq/plot/" +
|
|
63
|
+
`refs/tags/v${version}/docs/`;
|
|
64
|
+
return path.startsWith("/")
|
|
65
|
+
? new URL(`public${target}`, base).href
|
|
66
|
+
: new URL(target, `${base}${page}`).href;
|
|
67
|
+
}
|
|
68
|
+
const contents = pages.flatMap((page) => [
|
|
69
|
+
`- [${page}](#${pageId(page)})`,
|
|
70
|
+
...(sections.get(page) ?? []).map(({ title, id }) => ` - [${title.replace(/[\[\]]/g, "")}](#${id})`),
|
|
71
|
+
]).join("\n");
|
|
72
|
+
const combined = pages.map((page) => {
|
|
73
|
+
const headings = new Map(sections.get(page).map((heading) => [heading.line, heading]));
|
|
74
|
+
const body = proseLines(documents.get(page), (line, number) => {
|
|
75
|
+
const heading = headings.get(number);
|
|
76
|
+
// Inline code also remains verbatim. Plot's prose links have simple destinations.
|
|
77
|
+
line = line.split(/(`+[^`]*`+)/g).map((part, index) => {
|
|
78
|
+
if (index % 2)
|
|
79
|
+
return part;
|
|
80
|
+
return part.replace(/(\]\()([^\s)]+)([^)]*\))/g, (_, before, target, after) => `${before}${link(target, page)}${after}`).replace(/^( {0,3}\[[^\]]+\]:\s*)(\S+)/, (_, before, target) => `${before}${link(target, page)}`).replace(/(?<!:)\b(href|src)=(["'])([^"']+)\2/g, (_, attr, quote, target) => `${attr}=${quote}${link(target, page)}${quote}`).replace(/\bid=(["'])([^"']+)\1/g, (_, quote, id) => `id=${quote}${anchors.get(page)?.get(id) ?? id}${quote}`);
|
|
81
|
+
}).join("");
|
|
82
|
+
return heading
|
|
83
|
+
? `<a id="${heading.id}"></a>\n\n${line.replace(/\s*\{#[^}]+\}/g, "")}`
|
|
84
|
+
: line;
|
|
85
|
+
});
|
|
86
|
+
return `<a id="${pageId(page)}"></a>\n\n# ${page}\n\nSource: ${source}/${page}\n\n${body}`;
|
|
87
|
+
}).join("\n\n---\n\n");
|
|
88
|
+
return `# Observable Plot ${version}\n\nPackage: \`@observablehq/plot@${version}\`. Source: [v${version}](${source}).\n\nThis reference combines selected upstream documentation for static charts and maps. Introductory and site pages, interaction helpers, and the Auto and Tip marks are omitted. Vue components and plot fences are retained as source examples. Use the table of contents to find API signatures and examples; links to omitted pages lead to the tagged upstream documentation.\n\n## Table of contents\n\n${contents}\n\n---\n\n${combined}\n\n<!-- setup-data-project:observable-plot:${version}:complete -->\n`;
|
|
89
|
+
}
|
|
90
|
+
function proseLines(content, transform) {
|
|
91
|
+
let fence;
|
|
92
|
+
let script = false;
|
|
93
|
+
return content.split("\n").map((line, number) => {
|
|
94
|
+
const marker = line.match(/^ {0,3}(`{3,}|~{3,})/);
|
|
95
|
+
if (fence) {
|
|
96
|
+
if (marker?.[1][0] === fence.character &&
|
|
97
|
+
marker[1].length >= fence.length && /^ {0,3}(?:`+|~+)\s*$/.test(line))
|
|
98
|
+
fence = undefined;
|
|
99
|
+
return line;
|
|
100
|
+
}
|
|
101
|
+
if (marker) {
|
|
102
|
+
fence = { character: marker[1][0], length: marker[1].length };
|
|
103
|
+
return line;
|
|
104
|
+
}
|
|
105
|
+
if (/^\s*<script\b/.test(line))
|
|
106
|
+
script = true;
|
|
107
|
+
if (script) {
|
|
108
|
+
if (/<\/script>/.test(line))
|
|
109
|
+
script = false;
|
|
110
|
+
return line;
|
|
111
|
+
}
|
|
112
|
+
return transform(line, number);
|
|
113
|
+
}).join("\n");
|
|
114
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensureAgents.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureAgents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOzD,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACxC,OAAO,EAAE,MAAM,EACf,iBAAiB,GAAE,MAAM,EAA6B,
|
|
1
|
+
{"version":3,"file":"ensureAgents.d.ts","sourceRoot":"","sources":["../../src/helpers/ensureAgents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOzD,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACxC,OAAO,EAAE,MAAM,EACf,iBAAiB,GAAE,MAAM,EAA6B,QA+LvD"}
|
|
@@ -103,6 +103,14 @@ Always prioritize the installed ${libraryNames} ${libraryNoun} when relevant.
|
|
|
103
103
|
const docs = docsMapping[pkg.value];
|
|
104
104
|
if (!docs)
|
|
105
105
|
return [];
|
|
106
|
+
if (docs.plot) {
|
|
107
|
+
return [
|
|
108
|
+
"- `@observablehq/plot`: use Observable Plot to create charts and maps " +
|
|
109
|
+
"with `writeChart` and `writeMap`. Import with " +
|
|
110
|
+
'`import { plot } from "@observablehq/plot";`. ' +
|
|
111
|
+
"Documentation and examples at `./docs/observable-plot/llm.md`",
|
|
112
|
+
];
|
|
113
|
+
}
|
|
106
114
|
const repoName = pkg.value.split("/")[1];
|
|
107
115
|
const availableDocs = [
|
|
108
116
|
docs.readme === undefined
|
|
@@ -118,13 +126,15 @@ Always prioritize the installed ${libraryNames} ${libraryNoun} when relevant.
|
|
|
118
126
|
});
|
|
119
127
|
if (documentationGuidance.length > 0) {
|
|
120
128
|
libraryGuidance += `
|
|
129
|
+
The \`docs/\` folder contains long, exhaustive library references. Search for the relevant methods or topics, then read only the matching sections and any related definitions or examples you need.
|
|
130
|
+
|
|
121
131
|
The following documentation was fetched for the exact installed library versions. Consult it when relevant:
|
|
122
132
|
|
|
123
133
|
${documentationGuidance.join("\n")}
|
|
124
134
|
`;
|
|
125
135
|
}
|
|
126
136
|
if (importExamples.length > 0) {
|
|
127
|
-
libraryGuidance += `APIs can be imported
|
|
137
|
+
libraryGuidance += `APIs can be imported like this:
|
|
128
138
|
\`\`\`typescript
|
|
129
139
|
${importExamples.join("\n")}
|
|
130
140
|
\`\`\`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchPackageDocs.d.ts","sourceRoot":"","sources":["../../src/helpers/fetchPackageDocs.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"fetchPackageDocs.d.ts","sourceRoot":"","sources":["../../src/helpers/fetchPackageDocs.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC7C;AAiBD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,WAAW,CAAC,CA4DtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchPlotDocs.d.ts","sourceRoot":"","sources":["../../src/helpers/fetchPlotDocs.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,OAAO,CAAC,WAAW,CAAC,CAsCtB"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchPlotDocs = fetchPlotDocs;
|
|
4
|
+
const prompts_1 = require("@clack/prompts");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const combinePlotDocs_js_1 = require("./combinePlotDocs.js");
|
|
8
|
+
const plotDocPages_js_1 = require("./plotDocPages.js");
|
|
9
|
+
// Publish one reference only after every tagged page has been fetched.
|
|
10
|
+
async function fetchPlotDocs(version, options = {}) {
|
|
11
|
+
const tag = `v${version}`;
|
|
12
|
+
const directory = (0, node_path_1.join)("docs", "observable-plot");
|
|
13
|
+
try {
|
|
14
|
+
let llm;
|
|
15
|
+
if (options.preferStored !== false) {
|
|
16
|
+
try {
|
|
17
|
+
const response = await fetch("https://raw.githubusercontent.com/nshiab/setup-data-project/" +
|
|
18
|
+
`refs/heads/main/docs-cache/observable-plot/${version}/llm.md`);
|
|
19
|
+
if (response.ok) {
|
|
20
|
+
const cached = await response.text();
|
|
21
|
+
if (isStoredReference(cached, version))
|
|
22
|
+
llm = cached;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// A cache is an optimization. An unavailable cache never blocks the tag.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (llm === undefined)
|
|
30
|
+
llm = await generateReference(version);
|
|
31
|
+
(0, node_fs_1.mkdirSync)(directory, { recursive: true });
|
|
32
|
+
const temporaryPath = (0, node_path_1.join)(directory, ".llm.md.tmp");
|
|
33
|
+
try {
|
|
34
|
+
(0, node_fs_1.writeFileSync)(temporaryPath, llm);
|
|
35
|
+
(0, node_fs_1.renameSync)(temporaryPath, (0, node_path_1.join)(directory, "llm.md"));
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
(0, node_fs_1.rmSync)(temporaryPath, { force: true });
|
|
39
|
+
}
|
|
40
|
+
return { llm, plot: { version, pages: [...plotDocPages_js_1.PLOT_DOC_PAGES] } };
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
prompts_1.log.warn(`Could not fetch complete Observable Plot documentation for ${tag}. ` +
|
|
44
|
+
"Existing files were preserved, but may not match the installed " +
|
|
45
|
+
"version. Plot documentation will not be included in AGENTS.md. " +
|
|
46
|
+
String(error));
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function generateReference(version) {
|
|
51
|
+
const tag = `v${version}`;
|
|
52
|
+
const pages = plotDocPages_js_1.PLOT_DOC_PAGES;
|
|
53
|
+
const documents = new Map();
|
|
54
|
+
const failed = [];
|
|
55
|
+
// Fetch in small batches to avoid overwhelming GitHub on the first run.
|
|
56
|
+
for (let offset = 0; offset < pages.length; offset += 8) {
|
|
57
|
+
await Promise.all(pages.slice(offset, offset + 8).map(async (page) => {
|
|
58
|
+
try {
|
|
59
|
+
const url = "https://raw.githubusercontent.com/observablehq/plot/" +
|
|
60
|
+
`refs/tags/${tag}/docs/${page}`;
|
|
61
|
+
const response = await fetch(url);
|
|
62
|
+
if (!response.ok)
|
|
63
|
+
throw new Error(`HTTP ${response.status}`);
|
|
64
|
+
const content = await response.text();
|
|
65
|
+
documents.set(page, content);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
failed.push(page);
|
|
69
|
+
}
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
if (failed.length > 0) {
|
|
73
|
+
throw new Error(`Could not fetch ${failed.length} Markdown pages`);
|
|
74
|
+
}
|
|
75
|
+
return (0, combinePlotDocs_js_1.combinePlotDocs)(version, documents);
|
|
76
|
+
}
|
|
77
|
+
function isStoredReference(content, version) {
|
|
78
|
+
const source = `https://github.com/observablehq/plot/tree/v${version}/docs`;
|
|
79
|
+
const metadata = content.split(/\n\s*\n/)[1]?.replace(/\s+/g, " ");
|
|
80
|
+
if (!content.startsWith(`# Observable Plot ${version}\n\n`) ||
|
|
81
|
+
metadata !==
|
|
82
|
+
`Package: \`@observablehq/plot@${version}\`. Source: [v${version}](${source}).` ||
|
|
83
|
+
!content.trimEnd().endsWith(`<!-- setup-data-project:observable-plot:${version}:complete -->`))
|
|
84
|
+
return false;
|
|
85
|
+
// Match actual page sections, not TOC entries. Require every selected page
|
|
86
|
+
// exactly once and some upstream heading/content after its source record.
|
|
87
|
+
const sections = [
|
|
88
|
+
...content.matchAll(/<a id="(plot-[^"]+)"><\/a>\n\n# ([^\n]+\.md)\n\nSource:\s+([^\s]+)\n\n/g),
|
|
89
|
+
];
|
|
90
|
+
if (sections.length !== plotDocPages_js_1.PLOT_DOC_PAGES.length)
|
|
91
|
+
return false;
|
|
92
|
+
const found = new Set();
|
|
93
|
+
for (let index = 0; index < sections.length; index++) {
|
|
94
|
+
const section = sections[index];
|
|
95
|
+
const page = section[2];
|
|
96
|
+
const id = `plot-${page.replace(/\.md$/, "").replaceAll("/", "--")}`;
|
|
97
|
+
if (!plotDocPages_js_1.PLOT_DOC_PAGES.includes(page) || found.has(page) || section[1] !== id ||
|
|
98
|
+
section[3] !== `${source}/${page}`)
|
|
99
|
+
return false;
|
|
100
|
+
const body = content.slice(section.index + section[0].length, sections[index + 1]?.index);
|
|
101
|
+
if (!/^#{1,6}\s+\S/m.test(body))
|
|
102
|
+
return false;
|
|
103
|
+
found.add(page);
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getInstalledPackageVersions.d.ts","sourceRoot":"","sources":["../../src/helpers/getInstalledPackageVersions.ts"],"names":[],"mappings":"AAKA,wBAAgB,2BAA2B,CACzC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"getInstalledPackageVersions.d.ts","sourceRoot":"","sources":["../../src/helpers/getInstalledPackageVersions.ts"],"names":[],"mappings":"AAKA,wBAAgB,2BAA2B,CACzC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0BxB"}
|
|
@@ -11,10 +11,12 @@ function getInstalledPackageVersions(packageSpecifiers) {
|
|
|
11
11
|
: undefined;
|
|
12
12
|
const versions = {};
|
|
13
13
|
for (const [pkg, specifier] of Object.entries(packageSpecifiers)) {
|
|
14
|
+
const denoVersion = specifier.startsWith("jsr:") || specifier.startsWith("npm:")
|
|
15
|
+
? getDenoLockVersion(pkg, specifier, denoLock)
|
|
16
|
+
: undefined;
|
|
14
17
|
const version = specifier.startsWith("jsr:")
|
|
15
|
-
?
|
|
16
|
-
|
|
17
|
-
: getNodeModulesVersion(pkg) ??
|
|
18
|
+
? denoVersion ?? getExactVersion(specifier)
|
|
19
|
+
: denoVersion ?? getNodeModulesVersion(pkg) ??
|
|
18
20
|
getPackageLockVersion(pkg, packageLock) ??
|
|
19
21
|
getBunLockVersion(pkg, bunLock) ??
|
|
20
22
|
getExactVersion(specifier);
|
|
@@ -31,7 +33,7 @@ function getNodeModulesVersion(pkg) {
|
|
|
31
33
|
: undefined;
|
|
32
34
|
}
|
|
33
35
|
function getDenoLockVersion(pkg, specifier, lock) {
|
|
34
|
-
if (!lock
|
|
36
|
+
if (!lock)
|
|
35
37
|
return undefined;
|
|
36
38
|
const specifiers = asObject(lock.specifiers);
|
|
37
39
|
if (!specifiers)
|
|
@@ -39,7 +41,8 @@ function getDenoLockVersion(pkg, specifier, lock) {
|
|
|
39
41
|
const directVersion = specifiers[specifier];
|
|
40
42
|
if (typeof directVersion === "string")
|
|
41
43
|
return getExactVersion(directVersion);
|
|
42
|
-
const
|
|
44
|
+
const protocol = specifier.startsWith("npm:") ? "npm" : "jsr";
|
|
45
|
+
const prefix = `${protocol}:${pkg}@`;
|
|
43
46
|
const matchingVersions = Object.entries(specifiers)
|
|
44
47
|
.filter(([key, value]) => key.startsWith(prefix) && typeof value === "string")
|
|
45
48
|
.flatMap(([, value]) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installPackages.d.ts","sourceRoot":"","sources":["../../src/helpers/installPackages.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa;;CAEzB,CAAC;
|
|
1
|
+
{"version":3,"file":"installPackages.d.ts","sourceRoot":"","sources":["../../src/helpers/installPackages.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAEF,wBAAsB,eAAe,CACnC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CA8Cf"}
|
|
@@ -41,12 +41,6 @@ const getRuntime_js_1 = require("./getRuntime.js");
|
|
|
41
41
|
exports.commandRunner = {
|
|
42
42
|
exec: childProcess.exec,
|
|
43
43
|
};
|
|
44
|
-
// Temporary: remove this bypass after the 2.0 release window.
|
|
45
|
-
// https://github.com/nshiab/setup-data-project/issues/15
|
|
46
|
-
const PACKAGES_WITH_FRESH_DENO_RELEASES = new Set([
|
|
47
|
-
"@nshiab/simple-data-analysis-core",
|
|
48
|
-
"@nshiab/simple-data-analysis",
|
|
49
|
-
]);
|
|
50
44
|
async function installPackages(selectedPackages, options = {}) {
|
|
51
45
|
const runtime = (0, getRuntime_js_1.getRuntime)();
|
|
52
46
|
for (const selectedPackage of selectedPackages) {
|
|
@@ -58,12 +52,8 @@ async function installPackages(selectedPackages, options = {}) {
|
|
|
58
52
|
for (const pkg of packagesToInstall) {
|
|
59
53
|
const s = (0, prompts_1.spinner)();
|
|
60
54
|
const isObservablePlot = pkg === "@observablehq/plot";
|
|
61
|
-
const minimumDependencyAgeOption = PACKAGES_WITH_FRESH_DENO_RELEASES.has(pkg) ? " --min-dep-age=0" : "";
|
|
62
55
|
const installCmd = runtime === "deno"
|
|
63
|
-
? (isObservablePlot
|
|
64
|
-
? "deno add npm:" + pkg
|
|
65
|
-
: "deno add" + minimumDependencyAgeOption + " jsr:" +
|
|
66
|
-
pkg)
|
|
56
|
+
? (isObservablePlot ? "deno add npm:" + pkg : "deno add jsr:" + pkg)
|
|
67
57
|
: runtime === "bun"
|
|
68
58
|
? "bun add " + pkg
|
|
69
59
|
: "npm install " + pkg;
|
|
@@ -5,5 +5,6 @@ export interface PackageConfig {
|
|
|
5
5
|
hint?: string;
|
|
6
6
|
}
|
|
7
7
|
export declare const SUPPORTED_PACKAGES: PackageConfig[];
|
|
8
|
+
export declare const DOCUMENTED_PACKAGES: PackageConfig[];
|
|
8
9
|
export declare function getInstalledPackageConfigs(installedPackages: string[]): PackageConfig[];
|
|
9
10
|
//# sourceMappingURL=packageRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageRegistry.d.ts","sourceRoot":"","sources":["../../src/helpers/packageRegistry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,GAAG,YAAY,GAAG,OAAO,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,kBAAkB,EAAE,aAAa,EAwF7C,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,iBAAiB,EAAE,MAAM,EAAE,GAC1B,aAAa,EAAE,CAGjB"}
|
|
1
|
+
{"version":3,"file":"packageRegistry.d.ts","sourceRoot":"","sources":["../../src/helpers/packageRegistry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,GAAG,YAAY,GAAG,OAAO,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,kBAAkB,EAAE,aAAa,EAwF7C,CAAC;AAGF,eAAO,MAAM,mBAAmB,EAAE,aAAa,EAG9C,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,iBAAiB,EAAE,MAAM,EAAE,GAC1B,aAAa,EAAE,CAGjB"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SUPPORTED_PACKAGES = void 0;
|
|
3
|
+
exports.DOCUMENTED_PACKAGES = exports.SUPPORTED_PACKAGES = void 0;
|
|
4
4
|
exports.getInstalledPackageConfigs = getInstalledPackageConfigs;
|
|
5
5
|
exports.SUPPORTED_PACKAGES = [
|
|
6
|
-
{
|
|
7
|
-
value: "@nshiab/simple-data-analysis-core",
|
|
8
|
-
label: "simple-data-analysis-core",
|
|
9
|
-
type: "sda",
|
|
10
|
-
hint: "No fluff. Great for constrained environments, like a cheap server.",
|
|
11
|
-
},
|
|
12
6
|
{
|
|
13
7
|
value: "@nshiab/simple-data-analysis",
|
|
14
8
|
label: "simple-data-analysis",
|
|
15
9
|
type: "sda",
|
|
16
10
|
hint: "All the core functionality, plus methods for dataviz, AI, Google sheets, etc.",
|
|
17
11
|
},
|
|
12
|
+
{
|
|
13
|
+
value: "@nshiab/simple-data-analysis-core",
|
|
14
|
+
label: "simple-data-analysis-core",
|
|
15
|
+
type: "sda",
|
|
16
|
+
hint: "No fluff. Great for constrained environments, like a cheap server.",
|
|
17
|
+
},
|
|
18
18
|
{
|
|
19
19
|
value: "@nshiab/journalism-ai",
|
|
20
20
|
label: "journalism-ai",
|
|
@@ -82,7 +82,12 @@ exports.SUPPORTED_PACKAGES = [
|
|
|
82
82
|
hint: "Functions to zip/unzip, sleep, reencode files, create nested directories...",
|
|
83
83
|
},
|
|
84
84
|
];
|
|
85
|
+
// Plot is installed alongside charting libraries, but is not a setup menu option.
|
|
86
|
+
exports.DOCUMENTED_PACKAGES = [
|
|
87
|
+
...exports.SUPPORTED_PACKAGES,
|
|
88
|
+
{ value: "@observablehq/plot", label: "Observable Plot", type: "other" },
|
|
89
|
+
];
|
|
85
90
|
function getInstalledPackageConfigs(installedPackages) {
|
|
86
91
|
const installedSet = new Set(installedPackages);
|
|
87
|
-
return exports.
|
|
92
|
+
return exports.DOCUMENTED_PACKAGES.filter((pkg) => installedSet.has(pkg.value));
|
|
88
93
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface CliOptions {
|
|
2
|
+
help: boolean;
|
|
3
|
+
package?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const CLI_HELP = "Usage: setup-data-project [--sda | --sda-core] [--help]\n\n --sda Select simple-data-analysis without prompting.\n --sda-core Select simple-data-analysis-core without prompting.\n -h, --help Show this help and exit.\n\nWithout a package flag, choose packages interactively.\nPackage flags keep existing versions and still set up project files and docs.\n--sda and --sda-core cannot be combined.";
|
|
6
|
+
export declare function parseArguments(args: string[]): CliOptions;
|
|
7
|
+
//# sourceMappingURL=parseArguments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseArguments.d.ts","sourceRoot":"","sources":["../../src/helpers/parseArguments.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,QAAQ,0ZAQoB,CAAC;AAE1C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAoBzD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLI_HELP = void 0;
|
|
4
|
+
exports.parseArguments = parseArguments;
|
|
5
|
+
exports.CLI_HELP = `Usage: setup-data-project [--sda | --sda-core] [--help]
|
|
6
|
+
|
|
7
|
+
--sda Select simple-data-analysis without prompting.
|
|
8
|
+
--sda-core Select simple-data-analysis-core without prompting.
|
|
9
|
+
-h, --help Show this help and exit.
|
|
10
|
+
|
|
11
|
+
Without a package flag, choose packages interactively.
|
|
12
|
+
Package flags keep existing versions and still set up project files and docs.
|
|
13
|
+
--sda and --sda-core cannot be combined.`;
|
|
14
|
+
function parseArguments(args) {
|
|
15
|
+
const options = { help: false };
|
|
16
|
+
for (const arg of args) {
|
|
17
|
+
if (arg === "--help" || arg === "-h") {
|
|
18
|
+
options.help = true;
|
|
19
|
+
}
|
|
20
|
+
else if (arg === "--sda" || arg === "--sda-core") {
|
|
21
|
+
const pkg = arg === "--sda"
|
|
22
|
+
? "@nshiab/simple-data-analysis"
|
|
23
|
+
: "@nshiab/simple-data-analysis-core";
|
|
24
|
+
if (options.package && options.package !== pkg) {
|
|
25
|
+
throw new Error("--sda and --sda-core cannot be combined.");
|
|
26
|
+
}
|
|
27
|
+
options.package = pkg;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
throw new Error(`Unknown argument: ${arg}. Use --help for usage.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return options;
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plotDocPages.d.ts","sourceRoot":"","sources":["../../src/helpers/plotDocPages.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,EAAE,MAAM,EA2C3B,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PLOT_DOC_PAGES = void 0;
|
|
4
|
+
// Static chart creation references. Keep this explicit so new upstream pages do
|
|
5
|
+
// not silently expand the installed agent reference.
|
|
6
|
+
exports.PLOT_DOC_PAGES = [
|
|
7
|
+
"features/plots.md",
|
|
8
|
+
"features/marks.md",
|
|
9
|
+
"features/scales.md",
|
|
10
|
+
"features/projections.md",
|
|
11
|
+
"features/legends.md",
|
|
12
|
+
"features/facets.md",
|
|
13
|
+
"features/formats.md",
|
|
14
|
+
"features/curves.md",
|
|
15
|
+
"transforms/bin.md",
|
|
16
|
+
"transforms/group.md",
|
|
17
|
+
"transforms/stack.md",
|
|
18
|
+
"transforms/normalize.md",
|
|
19
|
+
"transforms/centroid.md",
|
|
20
|
+
"transforms/sort.md",
|
|
21
|
+
"marks/area.md",
|
|
22
|
+
"marks/arrow.md",
|
|
23
|
+
"marks/axis.md",
|
|
24
|
+
"marks/bar.md",
|
|
25
|
+
"marks/bollinger.md",
|
|
26
|
+
"marks/box.md",
|
|
27
|
+
"marks/cell.md",
|
|
28
|
+
"marks/contour.md",
|
|
29
|
+
"marks/delaunay.md",
|
|
30
|
+
"marks/density.md",
|
|
31
|
+
"marks/difference.md",
|
|
32
|
+
"marks/dot.md",
|
|
33
|
+
"marks/frame.md",
|
|
34
|
+
"marks/geo.md",
|
|
35
|
+
"marks/grid.md",
|
|
36
|
+
"marks/hexgrid.md",
|
|
37
|
+
"marks/image.md",
|
|
38
|
+
"marks/line.md",
|
|
39
|
+
"marks/linear-regression.md",
|
|
40
|
+
"marks/link.md",
|
|
41
|
+
"marks/raster.md",
|
|
42
|
+
"marks/rect.md",
|
|
43
|
+
"marks/rule.md",
|
|
44
|
+
"marks/text.md",
|
|
45
|
+
"marks/tick.md",
|
|
46
|
+
"marks/tree.md",
|
|
47
|
+
"marks/vector.md",
|
|
48
|
+
"marks/waffle.md",
|
|
49
|
+
].sort();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncPackageDocs.d.ts","sourceRoot":"","sources":["../../src/helpers/syncPackageDocs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"syncPackageDocs.d.ts","sourceRoot":"","sources":["../../src/helpers/syncPackageDocs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAI3E,wBAAsB,eAAe,CACnC,iBAAiB,EAAE,MAAM,EAAE,EAC3B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAkDtC"}
|
|
@@ -5,12 +5,14 @@ const prompts_1 = require("@clack/prompts");
|
|
|
5
5
|
const node_fs_1 = require("node:fs");
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
7
|
const fetchPackageDocs_js_1 = require("./fetchPackageDocs.js");
|
|
8
|
+
const fetchPlotDocs_js_1 = require("./fetchPlotDocs.js");
|
|
8
9
|
const packageRegistry_js_1 = require("./packageRegistry.js");
|
|
9
10
|
async function syncPackageDocs(installedPackages, installedVersions) {
|
|
10
11
|
const installedSet = new Set(installedPackages);
|
|
11
12
|
const docsMapping = {};
|
|
12
|
-
for (const pkg of packageRegistry_js_1.
|
|
13
|
-
const
|
|
13
|
+
for (const pkg of packageRegistry_js_1.DOCUMENTED_PACKAGES) {
|
|
14
|
+
const isPlot = pkg.value === "@observablehq/plot";
|
|
15
|
+
const repoName = isPlot ? "observable-plot" : pkg.value.split("/")[1];
|
|
14
16
|
const docsDirectory = (0, node_path_1.join)("docs", repoName);
|
|
15
17
|
const llmDocsPath = (0, node_path_1.join)(docsDirectory, "llm.md");
|
|
16
18
|
const legacyDocsPath = (0, node_path_1.join)("docs", repoName + ".md");
|
|
@@ -40,8 +42,10 @@ async function syncPackageDocs(installedPackages, installedVersions) {
|
|
|
40
42
|
"included in AGENTS.md.");
|
|
41
43
|
continue;
|
|
42
44
|
}
|
|
43
|
-
const docs =
|
|
44
|
-
|
|
45
|
+
const docs = isPlot
|
|
46
|
+
? await (0, fetchPlotDocs_js_1.fetchPlotDocs)(version)
|
|
47
|
+
: await (0, fetchPackageDocs_js_1.fetchPackageDocs)(pkg.value, version, { silent: true });
|
|
48
|
+
if (docs.readme !== undefined || docs.llm !== undefined || docs.plot) {
|
|
45
49
|
docsMapping[pkg.value] = docs;
|
|
46
50
|
}
|
|
47
51
|
}
|
package/script/main.js
CHANGED
|
@@ -19,7 +19,13 @@ const packageRegistry_js_1 = require("./helpers/packageRegistry.js");
|
|
|
19
19
|
const projectManifest_js_1 = require("./helpers/projectManifest.js");
|
|
20
20
|
const syncPackageDocs_js_1 = require("./helpers/syncPackageDocs.js");
|
|
21
21
|
const getInstalledPackageVersions_js_1 = require("./helpers/getInstalledPackageVersions.js");
|
|
22
|
+
const parseArguments_js_1 = require("./helpers/parseArguments.js");
|
|
22
23
|
async function main() {
|
|
24
|
+
const cliOptions = (0, parseArguments_js_1.parseArguments)(node_process_1.default.argv.slice(2));
|
|
25
|
+
if (cliOptions.help) {
|
|
26
|
+
console.log(parseArguments_js_1.CLI_HELP);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
23
29
|
const runtime = (0, getRuntime_js_1.getRuntime)();
|
|
24
30
|
console.log();
|
|
25
31
|
(0, prompts_1.intro)(`Hi! 👋 (Running on ${runtime})`);
|
|
@@ -32,11 +38,13 @@ async function main() {
|
|
|
32
38
|
? `${opt.label} \x1b[2m(installed)\x1b[22m`
|
|
33
39
|
: opt.label,
|
|
34
40
|
}));
|
|
35
|
-
const selectedPackages =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
const selectedPackages = cliOptions.package
|
|
42
|
+
? [cliOptions.package]
|
|
43
|
+
: (await (0, prompts_1.multiselect)({
|
|
44
|
+
message: "Which libraries would you like to install?\n\x1b[2m(space to select, arrows to navigate, enter to confirm)\x1b[22m\n",
|
|
45
|
+
options,
|
|
46
|
+
required: false,
|
|
47
|
+
}));
|
|
40
48
|
if ((0, prompts_1.isCancel)(selectedPackages)) {
|
|
41
49
|
(0, prompts_1.cancel)("Installation cancelled.");
|
|
42
50
|
node_process_1.default.exit(0);
|
|
@@ -45,6 +53,8 @@ async function main() {
|
|
|
45
53
|
const packagesToInstall = [];
|
|
46
54
|
for (const pkg of selectedPackages) {
|
|
47
55
|
if (alreadyInstalled.includes(pkg)) {
|
|
56
|
+
if (cliOptions.package)
|
|
57
|
+
continue;
|
|
48
58
|
const action = await (0, prompts_1.select)({
|
|
49
59
|
message: `${pkg} is already installed. What would you like to do?`,
|
|
50
60
|
options: [
|