@open-feishu-card/language-server 0.1.15 → 0.1.17
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/dist/index.cjs +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/rpc.d.ts +4 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/server.cjs +21 -17
- package/dist/server.js +22 -18
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -136,10 +136,12 @@ function quickFixes(source, range) {
|
|
|
136
136
|
return actions;
|
|
137
137
|
}
|
|
138
138
|
function sanitizeAllAction(source) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
const parsed = parser.parse(source);
|
|
140
|
+
const resolved = parser.resolveCardDocument(parsed);
|
|
141
|
+
if (!resolved) return void 0;
|
|
142
|
+
const { stripped, card } = compiler.sanitize(resolved.cardData, { mode: "strip" });
|
|
142
143
|
if (stripped.length === 0) return void 0;
|
|
144
|
+
const output = parser.serializeCardDocument(resolved, card);
|
|
143
145
|
const lines = source.split("\n");
|
|
144
146
|
const lastLine = lines.length - 1;
|
|
145
147
|
return {
|
|
@@ -152,7 +154,7 @@ function sanitizeAllAction(source) {
|
|
|
152
154
|
start: { line: 0, character: 0 },
|
|
153
155
|
end: { line: lastLine, character: lines[lastLine].length }
|
|
154
156
|
},
|
|
155
|
-
newText: JSON.stringify(
|
|
157
|
+
newText: JSON.stringify(output, null, 2) + "\n"
|
|
156
158
|
}
|
|
157
159
|
]
|
|
158
160
|
};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAKlC,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,GAAG,EAAE,cAAc,GAAG,SAAS,CAAC;CACjC;AASD,yBAAyB;AACzB,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAqBpD;AAMD,eAAO,MAAM,mBAAmB,EAAE,cAAc,EAM/C,CAAC;AASF,eAAO,MAAM,uBAAuB,EAAE,cAAc,EAKjD,CAAC;AAaJ;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,CAOzE;AAkBD,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAUvE;AAMD,4BAA4B;AAC5B,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,UAAU,EAAE,CA2BxE;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAuBxE"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parse } from '@open-feishu-card/parser';
|
|
1
|
+
import { parse, resolveCardDocument, serializeCardDocument } from '@open-feishu-card/parser';
|
|
2
2
|
import { sanitize } from '@open-feishu-card/compiler';
|
|
3
3
|
import { validateAst } from '@open-feishu-card/validator';
|
|
4
4
|
import { lintAst } from '@open-feishu-card/linter';
|
|
@@ -134,10 +134,12 @@ function quickFixes(source, range) {
|
|
|
134
134
|
return actions;
|
|
135
135
|
}
|
|
136
136
|
function sanitizeAllAction(source) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
const parsed = parse(source);
|
|
138
|
+
const resolved = resolveCardDocument(parsed);
|
|
139
|
+
if (!resolved) return void 0;
|
|
140
|
+
const { stripped, card } = sanitize(resolved.cardData, { mode: "strip" });
|
|
140
141
|
if (stripped.length === 0) return void 0;
|
|
142
|
+
const output = serializeCardDocument(resolved, card);
|
|
141
143
|
const lines = source.split("\n");
|
|
142
144
|
const lastLine = lines.length - 1;
|
|
143
145
|
return {
|
|
@@ -150,7 +152,7 @@ function sanitizeAllAction(source) {
|
|
|
150
152
|
start: { line: 0, character: 0 },
|
|
151
153
|
end: { line: lastLine, character: lines[lastLine].length }
|
|
152
154
|
},
|
|
153
|
-
newText: JSON.stringify(
|
|
155
|
+
newText: JSON.stringify(output, null, 2) + "\n"
|
|
154
156
|
}
|
|
155
157
|
]
|
|
156
158
|
};
|
package/dist/rpc.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 极简 JSON-RPC 2.0 / LSP stdio 传输层(Content-Length 分帧)。
|
|
3
3
|
* 零依赖,Node 流输入输出;WebWorker 环境可换用 MessagePort 适配。
|
|
4
|
+
*
|
|
5
|
+
* Content-Length 按 UTF-8 **字节**计数(LSP 规范)。接收侧必须用 Buffer,
|
|
6
|
+
* 不能用 setEncoding('utf8') 后按字符串 length 切片,否则正文含中文等
|
|
7
|
+
* 多字节字符时 didOpen 永远解不完,诊断/补全会全部静默失效。
|
|
4
8
|
*/
|
|
5
9
|
import type { Readable, Writable } from 'node:stream';
|
|
6
10
|
export declare class Connection {
|
package/dist/rpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQtD,qBAAa,UAAU;IAOT,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAY,OAAO,CAAC,QAAQ,CAAC,MAAM;IANrE,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAA8C;IAC7D,OAAO,CAAC,eAAe,CAAmD;IAC1E,OAAO,CAAC,oBAAoB,CAAgD;IAE5E,YAA6B,KAAK,EAAE,QAAQ,EAAmB,MAAM,EAAE,QAAQ,EAAI;IAEnF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,OAAO,GAAG,IAAI,CAEnE;IAED,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAErE;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAEtD;IAED,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAM7D;IAED,OAAO,CAAC,KAAK;IAMb,MAAM,IAAI,IAAI,CAOb;IAED,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;CAiBtB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,UAAU,CAE9E"}
|
package/dist/server.cjs
CHANGED
|
@@ -136,10 +136,12 @@ function quickFixes(source, range) {
|
|
|
136
136
|
return actions;
|
|
137
137
|
}
|
|
138
138
|
function sanitizeAllAction(source) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
const parsed = parser.parse(source);
|
|
140
|
+
const resolved = parser.resolveCardDocument(parsed);
|
|
141
|
+
if (!resolved) return void 0;
|
|
142
|
+
const { stripped, card } = compiler.sanitize(resolved.cardData, { mode: "strip" });
|
|
142
143
|
if (stripped.length === 0) return void 0;
|
|
144
|
+
const output = parser.serializeCardDocument(resolved, card);
|
|
143
145
|
const lines = source.split("\n");
|
|
144
146
|
const lastLine = lines.length - 1;
|
|
145
147
|
return {
|
|
@@ -152,13 +154,14 @@ function sanitizeAllAction(source) {
|
|
|
152
154
|
start: { line: 0, character: 0 },
|
|
153
155
|
end: { line: lastLine, character: lines[lastLine].length }
|
|
154
156
|
},
|
|
155
|
-
newText: JSON.stringify(
|
|
157
|
+
newText: JSON.stringify(output, null, 2) + "\n"
|
|
156
158
|
}
|
|
157
159
|
]
|
|
158
160
|
};
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
// src/rpc.ts
|
|
164
|
+
var HEADER_SEP = Buffer.from("\r\n\r\n", "utf8");
|
|
162
165
|
var Connection = class {
|
|
163
166
|
constructor(input, output) {
|
|
164
167
|
this.input = input;
|
|
@@ -166,7 +169,7 @@ var Connection = class {
|
|
|
166
169
|
}
|
|
167
170
|
input;
|
|
168
171
|
output;
|
|
169
|
-
buffer =
|
|
172
|
+
buffer = Buffer.alloc(0);
|
|
170
173
|
nextId = 1;
|
|
171
174
|
pending = /* @__PURE__ */ new Map();
|
|
172
175
|
requestHandlers = /* @__PURE__ */ new Map();
|
|
@@ -188,34 +191,35 @@ var Connection = class {
|
|
|
188
191
|
});
|
|
189
192
|
}
|
|
190
193
|
write(msg) {
|
|
191
|
-
const body = JSON.stringify(msg);
|
|
192
|
-
|
|
194
|
+
const body = Buffer.from(JSON.stringify(msg), "utf8");
|
|
195
|
+
const header = Buffer.from(`Content-Length: ${body.length}\r
|
|
193
196
|
\r
|
|
194
|
-
|
|
197
|
+
`, "utf8");
|
|
198
|
+
this.output.write(Buffer.concat([header, body]));
|
|
195
199
|
}
|
|
196
200
|
listen() {
|
|
197
|
-
this.input.setEncoding("utf8");
|
|
198
201
|
this.input.on("data", (chunk) => {
|
|
199
|
-
|
|
202
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
203
|
+
this.buffer = Buffer.concat([this.buffer, buf]);
|
|
200
204
|
this.tryParse();
|
|
201
205
|
});
|
|
202
206
|
this.input.on("close", () => process.exit(0));
|
|
203
207
|
}
|
|
204
208
|
tryParse() {
|
|
205
209
|
for (; ; ) {
|
|
206
|
-
const headerEnd = this.buffer.indexOf(
|
|
210
|
+
const headerEnd = this.buffer.indexOf(HEADER_SEP);
|
|
207
211
|
if (headerEnd < 0) return;
|
|
208
|
-
const header = this.buffer.
|
|
212
|
+
const header = this.buffer.subarray(0, headerEnd).toString("utf8");
|
|
209
213
|
const m = /Content-Length:\s*(\d+)/i.exec(header);
|
|
210
214
|
if (!m) {
|
|
211
|
-
this.buffer = this.buffer.
|
|
215
|
+
this.buffer = this.buffer.subarray(headerEnd + HEADER_SEP.length);
|
|
212
216
|
continue;
|
|
213
217
|
}
|
|
214
218
|
const length = Number(m[1]);
|
|
215
|
-
const bodyStart = headerEnd +
|
|
219
|
+
const bodyStart = headerEnd + HEADER_SEP.length;
|
|
216
220
|
if (this.buffer.length < bodyStart + length) return;
|
|
217
|
-
const body = this.buffer.
|
|
218
|
-
this.buffer = this.buffer.
|
|
221
|
+
const body = this.buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
|
|
222
|
+
this.buffer = this.buffer.subarray(bodyStart + length);
|
|
219
223
|
try {
|
|
220
224
|
this.handleMessage(JSON.parse(body));
|
|
221
225
|
} catch {
|
|
@@ -232,7 +236,7 @@ ${body}`);
|
|
|
232
236
|
} else {
|
|
233
237
|
this.notificationHandlers.get(msg.method)?.(msg.params);
|
|
234
238
|
}
|
|
235
|
-
} else if (typeof msg.id === "number") {
|
|
239
|
+
} else if (typeof msg.id === "number" || typeof msg.id === "string") {
|
|
236
240
|
this.pending.get(msg.id)?.resolve(msg.result);
|
|
237
241
|
this.pending.delete(msg.id);
|
|
238
242
|
}
|
package/dist/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { parse } from '@open-feishu-card/parser';
|
|
2
|
+
import { parse, resolveCardDocument, serializeCardDocument } from '@open-feishu-card/parser';
|
|
3
3
|
import { sanitize } from '@open-feishu-card/compiler';
|
|
4
4
|
import { validateAst } from '@open-feishu-card/validator';
|
|
5
5
|
import { lintAst } from '@open-feishu-card/linter';
|
|
@@ -134,10 +134,12 @@ function quickFixes(source, range) {
|
|
|
134
134
|
return actions;
|
|
135
135
|
}
|
|
136
136
|
function sanitizeAllAction(source) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
const parsed = parse(source);
|
|
138
|
+
const resolved = resolveCardDocument(parsed);
|
|
139
|
+
if (!resolved) return void 0;
|
|
140
|
+
const { stripped, card } = sanitize(resolved.cardData, { mode: "strip" });
|
|
140
141
|
if (stripped.length === 0) return void 0;
|
|
142
|
+
const output = serializeCardDocument(resolved, card);
|
|
141
143
|
const lines = source.split("\n");
|
|
142
144
|
const lastLine = lines.length - 1;
|
|
143
145
|
return {
|
|
@@ -150,13 +152,14 @@ function sanitizeAllAction(source) {
|
|
|
150
152
|
start: { line: 0, character: 0 },
|
|
151
153
|
end: { line: lastLine, character: lines[lastLine].length }
|
|
152
154
|
},
|
|
153
|
-
newText: JSON.stringify(
|
|
155
|
+
newText: JSON.stringify(output, null, 2) + "\n"
|
|
154
156
|
}
|
|
155
157
|
]
|
|
156
158
|
};
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
// src/rpc.ts
|
|
162
|
+
var HEADER_SEP = Buffer.from("\r\n\r\n", "utf8");
|
|
160
163
|
var Connection = class {
|
|
161
164
|
constructor(input, output) {
|
|
162
165
|
this.input = input;
|
|
@@ -164,7 +167,7 @@ var Connection = class {
|
|
|
164
167
|
}
|
|
165
168
|
input;
|
|
166
169
|
output;
|
|
167
|
-
buffer =
|
|
170
|
+
buffer = Buffer.alloc(0);
|
|
168
171
|
nextId = 1;
|
|
169
172
|
pending = /* @__PURE__ */ new Map();
|
|
170
173
|
requestHandlers = /* @__PURE__ */ new Map();
|
|
@@ -186,34 +189,35 @@ var Connection = class {
|
|
|
186
189
|
});
|
|
187
190
|
}
|
|
188
191
|
write(msg) {
|
|
189
|
-
const body = JSON.stringify(msg);
|
|
190
|
-
|
|
192
|
+
const body = Buffer.from(JSON.stringify(msg), "utf8");
|
|
193
|
+
const header = Buffer.from(`Content-Length: ${body.length}\r
|
|
191
194
|
\r
|
|
192
|
-
|
|
195
|
+
`, "utf8");
|
|
196
|
+
this.output.write(Buffer.concat([header, body]));
|
|
193
197
|
}
|
|
194
198
|
listen() {
|
|
195
|
-
this.input.setEncoding("utf8");
|
|
196
199
|
this.input.on("data", (chunk) => {
|
|
197
|
-
|
|
200
|
+
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
201
|
+
this.buffer = Buffer.concat([this.buffer, buf]);
|
|
198
202
|
this.tryParse();
|
|
199
203
|
});
|
|
200
204
|
this.input.on("close", () => process.exit(0));
|
|
201
205
|
}
|
|
202
206
|
tryParse() {
|
|
203
207
|
for (; ; ) {
|
|
204
|
-
const headerEnd = this.buffer.indexOf(
|
|
208
|
+
const headerEnd = this.buffer.indexOf(HEADER_SEP);
|
|
205
209
|
if (headerEnd < 0) return;
|
|
206
|
-
const header = this.buffer.
|
|
210
|
+
const header = this.buffer.subarray(0, headerEnd).toString("utf8");
|
|
207
211
|
const m = /Content-Length:\s*(\d+)/i.exec(header);
|
|
208
212
|
if (!m) {
|
|
209
|
-
this.buffer = this.buffer.
|
|
213
|
+
this.buffer = this.buffer.subarray(headerEnd + HEADER_SEP.length);
|
|
210
214
|
continue;
|
|
211
215
|
}
|
|
212
216
|
const length = Number(m[1]);
|
|
213
|
-
const bodyStart = headerEnd +
|
|
217
|
+
const bodyStart = headerEnd + HEADER_SEP.length;
|
|
214
218
|
if (this.buffer.length < bodyStart + length) return;
|
|
215
|
-
const body = this.buffer.
|
|
216
|
-
this.buffer = this.buffer.
|
|
219
|
+
const body = this.buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
|
|
220
|
+
this.buffer = this.buffer.subarray(bodyStart + length);
|
|
217
221
|
try {
|
|
218
222
|
this.handleMessage(JSON.parse(body));
|
|
219
223
|
} catch {
|
|
@@ -230,7 +234,7 @@ ${body}`);
|
|
|
230
234
|
} else {
|
|
231
235
|
this.notificationHandlers.get(msg.method)?.(msg.params);
|
|
232
236
|
}
|
|
233
|
-
} else if (typeof msg.id === "number") {
|
|
237
|
+
} else if (typeof msg.id === "number" || typeof msg.id === "string") {
|
|
234
238
|
this.pending.get(msg.id)?.resolve(msg.result);
|
|
235
239
|
this.pending.delete(msg.id);
|
|
236
240
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-feishu-card/language-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "飞书卡片 LSP 语言服务器:诊断、智能补全、Hover、Code Action 快速修复",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"dist"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@open-feishu-card/compiler": "0.1.
|
|
25
|
-
"@open-feishu-card/
|
|
26
|
-
"@open-feishu-card/
|
|
27
|
-
"@open-feishu-card/
|
|
28
|
-
"@open-feishu-card/
|
|
24
|
+
"@open-feishu-card/compiler": "0.1.16",
|
|
25
|
+
"@open-feishu-card/linter": "0.1.3",
|
|
26
|
+
"@open-feishu-card/parser": "0.1.3",
|
|
27
|
+
"@open-feishu-card/schema": "0.1.5",
|
|
28
|
+
"@open-feishu-card/validator": "0.1.6"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"tsup": "^8.3.5",
|