@contractkit/prettier-plugin 0.12.1 → 0.13.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/.turbo/turbo-build$colon$ci.log +5 -5
- package/.turbo/turbo-test$colon$ci.log +13 -10
- package/CHANGELOG.md +25 -0
- package/README.md +12 -3
- package/dist/index.js +170 -52
- package/dist/index.js.map +1 -1
- package/dist/print-ck.d.ts +10 -3
- package/dist/print-ck.d.ts.map +1 -1
- package/dist/print-contract.d.ts +10 -0
- package/dist/print-contract.d.ts.map +1 -1
- package/dist/print-operation.d.ts +13 -0
- package/dist/print-operation.d.ts.map +1 -1
- package/dist/print-type.d.ts +3 -1
- package/dist/print-type.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/print-ck.ts +60 -13
- package/src/print-contract.ts +19 -2
- package/src/print-operation.ts +124 -41
- package/src/print-type.ts +8 -2
- package/tests/print-ck.test.ts +318 -1
- package/tests/round-trip.test.ts +268 -0
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/clover.xml +0 -358
- package/coverage/coverage-final.json +0 -6
- package/coverage/favicon.png +0 -0
- package/coverage/indent.ts.html +0 -88
- package/coverage/index.html +0 -176
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/print-ck.ts.html +0 -424
- package/coverage/print-contract.ts.html +0 -292
- package/coverage/print-operation.ts.html +0 -1078
- package/coverage/print-type.ts.html +0 -532
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
|
@@ -5,9 +5,9 @@ $ tsup src/index.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly
|
|
|
5
5
|
[34mCLI[39m tsup v8.5.1
|
|
6
6
|
[34mCLI[39m Target: esnext
|
|
7
7
|
[34mESM[39m Build start
|
|
8
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
9
|
-
[32mESM[39m [1mdist/index.js.map [22m[
|
|
10
|
-
[32mESM[39m ⚡️ Build success in
|
|
8
|
+
[32mESM[39m [1mdist/index.js [22m[32m24.87 KB[39m
|
|
9
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m62.23 KB[39m
|
|
10
|
+
[32mESM[39m ⚡️ Build success in 191ms
|
|
11
11
|
[34mDTS[39m Build start
|
|
12
|
-
[32mDTS[39m ⚡️ Build success in
|
|
13
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
12
|
+
[32mDTS[39m ⚡️ Build success in 4964ms
|
|
13
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.13 KB[39m
|
|
@@ -3,21 +3,24 @@ $ vitest run --coverage
|
|
|
3
3
|
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/ContractKit/ContractKit/apps/prettier-plugin[39m
|
|
4
4
|
[2mCoverage enabled with [22m[33mv8[39m
|
|
5
5
|
|
|
6
|
-
[32m✓[39m tests/print-ck.test.ts [2m([22m[
|
|
6
|
+
[32m✓[39m tests/print-ck.test.ts [2m([22m[2m81 tests[22m[2m)[22m[33m 676[2mms[22m[39m
|
|
7
|
+
[32m✓[39m tests/round-trip.test.ts [2m([22m[2m20 tests[22m[2m)[22m[33m 1570[2mms[22m[39m
|
|
8
|
+
[33m[2m✓[22m[39m formats test.ck to itself [33m 587[2mms[22m[39m
|
|
9
|
+
[33m[2m✓[22m[39m formatting is a fixed point for source #0 [33m 769[2mms[22m[39m
|
|
7
10
|
|
|
8
|
-
[2m Test Files [22m [1m[
|
|
9
|
-
[2m Tests [22m [1m[
|
|
10
|
-
[2m Start at [22m 15:
|
|
11
|
-
[2m Duration [22m
|
|
11
|
+
[2m Test Files [22m [1m[32m2 passed[39m[22m[90m (2)[39m
|
|
12
|
+
[2m Tests [22m [1m[32m101 passed[39m[22m[90m (101)[39m
|
|
13
|
+
[2m Start at [22m 15:07:02
|
|
14
|
+
[2m Duration [22m 7.40s[2m (transform 3.64s, setup 0ms, import 9.29s, tests 2.25s, environment 0ms)[22m
|
|
12
15
|
|
|
13
16
|
[34m % [39m[2mCoverage report from [22m[33mv8[39m
|
|
14
17
|
-------------------|---------|----------|---------|---------|-------------------
|
|
15
18
|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
|
16
19
|
-------------------|---------|----------|---------|---------|-------------------
|
|
17
|
-
All files |
|
|
20
|
+
All files | 75.62 | 69.04 | 84.21 | 81.34 |
|
|
18
21
|
indent.ts | 100 | 100 | 100 | 100 |
|
|
19
|
-
print-ck.ts |
|
|
20
|
-
print-contract.ts |
|
|
21
|
-
...t-operation.ts |
|
|
22
|
-
print-type.ts |
|
|
22
|
+
print-ck.ts | 88.34 | 85 | 100 | 97.18 | 80-81
|
|
23
|
+
print-contract.ts | 45.71 | 38.23 | 50 | 46.66 | 20,52-85
|
|
24
|
+
...t-operation.ts | 78.32 | 69.46 | 94.44 | 86.12 | ...37,354,362-373
|
|
25
|
+
print-type.ts | 64.13 | 63.46 | 63.63 | 66.66 | ...02-103,148-151
|
|
23
26
|
-------------------|---------|----------|---------|---------|-------------------
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @contractkit/prettier-plugin-contractkit
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 23e4beb: Fix the formatter rewriting `.ck` files it should have left alone. Running Prettier on a contract folded standalone `#` comment blocks into a trailing comment on the following declaration (`# ─── Pet endpoints ───` became `operation /pet: { # ─── Pet endpoints ───`), reordered operation body keys into a canonical order, dropped blank lines between operations, and expanded single-line response bodies like `200: { application/json: Pet }` onto three lines. An inline contract comment (`contract Pet: { # A pet`) was also attributed to the first field, so it printed twice.
|
|
8
|
+
|
|
9
|
+
The parser now records the author's layout alongside the semantics — comment placement (`leadingComments`, `descriptionInline`), operation body key order (`keyOrder`), blank lines (`blankLineBefore`), and single-line response blocks (`inline`) — and the printer reproduces it. A `#` comment separated from the declaration below it by a blank line is a standalone divider rather than a doc comment; one written directly above is a doc comment and is emitted above the declaration, not on its header line.
|
|
10
|
+
|
|
11
|
+
Comments may now also sit directly inside an `options { ... }` block, between its sub-blocks, where the grammar previously rejected them.
|
|
12
|
+
|
|
13
|
+
These AST fields are additive and optional; codegen plugins ignore them.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [23e4beb]
|
|
18
|
+
- @contractkit/core@0.24.0
|
|
19
|
+
|
|
20
|
+
## 0.12.2
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 2bf01f1: Preserve trailing comments instead of dropping them on format: a comment as the last line of a contract/model body, an operation/route body, an inline object type, or an options `keys`/`services` block now round-trips.
|
|
25
|
+
- Updated dependencies [2bf01f1]
|
|
26
|
+
- @contractkit/core@0.23.0
|
|
27
|
+
|
|
3
28
|
## 0.12.1
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -33,12 +33,10 @@ Most editors with a Prettier integration (VS Code, JetBrains, Neovim) pick the p
|
|
|
33
33
|
|
|
34
34
|
## What it does
|
|
35
35
|
|
|
36
|
-
The printer round-trips the parser's AST back into
|
|
36
|
+
The printer round-trips the parser's AST back into `.ck` source:
|
|
37
37
|
|
|
38
38
|
- 4-space indentation (matches Prettier's default `tabWidth`)
|
|
39
39
|
- Canonical modifier order on fields: `override → deprecated → readonly|writeonly`
|
|
40
|
-
- Stable ordering of `options` block items, route bodies, and operation blocks
|
|
41
|
-
- Inline `# comment` placement preserved on field/operation/status lines
|
|
42
40
|
- Multi-base inheritance: `contract C: A & B & { ... }` with the inline block always last
|
|
43
41
|
- Multi-line unions: a leading `|` is preserved on type aliases like `contract X: A | B | C`
|
|
44
42
|
- Discriminated unions render as `discriminated(by=field, A | B | C)`
|
|
@@ -46,6 +44,17 @@ The printer round-trips the parser's AST back into canonical `.ck` source:
|
|
|
46
44
|
|
|
47
45
|
The plugin honours Prettier's `printWidth` for line-wrapping decisions where applicable, but most CK constructs format to a fixed multi-line shape regardless of width.
|
|
48
46
|
|
|
47
|
+
## What it preserves
|
|
48
|
+
|
|
49
|
+
Formatting a well-formed `.ck` file leaves it byte-identical. The formatter deliberately does **not** impose a canonical layout where the language allows more than one form — it reproduces what the author wrote:
|
|
50
|
+
|
|
51
|
+
- **Comment placement.** A `#` block separated from the declaration below it by a blank line stays a standalone divider; one directly above becomes that declaration's doc comment and is re-emitted above it, not folded onto the header line. A comment written inline (`contract Pet: { # ...`) stays inline.
|
|
52
|
+
- **Operation body key order.** `sdk` before `service` stays that way; the printer never sorts a user's keys into a canonical order.
|
|
53
|
+
- **Blank lines** between operations inside a route.
|
|
54
|
+
- **Single-line response blocks.** `200: { application/json: Pet }` is not expanded, and an expanded block is not collapsed.
|
|
55
|
+
|
|
56
|
+
This is covered by `tests/round-trip.test.ts`, which formats every `.ck` file under `contracts/` and asserts the output is unchanged, plus checks that formatting is a fixed point. Anything that makes the printer normalize rather than preserve will fail it.
|
|
57
|
+
|
|
49
58
|
## Source layout
|
|
50
59
|
|
|
51
60
|
| Path | Purpose |
|
package/dist/index.js
CHANGED
|
@@ -106,7 +106,11 @@ function printField(field, indent, printWidth = 80) {
|
|
|
106
106
|
}
|
|
107
107
|
__name(printField, "printField");
|
|
108
108
|
function printInlineObjectExpanded(obj, indent, printWidth = 80) {
|
|
109
|
-
|
|
109
|
+
const lines = obj.fields.map((f) => printField(f, indent, printWidth));
|
|
110
|
+
for (const comment of obj.trailingComments ?? []) {
|
|
111
|
+
lines.push(`${indent}# ${comment}`);
|
|
112
|
+
}
|
|
113
|
+
return lines;
|
|
110
114
|
}
|
|
111
115
|
__name(printInlineObjectExpanded, "printInlineObjectExpanded");
|
|
112
116
|
function formatEnumValue(v) {
|
|
@@ -146,7 +150,7 @@ function printModelDecl(model, printWidth = 80) {
|
|
|
146
150
|
if (model.type !== void 0) {
|
|
147
151
|
return printTypeAlias(model, printWidth);
|
|
148
152
|
}
|
|
149
|
-
const commentSuffix = model.description ? ` # ${model.description}` : "";
|
|
153
|
+
const commentSuffix = model.description && model.descriptionInline ? ` # ${model.description}` : "";
|
|
150
154
|
const modifiers = [
|
|
151
155
|
model.deprecated ? "deprecated" : "",
|
|
152
156
|
model.inputCase || model.outputCase ? `format(${[
|
|
@@ -164,13 +168,16 @@ function printModelDecl(model, printWidth = 80) {
|
|
|
164
168
|
for (const field of model.fields) {
|
|
165
169
|
lines.push(printField(field, INDENT, printWidth));
|
|
166
170
|
}
|
|
171
|
+
for (const comment of model.trailingComments ?? []) {
|
|
172
|
+
lines.push(`${INDENT}# ${comment}`);
|
|
173
|
+
}
|
|
167
174
|
lines.push("}");
|
|
168
175
|
return lines.join("\n");
|
|
169
176
|
}
|
|
170
177
|
__name(printModelDecl, "printModelDecl");
|
|
171
178
|
function printTypeAlias(model, printWidth) {
|
|
172
179
|
const type = model.type;
|
|
173
|
-
const commentSuffix = model.description ? ` # ${model.description}` : "";
|
|
180
|
+
const commentSuffix = model.description && model.descriptionInline ? ` # ${model.description}` : "";
|
|
174
181
|
const modifiers = [
|
|
175
182
|
model.deprecated ? "deprecated" : "",
|
|
176
183
|
model.inputCase || model.outputCase ? `format(${[
|
|
@@ -215,8 +222,7 @@ function flushBlocks(out, blocks, idx, beforeLine, _indent = "") {
|
|
|
215
222
|
__name(flushBlocks, "flushBlocks");
|
|
216
223
|
function printRoute(route, blocks, idx, nextRouteStart) {
|
|
217
224
|
const lines = [];
|
|
218
|
-
|
|
219
|
-
lines.push(`${route.path}: {${commentSuffix}`);
|
|
225
|
+
lines.push(`${route.path}: {`);
|
|
220
226
|
if (route.params !== void 0) {
|
|
221
227
|
lines.push(...printParamsBlock(route.params, I1, route.paramsMode));
|
|
222
228
|
}
|
|
@@ -224,10 +230,14 @@ function printRoute(route, blocks, idx, nextRouteStart) {
|
|
|
224
230
|
lines.push(...printSecurity(route.security, I1, I2));
|
|
225
231
|
}
|
|
226
232
|
for (const op of route.operations) {
|
|
233
|
+
if (op.blankLineBefore && lines.length > 1) lines.push("");
|
|
227
234
|
flushBlocks(lines, blocks, idx, op.loc.line, I1);
|
|
228
235
|
lines.push(...printOperation(op));
|
|
229
236
|
}
|
|
230
237
|
flushBlocks(lines, blocks, idx, nextRouteStart, I1);
|
|
238
|
+
for (const comment of route.trailingComments ?? []) {
|
|
239
|
+
lines.push(`${I1}# ${comment}`);
|
|
240
|
+
}
|
|
231
241
|
lines.push("}");
|
|
232
242
|
return lines.join("\n");
|
|
233
243
|
}
|
|
@@ -260,53 +270,131 @@ function printParamsBlock(source, indent, mode) {
|
|
|
260
270
|
];
|
|
261
271
|
}
|
|
262
272
|
__name(printParamsBlock, "printParamsBlock");
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
273
|
+
var CANONICAL_KEY_ORDER = [
|
|
274
|
+
"name",
|
|
275
|
+
"service",
|
|
276
|
+
"sdk",
|
|
277
|
+
"mcp",
|
|
278
|
+
"signature",
|
|
279
|
+
"security",
|
|
280
|
+
"plugins",
|
|
281
|
+
"query",
|
|
282
|
+
"headers",
|
|
283
|
+
"request",
|
|
284
|
+
"responses"
|
|
285
|
+
];
|
|
286
|
+
function printOperationKey(op, key) {
|
|
287
|
+
switch (key) {
|
|
288
|
+
case "name":
|
|
289
|
+
return op.name ? [
|
|
290
|
+
`${I2}name: ${op.name}`
|
|
291
|
+
] : [];
|
|
292
|
+
case "service":
|
|
293
|
+
return op.service ? [
|
|
294
|
+
`${I2}service: ${op.service}`
|
|
295
|
+
] : [];
|
|
296
|
+
case "sdk":
|
|
297
|
+
return op.sdk ? [
|
|
298
|
+
`${I2}sdk: ${op.sdk}`
|
|
299
|
+
] : [];
|
|
300
|
+
case "mcp":
|
|
301
|
+
if (op.mcp === true) return [
|
|
302
|
+
`${I2}mcp: true`
|
|
303
|
+
];
|
|
304
|
+
if (op.mcp === false) return [
|
|
305
|
+
`${I2}mcp: false`
|
|
306
|
+
];
|
|
307
|
+
return op.mcp ? printMcpBlock(op.mcp) : [];
|
|
308
|
+
case "signature": {
|
|
309
|
+
if (!op.signature) return [];
|
|
310
|
+
const comment = op.signatureDescription ? ` # ${op.signatureDescription}` : "";
|
|
311
|
+
if (op.signaturePolicy) {
|
|
312
|
+
return [
|
|
313
|
+
`${I2}signature: {`,
|
|
314
|
+
`${I3}options: ${formatSignatureValue(op.signature)}${comment}`,
|
|
315
|
+
`${I3}policy: ${op.signaturePolicy}`,
|
|
316
|
+
`${I2}}`
|
|
317
|
+
];
|
|
318
|
+
}
|
|
319
|
+
return [
|
|
320
|
+
`${I2}signature: ${formatSignatureValue(op.signature)}${comment}`
|
|
321
|
+
];
|
|
322
|
+
}
|
|
323
|
+
case "security":
|
|
324
|
+
return op.security !== void 0 ? printSecurity(op.security) : [];
|
|
325
|
+
case "plugins": {
|
|
326
|
+
if (!op.plugins || Object.keys(op.plugins).length === 0) return [];
|
|
327
|
+
const lines = [
|
|
328
|
+
`${I2}plugins: {`
|
|
329
|
+
];
|
|
330
|
+
for (const [k, val] of Object.entries(op.plugins)) lines.push(...printPluginEntry(k, val, I3));
|
|
277
331
|
lines.push(`${I2}}`);
|
|
278
|
-
|
|
279
|
-
lines.push(`${I2}signature: ${formatSignatureValue(op.signature)}${comment}`);
|
|
332
|
+
return lines;
|
|
280
333
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
334
|
+
case "query":
|
|
335
|
+
return op.query !== void 0 ? printQueryOrHeaders("query", op.query, op.queryMode) : [];
|
|
336
|
+
case "headers":
|
|
337
|
+
if (op.requestHeadersOptOut) return [
|
|
338
|
+
`${I2}headers: none`
|
|
339
|
+
];
|
|
340
|
+
return op.headers !== void 0 ? printQueryOrHeaders("headers", op.headers, op.headersMode) : [];
|
|
341
|
+
case "request": {
|
|
342
|
+
if (!op.request) return [];
|
|
343
|
+
const lines = [
|
|
344
|
+
`${I2}request: {`
|
|
345
|
+
];
|
|
346
|
+
for (const body of op.request.bodies) lines.push(...printContentTypeLine(body.contentType, body.bodyType, I3));
|
|
347
|
+
lines.push(`${I2}}`);
|
|
348
|
+
return lines;
|
|
287
349
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (op.query !== void 0) lines.push(...printQueryOrHeaders("query", op.query, op.queryMode));
|
|
291
|
-
if (op.requestHeadersOptOut) {
|
|
292
|
-
lines.push(`${I2}headers: none`);
|
|
293
|
-
} else if (op.headers !== void 0) {
|
|
294
|
-
lines.push(...printQueryOrHeaders("headers", op.headers, op.headersMode));
|
|
350
|
+
case "responses":
|
|
351
|
+
return op.responses.length > 0 ? printResponseBlock(op.responses) : [];
|
|
295
352
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
353
|
+
}
|
|
354
|
+
__name(printOperationKey, "printOperationKey");
|
|
355
|
+
function printOperation(op) {
|
|
356
|
+
const lines = [];
|
|
357
|
+
const modPart = op.modifiers?.length ? `(${op.modifiers[0]})` : "";
|
|
358
|
+
const inlineDescription = op.descriptionInline ?? true;
|
|
359
|
+
if (op.description && !inlineDescription) {
|
|
360
|
+
for (const line of op.description.split("\n")) lines.push(`${I1}# ${line}`);
|
|
302
361
|
}
|
|
303
|
-
|
|
304
|
-
|
|
362
|
+
const commentSuffix = op.description && inlineDescription ? ` # ${op.description}` : "";
|
|
363
|
+
lines.push(`${I1}${op.method}${modPart}: {${commentSuffix}`);
|
|
364
|
+
const order = op.keyOrder ?? [];
|
|
365
|
+
const rest = CANONICAL_KEY_ORDER.filter((k) => !order.includes(k));
|
|
366
|
+
for (const key of [
|
|
367
|
+
...order,
|
|
368
|
+
...rest
|
|
369
|
+
]) {
|
|
370
|
+
lines.push(...printOperationKey(op, key));
|
|
305
371
|
}
|
|
306
372
|
lines.push(`${I1}}`);
|
|
307
373
|
return lines;
|
|
308
374
|
}
|
|
309
375
|
__name(printOperation, "printOperation");
|
|
376
|
+
function mcpHintTokens(mcp) {
|
|
377
|
+
const tokens = [];
|
|
378
|
+
if (mcp.readOnlyHint !== void 0) tokens.push(mcp.readOnlyHint ? "readOnly" : "nonReadOnly");
|
|
379
|
+
if (mcp.idempotentHint !== void 0) tokens.push(mcp.idempotentHint ? "idempotent" : "nonIdempotent");
|
|
380
|
+
if (mcp.destructiveHint !== void 0) tokens.push(mcp.destructiveHint ? "destructive" : "nonDestructive");
|
|
381
|
+
if (mcp.openWorldHint !== void 0) tokens.push(mcp.openWorldHint ? "openWorld" : "closedWorld");
|
|
382
|
+
return tokens;
|
|
383
|
+
}
|
|
384
|
+
__name(mcpHintTokens, "mcpHintTokens");
|
|
385
|
+
function printMcpBlock(mcp) {
|
|
386
|
+
const lines = [
|
|
387
|
+
`${I2}mcp: {`
|
|
388
|
+
];
|
|
389
|
+
if (mcp.name !== void 0) lines.push(`${I3}name: "${escapeString(mcp.name)}"`);
|
|
390
|
+
if (mcp.title !== void 0) lines.push(`${I3}title: "${escapeString(mcp.title)}"`);
|
|
391
|
+
if (mcp.description !== void 0) lines.push(`${I3}description: "${escapeString(mcp.description)}"`);
|
|
392
|
+
const tokens = mcpHintTokens(mcp);
|
|
393
|
+
if (tokens.length > 0) lines.push(`${I3}hint: ${tokens.join(", ")}`);
|
|
394
|
+
lines.push(`${I2}}`);
|
|
395
|
+
return lines;
|
|
396
|
+
}
|
|
397
|
+
__name(printMcpBlock, "printMcpBlock");
|
|
310
398
|
var IDENT_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
311
399
|
function escapeString(s) {
|
|
312
400
|
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
@@ -451,7 +539,9 @@ function printResponseBlock(responses) {
|
|
|
451
539
|
const hasBody = resp.contentType && resp.bodyType;
|
|
452
540
|
const hasHeaders = resp.headers && resp.headers.length > 0;
|
|
453
541
|
const optOut = resp.headersOptOut;
|
|
454
|
-
if (hasBody
|
|
542
|
+
if (resp.inline && hasBody && !hasHeaders && !optOut && resp.bodyType.kind !== "inlineObject") {
|
|
543
|
+
lines.push(`${I3}${resp.statusCode}: { ${resp.contentType}: ${printType(resp.bodyType)} }`);
|
|
544
|
+
} else if (hasBody || hasHeaders || optOut) {
|
|
455
545
|
lines.push(`${I3}${resp.statusCode}: {`);
|
|
456
546
|
if (hasBody) {
|
|
457
547
|
lines.push(...printContentTypeLine(resp.contentType, resp.bodyType, I4));
|
|
@@ -483,39 +573,55 @@ function quoteOptionsValue(value) {
|
|
|
483
573
|
return /^[a-zA-Z_$][a-zA-Z0-9_$\-.]*$/.test(value) ? value : `"${value}"`;
|
|
484
574
|
}
|
|
485
575
|
__name(quoteOptionsValue, "quoteOptionsValue");
|
|
576
|
+
function emitOptionsEntries(lines, entries, comments) {
|
|
577
|
+
const I22 = INDENT + INDENT;
|
|
578
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
579
|
+
for (const c of comments?.leading?.[key] ?? []) lines.push(`${I22}# ${c}`);
|
|
580
|
+
lines.push(`${I22}${key}: ${quoteOptionsValue(value)}`);
|
|
581
|
+
}
|
|
582
|
+
for (const c of comments?.trailing ?? []) lines.push(`${I22}# ${c}`);
|
|
583
|
+
}
|
|
584
|
+
__name(emitOptionsEntries, "emitOptionsEntries");
|
|
486
585
|
function printOptionsBlock(ast) {
|
|
487
586
|
const hasMeta = Object.keys(ast.meta).length > 0;
|
|
488
587
|
const hasServices = Object.keys(ast.services).length > 0;
|
|
489
588
|
const hasSecurity = ast.security !== void 0;
|
|
490
589
|
const hasRequestHeaders = (ast.requestHeaders?.length ?? 0) > 0;
|
|
491
590
|
const hasResponseHeaders = (ast.responseHeaders?.length ?? 0) > 0;
|
|
492
|
-
|
|
591
|
+
const hasBodyComments = ast.optionsComments?.body !== void 0;
|
|
592
|
+
if (!hasMeta && !hasServices && !hasSecurity && !hasRequestHeaders && !hasResponseHeaders && !hasBodyComments) return null;
|
|
493
593
|
const lines = [
|
|
494
594
|
"options {"
|
|
495
595
|
];
|
|
596
|
+
const body = ast.optionsComments?.body;
|
|
597
|
+
const emitLeading = /* @__PURE__ */ __name((scope) => {
|
|
598
|
+
for (const c of body?.leading?.[scope] ?? []) lines.push(`${INDENT}# ${c}`);
|
|
599
|
+
}, "emitLeading");
|
|
496
600
|
if (hasMeta) {
|
|
601
|
+
emitLeading("keys");
|
|
497
602
|
lines.push(`${INDENT}keys: {`);
|
|
498
|
-
|
|
499
|
-
lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);
|
|
500
|
-
}
|
|
603
|
+
emitOptionsEntries(lines, ast.meta, ast.optionsComments?.keys);
|
|
501
604
|
lines.push(`${INDENT}}`);
|
|
502
605
|
}
|
|
503
606
|
if (hasServices) {
|
|
607
|
+
emitLeading("services");
|
|
504
608
|
lines.push(`${INDENT}services: {`);
|
|
505
|
-
|
|
506
|
-
lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);
|
|
507
|
-
}
|
|
609
|
+
emitOptionsEntries(lines, ast.services, ast.optionsComments?.services);
|
|
508
610
|
lines.push(`${INDENT}}`);
|
|
509
611
|
}
|
|
510
612
|
if (hasRequestHeaders) {
|
|
613
|
+
emitLeading("request");
|
|
511
614
|
lines.push(...printOptionsHeaderScope("request", ast.requestHeaders));
|
|
512
615
|
}
|
|
513
616
|
if (hasResponseHeaders) {
|
|
617
|
+
emitLeading("response");
|
|
514
618
|
lines.push(...printOptionsHeaderScope("response", ast.responseHeaders));
|
|
515
619
|
}
|
|
516
620
|
if (hasSecurity) {
|
|
621
|
+
emitLeading("security");
|
|
517
622
|
lines.push(...printSecurity(ast.security, INDENT, INDENT + INDENT));
|
|
518
623
|
}
|
|
624
|
+
for (const c of body?.trailing ?? []) lines.push(`${INDENT}# ${c}`);
|
|
519
625
|
lines.push("}");
|
|
520
626
|
return lines.join("\n");
|
|
521
627
|
}
|
|
@@ -543,7 +649,7 @@ function printCk(ast, printWidth = DEFAULT_PRINT_WIDTH) {
|
|
|
543
649
|
if (options) parts.push(options);
|
|
544
650
|
for (const model of ast.models) {
|
|
545
651
|
if (parts.length > 0) parts.push("");
|
|
546
|
-
parts.push(`contract ${printModelDecl(model, printWidth)}`);
|
|
652
|
+
parts.push(printDeclLeadIn(model.leadingComments, model.descriptionInline ? void 0 : model.description) + `contract ${printModelDecl(model, printWidth)}`);
|
|
547
653
|
}
|
|
548
654
|
const emptyBlocks = [];
|
|
549
655
|
const emptyIdx = {
|
|
@@ -552,11 +658,23 @@ function printCk(ast, printWidth = DEFAULT_PRINT_WIDTH) {
|
|
|
552
658
|
for (const route of ast.routes) {
|
|
553
659
|
if (parts.length > 0) parts.push("");
|
|
554
660
|
const modPart = route.modifiers?.length ? `(${route.modifiers[0]})` : "";
|
|
555
|
-
parts.push(`operation${modPart} ${printRoute(route, emptyBlocks, emptyIdx, Infinity)}`);
|
|
661
|
+
parts.push(printDeclLeadIn(route.leadingComments, route.description) + `operation${modPart} ${printRoute(route, emptyBlocks, emptyIdx, Infinity)}`);
|
|
556
662
|
}
|
|
557
663
|
return parts.join("\n") + "\n";
|
|
558
664
|
}
|
|
559
665
|
__name(printCk, "printCk");
|
|
666
|
+
function printDeclLeadIn(leadingComments, description) {
|
|
667
|
+
const lines = [];
|
|
668
|
+
if (leadingComments?.length) {
|
|
669
|
+
for (const c of leadingComments) lines.push(`# ${c}`);
|
|
670
|
+
lines.push("");
|
|
671
|
+
}
|
|
672
|
+
if (description) {
|
|
673
|
+
for (const line of description.split("\n")) lines.push(`# ${line}`);
|
|
674
|
+
}
|
|
675
|
+
return lines.length > 0 ? lines.join("\n") + "\n" : "";
|
|
676
|
+
}
|
|
677
|
+
__name(printDeclLeadIn, "printDeclLeadIn");
|
|
560
678
|
|
|
561
679
|
// src/index.ts
|
|
562
680
|
var { hardline, join } = builders;
|