@svg-toolkit/svg-language-server 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kaj Kowalski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # svg-language-server
2
+
3
+ [![NPM](https://img.shields.io/npm/v/svg-language-server?logo=npm&labelColor=CB3837&color=black)](https://npm.im/svg-language-server)
4
+
5
+ LSP server for SVG: diagnostics, completions, hover, formatting, and references.
6
+
7
+ ```sh
8
+ npm install -g svg-language-server # unscoped
9
+ npm install -g @svg-toolkit/svg-language-server # same package, scoped
10
+ svg-language-server --version # `svg-ls` works too
11
+ ```
12
+
13
+ Both names ship byte-identical content; pick whichever you like. Or grab the
14
+ whole toolkit at once with
15
+ [`@kjanat/svg-toolkit`](https://npm.im/@kjanat/svg-toolkit).
16
+
17
+ The package resolves a prebuilt native binary for your platform via
18
+ `optionalDependencies` — no postinstall step, no install-time network access.
19
+ The server speaks LSP over stdio; point your editor's LSP client at the
20
+ `svg-language-server` executable.
21
+
22
+ At runtime the server fetches fresh browser-compat data on startup by default
23
+ (degrading cleanly to the baked catalog when offline). Set the
24
+ `svg.runtime_compat: false` initialization option to keep sessions fully
25
+ offline.
26
+
27
+ Editor setup, supported diagnostics, and configuration options:
28
+ <https://github.com/kjanat/svg#readme>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import launch from "#launch";
3
+ launch("svg-language-server");
package/lib/launch.mjs ADDED
@@ -0,0 +1,32 @@
1
+ import { resolveBinary } from '#resolve';
2
+ import { spawnSync } from 'node:child_process';
3
+ import process from 'node:process';
4
+
5
+ const { argv, exit, stderr } = process;
6
+
7
+ /** @param {string} name */
8
+ export default function launch(name) {
9
+ try {
10
+ const result = spawnSync(resolveBinary(name), argv.slice(2), {
11
+ stdio: 'inherit',
12
+ windowsHide: false,
13
+ });
14
+ if (result.error) throw result.error;
15
+ // Child died from a signal (SIGINT, SIGTERM, …).
16
+ // Re-raise it on ourselves so the parent shell sees `WIFSIGNALED` / exit
17
+ // code 128 + N instead of a generic 1 — `set -e`, trap handlers,
18
+ // and Ctrl+C chaining all depend on this. POSIX-only: Windows has no
19
+ // signal exit semantics (result.signal is effectively never set there,
20
+ // and re-raising would abort with an unrelated code), so fall through
21
+ // to the generic failure exit instead.
22
+ if (result.signal && process.platform !== 'win32') {
23
+ process.removeAllListeners(result.signal);
24
+ process.kill(process.pid, result.signal);
25
+ return;
26
+ }
27
+ exit(result.status ?? 1);
28
+ } catch (err) {
29
+ stderr.write(`${name}: ${err instanceof Error ? err.message : String(err)}\n`);
30
+ exit(1);
31
+ }
32
+ }
@@ -0,0 +1,73 @@
1
+ import { bold, cyan, link, red, yellow } from 'ansispeck';
2
+ import { existsSync } from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ import { dirname, join } from 'node:path';
5
+ import { arch, platform } from 'node:process';
6
+
7
+ const require = createRequire(import.meta.url);
8
+ // repository.url (canonical `git+<url>.git` form) and bugs.url are stamped
9
+ // into every published facade by build-packages.ts from Cargo.toml's
10
+ // `repository`; the strip below undoes exactly that stamped decoration.
11
+ const { optionalDependencies, name: pkgName, repository, bugs } = require('#pkg');
12
+
13
+ const repo = repository.url.replace(/^git\+/, '').replace(/\.git$/, '');
14
+ const issues = bugs.url;
15
+ const subPackages = Object.keys(optionalDependencies || {});
16
+
17
+ /**
18
+ * Locate the prebuilt executable matching the current platform and architecture.
19
+ *
20
+ * Searches optional-dependency sub-packages for a matching `bin/<exe>` and returns its filesystem path.
21
+ * If no candidate is found, an explanatory error message is written to stderr and an `Error` is thrown.
22
+ *
23
+ * @param {string} name - Base name of the executable (without platform-specific extension).
24
+ * @returns {string} The filesystem path to the resolved executable.
25
+ * @throws {Error} If no suitable binary is found for the current platform and architecture.
26
+ */
27
+ export function resolveBinary(name) {
28
+ const exe = platform === 'win32' ? `${name}.exe` : name;
29
+ const errors = [];
30
+ for (const subPkg of subPackages) {
31
+ let pkgJsonPath;
32
+ try {
33
+ pkgJsonPath = require.resolve(`${subPkg}/package.json`);
34
+ } catch (err) {
35
+ errors.push(`${subPkg}: ${err instanceof Error ? err.message : String(err)}`);
36
+ continue;
37
+ }
38
+ const binPath = join(dirname(pkgJsonPath), 'bin', exe);
39
+ // `require.resolve` proves the package.json exists, not the binary.
40
+ // Could mismatch if a user manually deletes the bin, or a partial
41
+ // install half-succeeded. Prefer a clear error here over an opaque
42
+ // `ENOENT` from `spawnSync` later in `launch.mjs`.
43
+ if (!existsSync(binPath)) {
44
+ errors.push(`${subPkg}: package present but bin missing at ${binPath}`);
45
+ continue;
46
+ }
47
+ return binPath;
48
+ }
49
+
50
+ const detail = errors.length > 0
51
+ ? '\n\nDetails of attempted resolutions:\n - ' + errors.join('\n - ')
52
+ : '';
53
+
54
+ const indent = ' ';
55
+
56
+ const errorText = `${red(pkgName)}: no prebuilt binary found for ${yellow(`${platform}-${arch}`)}.
57
+
58
+ This usually means your package manager skipped ${cyan('optionalDependencies')}
59
+ (common with ${cyan('--no-optional')}, ${cyan('--omit=optional')}, or some Docker/CI setups).
60
+
61
+ Workarounds:
62
+ ${indent}- reinstall without: ${cyan('--no-optional')} / ${cyan('--omit=optional')}
63
+ ${indent}- bun + ${cyan('minimumReleaseAge')}: add the platform packages (not just ${bold(pkgName)}) to ${
64
+ cyan('minimumReleaseAgeExcludes')
65
+ } — a fresh release is otherwise age-gated
66
+ ${indent}- install from source: ${cyan(`cargo install --git=${repo}/ ${name}`)}
67
+ ${indent}- file an issue if your platform is unsupported: ${link(issues, issues)}${detail}
68
+ `;
69
+
70
+ console.error(errorText);
71
+
72
+ throw new Error('No prebuilt binary found for the current platform and architecture.');
73
+ }
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@svg-toolkit/svg-language-server",
3
+ "description": "LSP server for SVG: diagnostics, completions, hover, formatting, and references.",
4
+ "keywords": [
5
+ "svg",
6
+ "lsp",
7
+ "language-server",
8
+ "diagnostics",
9
+ "completions",
10
+ "formatter",
11
+ "linter",
12
+ "ansispeck"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/kjanat/svg.git"
17
+ },
18
+ "type": "module",
19
+ "imports": {
20
+ "#launch": "./lib/launch.mjs",
21
+ "#pkg": "./package.json",
22
+ "#resolve": "./lib/resolve.mjs"
23
+ },
24
+ "exports": {
25
+ "./package.json": "./package.json",
26
+ "./bin/*": "./bin/*"
27
+ },
28
+ "bin": {
29
+ "svg-language-server": "bin/svg-language-server.mjs",
30
+ "svg-ls": "bin/svg-language-server.mjs"
31
+ },
32
+ "directories": {
33
+ "lib": "./lib"
34
+ },
35
+ "files": [
36
+ "bin/",
37
+ "lib/",
38
+ "README.md",
39
+ "LICENSE"
40
+ ],
41
+ "dependencies": {
42
+ "ansispeck": "^0.1.2"
43
+ },
44
+ "optionalDependencies": {
45
+ "@svg-toolkit/language-server-linux-x64-gnu": "0.1.1",
46
+ "@svg-toolkit/language-server-linux-x64-musl": "0.1.1",
47
+ "@svg-toolkit/language-server-linux-arm64-gnu": "0.1.1",
48
+ "@svg-toolkit/language-server-linux-arm64-musl": "0.1.1",
49
+ "@svg-toolkit/language-server-darwin-x64": "0.1.1",
50
+ "@svg-toolkit/language-server-darwin-arm64": "0.1.1",
51
+ "@svg-toolkit/language-server-win32-x64-msvc": "0.1.1",
52
+ "@svg-toolkit/language-server-win32-arm64-msvc": "0.1.1",
53
+ "@svg-toolkit/language-server-linux-armv7-gnueabihf": "0.1.1",
54
+ "@svg-toolkit/language-server-linux-armv7-musleabihf": "0.1.1",
55
+ "@svg-toolkit/language-server-linux-ia32-gnu": "0.1.1",
56
+ "@svg-toolkit/language-server-linux-ia32-musl": "0.1.1",
57
+ "@svg-toolkit/language-server-win32-ia32-msvc": "0.1.1",
58
+ "@svg-toolkit/language-server-linux-riscv64-gnu": "0.1.1",
59
+ "@svg-toolkit/language-server-linux-ppc64-gnu": "0.1.1",
60
+ "@svg-toolkit/language-server-linux-s390x-gnu": "0.1.1",
61
+ "@svg-toolkit/language-server-freebsd-x64": "0.1.1",
62
+ "@svg-toolkit/language-server-freebsd-arm64": "0.1.1",
63
+ "@svg-toolkit/language-server-netbsd-x64": "0.1.1",
64
+ "@svg-toolkit/language-server-linux-loong64-gnu": "0.1.1"
65
+ },
66
+ "license": "MIT",
67
+ "author": "Kaj Kowalski <info@kajkowalski.nl>",
68
+ "homepage": "https://github.com/kjanat/svg/tree/HEAD/crates/svg-language-server",
69
+ "bugs": {
70
+ "url": "https://github.com/kjanat/svg/issues"
71
+ },
72
+ "version": "0.1.1"
73
+ }