@graphenedata/cli 0.0.18 → 0.0.19
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 +3 -1
- package/dist/cli/athena-WROJBSLV.js +136 -0
- package/dist/cli/athena-WROJBSLV.js.map +7 -0
- package/dist/cli/{bigQuery-YIWXZPY6.js → bigQuery-3A7HPXZS.js} +2 -2
- package/dist/cli/{chunk-SQVXTHE5.js → chunk-KW66YQ62.js} +3 -1
- package/dist/cli/chunk-KW66YQ62.js.map +7 -0
- package/dist/cli/{chunk-UTV3ERGI.js → chunk-KYTXXLSS.js} +5219 -4592
- package/dist/cli/chunk-KYTXXLSS.js.map +7 -0
- package/dist/cli/chunk-OVF4UUFF.js +28 -0
- package/dist/cli/chunk-OVF4UUFF.js.map +7 -0
- package/dist/cli/cli.js +249 -20
- package/dist/cli/{duckdb-V6PJEA7H.js → duckdb-YOIX6QOQ.js} +2 -2
- package/dist/cli/installBrowser.js +11 -0
- package/dist/cli/installBrowser.js.map +7 -0
- package/dist/cli/postgres-NF43BPZY.js +147 -0
- package/dist/cli/postgres-NF43BPZY.js.map +7 -0
- package/dist/cli/{serve2-CGQSM7TD.js → serve2-XALOUIFB.js} +7 -3
- package/dist/cli/{serve2-CGQSM7TD.js.map → serve2-XALOUIFB.js.map} +2 -2
- package/dist/cli/{snowflake-HVSTYBLB.js → snowflake-GX4FSSWT.js} +2 -2
- package/dist/skills/graphene/SKILL.md +16 -9
- package/dist/skills/graphene/references/dropdown.md +12 -0
- package/dist/ui/component-utilities/enrich.ts +26 -22
- package/dist/ui/components/AreaChart.svelte +3 -2
- package/dist/ui/components/BarChart.svelte +4 -3
- package/dist/ui/components/LineChart.svelte +3 -2
- package/dist/ui/components/ScatterPlot.svelte +4 -3
- package/dist/ui/components/_Table.svelte +3 -1
- package/dist/ui/internal/LocalApp.svelte +5 -1
- package/package.json +13 -4
- package/dist/cli/chunk-SQVXTHE5.js.map +0 -7
- package/dist/cli/chunk-UTV3ERGI.js.map +0 -7
- /package/dist/cli/{bigQuery-YIWXZPY6.js.map → bigQuery-3A7HPXZS.js.map} +0 -0
- /package/dist/cli/{duckdb-V6PJEA7H.js.map → duckdb-YOIX6QOQ.js.map} +0 -0
- /package/dist/cli/{snowflake-HVSTYBLB.js.map → snowflake-GX4FSSWT.js.map} +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// installBrowser.ts
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
import path from "path";
|
|
5
|
+
var nodeRequire = createRequire(import.meta.url);
|
|
6
|
+
async function installBrowser(options = {}) {
|
|
7
|
+
if (options.postinstall && process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD) {
|
|
8
|
+
console.log("Skipping Graphene browser install because PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD is set.");
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
let cliPath = path.join(path.dirname(nodeRequire.resolve("playwright-core")), "cli.js");
|
|
12
|
+
let args = [cliPath, "install", "--only-shell", ...options.withDeps ? ["--with-deps"] : [], "chromium"];
|
|
13
|
+
let result = await new Promise((resolve, reject) => {
|
|
14
|
+
let child = spawn(process.execPath, args, { stdio: "inherit" });
|
|
15
|
+
child.on("error", reject);
|
|
16
|
+
child.on("close", (code) => resolve(code ?? 1));
|
|
17
|
+
});
|
|
18
|
+
if (result === 0) return true;
|
|
19
|
+
if (!options.postinstall) return false;
|
|
20
|
+
console.warn("Graphene could not install its headless browser during package install.");
|
|
21
|
+
console.warn("Run `graphene install-browser` before using `graphene run --headless` screenshots.");
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
installBrowser
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=chunk-OVF4UUFF.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../installBrowser.ts"],
|
|
4
|
+
"sourcesContent": ["import {spawn} from 'child_process'\nimport {createRequire} from 'module'\nimport path from 'path'\n\nconst nodeRequire = createRequire(import.meta.url)\n\nexport async function installBrowser(options: {withDeps?: boolean; postinstall?: boolean} = {}) {\n if (options.postinstall && process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD) {\n console.log('Skipping Graphene browser install because PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD is set.')\n return true\n }\n\n let cliPath = path.join(path.dirname(nodeRequire.resolve('playwright-core')), 'cli.js')\n let args = [cliPath, 'install', '--only-shell', ...(options.withDeps ? ['--with-deps'] : []), 'chromium']\n let result = await new Promise<number>((resolve, reject) => {\n let child = spawn(process.execPath, args, {stdio: 'inherit'})\n child.on('error', reject)\n child.on('close', code => resolve(code ?? 1))\n })\n\n if (result === 0) return true\n if (!options.postinstall) return false\n\n console.warn('Graphene could not install its headless browser during package install.')\n console.warn('Run `graphene install-browser` before using `graphene run --headless` screenshots.')\n return true\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAQ,aAAY;AACpB,SAAQ,qBAAoB;AAC5B,OAAO,UAAU;AAEjB,IAAM,cAAc,cAAc,YAAY,GAAG;AAEjD,eAAsB,eAAe,UAAuD,CAAC,GAAG;AAC9F,MAAI,QAAQ,eAAe,QAAQ,IAAI,kCAAkC;AACvE,YAAQ,IAAI,oFAAoF;AAChG,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,KAAK,KAAK,KAAK,QAAQ,YAAY,QAAQ,iBAAiB,CAAC,GAAG,QAAQ;AACtF,MAAI,OAAO,CAAC,SAAS,WAAW,gBAAgB,GAAI,QAAQ,WAAW,CAAC,aAAa,IAAI,CAAC,GAAI,UAAU;AACxG,MAAI,SAAS,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC1D,QAAI,QAAQ,MAAM,QAAQ,UAAU,MAAM,EAAC,OAAO,UAAS,CAAC;AAC5D,UAAM,GAAG,SAAS,MAAM;AACxB,UAAM,GAAG,SAAS,UAAQ,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAC9C,CAAC;AAED,MAAI,WAAW,EAAG,QAAO;AACzB,MAAI,CAAC,QAAQ,YAAa,QAAO;AAEjC,UAAQ,KAAK,yEAAyE;AACtF,UAAQ,KAAK,oFAAoF;AACjG,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/cli/cli.js
CHANGED
|
@@ -20,18 +20,21 @@ import {
|
|
|
20
20
|
runServeInBackground,
|
|
21
21
|
stopGrapheneIfRunning,
|
|
22
22
|
toSql
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-KYTXXLSS.js";
|
|
24
|
+
import {
|
|
25
|
+
installBrowser
|
|
26
|
+
} from "./chunk-OVF4UUFF.js";
|
|
24
27
|
import {
|
|
25
28
|
config,
|
|
26
29
|
loadConfig,
|
|
27
30
|
setGlobalConfig
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-KW66YQ62.js";
|
|
29
32
|
|
|
30
33
|
// cli.ts
|
|
31
34
|
import { Command } from "commander";
|
|
32
35
|
import dotenv from "dotenv";
|
|
33
|
-
import
|
|
34
|
-
import
|
|
36
|
+
import fs2 from "fs-extra";
|
|
37
|
+
import path3 from "path";
|
|
35
38
|
import { fileURLToPath } from "url";
|
|
36
39
|
|
|
37
40
|
// check.ts
|
|
@@ -47,9 +50,9 @@ async function check(options) {
|
|
|
47
50
|
let files = await loadWorkspace(config.root, !targetFile, config.ignoredFiles);
|
|
48
51
|
options.telemetry?.event("workspace_scanned", { command: "check", ...getWorkspaceScanCounts(files) });
|
|
49
52
|
if (process.env.NODE_ENV == "test") {
|
|
50
|
-
for (let [
|
|
51
|
-
if (targetFile &&
|
|
52
|
-
upsertFile(files, { path:
|
|
53
|
+
for (let [path4, contents] of Object.entries(mockFileMap)) {
|
|
54
|
+
if (targetFile && path4 != targetFile) continue;
|
|
55
|
+
upsertFile(files, { path: path4, contents });
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
if (targetFile) {
|
|
@@ -75,12 +78,226 @@ function upsertFile(files, next) {
|
|
|
75
78
|
else files.push(next);
|
|
76
79
|
}
|
|
77
80
|
|
|
81
|
+
// updateNotifier.ts
|
|
82
|
+
import ci from "ci-info";
|
|
83
|
+
import { randomUUID } from "node:crypto";
|
|
84
|
+
import * as fs from "node:fs/promises";
|
|
85
|
+
import path2 from "node:path";
|
|
86
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
87
|
+
var NOTICE_INTERVAL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
88
|
+
var DEFAULT_UPDATE_CHECK_URL = "https://registry.npmjs.org/%40graphenedata%2Fcli/latest";
|
|
89
|
+
var GITHUB_RELEASE_URL = "https://github.com/graphene-data/graphene/releases/tag";
|
|
90
|
+
var PACKAGE_NAME = "@graphenedata/cli";
|
|
91
|
+
async function showCachedUpdateNotice(options) {
|
|
92
|
+
let env = options.env || process.env;
|
|
93
|
+
let stderr = options.stderr || process.stderr;
|
|
94
|
+
if (!isUpdateNotifierEnabled(options.config, env, stderr, options.packageIsPrivate)) return;
|
|
95
|
+
let now = options.now || Date.now();
|
|
96
|
+
let stateTarget = await getUpdateStateTarget(options);
|
|
97
|
+
if (!stateTarget) return;
|
|
98
|
+
let state = await readUpdateState(stateTarget.filePath);
|
|
99
|
+
if (state.latestVersion && isNewerVersion(state.latestVersion, options.currentVersion) && shouldShowNotice(state, now)) {
|
|
100
|
+
let command = await getUpgradeCommand(options.config.root, env);
|
|
101
|
+
stderr.write(`Graphene ${state.latestVersion} is available. You are using ${options.currentVersion}.
|
|
102
|
+
`);
|
|
103
|
+
stderr.write(`Update: ${command}
|
|
104
|
+
`);
|
|
105
|
+
stderr.write(`Release notes: ${GITHUB_RELEASE_URL}/v${state.latestVersion}
|
|
106
|
+
`);
|
|
107
|
+
state = { ...state, lastNoticeVersion: state.latestVersion, lastNoticeAt: now };
|
|
108
|
+
await writeUpdateState(stateTarget, state);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function checkForUpdate(options) {
|
|
112
|
+
let env = options.env || process.env;
|
|
113
|
+
let stderr = options.stderr || process.stderr;
|
|
114
|
+
if (!isUpdateNotifierEnabled(options.config, env, stderr, options.packageIsPrivate)) return;
|
|
115
|
+
let now = options.now || Date.now();
|
|
116
|
+
let stateTarget = await getUpdateStateTarget(options);
|
|
117
|
+
if (!stateTarget) return;
|
|
118
|
+
let state = await readUpdateState(stateTarget.filePath);
|
|
119
|
+
if (!shouldCheckForUpdate(state, now)) return;
|
|
120
|
+
await writeUpdateState(stateTarget, { ...state, lastCheckedAt: now });
|
|
121
|
+
let latestVersion = await (options.fetchLatestVersion || fetchLatestVersion)(env.GRAPHENE_UPDATE_CHECK_URL || DEFAULT_UPDATE_CHECK_URL);
|
|
122
|
+
if (latestVersion && isStrictSemver(latestVersion)) await writeUpdateState(stateTarget, { ...state, lastCheckedAt: now, latestVersion });
|
|
123
|
+
}
|
|
124
|
+
function isUpdateNotifierEnabled(config2, env = process.env, stderr = process.stderr, packageIsPrivate = false) {
|
|
125
|
+
if (packageIsPrivate) return false;
|
|
126
|
+
if (config2.updateNotifier === false) return false;
|
|
127
|
+
if (env.GRAPHENE_NO_UPDATE_NOTIFIER == "1") return false;
|
|
128
|
+
if (env.NODE_ENV == "test") return false;
|
|
129
|
+
if (isCiEnv(env)) return false;
|
|
130
|
+
if (!stderr.isTTY) return false;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
function isNewerVersion(candidate, current) {
|
|
134
|
+
if (!isStrictSemver(candidate) || !isStrictSemver(current)) return false;
|
|
135
|
+
let candidateParts = candidate.split(".").map(Number);
|
|
136
|
+
let currentParts = current.split(".").map(Number);
|
|
137
|
+
for (let i = 0; i < candidateParts.length; i++) {
|
|
138
|
+
if (candidateParts[i] > currentParts[i]) return true;
|
|
139
|
+
if (candidateParts[i] < currentParts[i]) return false;
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
async function getUpgradeCommand(projectRoot, env = process.env) {
|
|
144
|
+
let packageManager = await detectPackageManager(projectRoot, env);
|
|
145
|
+
let dependencyFlag = await getGrapheneDependencyType(projectRoot) == "devDependencies" ? devDependencyFlag(packageManager) : "";
|
|
146
|
+
let command = `${packageManager} ${packageManager == "npm" ? "install" : "add"} ${PACKAGE_NAME}@latest`;
|
|
147
|
+
return dependencyFlag ? `${command} ${dependencyFlag}` : command;
|
|
148
|
+
}
|
|
149
|
+
async function detectPackageManager(projectRoot, env = process.env) {
|
|
150
|
+
let packageManager = await findPackageManagerField(projectRoot);
|
|
151
|
+
if (packageManager) return packageManager;
|
|
152
|
+
let lockfilePackageManager = await findLockfilePackageManager(projectRoot);
|
|
153
|
+
if (lockfilePackageManager) return lockfilePackageManager;
|
|
154
|
+
return parsePackageManager(env.npm_config_user_agent) || "npm";
|
|
155
|
+
}
|
|
156
|
+
function shouldShowNotice(state, now) {
|
|
157
|
+
if (state.lastNoticeVersion != state.latestVersion) return true;
|
|
158
|
+
return !state.lastNoticeAt || now - state.lastNoticeAt >= NOTICE_INTERVAL_MS;
|
|
159
|
+
}
|
|
160
|
+
function shouldCheckForUpdate(state, now) {
|
|
161
|
+
return !state.lastCheckedAt || now - state.lastCheckedAt >= CHECK_INTERVAL_MS;
|
|
162
|
+
}
|
|
163
|
+
async function fetchLatestVersion(url) {
|
|
164
|
+
let controller = new AbortController();
|
|
165
|
+
let timeout = setTimeout(() => controller.abort(), 500);
|
|
166
|
+
timeout.unref?.();
|
|
167
|
+
try {
|
|
168
|
+
let response = await fetch(url, { signal: controller.signal });
|
|
169
|
+
if (!response.ok) return null;
|
|
170
|
+
let body = await response.json();
|
|
171
|
+
return typeof body.version == "string" ? body.version : null;
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
} finally {
|
|
175
|
+
clearTimeout(timeout);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async function getUpdateStateTarget(options) {
|
|
179
|
+
if (options.statePath) return { filePath: options.statePath };
|
|
180
|
+
let nodeModulesPath = path2.join(options.config.root, "node_modules");
|
|
181
|
+
try {
|
|
182
|
+
if (!(await fs.stat(nodeModulesPath)).isDirectory()) return null;
|
|
183
|
+
} catch {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
return { filePath: path2.join(nodeModulesPath, ".graphene", "update-check.json"), requiredDir: nodeModulesPath };
|
|
187
|
+
}
|
|
188
|
+
async function readUpdateState(filePath) {
|
|
189
|
+
try {
|
|
190
|
+
return normalizeUpdateState(JSON.parse(await fs.readFile(filePath, "utf-8")));
|
|
191
|
+
} catch {
|
|
192
|
+
return {};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async function writeUpdateState(target, state) {
|
|
196
|
+
let filePath = target.filePath;
|
|
197
|
+
let tmpPath = `${filePath}.tmp-${randomUUID()}`;
|
|
198
|
+
try {
|
|
199
|
+
if (target.requiredDir && !(await fs.stat(target.requiredDir)).isDirectory()) return;
|
|
200
|
+
await fs.mkdir(path2.dirname(filePath), { recursive: true });
|
|
201
|
+
await fs.writeFile(tmpPath, JSON.stringify(state, null, 2) + "\n");
|
|
202
|
+
await fs.rename(tmpPath, filePath);
|
|
203
|
+
} catch {
|
|
204
|
+
try {
|
|
205
|
+
await fs.unlink(tmpPath);
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function normalizeUpdateState(state) {
|
|
211
|
+
return {
|
|
212
|
+
...typeof state.lastCheckedAt == "number" ? { lastCheckedAt: state.lastCheckedAt } : {},
|
|
213
|
+
...typeof state.latestVersion == "string" ? { latestVersion: state.latestVersion } : {},
|
|
214
|
+
...typeof state.lastNoticeVersion == "string" ? { lastNoticeVersion: state.lastNoticeVersion } : {},
|
|
215
|
+
...typeof state.lastNoticeAt == "number" ? { lastNoticeAt: state.lastNoticeAt } : {}
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
async function findPackageManagerField(projectRoot) {
|
|
219
|
+
for (let dir of ancestorDirs(projectRoot)) {
|
|
220
|
+
let packageJson = await readPackageJson(path2.join(dir, "package.json"));
|
|
221
|
+
let packageManager = parsePackageManager(packageJson?.packageManager);
|
|
222
|
+
if (packageManager) return packageManager;
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
async function findLockfilePackageManager(projectRoot) {
|
|
227
|
+
let lockfiles = [
|
|
228
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
229
|
+
["yarn.lock", "yarn"],
|
|
230
|
+
["package-lock.json", "npm"],
|
|
231
|
+
["npm-shrinkwrap.json", "npm"],
|
|
232
|
+
["bun.lock", "bun"],
|
|
233
|
+
["bun.lockb", "bun"]
|
|
234
|
+
];
|
|
235
|
+
for (let dir of ancestorDirs(projectRoot)) {
|
|
236
|
+
for (let [file, packageManager] of lockfiles) {
|
|
237
|
+
try {
|
|
238
|
+
await fs.access(path2.join(dir, file));
|
|
239
|
+
return packageManager;
|
|
240
|
+
} catch {
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
async function getGrapheneDependencyType(projectRoot) {
|
|
247
|
+
let packageJson = await readPackageJson(path2.join(projectRoot, "package.json"));
|
|
248
|
+
if (packageJson?.devDependencies?.[PACKAGE_NAME]) return "devDependencies";
|
|
249
|
+
if (packageJson?.dependencies?.[PACKAGE_NAME]) return "dependencies";
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
async function readPackageJson(filePath) {
|
|
253
|
+
try {
|
|
254
|
+
return JSON.parse(await fs.readFile(filePath, "utf-8"));
|
|
255
|
+
} catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function parsePackageManager(value) {
|
|
260
|
+
if (typeof value != "string") return null;
|
|
261
|
+
let normalized = value.toLowerCase();
|
|
262
|
+
if (normalized.includes("pnpm")) return "pnpm";
|
|
263
|
+
if (normalized.includes("yarn")) return "yarn";
|
|
264
|
+
if (normalized.includes("bun")) return "bun";
|
|
265
|
+
if (normalized.includes("npm")) return "npm";
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
function devDependencyFlag(packageManager) {
|
|
269
|
+
if (packageManager == "bun") return "-d";
|
|
270
|
+
return "-D";
|
|
271
|
+
}
|
|
272
|
+
function isStrictSemver(version) {
|
|
273
|
+
return /^\d+\.\d+\.\d+$/.test(version);
|
|
274
|
+
}
|
|
275
|
+
function isCiEnv(env) {
|
|
276
|
+
if (env === process.env) return ci.isCI;
|
|
277
|
+
return env.CI == "true" || env.CI == "1" || !!env.GITHUB_ACTIONS || !!env.BUILDKITE || !!env.CIRCLECI;
|
|
278
|
+
}
|
|
279
|
+
function ancestorDirs(startDir) {
|
|
280
|
+
let dirs = [];
|
|
281
|
+
let current = path2.resolve(startDir);
|
|
282
|
+
while (true) {
|
|
283
|
+
dirs.push(current);
|
|
284
|
+
let parent = path2.dirname(current);
|
|
285
|
+
if (parent == current) return dirs;
|
|
286
|
+
current = parent;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
78
290
|
// cli.ts
|
|
79
291
|
var program = new Command();
|
|
80
|
-
var __dirname =
|
|
81
|
-
var pkgPath =
|
|
82
|
-
var libPkg =
|
|
292
|
+
var __dirname = path3.dirname(fileURLToPath(import.meta.url));
|
|
293
|
+
var pkgPath = fs2.existsSync(path3.join(__dirname, "package.json")) ? path3.join(__dirname, "package.json") : path3.join(__dirname, "../../package.json");
|
|
294
|
+
var libPkg = fs2.readJsonSync(pkgPath);
|
|
83
295
|
program.name("graphene").description("Graphene CLI").version(libPkg.version, "-v, --version");
|
|
296
|
+
registerInstallBrowserCommand(program);
|
|
297
|
+
if (process.argv[2] === "install-browser") {
|
|
298
|
+
await program.parseAsync(process.argv);
|
|
299
|
+
process.exit(0);
|
|
300
|
+
}
|
|
84
301
|
var cfg = await loadConfig(process.cwd(), (envFiles) => {
|
|
85
302
|
dotenv.config({ quiet: true, path: envFiles });
|
|
86
303
|
});
|
|
@@ -97,20 +314,24 @@ program.command("compile").description("Translate a query to SQL and print it").
|
|
|
97
314
|
console.log(toSql(query));
|
|
98
315
|
})
|
|
99
316
|
);
|
|
100
|
-
program.command("run").description("Run a query or screenshot a Graphene page").argument("[input]", 'Path to file, a raw string, or "-" for stdin').option("-c, --chart <chartTitleOrComponentId>", "Title or component ID of a specific chart to capture").option("-q, --query <queryName>", "Query or table name to run from a markdown page").option("--input <key=value>", "Input value to use for parameters; repeat for multiple values", (value, previous) => previous.concat(value), []).action(
|
|
317
|
+
program.command("run").description("Run a query or screenshot a Graphene page").argument("[input]", 'Path to file, a raw string, or "-" for stdin').option("-c, --chart <chartTitleOrComponentId>", "Title or component ID of a specific chart to capture").option("--headless", "Run markdown pages in a headless browser instead of opening the system browser").option("-q, --query <queryName>", "Query or table name to run from a markdown page").option("--input <key=value>", "Input value to use for parameters; repeat for multiple values", (value, previous) => previous.concat(value), []).action(
|
|
101
318
|
withTelemetry("run", async (exit, input, options) => {
|
|
102
319
|
if (options.chart && options.query) {
|
|
103
320
|
console.error("Cannot use --chart and --query together");
|
|
104
321
|
return exit(1);
|
|
105
322
|
}
|
|
323
|
+
if (options.headless && options.query) {
|
|
324
|
+
console.error("Cannot use --headless and --query together");
|
|
325
|
+
return exit(1);
|
|
326
|
+
}
|
|
106
327
|
let inputs = parseRunInputs(options.input || [], exit);
|
|
107
328
|
let inputPath = getExistingPath(input);
|
|
108
329
|
if (inputPath && inputPath.endsWith(".md")) {
|
|
109
|
-
let res2 = options.query ? await runNamedQueryFromMd(inputPath, options.query, { inputs, telemetry }) : await runMdFile({ mdArg: inputPath, chart: options.chart, inputs, telemetry });
|
|
330
|
+
let res2 = options.query ? await runNamedQueryFromMd(inputPath, options.query, { inputs, telemetry }) : await runMdFile({ mdArg: inputPath, chart: options.chart, headless: options.headless, inputs, telemetry });
|
|
110
331
|
return exit(res2 ? 0 : 1);
|
|
111
332
|
}
|
|
112
|
-
if (options.chart || options.query) {
|
|
113
|
-
console.error("--chart and --query can only be used with a markdown file path");
|
|
333
|
+
if (options.chart || options.headless || options.query) {
|
|
334
|
+
console.error("--chart, --headless, and --query can only be used with a markdown file path");
|
|
114
335
|
return exit(1);
|
|
115
336
|
}
|
|
116
337
|
if (inputPath && inputPath.endsWith(".gsql")) {
|
|
@@ -193,7 +414,7 @@ program.command("serve").description("Run the local server").option("--bg", "Run
|
|
|
193
414
|
await runServeInBackground();
|
|
194
415
|
return exit(0);
|
|
195
416
|
} else {
|
|
196
|
-
let mod = await import("./serve2-
|
|
417
|
+
let mod = await import("./serve2-XALOUIFB.js");
|
|
197
418
|
await mod.serve2(telemetry);
|
|
198
419
|
}
|
|
199
420
|
})
|
|
@@ -217,6 +438,12 @@ program.command("login").description("Log in to Graphene Cloud").action(
|
|
|
217
438
|
})
|
|
218
439
|
);
|
|
219
440
|
program.parse(process.argv);
|
|
441
|
+
function registerInstallBrowserCommand(program2) {
|
|
442
|
+
program2.command("install-browser").description("Install the browser used by graphene run --headless screenshots").option("--with-deps", "Also install browser system dependencies where supported").action(async (options) => {
|
|
443
|
+
let ok = await installBrowser({ withDeps: options.withDeps });
|
|
444
|
+
process.exit(ok ? 0 : 1);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
220
447
|
async function readInput(arg) {
|
|
221
448
|
if (!arg || arg === "-") {
|
|
222
449
|
return await new Promise((resolve) => {
|
|
@@ -227,16 +454,16 @@ async function readInput(arg) {
|
|
|
227
454
|
process.stdin.resume();
|
|
228
455
|
});
|
|
229
456
|
}
|
|
230
|
-
let absolutePath =
|
|
231
|
-
if (
|
|
232
|
-
return await
|
|
457
|
+
let absolutePath = path3.resolve(arg);
|
|
458
|
+
if (fs2.existsSync(absolutePath)) {
|
|
459
|
+
return await fs2.promises.readFile(absolutePath, "utf-8");
|
|
233
460
|
}
|
|
234
461
|
return arg;
|
|
235
462
|
}
|
|
236
463
|
function getExistingPath(arg) {
|
|
237
464
|
if (!arg || arg === "-") return null;
|
|
238
|
-
let absolutePath =
|
|
239
|
-
return
|
|
465
|
+
let absolutePath = path3.resolve(arg);
|
|
466
|
+
return fs2.existsSync(absolutePath) ? absolutePath : null;
|
|
240
467
|
}
|
|
241
468
|
function validateInputQuery(analysis, exit) {
|
|
242
469
|
if (analysis.diagnostics.length) {
|
|
@@ -287,6 +514,7 @@ function withTelemetry(command, action) {
|
|
|
287
514
|
let exitCalled = false;
|
|
288
515
|
let caughtError;
|
|
289
516
|
telemetry.event("cli_command_started", { command, flags: getPresentFlags(command, process.argv.slice(2)) });
|
|
517
|
+
await showCachedUpdateNotice({ config, currentVersion: libPkg.version, packageIsPrivate: libPkg.private });
|
|
290
518
|
let exit = (code = 0) => {
|
|
291
519
|
exitCalled = true;
|
|
292
520
|
exitCode = code;
|
|
@@ -306,6 +534,7 @@ function withTelemetry(command, action) {
|
|
|
306
534
|
if (fromVersion) telemetry.event("cli_upgraded", { from_version: fromVersion, to_version: libPkg.version });
|
|
307
535
|
}
|
|
308
536
|
telemetry.event("cli_command_completed", { command, success, exit_code: exitCode, duration_ms: Date.now() - startedAt });
|
|
537
|
+
await checkForUpdate({ config, currentVersion: libPkg.version, packageIsPrivate: libPkg.private });
|
|
309
538
|
}
|
|
310
539
|
if (caughtError) throw caughtError;
|
|
311
540
|
else if (exitCalled) process.exit(exitCode);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
config
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KW66YQ62.js";
|
|
4
4
|
|
|
5
5
|
// connections/duckdb.ts
|
|
6
6
|
import { DuckDBTimestampValue, DuckDBInstance, DuckDBDateValue, DuckDBDecimalValue } from "@duckdb/node-api";
|
|
@@ -84,4 +84,4 @@ var DuckDBConnection = class {
|
|
|
84
84
|
export {
|
|
85
85
|
DuckDBConnection
|
|
86
86
|
};
|
|
87
|
-
//# sourceMappingURL=duckdb-
|
|
87
|
+
//# sourceMappingURL=duckdb-YOIX6QOQ.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
installBrowser
|
|
3
|
+
} from "./chunk-OVF4UUFF.js";
|
|
4
|
+
|
|
5
|
+
// installBrowserEntry.ts
|
|
6
|
+
var ok = await installBrowser({
|
|
7
|
+
withDeps: process.argv.includes("--with-deps"),
|
|
8
|
+
postinstall: process.argv.includes("--postinstall")
|
|
9
|
+
});
|
|
10
|
+
process.exit(ok ? 0 : 1);
|
|
11
|
+
//# sourceMappingURL=installBrowser.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../installBrowserEntry.ts"],
|
|
4
|
+
"sourcesContent": ["import {installBrowser} from './installBrowser.ts'\n\nlet ok = await installBrowser({\n withDeps: process.argv.includes('--with-deps'),\n postinstall: process.argv.includes('--postinstall'),\n})\nprocess.exit(ok ? 0 : 1)\n"],
|
|
5
|
+
"mappings": ";;;;;AAEA,IAAI,KAAK,MAAM,eAAe;AAAA,EAC5B,UAAU,QAAQ,KAAK,SAAS,aAAa;AAAA,EAC7C,aAAa,QAAQ,KAAK,SAAS,eAAe;AACpD,CAAC;AACD,QAAQ,KAAK,KAAK,IAAI,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
config
|
|
3
|
+
} from "./chunk-KW66YQ62.js";
|
|
4
|
+
|
|
5
|
+
// connections/postgres.ts
|
|
6
|
+
import pg from "pg";
|
|
7
|
+
var NUMERIC_OIDS = /* @__PURE__ */ new Set([20, 21, 23, 26, 700, 701, 1700]);
|
|
8
|
+
var DATE_OID = 1082;
|
|
9
|
+
var TIMESTAMP_OIDS = /* @__PURE__ */ new Set([1114, 1184]);
|
|
10
|
+
var { Pool } = pg;
|
|
11
|
+
var PostgresConnection = class {
|
|
12
|
+
pool;
|
|
13
|
+
defaultSchema;
|
|
14
|
+
onClose;
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.defaultSchema = options.schema || config.postgres?.schema || config.defaultNamespace || "public";
|
|
17
|
+
this.onClose = options.onClose;
|
|
18
|
+
this.pool = options.pool || new Pool({
|
|
19
|
+
connectionString: options.connectionString,
|
|
20
|
+
host: options.host,
|
|
21
|
+
port: options.port,
|
|
22
|
+
database: options.database,
|
|
23
|
+
user: options.user || options.username,
|
|
24
|
+
password: options.password,
|
|
25
|
+
ssl: options.ssl,
|
|
26
|
+
max: options.max,
|
|
27
|
+
idleTimeoutMillis: options.idleTimeoutMillis,
|
|
28
|
+
connectionTimeoutMillis: options.connectionTimeoutMillis,
|
|
29
|
+
query_timeout: options.queryTimeout,
|
|
30
|
+
statement_timeout: options.statementTimeout,
|
|
31
|
+
application_name: "Graphene"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async runQuery(sql, params) {
|
|
35
|
+
let [preparedSql, preparedParams] = preparePostgresParams(sql, params);
|
|
36
|
+
let result = await this.pool.query(preparedSql, preparedParams);
|
|
37
|
+
let rows = result.rows.map((row) => normalizeRow(row, result.fields));
|
|
38
|
+
return { rows, totalRows: result.rowCount ?? rows.length };
|
|
39
|
+
}
|
|
40
|
+
async listDatasets() {
|
|
41
|
+
let res = await this.runQuery(`
|
|
42
|
+
select schema_name
|
|
43
|
+
from information_schema.schemata
|
|
44
|
+
where schema_name not in ('information_schema', 'pg_catalog')
|
|
45
|
+
and schema_name not like 'pg_toast%'
|
|
46
|
+
and schema_name not like 'pg_temp%'
|
|
47
|
+
order by schema_name
|
|
48
|
+
`);
|
|
49
|
+
return res.rows.map((row) => String(row["schema_name"]).toLowerCase());
|
|
50
|
+
}
|
|
51
|
+
async listTables(schema = this.defaultSchema) {
|
|
52
|
+
let sql = `
|
|
53
|
+
select table_name
|
|
54
|
+
from information_schema.tables
|
|
55
|
+
where lower(table_schema) = lower($1)
|
|
56
|
+
and table_type in ('BASE TABLE', 'VIEW')
|
|
57
|
+
order by table_name
|
|
58
|
+
`.trim();
|
|
59
|
+
let res = await this.runQuery(sql, [schema]);
|
|
60
|
+
return res.rows.map((row) => String(row["table_name"]).toLowerCase());
|
|
61
|
+
}
|
|
62
|
+
async describeTable(target) {
|
|
63
|
+
let parts = target.split(".").filter(Boolean);
|
|
64
|
+
let table = parts.pop() || "";
|
|
65
|
+
let schema = parts.join(".") || this.defaultSchema;
|
|
66
|
+
let sql = `
|
|
67
|
+
select column_name, data_type, udt_name, ordinal_position
|
|
68
|
+
from information_schema.columns
|
|
69
|
+
where lower(table_schema) = lower($1)
|
|
70
|
+
and lower(table_name) = lower($2)
|
|
71
|
+
order by ordinal_position
|
|
72
|
+
`.trim();
|
|
73
|
+
let res = await this.runQuery(sql, [schema, table]);
|
|
74
|
+
return res.rows.map((row) => ({ name: String(row["column_name"]).toLowerCase(), dataType: postgresDisplayType(row) }));
|
|
75
|
+
}
|
|
76
|
+
async close() {
|
|
77
|
+
try {
|
|
78
|
+
await this.pool.end();
|
|
79
|
+
} finally {
|
|
80
|
+
await this.onClose?.();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
function preparePostgresParams(sql, params) {
|
|
85
|
+
if (!params) return [sql, void 0];
|
|
86
|
+
if (Array.isArray(params)) return [sql, params];
|
|
87
|
+
let values = [];
|
|
88
|
+
let indexes = /* @__PURE__ */ new Map();
|
|
89
|
+
let inString = false;
|
|
90
|
+
let out = "";
|
|
91
|
+
for (let i = 0; i < sql.length; i++) {
|
|
92
|
+
let ch = sql[i];
|
|
93
|
+
if (ch == "'") {
|
|
94
|
+
out += ch;
|
|
95
|
+
if (inString && sql[i + 1] == "'") {
|
|
96
|
+
out += sql[++i];
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
inString = !inString;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
let match = !inString && ch == "$" ? sql.slice(i).match(/^\$([A-Za-z_][A-Za-z0-9_]*)/) : null;
|
|
103
|
+
if (!match) {
|
|
104
|
+
out += ch;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
let name = match[1];
|
|
108
|
+
if (!(name in params)) throw new Error(`Missing param $${name}`);
|
|
109
|
+
if (!indexes.has(name)) {
|
|
110
|
+
values.push(params[name]);
|
|
111
|
+
indexes.set(name, values.length);
|
|
112
|
+
}
|
|
113
|
+
out += `$${indexes.get(name)}`;
|
|
114
|
+
i += name.length;
|
|
115
|
+
}
|
|
116
|
+
return [out, values];
|
|
117
|
+
}
|
|
118
|
+
function normalizeRow(row, fields) {
|
|
119
|
+
let out = {};
|
|
120
|
+
for (let [key, value] of Object.entries(row)) {
|
|
121
|
+
let field = fields.find((f) => f.name == key);
|
|
122
|
+
out[key] = normalizeValue(value, field?.dataTypeID);
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
function normalizeValue(value, oid) {
|
|
127
|
+
if (value === null) return null;
|
|
128
|
+
if (typeof value === "bigint") return Number(value);
|
|
129
|
+
if (typeof value === "string" && oid && NUMERIC_OIDS.has(oid) && value !== "") return Number(value);
|
|
130
|
+
if (value instanceof Date && oid == DATE_OID) return value.toISOString().slice(0, 10);
|
|
131
|
+
if (value instanceof Date && oid && TIMESTAMP_OIDS.has(oid)) return value.toISOString();
|
|
132
|
+
if (Array.isArray(value)) return value.map((item) => normalizeValue(item));
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
function postgresDisplayType(row) {
|
|
136
|
+
let dataType = String(row["data_type"]);
|
|
137
|
+
let udtName = String(row["udt_name"] || "");
|
|
138
|
+
let udtAliases = { int2: "smallint", int4: "integer", int8: "bigint", float4: "real", float8: "double precision", bool: "boolean", varchar: "character varying" };
|
|
139
|
+
if (dataType == "ARRAY" && udtName.startsWith("_")) return `${udtAliases[udtName.slice(1)] || udtName.slice(1)}[]`;
|
|
140
|
+
if (dataType == "timestamp without time zone" || dataType == "timestamp with time zone") return "timestamp";
|
|
141
|
+
if (dataType == "USER-DEFINED" && udtName) return udtName;
|
|
142
|
+
return dataType;
|
|
143
|
+
}
|
|
144
|
+
export {
|
|
145
|
+
PostgresConnection
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=postgres-NF43BPZY.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../connections/postgres.ts"],
|
|
4
|
+
"sourcesContent": ["import pg, {type FieldDef, type PoolConfig, type QueryResult as PgQueryResult} from 'pg'\n\nimport {config} from '../../lang/config.ts'\nimport {type QueryConnection, type QueryParams, type QueryResult, type SchemaColumn} from './types.ts'\n\nexport interface PostgresOptions {\n connectionString?: string\n host?: string\n port?: number\n database?: string\n user?: string\n username?: string\n password?: string\n schema?: string\n ssl?: PoolConfig['ssl']\n max?: number\n idleTimeoutMillis?: number\n connectionTimeoutMillis?: number\n queryTimeout?: number\n statementTimeout?: number\n pool?: PostgresPool\n onClose?: () => Promise<void>\n}\n\ninterface PostgresPool {\n query(sql: string, params?: unknown[]): Promise<PgQueryResult>\n end(): Promise<void>\n}\n\nconst NUMERIC_OIDS = new Set([20, 21, 23, 26, 700, 701, 1700])\nconst DATE_OID = 1082\nconst TIMESTAMP_OIDS = new Set([1114, 1184])\nconst {Pool} = pg\n\nexport class PostgresConnection implements QueryConnection {\n private pool: PostgresPool\n private defaultSchema: string\n private onClose?: () => Promise<void>\n\n constructor(options: PostgresOptions = {}) {\n this.defaultSchema = options.schema || config.postgres?.schema || config.defaultNamespace || 'public'\n this.onClose = options.onClose\n this.pool =\n options.pool ||\n new Pool({\n connectionString: options.connectionString,\n host: options.host,\n port: options.port,\n database: options.database,\n user: options.user || options.username,\n password: options.password,\n ssl: options.ssl,\n max: options.max,\n idleTimeoutMillis: options.idleTimeoutMillis,\n connectionTimeoutMillis: options.connectionTimeoutMillis,\n query_timeout: options.queryTimeout,\n statement_timeout: options.statementTimeout,\n application_name: 'Graphene',\n })\n }\n\n async runQuery(sql: string, params?: QueryParams): Promise<QueryResult> {\n let [preparedSql, preparedParams] = preparePostgresParams(sql, params)\n let result = await this.pool.query(preparedSql, preparedParams)\n let rows = result.rows.map(row => normalizeRow(row, result.fields))\n return {rows, totalRows: result.rowCount ?? rows.length}\n }\n\n async listDatasets(): Promise<string[]> {\n let res = await this.runQuery(`\n select schema_name\n from information_schema.schemata\n where schema_name not in ('information_schema', 'pg_catalog')\n and schema_name not like 'pg_toast%'\n and schema_name not like 'pg_temp%'\n order by schema_name\n `)\n return res.rows.map(row => String(row['schema_name']).toLowerCase())\n }\n\n async listTables(schema = this.defaultSchema): Promise<string[]> {\n let sql = `\n select table_name\n from information_schema.tables\n where lower(table_schema) = lower($1)\n and table_type in ('BASE TABLE', 'VIEW')\n order by table_name\n `.trim()\n let res = await this.runQuery(sql, [schema])\n return res.rows.map(row => String(row['table_name']).toLowerCase())\n }\n\n async describeTable(target: string): Promise<SchemaColumn[]> {\n let parts = target.split('.').filter(Boolean)\n let table = parts.pop() || ''\n let schema = parts.join('.') || this.defaultSchema\n let sql = `\n select column_name, data_type, udt_name, ordinal_position\n from information_schema.columns\n where lower(table_schema) = lower($1)\n and lower(table_name) = lower($2)\n order by ordinal_position\n `.trim()\n let res = await this.runQuery(sql, [schema, table])\n return res.rows.map(row => ({name: String(row['column_name']).toLowerCase(), dataType: postgresDisplayType(row)}))\n }\n\n async close(): Promise<void> {\n try {\n await this.pool.end()\n } finally {\n await this.onClose?.()\n }\n }\n}\n\nfunction preparePostgresParams(sql: string, params?: QueryParams): [string, unknown[] | undefined] {\n if (!params) return [sql, undefined]\n if (Array.isArray(params)) return [sql, params]\n\n let values: unknown[] = []\n let indexes = new Map<string, number>()\n let inString = false\n let out = ''\n\n for (let i = 0; i < sql.length; i++) {\n let ch = sql[i]\n if (ch == \"'\") {\n out += ch\n if (inString && sql[i + 1] == \"'\") {\n out += sql[++i]\n continue\n }\n inString = !inString\n continue\n }\n\n let match = !inString && ch == '$' ? sql.slice(i).match(/^\\$([A-Za-z_][A-Za-z0-9_]*)/) : null\n if (!match) {\n out += ch\n continue\n }\n\n let name = match[1]\n if (!(name in params)) throw new Error(`Missing param $${name}`)\n if (!indexes.has(name)) {\n values.push(params[name])\n indexes.set(name, values.length)\n }\n out += `$${indexes.get(name)}`\n i += name.length\n }\n\n return [out, values]\n}\n\nfunction normalizeRow(row: Record<string, unknown>, fields: FieldDef[]): Record<string, unknown> {\n let out: Record<string, unknown> = {}\n for (let [key, value] of Object.entries(row)) {\n let field = fields.find(f => f.name == key)\n out[key] = normalizeValue(value, field?.dataTypeID)\n }\n return out\n}\n\nfunction normalizeValue(value: unknown, oid?: number): unknown {\n if (value === null) return null\n if (typeof value === 'bigint') return Number(value)\n if (typeof value === 'string' && oid && NUMERIC_OIDS.has(oid) && value !== '') return Number(value)\n if (value instanceof Date && oid == DATE_OID) return value.toISOString().slice(0, 10)\n if (value instanceof Date && oid && TIMESTAMP_OIDS.has(oid)) return value.toISOString()\n if (Array.isArray(value)) return value.map(item => normalizeValue(item))\n return value\n}\n\nfunction postgresDisplayType(row: Record<string, unknown>) {\n let dataType = String(row['data_type'])\n let udtName = String(row['udt_name'] || '')\n let udtAliases: Record<string, string> = {int2: 'smallint', int4: 'integer', int8: 'bigint', float4: 'real', float8: 'double precision', bool: 'boolean', varchar: 'character varying'}\n if (dataType == 'ARRAY' && udtName.startsWith('_')) return `${udtAliases[udtName.slice(1)] || udtName.slice(1)}[]`\n if (dataType == 'timestamp without time zone' || dataType == 'timestamp with time zone') return 'timestamp'\n if (dataType == 'USER-DEFINED' && udtName) return udtName\n return dataType\n}\n"],
|
|
5
|
+
"mappings": ";;;;;AAAA,OAAO,QAA6E;AA6BpF,IAAM,eAAe,oBAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC;AAC7D,IAAM,WAAW;AACjB,IAAM,iBAAiB,oBAAI,IAAI,CAAC,MAAM,IAAI,CAAC;AAC3C,IAAM,EAAC,KAAI,IAAI;AAER,IAAM,qBAAN,MAAoD;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,UAA2B,CAAC,GAAG;AACzC,SAAK,gBAAgB,QAAQ,UAAU,OAAO,UAAU,UAAU,OAAO,oBAAoB;AAC7F,SAAK,UAAU,QAAQ;AACvB,SAAK,OACH,QAAQ,QACR,IAAI,KAAK;AAAA,MACP,kBAAkB,QAAQ;AAAA,MAC1B,MAAM,QAAQ;AAAA,MACd,MAAM,QAAQ;AAAA,MACd,UAAU,QAAQ;AAAA,MAClB,MAAM,QAAQ,QAAQ,QAAQ;AAAA,MAC9B,UAAU,QAAQ;AAAA,MAClB,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,mBAAmB,QAAQ;AAAA,MAC3B,yBAAyB,QAAQ;AAAA,MACjC,eAAe,QAAQ;AAAA,MACvB,mBAAmB,QAAQ;AAAA,MAC3B,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,SAAS,KAAa,QAA4C;AACtE,QAAI,CAAC,aAAa,cAAc,IAAI,sBAAsB,KAAK,MAAM;AACrE,QAAI,SAAS,MAAM,KAAK,KAAK,MAAM,aAAa,cAAc;AAC9D,QAAI,OAAO,OAAO,KAAK,IAAI,SAAO,aAAa,KAAK,OAAO,MAAM,CAAC;AAClE,WAAO,EAAC,MAAM,WAAW,OAAO,YAAY,KAAK,OAAM;AAAA,EACzD;AAAA,EAEA,MAAM,eAAkC;AACtC,QAAI,MAAM,MAAM,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAO7B;AACD,WAAO,IAAI,KAAK,IAAI,SAAO,OAAO,IAAI,aAAa,CAAC,EAAE,YAAY,CAAC;AAAA,EACrE;AAAA,EAEA,MAAM,WAAW,SAAS,KAAK,eAAkC;AAC/D,QAAI,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMR,KAAK;AACP,QAAI,MAAM,MAAM,KAAK,SAAS,KAAK,CAAC,MAAM,CAAC;AAC3C,WAAO,IAAI,KAAK,IAAI,SAAO,OAAO,IAAI,YAAY,CAAC,EAAE,YAAY,CAAC;AAAA,EACpE;AAAA,EAEA,MAAM,cAAc,QAAyC;AAC3D,QAAI,QAAQ,OAAO,MAAM,GAAG,EAAE,OAAO,OAAO;AAC5C,QAAI,QAAQ,MAAM,IAAI,KAAK;AAC3B,QAAI,SAAS,MAAM,KAAK,GAAG,KAAK,KAAK;AACrC,QAAI,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMR,KAAK;AACP,QAAI,MAAM,MAAM,KAAK,SAAS,KAAK,CAAC,QAAQ,KAAK,CAAC;AAClD,WAAO,IAAI,KAAK,IAAI,UAAQ,EAAC,MAAM,OAAO,IAAI,aAAa,CAAC,EAAE,YAAY,GAAG,UAAU,oBAAoB,GAAG,EAAC,EAAE;AAAA,EACnH;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI;AACF,YAAM,KAAK,KAAK,IAAI;AAAA,IACtB,UAAE;AACA,YAAM,KAAK,UAAU;AAAA,IACvB;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,KAAa,QAAuD;AACjG,MAAI,CAAC,OAAQ,QAAO,CAAC,KAAK,MAAS;AACnC,MAAI,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC,KAAK,MAAM;AAE9C,MAAI,SAAoB,CAAC;AACzB,MAAI,UAAU,oBAAI,IAAoB;AACtC,MAAI,WAAW;AACf,MAAI,MAAM;AAEV,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,QAAI,KAAK,IAAI,CAAC;AACd,QAAI,MAAM,KAAK;AACb,aAAO;AACP,UAAI,YAAY,IAAI,IAAI,CAAC,KAAK,KAAK;AACjC,eAAO,IAAI,EAAE,CAAC;AACd;AAAA,MACF;AACA,iBAAW,CAAC;AACZ;AAAA,IACF;AAEA,QAAI,QAAQ,CAAC,YAAY,MAAM,MAAM,IAAI,MAAM,CAAC,EAAE,MAAM,6BAA6B,IAAI;AACzF,QAAI,CAAC,OAAO;AACV,aAAO;AACP;AAAA,IACF;AAEA,QAAI,OAAO,MAAM,CAAC;AAClB,QAAI,EAAE,QAAQ,QAAS,OAAM,IAAI,MAAM,kBAAkB,IAAI,EAAE;AAC/D,QAAI,CAAC,QAAQ,IAAI,IAAI,GAAG;AACtB,aAAO,KAAK,OAAO,IAAI,CAAC;AACxB,cAAQ,IAAI,MAAM,OAAO,MAAM;AAAA,IACjC;AACA,WAAO,IAAI,QAAQ,IAAI,IAAI,CAAC;AAC5B,SAAK,KAAK;AAAA,EACZ;AAEA,SAAO,CAAC,KAAK,MAAM;AACrB;AAEA,SAAS,aAAa,KAA8B,QAA6C;AAC/F,MAAI,MAA+B,CAAC;AACpC,WAAS,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC5C,QAAI,QAAQ,OAAO,KAAK,OAAK,EAAE,QAAQ,GAAG;AAC1C,QAAI,GAAG,IAAI,eAAe,OAAO,OAAO,UAAU;AAAA,EACpD;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAgB,KAAuB;AAC7D,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAClD,MAAI,OAAO,UAAU,YAAY,OAAO,aAAa,IAAI,GAAG,KAAK,UAAU,GAAI,QAAO,OAAO,KAAK;AAClG,MAAI,iBAAiB,QAAQ,OAAO,SAAU,QAAO,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AACpF,MAAI,iBAAiB,QAAQ,OAAO,eAAe,IAAI,GAAG,EAAG,QAAO,MAAM,YAAY;AACtF,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,UAAQ,eAAe,IAAI,CAAC;AACvE,SAAO;AACT;AAEA,SAAS,oBAAoB,KAA8B;AACzD,MAAI,WAAW,OAAO,IAAI,WAAW,CAAC;AACtC,MAAI,UAAU,OAAO,IAAI,UAAU,KAAK,EAAE;AAC1C,MAAI,aAAqC,EAAC,MAAM,YAAY,MAAM,WAAW,MAAM,UAAU,QAAQ,QAAQ,QAAQ,oBAAoB,MAAM,WAAW,SAAS,oBAAmB;AACtL,MAAI,YAAY,WAAW,QAAQ,WAAW,GAAG,EAAG,QAAO,GAAG,WAAW,QAAQ,MAAM,CAAC,CAAC,KAAK,QAAQ,MAAM,CAAC,CAAC;AAC9G,MAAI,YAAY,iCAAiC,YAAY,2BAA4B,QAAO;AAChG,MAAI,YAAY,kBAAkB,QAAS,QAAO;AAClD,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
runQuery,
|
|
7
7
|
runVitePlugin,
|
|
8
8
|
toSql
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KYTXXLSS.js";
|
|
10
10
|
import {
|
|
11
11
|
config
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KW66YQ62.js";
|
|
13
13
|
|
|
14
14
|
// serve2.ts
|
|
15
15
|
import { svelte, vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
|
@@ -408,6 +408,10 @@ var handleRequestPlugin = {
|
|
|
408
408
|
if (!pathName || pathName == "/") pathName = "index";
|
|
409
409
|
let relativeMdPath = pathName.replace(/^\//, "") + ".md";
|
|
410
410
|
let mdPath = path2.join(config.root, relativeMdPath);
|
|
411
|
+
if (!mockFileMap[relativeMdPath] && !await fs2.exists(mdPath)) {
|
|
412
|
+
relativeMdPath = pathName.replace(/^\//, "") + "/index.md";
|
|
413
|
+
mdPath = path2.join(config.root, relativeMdPath);
|
|
414
|
+
}
|
|
411
415
|
if (mockFileMap[relativeMdPath] || await fs2.exists(mdPath)) {
|
|
412
416
|
await handlePage(s, res);
|
|
413
417
|
} else {
|
|
@@ -445,4 +449,4 @@ export {
|
|
|
445
449
|
serve2,
|
|
446
450
|
svelteWarnings
|
|
447
451
|
};
|
|
448
|
-
//# sourceMappingURL=serve2-
|
|
452
|
+
//# sourceMappingURL=serve2-XALOUIFB.js.map
|