@typed-sql/cli 2.1.0 → 2.2.0-rc.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/CHANGELOG.md +26 -0
- package/dist/packages/cli/src/cli.js +47 -41
- package/dist/packages/cli/src/cli.js.map +1 -1
- package/dist/packages/cli/src/init-apply.d.ts +11 -0
- package/dist/packages/cli/src/init-apply.d.ts.map +1 -0
- package/dist/packages/cli/src/init-apply.js +152 -0
- package/dist/packages/cli/src/init-apply.js.map +1 -0
- package/dist/packages/cli/src/init-files.d.ts +13 -0
- package/dist/packages/cli/src/init-files.d.ts.map +1 -0
- package/dist/packages/cli/src/init-files.js +116 -0
- package/dist/packages/cli/src/init-files.js.map +1 -0
- package/dist/packages/cli/src/init-install.d.ts +3 -0
- package/dist/packages/cli/src/init-install.d.ts.map +1 -0
- package/dist/packages/cli/src/init-install.js +27 -0
- package/dist/packages/cli/src/init-install.js.map +1 -0
- package/dist/packages/cli/src/init-json.d.ts +3 -0
- package/dist/packages/cli/src/init-json.d.ts.map +1 -0
- package/dist/packages/cli/src/init-json.js +29 -0
- package/dist/packages/cli/src/init-json.js.map +1 -0
- package/dist/packages/cli/src/init-plan.d.ts +38 -0
- package/dist/packages/cli/src/init-plan.d.ts.map +1 -0
- package/dist/packages/cli/src/init-plan.js +244 -0
- package/dist/packages/cli/src/init-plan.js.map +1 -0
- package/dist/packages/cli/src/init-verify.d.ts +3 -0
- package/dist/packages/cli/src/init-verify.d.ts.map +1 -0
- package/dist/packages/cli/src/init-verify.js +99 -0
- package/dist/packages/cli/src/init-verify.js.map +1 -0
- package/dist/packages/cli/src/init.d.ts +2 -0
- package/dist/packages/cli/src/init.d.ts.map +1 -0
- package/dist/packages/cli/src/init.js +54 -0
- package/dist/packages/cli/src/init.js.map +1 -0
- package/package.json +7 -5
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { link, lstat, mkdir, open, rename, unlink } from "node:fs/promises";
|
|
4
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
5
|
+
export const initHash = (text) => createHash("sha256").update(text).digest("hex");
|
|
6
|
+
export function assertInitProjectPath(root, file) {
|
|
7
|
+
const path = relative(root, resolve(file));
|
|
8
|
+
if (!isAbsolute(file) ||
|
|
9
|
+
file !== resolve(file) ||
|
|
10
|
+
path === "" ||
|
|
11
|
+
path.startsWith("..") ||
|
|
12
|
+
isAbsolute(path) ||
|
|
13
|
+
path.split(/[\\/]/u)[0] === ".typed-sql")
|
|
14
|
+
throw new Error(`Invalid setup project path: ${file}`);
|
|
15
|
+
}
|
|
16
|
+
export async function syncInitDirectory(directory) {
|
|
17
|
+
if (process.platform === "win32")
|
|
18
|
+
return;
|
|
19
|
+
const handle = await open(directory, "r");
|
|
20
|
+
try {
|
|
21
|
+
await handle.sync();
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
await handle.close();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function readInitFile(file) {
|
|
28
|
+
try {
|
|
29
|
+
const handle = await open(file, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
30
|
+
try {
|
|
31
|
+
const info = await handle.stat();
|
|
32
|
+
// Validate the opened descriptor, not a path checked before open. On Windows,
|
|
33
|
+
// where O_NOFOLLOW is unavailable, also reject a link or replaced pathname.
|
|
34
|
+
const existing = await lstat(file);
|
|
35
|
+
if (existing.isSymbolicLink() || existing.dev !== info.dev || existing.ino !== info.ino)
|
|
36
|
+
throw new Error(`Setup requires a regular non-symlink file: ${file}`);
|
|
37
|
+
if (!info.isFile() || info.size > 16 * 1024 * 1024)
|
|
38
|
+
throw new Error(`Setup requires a regular file of at most 16 MiB: ${file}`);
|
|
39
|
+
return { text: await handle.readFile("utf8"), mode: info.mode & 0o777 };
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await handle.close();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
47
|
+
return undefined;
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Reject escapes and symlinked ancestors before reading or replacing project files. */
|
|
52
|
+
export async function checkInitPath(root, file, createParents = false) {
|
|
53
|
+
const path = relative(root, file);
|
|
54
|
+
if (!path || path.startsWith("..") || isAbsolute(path))
|
|
55
|
+
throw new Error(`Setup path is outside the application: ${file}`);
|
|
56
|
+
let current = root;
|
|
57
|
+
const parts = path.split(/[\\/]/u);
|
|
58
|
+
for (const [index, part] of parts.entries()) {
|
|
59
|
+
current = join(current, part);
|
|
60
|
+
const parent = index < parts.length - 1;
|
|
61
|
+
let info;
|
|
62
|
+
try {
|
|
63
|
+
info = await lstat(current);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
|
|
67
|
+
throw error;
|
|
68
|
+
if (!createParents || !parent)
|
|
69
|
+
return;
|
|
70
|
+
await mkdir(current, { mode: current === join(root, ".typed-sql") ? 0o700 : 0o755 }).catch((failure) => {
|
|
71
|
+
if (!(failure instanceof Error && "code" in failure && failure.code === "EEXIST"))
|
|
72
|
+
throw failure;
|
|
73
|
+
});
|
|
74
|
+
info = await lstat(current);
|
|
75
|
+
}
|
|
76
|
+
if (info.isSymbolicLink() || (parent ? !info.isDirectory() : !info.isFile()))
|
|
77
|
+
throw new Error(`Setup refuses a symlink or unexpected file type: ${current}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export async function assertInitFile(root, file, expected) {
|
|
81
|
+
await checkInitPath(root, file);
|
|
82
|
+
const current = await readInitFile(file);
|
|
83
|
+
if ((current === undefined ? null : initHash(current.text)) !== expected)
|
|
84
|
+
throw new Error(`Concurrent edit detected; regenerate the setup plan: ${file}`);
|
|
85
|
+
return current;
|
|
86
|
+
}
|
|
87
|
+
export async function writeInitFile(root, file, content, expected, mode) {
|
|
88
|
+
await checkInitPath(root, file, true);
|
|
89
|
+
const previous = await assertInitFile(root, file, expected);
|
|
90
|
+
const temporary = join(dirname(file), `.typed-sql-init-${randomUUID()}`);
|
|
91
|
+
try {
|
|
92
|
+
const handle = await open(temporary, "wx", mode ?? previous?.mode ?? 0o666 & ~process.umask());
|
|
93
|
+
try {
|
|
94
|
+
if (previous !== undefined || mode !== undefined)
|
|
95
|
+
await handle.chmod(mode ?? previous.mode);
|
|
96
|
+
await handle.writeFile(content, "utf8");
|
|
97
|
+
await handle.sync();
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
await handle.close();
|
|
101
|
+
}
|
|
102
|
+
await assertInitFile(root, file, expected);
|
|
103
|
+
if (expected === null)
|
|
104
|
+
await link(temporary, file); // Atomic creation must never overwrite a new user file.
|
|
105
|
+
else
|
|
106
|
+
await rename(temporary, file);
|
|
107
|
+
await syncInitDirectory(dirname(file));
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await unlink(temporary).catch((error) => {
|
|
111
|
+
if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
|
|
112
|
+
throw error;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=init-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-files.js","sourceRoot":"","sources":["../../../../src/init-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-install.d.ts","sourceRoot":"","sources":["../../../../src/init-install.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI/C,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBlG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { execFile as callback } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFile = promisify(callback);
|
|
4
|
+
export async function installInitDependencies(plan, allowScripts) {
|
|
5
|
+
const args = ["install", ...(allowScripts || plan.packageManager === "yarn" ? [] : ["--ignore-scripts"])];
|
|
6
|
+
const env = {
|
|
7
|
+
...process.env,
|
|
8
|
+
...(allowScripts ? {} : { YARN_ENABLE_SCRIPTS: "false", YARN_IGNORE_SCRIPTS: "true" }),
|
|
9
|
+
};
|
|
10
|
+
// Never execute npm_execpath or ComSpec supplied by the caller's environment.
|
|
11
|
+
const manager = plan.packageManager === "pnpm"
|
|
12
|
+
? "pnpm"
|
|
13
|
+
: plan.packageManager === "npm"
|
|
14
|
+
? "npm"
|
|
15
|
+
: plan.packageManager === "yarn"
|
|
16
|
+
? "yarn"
|
|
17
|
+
: plan.packageManager === "bun"
|
|
18
|
+
? "bun"
|
|
19
|
+
: undefined;
|
|
20
|
+
if (manager === undefined)
|
|
21
|
+
throw new Error("Unsupported package manager");
|
|
22
|
+
const command = process.platform === "win32" ? "cmd.exe" : manager;
|
|
23
|
+
// Only fixed manager names and flags enter Windows command syntax.
|
|
24
|
+
const commandArgs = process.platform === "win32" ? ["/d", "/v:off", "/s", "/c", [manager, ...args].join(" ")] : args;
|
|
25
|
+
await execFile(command, commandArgs, { cwd: plan.root, env, timeout: 600_000, maxBuffer: 8 * 1024 * 1024 });
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=init-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-install.js","sourceRoot":"","sources":["../../../../src/init-install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAAc,EAAE,YAAqB;IACjF,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC1G,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC;KACvF,CAAC;IACF,8EAA8E;IAC9E,MAAM,OAAO,GACX,IAAI,CAAC,cAAc,KAAK,MAAM;QAC5B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,IAAI,CAAC,cAAc,KAAK,KAAK;YAC7B,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,CAAC,cAAc,KAAK,MAAM;gBAC9B,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,IAAI,CAAC,cAAc,KAAK,KAAK;oBAC7B,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,SAAS,CAAC;IACtB,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,mEAAmE;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrH,MAAM,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;AAC9G,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-json.d.ts","sourceRoot":"","sources":["../../../../src/init-json.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,UAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmB9F;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAKrG"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { applyEdits, getNodeValue, modify, parseTree } from "jsonc-parser";
|
|
2
|
+
export function initJson(text, label, comments = true) {
|
|
3
|
+
const errors = [];
|
|
4
|
+
const root = parseTree(text, errors, { allowTrailingComma: comments, disallowComments: !comments });
|
|
5
|
+
if (errors.length > 0 || root?.type !== "object")
|
|
6
|
+
throw new Error(`${label} must be an object with valid ${comments ? "JSONC" : "JSON"}`);
|
|
7
|
+
const visit = (node) => {
|
|
8
|
+
if (node.type === "object") {
|
|
9
|
+
const keys = new Set();
|
|
10
|
+
for (const property of node.children ?? []) {
|
|
11
|
+
const key = property.children?.[0]?.value;
|
|
12
|
+
if (keys.has(key))
|
|
13
|
+
throw new Error(`Duplicate key ${JSON.stringify(key)} in ${label}; reconcile it before setup`);
|
|
14
|
+
keys.add(key);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
for (const child of node.children ?? [])
|
|
18
|
+
visit(child);
|
|
19
|
+
};
|
|
20
|
+
visit(root);
|
|
21
|
+
return getNodeValue(root);
|
|
22
|
+
}
|
|
23
|
+
export function editInitJson(text, path, value) {
|
|
24
|
+
const edits = modify(text, [...path], value, {
|
|
25
|
+
formattingOptions: { insertSpaces: true, tabSize: 2, eol: text.includes("\r\n") ? "\r\n" : "\n" },
|
|
26
|
+
});
|
|
27
|
+
return applyEdits(text, edits);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=init-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-json.js","sourceRoot":"","sources":["../../../../src/init-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAA8B,SAAS,EAAE,MAAM,cAAc,CAAC;AAEvG,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa,EAAE,QAAQ,GAAG,IAAI;IACnE,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpG,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,QAAQ;QAC9C,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iCAAiC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,CAAC,IAAU,EAAQ,EAAE;QACjC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;YAC/B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;gBAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,KAAe,CAAC;gBACpD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,KAAK,6BAA6B,CAAC,CAAC;gBACjG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE;YAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,OAAO,YAAY,CAAC,IAAI,CAA4B,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAkC,EAAE,KAAc;IAC3F,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE;QAC3C,iBAAiB,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE;KAClG,CAAC,CAAC;IACH,OAAO,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
declare const grammars: {
|
|
2
|
+
readonly postgres: {
|
|
3
|
+
readonly package: "@typed-sql/postgres";
|
|
4
|
+
readonly factory: "postgres";
|
|
5
|
+
};
|
|
6
|
+
readonly mysql: {
|
|
7
|
+
readonly package: "@typed-sql/mysql";
|
|
8
|
+
readonly factory: "mysql";
|
|
9
|
+
};
|
|
10
|
+
readonly sqlite: {
|
|
11
|
+
readonly package: "@typed-sql/sqlite";
|
|
12
|
+
readonly factory: "sqlite";
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
declare const managers: readonly ["npm", "pnpm", "yarn", "bun"];
|
|
16
|
+
type Manager = (typeof managers)[number];
|
|
17
|
+
export interface InitFile {
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly beforeHash: string | null;
|
|
20
|
+
readonly content: string;
|
|
21
|
+
}
|
|
22
|
+
export interface InitPlan {
|
|
23
|
+
readonly formatVersion: 1;
|
|
24
|
+
readonly mode: "plan";
|
|
25
|
+
readonly root: string;
|
|
26
|
+
readonly packageManager: Manager;
|
|
27
|
+
readonly grammar: keyof typeof grammars;
|
|
28
|
+
readonly editor: "none" | "vscode" | "zed";
|
|
29
|
+
readonly files: readonly InitFile[];
|
|
30
|
+
readonly dependencies: Readonly<Record<string, string>>;
|
|
31
|
+
readonly scripts: Readonly<Record<string, string>>;
|
|
32
|
+
readonly detected: readonly string[];
|
|
33
|
+
readonly pending: readonly string[];
|
|
34
|
+
readonly warnings: readonly string[];
|
|
35
|
+
}
|
|
36
|
+
export declare function planInit(options: Readonly<Record<string, string>>, version: string): Promise<InitPlan>;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=init-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-plan.d.ts","sourceRoot":"","sources":["../../../../src/init-plan.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,QAAQ;aACZ,QAAQ;iBAAI,OAAO,EAAE,qBAAqB;iBAAE,OAAO,EAAE,UAAU;;aAC/D,KAAK;iBAAI,OAAO,EAAE,kBAAkB;iBAAE,OAAO,EAAE,OAAO;;aACtD,MAAM;iBAAI,OAAO,EAAE,mBAAmB;iBAAE,OAAO,EAAE,QAAQ;;CACjD,CAAC;AACX,QAAA,MAAM,QAAQ,YAAI,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAC;AACzD,KAAK,OAAO,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAGzC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,QAAQ,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAiBD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0O5G"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { lstat, realpath } from "node:fs/promises";
|
|
3
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
4
|
+
import { TYPESCRIPT_COMPILER_SUPPORT_POLICY } from "@typed-sql/compiler";
|
|
5
|
+
import { checkInitPath, readInitFile } from "./init-files.js";
|
|
6
|
+
import { editInitJson, initJson } from "./init-json.js";
|
|
7
|
+
const grammars = {
|
|
8
|
+
postgres: { package: "@typed-sql/postgres", factory: "postgres" },
|
|
9
|
+
mysql: { package: "@typed-sql/mysql", factory: "mysql" },
|
|
10
|
+
sqlite: { package: "@typed-sql/sqlite", factory: "sqlite" },
|
|
11
|
+
};
|
|
12
|
+
const managers = ["npm", "pnpm", "yarn", "bun"];
|
|
13
|
+
function object(value, label) {
|
|
14
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
15
|
+
throw new Error(`${label} must be an object`);
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
async function read(path) {
|
|
19
|
+
return (await readInitFile(path))?.text;
|
|
20
|
+
}
|
|
21
|
+
function manager(value) {
|
|
22
|
+
if (!managers.includes(value))
|
|
23
|
+
throw new Error(`Unsupported package manager: ${value}`);
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
export async function planInit(options, version) {
|
|
27
|
+
const allowed = new Set(["cwd", "package", "grammar", "editor", "package-manager", "dry-run", "json"]);
|
|
28
|
+
for (const [key, value] of Object.entries(options)) {
|
|
29
|
+
if (!allowed.has(key))
|
|
30
|
+
throw new Error(`Unknown init option --${key}`);
|
|
31
|
+
if ((key === "dry-run" || key === "json") && value !== "true")
|
|
32
|
+
throw new Error(`--${key} does not accept a value`);
|
|
33
|
+
}
|
|
34
|
+
const grammar = options.grammar;
|
|
35
|
+
if (!Object.hasOwn(grammars, grammar ?? ""))
|
|
36
|
+
throw new Error("init requires --grammar postgres|mysql|sqlite");
|
|
37
|
+
const editor = options.editor ?? "none";
|
|
38
|
+
if (editor !== "none" && editor !== "vscode" && editor !== "zed")
|
|
39
|
+
throw new Error("--editor must be none, vscode, or zed");
|
|
40
|
+
const base = await realpath(resolve(options.cwd ?? process.cwd()));
|
|
41
|
+
let root = base;
|
|
42
|
+
if (options.package !== undefined) {
|
|
43
|
+
const target = resolve(base, options.package);
|
|
44
|
+
const path = relative(base, target);
|
|
45
|
+
if (isAbsolute(options.package) || path.startsWith("..") || isAbsolute(path))
|
|
46
|
+
throw new Error("--package must select a directory inside --cwd");
|
|
47
|
+
let current = base;
|
|
48
|
+
for (const part of path.split(/[\\/]/u).filter(Boolean)) {
|
|
49
|
+
current = join(current, part);
|
|
50
|
+
const stat = await lstat(current);
|
|
51
|
+
if (stat.isSymbolicLink() || !stat.isDirectory())
|
|
52
|
+
throw new Error("--package cannot traverse symlinks or files");
|
|
53
|
+
}
|
|
54
|
+
root = target;
|
|
55
|
+
}
|
|
56
|
+
const manifestText = await read(join(root, "package.json"));
|
|
57
|
+
const manifest = manifestText === undefined ? { private: true, type: "module" } : initJson(manifestText, "package.json", false);
|
|
58
|
+
if ((manifest.workspaces !== undefined || (await read(join(root, "pnpm-workspace.yaml"))) !== undefined) &&
|
|
59
|
+
options.package === undefined)
|
|
60
|
+
throw new Error("Workspace root is ambiguous; select an application with --package");
|
|
61
|
+
const detected = [];
|
|
62
|
+
const candidates = new Set();
|
|
63
|
+
for (let directory = root;; directory = dirname(directory)) {
|
|
64
|
+
const parentText = directory === root ? manifestText : await read(join(directory, "package.json"));
|
|
65
|
+
const parent = parentText === undefined ? {} : initJson(parentText, "package.json", false);
|
|
66
|
+
if (parent.packageManager !== undefined) {
|
|
67
|
+
if (typeof parent.packageManager !== "string" || !/^(npm|pnpm|yarn|bun)@[^\s]+$/u.test(parent.packageManager))
|
|
68
|
+
throw new Error(`Invalid packageManager in ${directory}`);
|
|
69
|
+
candidates.add(manager(parent.packageManager.split("@")[0]));
|
|
70
|
+
}
|
|
71
|
+
for (const [file, name] of [
|
|
72
|
+
["package-lock.json", "npm"],
|
|
73
|
+
["npm-shrinkwrap.json", "npm"],
|
|
74
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
75
|
+
["yarn.lock", "yarn"],
|
|
76
|
+
["bun.lock", "bun"],
|
|
77
|
+
["bun.lockb", "bun"],
|
|
78
|
+
]) {
|
|
79
|
+
if ((await read(join(directory, file))) !== undefined) {
|
|
80
|
+
candidates.add(name);
|
|
81
|
+
detected.push(join(directory, file));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (parent.workspaces !== undefined ||
|
|
85
|
+
(await read(join(directory, "pnpm-workspace.yaml"))) !== undefined ||
|
|
86
|
+
dirname(directory) === directory)
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
if (options["package-manager"] !== undefined)
|
|
90
|
+
candidates.add(manager(options["package-manager"]));
|
|
91
|
+
if (candidates.size > 1)
|
|
92
|
+
throw new Error(`Conflicting package managers: ${[...candidates].sort().join(", ")}`);
|
|
93
|
+
const packageManager = [...candidates][0] ?? "npm";
|
|
94
|
+
const dependencies = {};
|
|
95
|
+
const existing = {
|
|
96
|
+
...object(manifest.devDependencies ?? {}, "devDependencies"),
|
|
97
|
+
...object(manifest.dependencies ?? {}, "dependencies"),
|
|
98
|
+
};
|
|
99
|
+
for (const [name, range] of [
|
|
100
|
+
["@typed-sql/cli", `^${version}`],
|
|
101
|
+
["@typed-sql/core", `^${version}`],
|
|
102
|
+
[grammars[grammar].package, `^${version}`],
|
|
103
|
+
["typescript", TYPESCRIPT_COMPILER_SUPPORT_POLICY.exactVersion],
|
|
104
|
+
]) {
|
|
105
|
+
const value = existing[name];
|
|
106
|
+
if (value !== undefined && typeof value !== "string")
|
|
107
|
+
throw new Error(`Invalid dependency ${name}`);
|
|
108
|
+
if (value === undefined)
|
|
109
|
+
dependencies[name] = range;
|
|
110
|
+
}
|
|
111
|
+
if (editor !== "none" && existing["@typed-sql/language-server"] === undefined)
|
|
112
|
+
dependencies["@typed-sql/language-server"] = "next";
|
|
113
|
+
const files = [];
|
|
114
|
+
const add = (path, content, before) => files.push({
|
|
115
|
+
path: join(root, path),
|
|
116
|
+
beforeHash: before === undefined ? null : createHash("sha256").update(before).digest("hex"),
|
|
117
|
+
content,
|
|
118
|
+
});
|
|
119
|
+
const warnings = [];
|
|
120
|
+
if (Object.keys(existing).length > 0)
|
|
121
|
+
warnings.push("Existing dependency ranges are preserved; compatibility and registry availability have not been checked.");
|
|
122
|
+
const scripts = {};
|
|
123
|
+
const existingScripts = object(manifest.scripts ?? {}, "scripts");
|
|
124
|
+
for (const [name, command] of [
|
|
125
|
+
["typed-sql:generate", "typed-sql generate"],
|
|
126
|
+
["typed-sql:check", "typed-sql check"],
|
|
127
|
+
]) {
|
|
128
|
+
if (existingScripts[name] === undefined)
|
|
129
|
+
scripts[name] = command;
|
|
130
|
+
else if (existingScripts[name] !== command)
|
|
131
|
+
warnings.push(`Preserve existing script ${name}; proposed command is ${command}.`);
|
|
132
|
+
}
|
|
133
|
+
const pending = [
|
|
134
|
+
"Supply or introspect a real schema snapshot, then run typed-sql generate and doctor. No database access is authorized by this plan.",
|
|
135
|
+
];
|
|
136
|
+
if (Object.keys(dependencies).length > 0)
|
|
137
|
+
pending.push(`Install the listed dependencies with ${packageManager}; installation and lifecycle scripts require separate approval.`);
|
|
138
|
+
let updatedManifest = manifestText ?? `${JSON.stringify(manifest, null, 2)}\n`;
|
|
139
|
+
for (const [name, range] of Object.entries(dependencies))
|
|
140
|
+
updatedManifest = editInitJson(updatedManifest, [name === "@typed-sql/core" || name === grammars[grammar].package ? "dependencies" : "devDependencies", name], range);
|
|
141
|
+
for (const [name, command] of Object.entries(scripts))
|
|
142
|
+
updatedManifest = editInitJson(updatedManifest, ["scripts", name], command);
|
|
143
|
+
if (updatedManifest !== manifestText)
|
|
144
|
+
add("package.json", updatedManifest, manifestText);
|
|
145
|
+
if (manifestText !== undefined)
|
|
146
|
+
detected.push(join(root, "package.json"));
|
|
147
|
+
const configs = [
|
|
148
|
+
"typed-sql.config.ts",
|
|
149
|
+
"typed-sql.config.mts",
|
|
150
|
+
"typed-sql.config.cts",
|
|
151
|
+
"typed-sql.config.js",
|
|
152
|
+
"typed-sql.config.mjs",
|
|
153
|
+
"typed-sql.config.cjs",
|
|
154
|
+
];
|
|
155
|
+
const found = [];
|
|
156
|
+
for (const file of configs)
|
|
157
|
+
if ((await read(join(root, file))) !== undefined)
|
|
158
|
+
found.push(file);
|
|
159
|
+
if (found.length > 1)
|
|
160
|
+
throw new Error(`Multiple typed-sql configurations: ${found.join(", ")}`);
|
|
161
|
+
if (found.length === 0)
|
|
162
|
+
add("typed-sql.config.ts", `import { ${grammars[grammar].factory} } from ${JSON.stringify(grammars[grammar].package)};\n\nexport default {\n dialect: ${grammars[grammar].factory}(),\n schema: { file: "schema.json" },\n outDir: "generated",\n projects: ["tsconfig.json"],\n};\n`);
|
|
163
|
+
else {
|
|
164
|
+
detected.push(join(root, found[0]));
|
|
165
|
+
warnings.push("Existing typed-sql configuration is preserved and was not executed; its grammar and paths are unverified.");
|
|
166
|
+
}
|
|
167
|
+
for (const file of ["tsconfig.json", "schema.json"]) {
|
|
168
|
+
if ((await read(join(root, file))) !== undefined)
|
|
169
|
+
detected.push(join(root, file));
|
|
170
|
+
else if (file === "tsconfig.json")
|
|
171
|
+
add(file, `${JSON.stringify({ compilerOptions: { strict: true, noEmit: true, target: "ES2024", module: "NodeNext", jsx: "preserve", skipLibCheck: true }, include: ["src/**/*.ts", "src/**/*.tsx"] }, null, 2)}\n`);
|
|
172
|
+
}
|
|
173
|
+
const ignorePath = join(root, ".gitignore");
|
|
174
|
+
await checkInitPath(root, ignorePath);
|
|
175
|
+
const ignore = await read(ignorePath);
|
|
176
|
+
if (!ignore?.split(/\r?\n/u).includes("/.typed-sql/"))
|
|
177
|
+
add(".gitignore", `${ignore ?? ""}${ignore === undefined || ignore.endsWith("\n") ? "" : "\n"}/.typed-sql/\n`, ignore);
|
|
178
|
+
if (editor !== "none") {
|
|
179
|
+
const editorFile = editor === "vscode" ? ".vscode/settings.json" : ".zed/settings.json";
|
|
180
|
+
const path = join(root, editorFile);
|
|
181
|
+
await checkInitPath(root, path);
|
|
182
|
+
const before = await read(path);
|
|
183
|
+
const settings = initJson(before ?? "{}\n", editorFile);
|
|
184
|
+
let content = before ?? "{}\n";
|
|
185
|
+
if (editor === "vscode") {
|
|
186
|
+
const values = {
|
|
187
|
+
"typedSql.providerMode": "native-sdk",
|
|
188
|
+
"js/ts.experimental.useTsgo": true,
|
|
189
|
+
"js/ts.tsdk.path": `./node_modules/@typed-sql/language-server/sdk/${process.platform}-${process.arch}`,
|
|
190
|
+
};
|
|
191
|
+
for (const [key, value] of Object.entries(values)) {
|
|
192
|
+
if (settings[key] === undefined)
|
|
193
|
+
content = editInitJson(content, [key], value);
|
|
194
|
+
else if (settings[key] !== value)
|
|
195
|
+
warnings.push(`Preserve existing editor setting ${key}; requested value is ${JSON.stringify(value)}.`);
|
|
196
|
+
}
|
|
197
|
+
const extensionPath = join(root, ".vscode/extensions.json");
|
|
198
|
+
await checkInitPath(root, extensionPath);
|
|
199
|
+
const extensionBefore = await read(extensionPath);
|
|
200
|
+
const extensions = initJson(extensionBefore ?? "{}\n", ".vscode/extensions.json");
|
|
201
|
+
if (extensions.recommendations !== undefined &&
|
|
202
|
+
(!Array.isArray(extensions.recommendations) ||
|
|
203
|
+
!extensions.recommendations.every((value) => typeof value === "string")))
|
|
204
|
+
throw new Error(".vscode/extensions.json recommendations must be an array of strings");
|
|
205
|
+
let extensionContent = extensionBefore ?? "{}\n";
|
|
206
|
+
const recommended = (extensions.recommendations ?? []);
|
|
207
|
+
if (extensions.recommendations === undefined)
|
|
208
|
+
extensionContent = editInitJson(extensionContent, ["recommendations"], []);
|
|
209
|
+
for (const id of ["TypeScriptTeam.native-preview", "lojhan.typed-sql"])
|
|
210
|
+
if (!recommended.some((value) => value.toLowerCase() === id.toLowerCase()))
|
|
211
|
+
extensionContent = editInitJson(extensionContent, ["recommendations", -1], id);
|
|
212
|
+
if (extensionContent !== extensionBefore)
|
|
213
|
+
add(".vscode/extensions.json", extensionContent, extensionBefore);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
const languages = object(settings.languages ?? {}, "Zed languages");
|
|
217
|
+
for (const name of ["TypeScript", "TSX"]) {
|
|
218
|
+
const language = object(languages[name] ?? {}, `Zed ${name}`);
|
|
219
|
+
if (language.language_servers === undefined)
|
|
220
|
+
content = editInitJson(content, ["languages", name, "language_servers"], ["typed-sql", "!vtsls", "!tsgo", "!typescript-language-server", "..."]);
|
|
221
|
+
else
|
|
222
|
+
warnings.push(`Preserve existing Zed ${name} language_servers; ensure typed-sql is the sole TypeScript provider.`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (content !== before)
|
|
226
|
+
add(editorFile, content, before);
|
|
227
|
+
pending.push(`${editor}: install the editor extensions separately and trust the application workspace. For VS Code, select Use Workspace Version for the native SDK. Configuration alone does not prove server readiness or host verification.`);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
formatVersion: 1,
|
|
231
|
+
mode: "plan",
|
|
232
|
+
root,
|
|
233
|
+
packageManager,
|
|
234
|
+
grammar,
|
|
235
|
+
editor,
|
|
236
|
+
files,
|
|
237
|
+
dependencies,
|
|
238
|
+
scripts,
|
|
239
|
+
detected: detected.sort(),
|
|
240
|
+
pending,
|
|
241
|
+
warnings,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=init-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-plan.js","sourceRoot":"","sources":["../../../../src/init-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,kCAAkC,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,QAAQ,GAAG;IACf,QAAQ,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,UAAU,EAAE;IACjE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,EAAE;IACxD,MAAM,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,QAAQ,EAAE;CACnD,CAAC;AACX,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAC;AAyBzD,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa;IAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,CAAC,CAAC;IAChD,OAAO,KAAmB,CAAC;AAC7B,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,IAAY;IAC9B,OAAO,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAC1C,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAgB,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;IACnG,OAAO,KAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAyC,EAAE,OAAe;IACvF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IACvG,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,MAAM,CAAC,IAAI,KAAK,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,KAAK,GAAG,0BAA0B,CAAC,CAAC;IACrH,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAgC,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC9G,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC;IACxC,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,KAAK;QAC9D,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACnE,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;YAC1E,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACxD,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACnH,CAAC;QACD,IAAI,GAAG,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;IAC5D,MAAM,QAAQ,GACZ,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;IACjH,IACE,CAAC,QAAQ,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;QACpG,OAAO,CAAC,OAAO,KAAK,SAAS;QAE7B,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAW,CAAC;IACtC,KAAK,IAAI,SAAS,GAAG,IAAI,GAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5D,MAAM,UAAU,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;QACnG,MAAM,MAAM,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;QAC3F,IAAI,MAAM,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACxC,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,QAAQ,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;gBAC3G,MAAM,IAAI,KAAK,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC;YAC5D,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI;YACzB,CAAC,mBAAmB,EAAE,KAAK,CAAC;YAC5B,CAAC,qBAAqB,EAAE,KAAK,CAAC;YAC9B,CAAC,gBAAgB,EAAE,MAAM,CAAC;YAC1B,CAAC,WAAW,EAAE,MAAM,CAAC;YACrB,CAAC,UAAU,EAAE,KAAK,CAAC;YACnB,CAAC,WAAW,EAAE,KAAK,CAAC;SACZ,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBACtD,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QACD,IACE,MAAM,CAAC,UAAU,KAAK,SAAS;YAC/B,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,SAAS;YAClE,OAAO,CAAC,SAAS,CAAC,KAAK,SAAS;YAEhC,MAAM;IACV,CAAC;IACD,IAAI,OAAO,CAAC,iBAAiB,CAAC,KAAK,SAAS;QAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAClG,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/G,MAAM,cAAc,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;IACnD,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG;QACf,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,IAAI,EAAE,EAAE,iBAAiB,CAAC;QAC5D,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,EAAE,cAAc,CAAC;KACvD,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI;QAC1B,CAAC,gBAAgB,EAAE,IAAI,OAAO,EAAE,CAAC;QACjC,CAAC,iBAAiB,EAAE,IAAI,OAAO,EAAE,CAAC;QAClC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,IAAI,OAAO,EAAE,CAAC;QAC1C,CAAC,YAAY,EAAE,kCAAkC,CAAC,YAAY,CAAC;KACvD,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;QACpG,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACtD,CAAC;IACD,IAAI,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,4BAA4B,CAAC,KAAK,SAAS;QAC3E,YAAY,CAAC,4BAA4B,CAAC,GAAG,MAAM,CAAC;IACtD,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,OAAe,EAAE,MAAe,EAAE,EAAE,CAC7D,KAAK,CAAC,IAAI,CAAC;QACT,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QACtB,UAAU,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAC3F,OAAO;KACR,CAAC,CAAC;IACL,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC;QAClC,QAAQ,CAAC,IAAI,CACX,0GAA0G,CAC3G,CAAC;IACJ,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;IAClE,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI;QAC5B,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;QAC5C,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;KAC9B,EAAE,CAAC;QACX,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;aAC5D,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,OAAO;YACxC,QAAQ,CAAC,IAAI,CAAC,4BAA4B,IAAI,yBAAyB,OAAO,GAAG,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,OAAO,GAAG;QACd,qIAAqI;KACtI,CAAC;IACF,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC;QACtC,OAAO,CAAC,IAAI,CACV,wCAAwC,cAAc,iEAAiE,CACxH,CAAC;IACJ,IAAI,eAAe,GAAG,YAAY,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAC/E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;QACtD,eAAe,GAAG,YAAY,CAC5B,eAAe,EACf,CAAC,IAAI,KAAK,iBAAiB,IAAI,IAAI,KAAK,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,EAAE,IAAI,CAAC,EAC7G,KAAK,CACN,CAAC;IACJ,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QACnD,eAAe,GAAG,YAAY,CAAC,eAAe,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9E,IAAI,eAAe,KAAK,YAAY;QAAE,GAAG,CAAC,cAAc,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;IACzF,IAAI,YAAY,KAAK,SAAS;QAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG;QACd,qBAAqB;QACrB,sBAAsB;QACtB,sBAAsB;QACtB,qBAAqB;QACrB,sBAAsB;QACtB,sBAAsB;KACvB,CAAC;IACF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,OAAO;QAAE,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/F,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QACpB,GAAG,CACD,qBAAqB,EACrB,YAAY,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,WAAW,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,qCAAqC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,uGAAuG,CAC/P,CAAC;SACC,CAAC;QACJ,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;QACrC,QAAQ,CAAC,IAAI,CACX,2GAA2G,CAC5G,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;aAC7E,IAAI,IAAI,KAAK,eAAe;YAC/B,GAAG,CACD,IAAI,EACJ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzM,CAAC;IACN,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC5C,MAAM,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QACnD,GAAG,CACD,YAAY,EACZ,GAAG,MAAM,IAAI,EAAE,GAAG,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,gBAAgB,EAC3F,MAAM,CACP,CAAC;IACJ,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,oBAAoB,CAAC;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACpC,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,MAAM,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC;QAC/B,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG;gBACb,uBAAuB,EAAE,YAAY;gBACrC,4BAA4B,EAAE,IAAI;gBAClC,iBAAiB,EAAE,iDAAiD,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE;aACvG,CAAC;YACF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,SAAS;oBAAE,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;qBAC1E,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,KAAK;oBAC9B,QAAQ,CAAC,IAAI,CAAC,oCAAoC,GAAG,wBAAwB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3G,CAAC;YACD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;YAC5D,MAAM,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;YACzC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,QAAQ,CAAC,eAAe,IAAI,MAAM,EAAE,yBAAyB,CAAC,CAAC;YAClF,IACE,UAAU,CAAC,eAAe,KAAK,SAAS;gBACxC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC;oBACzC,CAAC,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;gBAE1E,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;YACzF,IAAI,gBAAgB,GAAG,eAAe,IAAI,MAAM,CAAC;YACjD,MAAM,WAAW,GAAG,CAAC,UAAU,CAAC,eAAe,IAAI,EAAE,CAAa,CAAC;YACnE,IAAI,UAAU,CAAC,eAAe,KAAK,SAAS;gBAC1C,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7E,KAAK,MAAM,EAAE,IAAI,CAAC,+BAA+B,EAAE,kBAAkB,CAAC;gBACpE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;oBACxE,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnF,IAAI,gBAAgB,KAAK,eAAe;gBAAE,GAAG,CAAC,yBAAyB,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC;QAC9G,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC;YACpE,KAAK,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;gBACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;gBAC9D,IAAI,QAAQ,CAAC,gBAAgB,KAAK,SAAS;oBACzC,OAAO,GAAG,YAAY,CACpB,OAAO,EACP,CAAC,WAAW,EAAE,IAAI,EAAE,kBAAkB,CAAC,EACvC,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,6BAA6B,EAAE,KAAK,CAAC,CACvE,CAAC;;oBAEF,QAAQ,CAAC,IAAI,CACX,yBAAyB,IAAI,sEAAsE,CACpG,CAAC;YACN,CAAC;QACH,CAAC;QACD,IAAI,OAAO,KAAK,MAAM;YAAE,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CACV,GAAG,MAAM,yNAAyN,CACnO,CAAC;IACJ,CAAC;IACD,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,cAAc;QACd,OAAO;QACP,MAAM;QACN,KAAK;QACL,YAAY;QACZ,OAAO;QACP,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;QACzB,OAAO;QACP,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-verify.d.ts","sourceRoot":"","sources":["../../../../src/init-verify.ts"],"names":[],"mappings":"AAKA,4FAA4F;AAC5F,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFlE"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
/** Verify the application-installed server over stdio; this is not editor-host evidence. */
|
|
6
|
+
export async function verifyInitServer(root) {
|
|
7
|
+
const require = createRequire(join(root, "package.json"));
|
|
8
|
+
const entry = require.resolve("@typed-sql/language-server");
|
|
9
|
+
const server = join(dirname(entry), "server.js");
|
|
10
|
+
const child = spawn(process.execPath, [server, "--stdio"], { cwd: root, stdio: "pipe" });
|
|
11
|
+
let buffer = Buffer.alloc(0);
|
|
12
|
+
let nextId = 0;
|
|
13
|
+
const pending = new Map();
|
|
14
|
+
const fail = (error) => {
|
|
15
|
+
for (const request of pending.values())
|
|
16
|
+
request.reject(error);
|
|
17
|
+
pending.clear();
|
|
18
|
+
};
|
|
19
|
+
const timeout = setTimeout(() => {
|
|
20
|
+
fail(new Error("Installed language server did not complete its handshake within 30 seconds"));
|
|
21
|
+
child.kill();
|
|
22
|
+
}, 30_000);
|
|
23
|
+
const send = (value) => {
|
|
24
|
+
const body = Buffer.from(JSON.stringify(value));
|
|
25
|
+
child.stdin.write(`Content-Length: ${body.length}\r\n\r\n`);
|
|
26
|
+
child.stdin.write(body);
|
|
27
|
+
};
|
|
28
|
+
const request = (method, params) => new Promise((resolve, reject) => {
|
|
29
|
+
const id = ++nextId;
|
|
30
|
+
pending.set(id, { resolve, reject });
|
|
31
|
+
send({ jsonrpc: "2.0", id, method, params });
|
|
32
|
+
});
|
|
33
|
+
child.once("error", fail);
|
|
34
|
+
child.stdin.on("error", fail);
|
|
35
|
+
child.stderr.resume();
|
|
36
|
+
child.once("exit", () => fail(new Error("Installed language server exited before completing verification")));
|
|
37
|
+
child.stdout.on("data", (chunk) => {
|
|
38
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
39
|
+
try {
|
|
40
|
+
if (buffer.length > 16 * 1024 * 1024)
|
|
41
|
+
throw new Error("Oversized language-server response");
|
|
42
|
+
while (true) {
|
|
43
|
+
const end = buffer.indexOf("\r\n\r\n");
|
|
44
|
+
if (end < 0)
|
|
45
|
+
return;
|
|
46
|
+
const match = /(?:^|\r\n)Content-Length: (\d+)/iu.exec(buffer.subarray(0, end).toString("ascii"));
|
|
47
|
+
if (match === null)
|
|
48
|
+
throw new Error("Malformed language-server response");
|
|
49
|
+
const length = Number(match[1]);
|
|
50
|
+
if (!Number.isSafeInteger(length) || length > 16 * 1024 * 1024)
|
|
51
|
+
throw new Error("Invalid language-server response length");
|
|
52
|
+
if (buffer.length < end + 4 + length)
|
|
53
|
+
return;
|
|
54
|
+
const message = JSON.parse(buffer.subarray(end + 4, end + 4 + length).toString("utf8"));
|
|
55
|
+
buffer = buffer.subarray(end + 4 + length);
|
|
56
|
+
if (message.id === undefined)
|
|
57
|
+
continue;
|
|
58
|
+
if (message.method !== undefined) {
|
|
59
|
+
send({ jsonrpc: "2.0", id: message.id, result: null });
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const current = pending.get(message.id);
|
|
63
|
+
pending.delete(message.id);
|
|
64
|
+
if (message.error !== undefined)
|
|
65
|
+
current?.reject(new Error(message.error.message ?? "Language-server request failed"));
|
|
66
|
+
else
|
|
67
|
+
current?.resolve(message.result);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
fail(error instanceof Error ? error : new Error("Invalid server response"));
|
|
72
|
+
child.kill();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
try {
|
|
76
|
+
const initialized = (await request("initialize", {
|
|
77
|
+
processId: process.pid,
|
|
78
|
+
rootUri: pathToFileURL(root).href,
|
|
79
|
+
workspaceFolders: [{ uri: pathToFileURL(root).href, name: "application" }],
|
|
80
|
+
capabilities: {},
|
|
81
|
+
initializationOptions: { protocolVersion: 1, protocolCapabilities: ["status"] },
|
|
82
|
+
}));
|
|
83
|
+
if (initialized?.serverInfo?.name !== "typed-sql + TypeScript preview")
|
|
84
|
+
throw new Error("Unexpected language server implementation");
|
|
85
|
+
send({ jsonrpc: "2.0", method: "initialized", params: {} });
|
|
86
|
+
const status = (await request("typedSql/status", {}));
|
|
87
|
+
if (status?.name !== "@typed-sql/language-server" || status.typescriptVersion !== "7.1.0-beta")
|
|
88
|
+
throw new Error("The installed language server does not provide the supported TypeScript 7.1.0-beta backend");
|
|
89
|
+
await request("shutdown", null);
|
|
90
|
+
send({ jsonrpc: "2.0", method: "exit", params: null });
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
clearTimeout(timeout);
|
|
94
|
+
child.stdin.end();
|
|
95
|
+
if (child.exitCode === null)
|
|
96
|
+
child.kill();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=init-verify.js.map
|