@contractkit/prettier-plugin 0.8.1 → 0.9.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/.turbo/turbo-build$colon$ci.log +19 -35
- package/.turbo/turbo-test$colon$ci.log +26 -105
- package/CHANGELOG.md +32 -0
- package/README.md +58 -0
- package/coverage/clover.xml +159 -155
- package/coverage/coverage-final.json +5 -5
- package/coverage/indent.ts.html +1 -1
- package/coverage/index.html +27 -27
- package/coverage/print-ck.ts.html +111 -57
- package/coverage/print-contract.ts.html +1 -1
- package/coverage/print-operation.ts.html +58 -37
- package/coverage/print-type.ts.html +1 -1
- package/dist/index.js +13 -4
- package/dist/index.js.map +1 -1
- package/dist/print-ck.d.ts +8 -0
- package/dist/print-ck.d.ts.map +1 -1
- package/dist/print-operation.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/print-ck.ts +22 -4
- package/src/print-operation.ts +7 -0
- package/tests/print-ck.test.ts +109 -0
- package/.turbo/turbo-build.log +0 -15
- package/.turbo/turbo-format.log +0 -29
- package/.turbo/turbo-test.log +0 -14
- package/dist/__tests__/print-ck.test.d.ts +0 -2
- package/dist/__tests__/print-ck.test.d.ts.map +0 -1
- package/dist/__tests__/print-op.test.d.ts +0 -2
- package/dist/__tests__/print-op.test.d.ts.map +0 -1
- package/dist/__tests__/print-op.test.js +0 -359
- package/dist/__tests__/print-op.test.js.map +0 -1
- package/dist/print-dto.d.ts +0 -3
- package/dist/print-dto.d.ts.map +0 -1
- package/dist/print-dto.js +0 -100
- package/dist/print-dto.js.map +0 -1
- package/dist/print-op.d.ts +0 -24
- package/dist/print-op.d.ts.map +0 -1
- package/dist/print-op.js +0 -224
- package/dist/print-op.js.map +0 -1
- package/dist/print-type.js +0 -110
- package/dist/print-type.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -268,6 +268,13 @@ function printOperation(op) {
|
|
|
268
268
|
lines.push(`${I2}signature: ${formatSignatureValue(op.signature)}${comment}`);
|
|
269
269
|
}
|
|
270
270
|
if (op.security !== void 0) lines.push(...printSecurity(op.security));
|
|
271
|
+
if (op.plugins && Object.keys(op.plugins).length > 0) {
|
|
272
|
+
lines.push(`${I2}plugins: {`);
|
|
273
|
+
for (const [key, val] of Object.entries(op.plugins)) {
|
|
274
|
+
lines.push(`${I3}${key}: "${val.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`);
|
|
275
|
+
}
|
|
276
|
+
lines.push(`${I2}}`);
|
|
277
|
+
}
|
|
271
278
|
if (op.query !== void 0) lines.push(...printQueryOrHeaders("query", op.query, op.queryMode));
|
|
272
279
|
if (op.requestHeadersOptOut) {
|
|
273
280
|
lines.push(`${I2}headers: none`);
|
|
@@ -394,6 +401,10 @@ __name(printResponseBlock, "printResponseBlock");
|
|
|
394
401
|
|
|
395
402
|
// src/print-ck.ts
|
|
396
403
|
var DEFAULT_PRINT_WIDTH = 80;
|
|
404
|
+
function quoteOptionsValue(value) {
|
|
405
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$\-.]*$/.test(value) ? value : `"${value}"`;
|
|
406
|
+
}
|
|
407
|
+
__name(quoteOptionsValue, "quoteOptionsValue");
|
|
397
408
|
function printOptionsBlock(ast) {
|
|
398
409
|
const hasMeta = Object.keys(ast.meta).length > 0;
|
|
399
410
|
const hasServices = Object.keys(ast.services).length > 0;
|
|
@@ -407,16 +418,14 @@ function printOptionsBlock(ast) {
|
|
|
407
418
|
if (hasMeta) {
|
|
408
419
|
lines.push(`${INDENT}keys: {`);
|
|
409
420
|
for (const [key, value] of Object.entries(ast.meta)) {
|
|
410
|
-
|
|
411
|
-
lines.push(`${INDENT}${INDENT}${key}: ${v}`);
|
|
421
|
+
lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);
|
|
412
422
|
}
|
|
413
423
|
lines.push(`${INDENT}}`);
|
|
414
424
|
}
|
|
415
425
|
if (hasServices) {
|
|
416
426
|
lines.push(`${INDENT}services: {`);
|
|
417
427
|
for (const [key, value] of Object.entries(ast.services)) {
|
|
418
|
-
|
|
419
|
-
lines.push(`${INDENT}${INDENT}${key}: ${v}`);
|
|
428
|
+
lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);
|
|
420
429
|
}
|
|
421
430
|
lines.push(`${INDENT}}`);
|
|
422
431
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/indent.ts","../src/print-type.ts","../src/print-contract.ts","../src/print-operation.ts","../src/print-ck.ts"],"sourcesContent":["import type { Plugin } from 'prettier';\nimport { builders } from 'prettier/doc';\nimport { parseCk, DiagnosticCollector } from '@contractkit/core';\nimport type { CkRootNode } from '@contractkit/core';\nimport { printCk } from './print-ck.js';\n\nconst { hardline, join } = builders;\n\nfunction toDoc(text: string) {\n const lines = text.trimEnd().split('\\n');\n return join(hardline, lines);\n}\n\nconst plugin: Plugin<CkRootNode> = {\n languages: [\n {\n name: 'ContractDSL',\n parsers: ['contract-ck'],\n extensions: ['.ck'],\n vscodeLanguageIds: ['contract-ck'],\n },\n ],\n\n parsers: {\n 'contract-ck': {\n parse(text, _options) {\n const diag = new DiagnosticCollector();\n return parseCk(text, '<stdin>', diag);\n },\n astFormat: 'contract-ck',\n locStart: () => 0,\n locEnd: _node => 0,\n },\n },\n\n printers: {\n 'contract-ck': {\n print(path, options) {\n const node = path.node as CkRootNode;\n return toDoc(printCk(node, options.printWidth));\n },\n },\n },\n};\n\nexport default plugin;\n","export const INDENT = ' ';\n","import type { ContractTypeNode, FieldNode, InlineObjectTypeNode } from '@contractkit/core';\nimport { INDENT } from './indent.js';\n\n// ─── Type expression printer ────────────────────────────────────────────────\n\nexport function printType(type: ContractTypeNode): string {\n switch (type.kind) {\n case 'scalar': {\n const constraints: string[] = [];\n if (type.format !== undefined) {\n // Print unquoted when format contains only safe chars; quote otherwise\n const fmt = type.format;\n constraints.push(/^[a-zA-Z0-9\\-.:/]+$/.test(fmt) ? fmt : `\"${fmt}\"`);\n }\n if (type.min !== undefined) constraints.push(`min=${type.min}`);\n if (type.max !== undefined) constraints.push(`max=${type.max}`);\n if (type.len !== undefined) constraints.push(`len=${type.len}`);\n if (type.regex !== undefined) constraints.push(`regex=/${type.regex}/`);\n return constraints.length > 0 ? `${type.name}(${constraints.join(', ')})` : type.name;\n }\n case 'array': {\n const args: string[] = [printType(type.item)];\n if (type.min !== undefined) args.push(`min=${type.min}`);\n if (type.max !== undefined) args.push(`max=${type.max}`);\n return `array(${args.join(', ')})`;\n }\n case 'tuple':\n return `tuple(${type.items.map(printType).join(', ')})`;\n case 'record':\n return `record(${printType(type.key)}, ${printType(type.value)})`;\n case 'enum':\n return `enum(${type.values.join(', ')})`;\n case 'literal':\n return typeof type.value === 'string' ? `literal(\"${type.value}\")` : `literal(${type.value})`;\n case 'union':\n return type.members.map(printType).join(' | ');\n case 'discriminatedUnion':\n return `discriminated(by=${type.discriminator}, ${type.members.map(printType).join(' | ')})`;\n case 'intersection':\n return type.members.map(printType).join(' & ');\n case 'ref':\n return type.name;\n case 'inlineObject':\n return printInlineObjectCompact(type);\n case 'lazy':\n return `lazy(${printType(type.inner)})`;\n }\n}\n\n/** Compact single-line form — used when inline object appears nested inside another type. */\nfunction printInlineObjectCompact(obj: InlineObjectTypeNode): string {\n const prefix = obj.mode ? `mode(${obj.mode}) ` : '';\n if (obj.fields.length === 0) return `${prefix}{}`;\n const parts = obj.fields.map(f => {\n const opt = f.optional ? '?' : '';\n let t = printType(f.type);\n if (f.nullable) t += ' | null';\n return `${f.name}${opt}: ${t}`;\n });\n return `${prefix}{ ${parts.join(', ')} }`;\n}\n\n/** Multi-line enum form — one value per line, used when single-line would exceed print width. */\nexport function printEnumExpanded(values: string[], indent: string): string {\n const innerIndent = indent + INDENT;\n return `enum(\\n${values.map(v => `${innerIndent}${v}`).join(',\\n')}\\n${indent})`;\n}\n\n// ─── Field printer ──────────────────────────────────────────────────────────\n\n/** Print a full field declaration, including visibility, default, and inline comment.\n * Modifier order is canonical: override → deprecated → readonly|writeonly → type. */\nexport function printField(field: FieldNode, indent: string, printWidth: number = 80): string {\n const opt = field.optional ? '?' : '';\n const ovr = field.override ? 'override ' : '';\n const dep = field.deprecated ? 'deprecated ' : '';\n const vis = field.visibility !== 'normal' ? `${field.visibility} ` : '';\n const mods = `${ovr}${dep}${vis}`;\n const def = field.default !== undefined ? ` = ${formatDefault(field.default)}` : '';\n const comment = field.description ? ` # ${field.description}` : '';\n const innerIndent = indent + INDENT;\n\n // Expand inline object types to multi-line — same rule as type aliases.\n // Only when there's no default and no nullable union (those can't split cleanly).\n if (!field.nullable && field.default === undefined) {\n const trailing = extractTrailingInlineObject(field.type);\n if (trailing) {\n const { prefix, inlineObj } = trailing;\n const modePart = inlineObj.mode ? `mode(${inlineObj.mode}) ` : '';\n const header = prefix\n ? `${indent}${field.name}${opt}: ${mods}${prefix} & ${modePart}{${comment}`\n : `${indent}${field.name}${opt}: ${mods}${modePart}{${comment}`;\n return [header, ...printInlineObjectExpanded(inlineObj, innerIndent, printWidth), `${indent}}`].join('\\n');\n }\n }\n\n let typeStr = printType(field.type);\n if (field.nullable) typeStr += ' | null';\n const fullLine = `${indent}${field.name}${opt}: ${mods}${typeStr}${def}${comment}`;\n if (field.type.kind === 'enum' && !field.nullable && field.default === undefined && fullLine.length > printWidth) {\n const enumStr = printEnumExpanded(field.type.values, indent);\n return `${indent}${field.name}${opt}: ${mods}${enumStr}${comment}`;\n }\n return fullLine;\n}\n\n/** Print inline-object fields expanded (used when an inline brace object trails a type alias). */\nexport function printInlineObjectExpanded(obj: InlineObjectTypeNode, indent: string, printWidth: number = 80): string[] {\n return obj.fields.map(f => printField(f, indent, printWidth));\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/** Format a default value: quote strings that aren't valid bare identifiers. */\nexport function formatDefault(val: string | number | boolean): string {\n if (typeof val === 'number' || typeof val === 'boolean') return String(val);\n // If it looks like a bare identifier (enum value, unquoted token), keep it bare.\n if (/^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/.test(val)) return val;\n return `\"${val}\"`;\n}\n\n/**\n * Detect whether the last member of a type is an inline brace object, and if so\n * return the prefix type string and the inline object for expanded printing.\n * Returns null if the type doesn't end with an inline object.\n */\nexport function extractTrailingInlineObject(type: ContractTypeNode): {\n prefix: string | null;\n inlineObj: InlineObjectTypeNode;\n} | null {\n if (type.kind === 'inlineObject') {\n return { prefix: null, inlineObj: type };\n }\n if (type.kind === 'intersection') {\n const last = type.members[type.members.length - 1];\n if (last?.kind === 'inlineObject') {\n const prefixStr = type.members.slice(0, -1).map(printType).join(' & ');\n return { prefix: prefixStr, inlineObj: last };\n }\n }\n return null;\n}\n","import type { ModelNode } from '@contractkit/core';\nimport { printField, printInlineObjectExpanded, extractTrailingInlineObject, printType, printEnumExpanded } from './print-type.js';\nimport { INDENT } from './indent.js';\n\n// ─── Model declaration ───────────────────────────────────────────────────────\n\nexport function printModelDecl(model: ModelNode, printWidth: number = 80): string {\n // Type alias form: Name : typeExpression\n if (model.type !== undefined) {\n return printTypeAlias(model, printWidth);\n }\n\n // Regular model with fields (possibly inherited)\n const commentSuffix = model.description ? ` # ${model.description}` : '';\n const modifiers = [\n model.deprecated ? 'deprecated' : '',\n model.inputCase || model.outputCase\n ? `format(${[model.inputCase ? `input=${model.inputCase}` : '', model.outputCase ? `output=${model.outputCase}` : ''].filter(Boolean).join(', ')})`\n : '',\n model.mode ? `mode(${model.mode})` : '',\n ]\n .filter(Boolean)\n .join(' ');\n const modePrefix = modifiers ? `${modifiers} ` : '';\n const baseChain = model.bases && model.bases.length > 0 ? `${model.bases.join(' & ')} & ` : '';\n const header = `${modePrefix}${model.name}: ${baseChain}{${commentSuffix}`;\n\n const lines: string[] = [header];\n for (const field of model.fields) {\n lines.push(printField(field, INDENT, printWidth));\n }\n lines.push('}');\n return lines.join('\\n');\n}\n\nfunction printTypeAlias(model: ModelNode, printWidth: number): string {\n const type = model.type!;\n const commentSuffix = model.description ? ` # ${model.description}` : '';\n const modifiers = [\n model.deprecated ? 'deprecated' : '',\n model.inputCase || model.outputCase\n ? `format(${[model.inputCase ? `input=${model.inputCase}` : '', model.outputCase ? `output=${model.outputCase}` : ''].filter(Boolean).join(', ')})`\n : '',\n model.mode ? `mode(${model.mode})` : '',\n ]\n .filter(Boolean)\n .join(' ');\n const modePrefix = modifiers ? `${modifiers} ` : '';\n\n // If the type ends with an inline brace object, expand it as a pseudo-model block.\n const trailing = extractTrailingInlineObject(type);\n if (trailing) {\n const { prefix, inlineObj } = trailing;\n const modePart = inlineObj.mode ? `mode(${inlineObj.mode}) ` : '';\n const header = prefix\n ? `${modePrefix}${model.name}: ${prefix} & ${modePart}{${commentSuffix}`\n : `${modePrefix}${model.name}: ${modePart}{${commentSuffix}`;\n const lines: string[] = [header, ...printInlineObjectExpanded(inlineObj, INDENT, printWidth), '}'];\n return lines.join('\\n');\n }\n\n // Simple type alias — single line, unless it's a long enum.\n // Note: the contract prefix \"contract \" (9 chars) is prepended by the caller.\n const singleLine = `${modePrefix}${model.name}: ${printType(type)}${commentSuffix}`;\n if (type.kind === 'enum' && 'contract '.length + singleLine.length > printWidth) {\n return `${modePrefix}${model.name}: ${printEnumExpanded(type.values, '')}${commentSuffix}`;\n }\n return singleLine;\n}\n","import type {\n OpRouteNode,\n OpOperationNode,\n OpResponseNode,\n ParamSource,\n SecurityNode,\n SecurityFields,\n ContractTypeNode,\n ObjectMode,\n} from '@contractkit/core';\nimport { SECURITY_NONE } from '@contractkit/core';\nimport { printType, formatDefault } from './print-type.js';\nimport { INDENT } from './indent.js';\n\nconst I1 = INDENT;\nconst I2 = INDENT.repeat(2);\nconst I3 = INDENT.repeat(3);\nconst I4 = INDENT.repeat(4);\n\n// ─── Orphan comment helpers ──────────────────────────────────────────────────\n\ntype CommentEntry = { line: number; text: string };\nexport type CommentBlock = { startLine: number; lines: string[] };\n\n/** Group sorted orphan comment entries into consecutive-line blocks. */\nexport function groupComments(entries: CommentEntry[]): CommentBlock[] {\n const blocks: CommentBlock[] = [];\n let current: CommentBlock | null = null;\n for (const { line, text } of entries) {\n if (current && line === current.startLine + current.lines.length) {\n current.lines.push(text);\n } else {\n if (current) blocks.push(current);\n current = { startLine: line, lines: [text] };\n }\n }\n if (current) blocks.push(current);\n return blocks;\n}\n\n/**\n * Emit any comment blocks whose startLine is < beforeLine.\n * Lines are emitted verbatim — they already carry their original indentation.\n */\nexport function flushBlocks(out: string[], blocks: CommentBlock[], idx: { value: number }, beforeLine: number, _indent = '') {\n while (idx.value < blocks.length && blocks[idx.value]!.startLine < beforeLine) {\n for (const l of blocks[idx.value]!.lines) out.push(l);\n idx.value++;\n }\n}\n\n// ─── Route ───────────────────────────────────────────────────────────────────\n\nexport function printRoute(route: OpRouteNode, blocks: CommentBlock[], idx: { value: number }, nextRouteStart: number): string {\n const lines: string[] = [];\n const commentSuffix = route.description ? ` # ${route.description}` : '';\n lines.push(`${route.path}: {${commentSuffix}`);\n\n if (route.params !== undefined) {\n lines.push(...printParamsBlock(route.params, I1, route.paramsMode));\n }\n\n if (route.security !== undefined) {\n lines.push(...printSecurity(route.security, I1, I2));\n }\n\n for (const op of route.operations) {\n // Flush comment blocks that appear before this operation (inside the route)\n flushBlocks(lines, blocks, idx, op.loc.line, I1);\n lines.push(...printOperation(op));\n }\n\n // Flush comment blocks between last operation and the next route\n flushBlocks(lines, blocks, idx, nextRouteStart, I1);\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n// ─── Params block ────────────────────────────────────────────────────────────\n\nfunction printParamsBlock(source: ParamSource, indent: string, mode?: ObjectMode): string[] {\n const prefix = mode ? `mode(${mode}) ` : '';\n if (source.kind === 'ref') {\n return [`${indent}${prefix}params: ${source.name}`];\n }\n if (source.kind === 'params') {\n const lines: string[] = [`${indent}${prefix}params: {`];\n const inner = indent + INDENT;\n for (const p of source.nodes) {\n const opt = p.optional ? '?' : '';\n let t = printType(p.type);\n if (p.nullable) t += ' | null';\n const def = p.default !== undefined ? ` = ${formatDefault(p.default)}` : '';\n const comment = p.description ? ` # ${p.description}` : '';\n lines.push(`${inner}${p.name}${opt}: ${t}${def}${comment}`);\n }\n lines.push(`${indent}}`);\n return lines;\n }\n // ContractTypeNode\n return [`${indent}${prefix}params: ${printType(source.node)}`];\n}\n\n// ─── HTTP operation ──────────────────────────────────────────────────────────\n\nfunction printOperation(op: OpOperationNode): string[] {\n const lines: string[] = [];\n const commentSuffix = op.description ? ` # ${op.description}` : '';\n const modPart = op.modifiers?.length ? `(${op.modifiers[0]})` : '';\n lines.push(`${I1}${op.method}${modPart}: {${commentSuffix}`);\n\n if (op.name) lines.push(`${I2}name: ${op.name}`);\n if (op.service) lines.push(`${I2}service: ${op.service}`);\n if (op.sdk) lines.push(`${I2}sdk: ${op.sdk}`);\n if (op.signature) {\n const comment = op.signatureDescription ? ` # ${op.signatureDescription}` : '';\n lines.push(`${I2}signature: ${formatSignatureValue(op.signature)}${comment}`);\n }\n if (op.security !== undefined) lines.push(...printSecurity(op.security));\n if (op.query !== undefined) lines.push(...printQueryOrHeaders('query', op.query, op.queryMode));\n if (op.requestHeadersOptOut) {\n lines.push(`${I2}headers: none`);\n } else if (op.headers !== undefined) {\n lines.push(...printQueryOrHeaders('headers', op.headers, op.headersMode));\n }\n if (op.request) {\n lines.push(`${I2}request: {`);\n for (const body of op.request.bodies) {\n lines.push(...printContentTypeLine(body.contentType, body.bodyType, I3));\n }\n lines.push(`${I2}}`);\n }\n if (op.responses.length > 0) {\n lines.push(...printResponseBlock(op.responses));\n }\n\n lines.push(`${I1}}`);\n return lines;\n}\n\n// ─── Security ────────────────────────────────────────────────────────────────\n\n/** Print a signature key: unquoted when it's a plain identifier, quoted otherwise. */\nfunction formatSignatureValue(value: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(value) ? value : `\"${value}\"`;\n}\n\n// indent: indentation for the `security` keyword line\n// innerIndent: indentation for field lines inside the block\nexport function printSecurity(security: SecurityNode, indent = I2, innerIndent = I3): string[] {\n if (security === SECURITY_NONE) return [`${indent}security: none`];\n const fields = security as SecurityFields;\n const hasRoles = fields.roles && fields.roles.length > 0;\n if (!hasRoles) return [];\n const lines = [`${indent}security: {`];\n const comment = fields.rolesDescription ? ` # ${fields.rolesDescription}` : '';\n lines.push(`${innerIndent}roles: ${fields.roles!.join(' ')}${comment}`);\n lines.push(`${indent}}`);\n return lines;\n}\n\n// ─── Query / headers ─────────────────────────────────────────────────────────\n\nfunction printQueryOrHeaders(keyword: 'query' | 'headers', source: ParamSource, mode?: ObjectMode): string[] {\n const prefix = mode ? `mode(${mode}) ` : '';\n if (source.kind === 'ref') {\n return [`${I2}${prefix}${keyword}: ${source.name}`];\n }\n if (source.kind === 'params') {\n if (source.nodes.length === 0) return [];\n const lines: string[] = [`${I2}${prefix}${keyword}: {`];\n for (const p of source.nodes) {\n const opt = p.optional ? '?' : '';\n let t = printType(p.type);\n if (p.nullable) t += ' | null';\n const def = p.default !== undefined ? ` = ${formatDefault(p.default)}` : '';\n const comment = p.description ? ` # ${p.description}` : '';\n lines.push(`${I3}${p.name}${opt}: ${t}${def}${comment}`);\n }\n lines.push(`${I2}}`);\n return lines;\n }\n // ContractTypeNode (e.g. intersection)\n return [`${I2}${prefix}${keyword}: ${printType(source.node)}`];\n}\n\n// ─── Content-type line ───────────────────────────────────────────────────────\n\n/** Print a `contentType: bodyType` line, expanding inline brace objects onto separate lines. */\nfunction printContentTypeLine(contentType: string, bodyType: ContractTypeNode, lineIndent: string): string[] {\n if (bodyType.kind === 'inlineObject') {\n const fieldIndent = lineIndent + INDENT;\n const lines: string[] = [`${lineIndent}${contentType}: {`];\n for (const f of bodyType.fields) {\n const opt = f.optional ? '?' : '';\n let t = printType(f.type);\n if (f.nullable) t += ' | null';\n const def = f.default !== undefined ? ` = ${formatDefault(f.default)}` : '';\n const comment = f.description ? ` # ${f.description}` : '';\n lines.push(`${fieldIndent}${f.name}${opt}: ${t}${def}${comment}`);\n }\n lines.push(`${lineIndent}}`);\n return lines;\n }\n return [`${lineIndent}${contentType}: ${printType(bodyType)}`];\n}\n\n// ─── Response block ──────────────────────────────────────────────────────────\n\nfunction printResponseBlock(responses: OpResponseNode[]): string[] {\n const lines: string[] = [`${I2}response: {`];\n\n for (const resp of responses) {\n const hasBody = resp.contentType && resp.bodyType;\n const hasHeaders = resp.headers && resp.headers.length > 0;\n const optOut = resp.headersOptOut;\n if (hasBody || hasHeaders || optOut) {\n lines.push(`${I3}${resp.statusCode}: {`);\n if (hasBody) {\n lines.push(...printContentTypeLine(resp.contentType!, resp.bodyType!, I4));\n }\n if (optOut) {\n lines.push(`${I4}headers: none`);\n } else if (hasHeaders) {\n lines.push(`${I4}headers: {`);\n for (const h of resp.headers!) {\n const opt = h.optional ? '?' : '';\n const trail = h.description ? ` # ${h.description}` : '';\n lines.push(`${I4}${INDENT}${h.name}${opt}: ${printType(h.type)}${trail}`);\n }\n lines.push(`${I4}}`);\n }\n lines.push(`${I3}}`);\n } else {\n lines.push(`${I3}${resp.statusCode}:`);\n }\n }\n\n lines.push(`${I2}}`);\n return lines;\n}\n","import type { CkRootNode, OpResponseHeaderNode } from '@contractkit/core';\nimport { printModelDecl } from './print-contract.js';\nimport { printRoute, printSecurity, type CommentBlock } from './print-operation.js';\nimport { printType } from './print-type.js';\nimport { INDENT } from './indent.js';\n\nexport const DEFAULT_PRINT_WIDTH = 80;\n\n// ─── Options block ──────────────────────────────────────────────────────────\n\nfunction printOptionsBlock(ast: CkRootNode): string | null {\n const hasMeta = Object.keys(ast.meta).length > 0;\n const hasServices = Object.keys(ast.services).length > 0;\n const hasSecurity = ast.security !== undefined;\n const hasRequestHeaders = (ast.requestHeaders?.length ?? 0) > 0;\n const hasResponseHeaders = (ast.responseHeaders?.length ?? 0) > 0;\n\n if (!hasMeta && !hasServices && !hasSecurity && !hasRequestHeaders && !hasResponseHeaders) return null;\n\n const lines: string[] = ['options {'];\n\n if (hasMeta) {\n lines.push(`${INDENT}keys: {`);\n for (const [key, value] of Object.entries(ast.meta)) {\n const v = value.startsWith('#') || value.includes(' ') ? `\"${value}\"` : value;\n lines.push(`${INDENT}${INDENT}${key}: ${v}`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasServices) {\n lines.push(`${INDENT}services: {`);\n for (const [key, value] of Object.entries(ast.services)) {\n const v = value.startsWith('#') || value.includes(' ') ? `\"${value}\"` : value;\n lines.push(`${INDENT}${INDENT}${key}: ${v}`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasRequestHeaders) {\n lines.push(...printOptionsHeaderScope('request', ast.requestHeaders!));\n }\n\n if (hasResponseHeaders) {\n lines.push(...printOptionsHeaderScope('response', ast.responseHeaders!));\n }\n\n if (hasSecurity) {\n lines.push(...printSecurity(ast.security!, INDENT, INDENT + INDENT));\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\nfunction printOptionsHeaderScope(keyword: 'request' | 'response', headers: OpResponseHeaderNode[]): string[] {\n const I2 = INDENT + INDENT;\n const I3 = INDENT + INDENT + INDENT;\n const lines = [`${INDENT}${keyword}: {`, `${I2}headers: {`];\n for (const h of headers) {\n const opt = h.optional ? '?' : '';\n const trail = h.description ? ` # ${h.description}` : '';\n lines.push(`${I3}${h.name}${opt}: ${printType(h.type)}${trail}`);\n }\n lines.push(`${I2}}`);\n lines.push(`${INDENT}}`);\n return lines;\n}\n\n// ─── CK file printer ───────────────────────────────────────────────────────\n\nexport function printCk(ast: CkRootNode, printWidth: number = DEFAULT_PRINT_WIDTH): string {\n const parts: string[] = [];\n\n // Options block\n const options = printOptionsBlock(ast);\n if (options) parts.push(options);\n\n // Contracts (models)\n for (const model of ast.models) {\n if (parts.length > 0) parts.push('');\n parts.push(`contract ${printModelDecl(model, printWidth)}`);\n }\n\n // Operations (routes)\n const emptyBlocks: CommentBlock[] = [];\n const emptyIdx = { value: 0 };\n for (const route of ast.routes) {\n if (parts.length > 0) parts.push('');\n const modPart = route.modifiers?.length ? `(${route.modifiers[0]})` : '';\n parts.push(`operation${modPart} ${printRoute(route, emptyBlocks, emptyIdx, Infinity)}`);\n }\n\n return parts.join('\\n') + '\\n';\n}\n"],"mappings":"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","names":["builders","parseCk","DiagnosticCollector","INDENT","printType","type","kind","constraints","format","undefined","fmt","push","test","min","max","len","regex","length","name","join","args","item","items","map","key","value","values","members","discriminator","printInlineObjectCompact","inner","obj","prefix","mode","fields","parts","f","opt","optional","t","nullable","printEnumExpanded","indent","innerIndent","INDENT","v","printField","field","printWidth","ovr","override","dep","deprecated","vis","visibility","mods","def","default","formatDefault","comment","description","trailing","extractTrailingInlineObject","inlineObj","modePart","header","printInlineObjectExpanded","typeStr","fullLine","enumStr","val","String","last","prefixStr","slice","printModelDecl","model","printWidth","type","undefined","printTypeAlias","commentSuffix","description","modifiers","deprecated","inputCase","outputCase","filter","Boolean","join","mode","modePrefix","baseChain","bases","length","header","name","lines","field","fields","push","printField","INDENT","trailing","extractTrailingInlineObject","prefix","inlineObj","modePart","printInlineObjectExpanded","singleLine","printType","kind","printEnumExpanded","values","SECURITY_NONE","I1","INDENT","I2","repeat","I3","I4","flushBlocks","out","blocks","idx","beforeLine","_indent","value","length","startLine","l","lines","push","printRoute","route","nextRouteStart","commentSuffix","description","path","params","undefined","printParamsBlock","I1","paramsMode","security","printSecurity","I2","op","operations","loc","line","printOperation","join","source","indent","mode","prefix","kind","name","inner","INDENT","p","nodes","opt","optional","t","printType","type","nullable","def","default","formatDefault","comment","node","modPart","modifiers","method","service","sdk","signature","signatureDescription","formatSignatureValue","query","printQueryOrHeaders","queryMode","requestHeadersOptOut","headers","headersMode","request","body","bodies","printContentTypeLine","contentType","bodyType","I3","responses","printResponseBlock","test","innerIndent","SECURITY_NONE","fields","hasRoles","roles","rolesDescription","keyword","lineIndent","fieldIndent","f","resp","hasBody","hasHeaders","optOut","headersOptOut","statusCode","I4","h","trail","DEFAULT_PRINT_WIDTH","printOptionsBlock","ast","hasMeta","Object","keys","meta","length","hasServices","services","hasSecurity","security","undefined","hasRequestHeaders","requestHeaders","hasResponseHeaders","responseHeaders","lines","push","INDENT","key","value","entries","v","startsWith","includes","printOptionsHeaderScope","printSecurity","join","keyword","headers","I2","I3","h","opt","optional","trail","description","name","printType","type","printCk","printWidth","parts","options","model","models","printModelDecl","emptyBlocks","emptyIdx","route","routes","modPart","modifiers","printRoute","Infinity","hardline","join","builders","toDoc","text","lines","trimEnd","split","plugin","languages","name","parsers","extensions","vscodeLanguageIds","parse","_options","diag","DiagnosticCollector","parseCk","astFormat","locStart","locEnd","_node","printers","print","path","options","node","printCk","printWidth"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/indent.ts","../src/print-type.ts","../src/print-contract.ts","../src/print-operation.ts","../src/print-ck.ts"],"sourcesContent":["import type { Plugin } from 'prettier';\nimport { builders } from 'prettier/doc';\nimport { parseCk, DiagnosticCollector } from '@contractkit/core';\nimport type { CkRootNode } from '@contractkit/core';\nimport { printCk } from './print-ck.js';\n\nconst { hardline, join } = builders;\n\nfunction toDoc(text: string) {\n const lines = text.trimEnd().split('\\n');\n return join(hardline, lines);\n}\n\nconst plugin: Plugin<CkRootNode> = {\n languages: [\n {\n name: 'ContractDSL',\n parsers: ['contract-ck'],\n extensions: ['.ck'],\n vscodeLanguageIds: ['contract-ck'],\n },\n ],\n\n parsers: {\n 'contract-ck': {\n parse(text, _options) {\n const diag = new DiagnosticCollector();\n return parseCk(text, '<stdin>', diag);\n },\n astFormat: 'contract-ck',\n locStart: () => 0,\n locEnd: _node => 0,\n },\n },\n\n printers: {\n 'contract-ck': {\n print(path, options) {\n const node = path.node as CkRootNode;\n return toDoc(printCk(node, options.printWidth));\n },\n },\n },\n};\n\nexport default plugin;\n","export const INDENT = ' ';\n","import type { ContractTypeNode, FieldNode, InlineObjectTypeNode } from '@contractkit/core';\nimport { INDENT } from './indent.js';\n\n// ─── Type expression printer ────────────────────────────────────────────────\n\nexport function printType(type: ContractTypeNode): string {\n switch (type.kind) {\n case 'scalar': {\n const constraints: string[] = [];\n if (type.format !== undefined) {\n // Print unquoted when format contains only safe chars; quote otherwise\n const fmt = type.format;\n constraints.push(/^[a-zA-Z0-9\\-.:/]+$/.test(fmt) ? fmt : `\"${fmt}\"`);\n }\n if (type.min !== undefined) constraints.push(`min=${type.min}`);\n if (type.max !== undefined) constraints.push(`max=${type.max}`);\n if (type.len !== undefined) constraints.push(`len=${type.len}`);\n if (type.regex !== undefined) constraints.push(`regex=/${type.regex}/`);\n return constraints.length > 0 ? `${type.name}(${constraints.join(', ')})` : type.name;\n }\n case 'array': {\n const args: string[] = [printType(type.item)];\n if (type.min !== undefined) args.push(`min=${type.min}`);\n if (type.max !== undefined) args.push(`max=${type.max}`);\n return `array(${args.join(', ')})`;\n }\n case 'tuple':\n return `tuple(${type.items.map(printType).join(', ')})`;\n case 'record':\n return `record(${printType(type.key)}, ${printType(type.value)})`;\n case 'enum':\n return `enum(${type.values.join(', ')})`;\n case 'literal':\n return typeof type.value === 'string' ? `literal(\"${type.value}\")` : `literal(${type.value})`;\n case 'union':\n return type.members.map(printType).join(' | ');\n case 'discriminatedUnion':\n return `discriminated(by=${type.discriminator}, ${type.members.map(printType).join(' | ')})`;\n case 'intersection':\n return type.members.map(printType).join(' & ');\n case 'ref':\n return type.name;\n case 'inlineObject':\n return printInlineObjectCompact(type);\n case 'lazy':\n return `lazy(${printType(type.inner)})`;\n }\n}\n\n/** Compact single-line form — used when inline object appears nested inside another type. */\nfunction printInlineObjectCompact(obj: InlineObjectTypeNode): string {\n const prefix = obj.mode ? `mode(${obj.mode}) ` : '';\n if (obj.fields.length === 0) return `${prefix}{}`;\n const parts = obj.fields.map(f => {\n const opt = f.optional ? '?' : '';\n let t = printType(f.type);\n if (f.nullable) t += ' | null';\n return `${f.name}${opt}: ${t}`;\n });\n return `${prefix}{ ${parts.join(', ')} }`;\n}\n\n/** Multi-line enum form — one value per line, used when single-line would exceed print width. */\nexport function printEnumExpanded(values: string[], indent: string): string {\n const innerIndent = indent + INDENT;\n return `enum(\\n${values.map(v => `${innerIndent}${v}`).join(',\\n')}\\n${indent})`;\n}\n\n// ─── Field printer ──────────────────────────────────────────────────────────\n\n/** Print a full field declaration, including visibility, default, and inline comment.\n * Modifier order is canonical: override → deprecated → readonly|writeonly → type. */\nexport function printField(field: FieldNode, indent: string, printWidth: number = 80): string {\n const opt = field.optional ? '?' : '';\n const ovr = field.override ? 'override ' : '';\n const dep = field.deprecated ? 'deprecated ' : '';\n const vis = field.visibility !== 'normal' ? `${field.visibility} ` : '';\n const mods = `${ovr}${dep}${vis}`;\n const def = field.default !== undefined ? ` = ${formatDefault(field.default)}` : '';\n const comment = field.description ? ` # ${field.description}` : '';\n const innerIndent = indent + INDENT;\n\n // Expand inline object types to multi-line — same rule as type aliases.\n // Only when there's no default and no nullable union (those can't split cleanly).\n if (!field.nullable && field.default === undefined) {\n const trailing = extractTrailingInlineObject(field.type);\n if (trailing) {\n const { prefix, inlineObj } = trailing;\n const modePart = inlineObj.mode ? `mode(${inlineObj.mode}) ` : '';\n const header = prefix\n ? `${indent}${field.name}${opt}: ${mods}${prefix} & ${modePart}{${comment}`\n : `${indent}${field.name}${opt}: ${mods}${modePart}{${comment}`;\n return [header, ...printInlineObjectExpanded(inlineObj, innerIndent, printWidth), `${indent}}`].join('\\n');\n }\n }\n\n let typeStr = printType(field.type);\n if (field.nullable) typeStr += ' | null';\n const fullLine = `${indent}${field.name}${opt}: ${mods}${typeStr}${def}${comment}`;\n if (field.type.kind === 'enum' && !field.nullable && field.default === undefined && fullLine.length > printWidth) {\n const enumStr = printEnumExpanded(field.type.values, indent);\n return `${indent}${field.name}${opt}: ${mods}${enumStr}${comment}`;\n }\n return fullLine;\n}\n\n/** Print inline-object fields expanded (used when an inline brace object trails a type alias). */\nexport function printInlineObjectExpanded(obj: InlineObjectTypeNode, indent: string, printWidth: number = 80): string[] {\n return obj.fields.map(f => printField(f, indent, printWidth));\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/** Format a default value: quote strings that aren't valid bare identifiers. */\nexport function formatDefault(val: string | number | boolean): string {\n if (typeof val === 'number' || typeof val === 'boolean') return String(val);\n // If it looks like a bare identifier (enum value, unquoted token), keep it bare.\n if (/^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/.test(val)) return val;\n return `\"${val}\"`;\n}\n\n/**\n * Detect whether the last member of a type is an inline brace object, and if so\n * return the prefix type string and the inline object for expanded printing.\n * Returns null if the type doesn't end with an inline object.\n */\nexport function extractTrailingInlineObject(type: ContractTypeNode): {\n prefix: string | null;\n inlineObj: InlineObjectTypeNode;\n} | null {\n if (type.kind === 'inlineObject') {\n return { prefix: null, inlineObj: type };\n }\n if (type.kind === 'intersection') {\n const last = type.members[type.members.length - 1];\n if (last?.kind === 'inlineObject') {\n const prefixStr = type.members.slice(0, -1).map(printType).join(' & ');\n return { prefix: prefixStr, inlineObj: last };\n }\n }\n return null;\n}\n","import type { ModelNode } from '@contractkit/core';\nimport { printField, printInlineObjectExpanded, extractTrailingInlineObject, printType, printEnumExpanded } from './print-type.js';\nimport { INDENT } from './indent.js';\n\n// ─── Model declaration ───────────────────────────────────────────────────────\n\nexport function printModelDecl(model: ModelNode, printWidth: number = 80): string {\n // Type alias form: Name : typeExpression\n if (model.type !== undefined) {\n return printTypeAlias(model, printWidth);\n }\n\n // Regular model with fields (possibly inherited)\n const commentSuffix = model.description ? ` # ${model.description}` : '';\n const modifiers = [\n model.deprecated ? 'deprecated' : '',\n model.inputCase || model.outputCase\n ? `format(${[model.inputCase ? `input=${model.inputCase}` : '', model.outputCase ? `output=${model.outputCase}` : ''].filter(Boolean).join(', ')})`\n : '',\n model.mode ? `mode(${model.mode})` : '',\n ]\n .filter(Boolean)\n .join(' ');\n const modePrefix = modifiers ? `${modifiers} ` : '';\n const baseChain = model.bases && model.bases.length > 0 ? `${model.bases.join(' & ')} & ` : '';\n const header = `${modePrefix}${model.name}: ${baseChain}{${commentSuffix}`;\n\n const lines: string[] = [header];\n for (const field of model.fields) {\n lines.push(printField(field, INDENT, printWidth));\n }\n lines.push('}');\n return lines.join('\\n');\n}\n\nfunction printTypeAlias(model: ModelNode, printWidth: number): string {\n const type = model.type!;\n const commentSuffix = model.description ? ` # ${model.description}` : '';\n const modifiers = [\n model.deprecated ? 'deprecated' : '',\n model.inputCase || model.outputCase\n ? `format(${[model.inputCase ? `input=${model.inputCase}` : '', model.outputCase ? `output=${model.outputCase}` : ''].filter(Boolean).join(', ')})`\n : '',\n model.mode ? `mode(${model.mode})` : '',\n ]\n .filter(Boolean)\n .join(' ');\n const modePrefix = modifiers ? `${modifiers} ` : '';\n\n // If the type ends with an inline brace object, expand it as a pseudo-model block.\n const trailing = extractTrailingInlineObject(type);\n if (trailing) {\n const { prefix, inlineObj } = trailing;\n const modePart = inlineObj.mode ? `mode(${inlineObj.mode}) ` : '';\n const header = prefix\n ? `${modePrefix}${model.name}: ${prefix} & ${modePart}{${commentSuffix}`\n : `${modePrefix}${model.name}: ${modePart}{${commentSuffix}`;\n const lines: string[] = [header, ...printInlineObjectExpanded(inlineObj, INDENT, printWidth), '}'];\n return lines.join('\\n');\n }\n\n // Simple type alias — single line, unless it's a long enum.\n // Note: the contract prefix \"contract \" (9 chars) is prepended by the caller.\n const singleLine = `${modePrefix}${model.name}: ${printType(type)}${commentSuffix}`;\n if (type.kind === 'enum' && 'contract '.length + singleLine.length > printWidth) {\n return `${modePrefix}${model.name}: ${printEnumExpanded(type.values, '')}${commentSuffix}`;\n }\n return singleLine;\n}\n","import type {\n OpRouteNode,\n OpOperationNode,\n OpResponseNode,\n ParamSource,\n SecurityNode,\n SecurityFields,\n ContractTypeNode,\n ObjectMode,\n} from '@contractkit/core';\nimport { SECURITY_NONE } from '@contractkit/core';\nimport { printType, formatDefault } from './print-type.js';\nimport { INDENT } from './indent.js';\n\nconst I1 = INDENT;\nconst I2 = INDENT.repeat(2);\nconst I3 = INDENT.repeat(3);\nconst I4 = INDENT.repeat(4);\n\n// ─── Orphan comment helpers ──────────────────────────────────────────────────\n\ntype CommentEntry = { line: number; text: string };\nexport type CommentBlock = { startLine: number; lines: string[] };\n\n/** Group sorted orphan comment entries into consecutive-line blocks. */\nexport function groupComments(entries: CommentEntry[]): CommentBlock[] {\n const blocks: CommentBlock[] = [];\n let current: CommentBlock | null = null;\n for (const { line, text } of entries) {\n if (current && line === current.startLine + current.lines.length) {\n current.lines.push(text);\n } else {\n if (current) blocks.push(current);\n current = { startLine: line, lines: [text] };\n }\n }\n if (current) blocks.push(current);\n return blocks;\n}\n\n/**\n * Emit any comment blocks whose startLine is < beforeLine.\n * Lines are emitted verbatim — they already carry their original indentation.\n */\nexport function flushBlocks(out: string[], blocks: CommentBlock[], idx: { value: number }, beforeLine: number, _indent = '') {\n while (idx.value < blocks.length && blocks[idx.value]!.startLine < beforeLine) {\n for (const l of blocks[idx.value]!.lines) out.push(l);\n idx.value++;\n }\n}\n\n// ─── Route ───────────────────────────────────────────────────────────────────\n\nexport function printRoute(route: OpRouteNode, blocks: CommentBlock[], idx: { value: number }, nextRouteStart: number): string {\n const lines: string[] = [];\n const commentSuffix = route.description ? ` # ${route.description}` : '';\n lines.push(`${route.path}: {${commentSuffix}`);\n\n if (route.params !== undefined) {\n lines.push(...printParamsBlock(route.params, I1, route.paramsMode));\n }\n\n if (route.security !== undefined) {\n lines.push(...printSecurity(route.security, I1, I2));\n }\n\n for (const op of route.operations) {\n // Flush comment blocks that appear before this operation (inside the route)\n flushBlocks(lines, blocks, idx, op.loc.line, I1);\n lines.push(...printOperation(op));\n }\n\n // Flush comment blocks between last operation and the next route\n flushBlocks(lines, blocks, idx, nextRouteStart, I1);\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n// ─── Params block ────────────────────────────────────────────────────────────\n\nfunction printParamsBlock(source: ParamSource, indent: string, mode?: ObjectMode): string[] {\n const prefix = mode ? `mode(${mode}) ` : '';\n if (source.kind === 'ref') {\n return [`${indent}${prefix}params: ${source.name}`];\n }\n if (source.kind === 'params') {\n const lines: string[] = [`${indent}${prefix}params: {`];\n const inner = indent + INDENT;\n for (const p of source.nodes) {\n const opt = p.optional ? '?' : '';\n let t = printType(p.type);\n if (p.nullable) t += ' | null';\n const def = p.default !== undefined ? ` = ${formatDefault(p.default)}` : '';\n const comment = p.description ? ` # ${p.description}` : '';\n lines.push(`${inner}${p.name}${opt}: ${t}${def}${comment}`);\n }\n lines.push(`${indent}}`);\n return lines;\n }\n // ContractTypeNode\n return [`${indent}${prefix}params: ${printType(source.node)}`];\n}\n\n// ─── HTTP operation ──────────────────────────────────────────────────────────\n\nfunction printOperation(op: OpOperationNode): string[] {\n const lines: string[] = [];\n const commentSuffix = op.description ? ` # ${op.description}` : '';\n const modPart = op.modifiers?.length ? `(${op.modifiers[0]})` : '';\n lines.push(`${I1}${op.method}${modPart}: {${commentSuffix}`);\n\n if (op.name) lines.push(`${I2}name: ${op.name}`);\n if (op.service) lines.push(`${I2}service: ${op.service}`);\n if (op.sdk) lines.push(`${I2}sdk: ${op.sdk}`);\n if (op.signature) {\n const comment = op.signatureDescription ? ` # ${op.signatureDescription}` : '';\n lines.push(`${I2}signature: ${formatSignatureValue(op.signature)}${comment}`);\n }\n if (op.security !== undefined) lines.push(...printSecurity(op.security));\n if (op.plugins && Object.keys(op.plugins).length > 0) {\n lines.push(`${I2}plugins: {`);\n for (const [key, val] of Object.entries(op.plugins)) {\n lines.push(`${I3}${key}: \"${val.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`);\n }\n lines.push(`${I2}}`);\n }\n if (op.query !== undefined) lines.push(...printQueryOrHeaders('query', op.query, op.queryMode));\n if (op.requestHeadersOptOut) {\n lines.push(`${I2}headers: none`);\n } else if (op.headers !== undefined) {\n lines.push(...printQueryOrHeaders('headers', op.headers, op.headersMode));\n }\n if (op.request) {\n lines.push(`${I2}request: {`);\n for (const body of op.request.bodies) {\n lines.push(...printContentTypeLine(body.contentType, body.bodyType, I3));\n }\n lines.push(`${I2}}`);\n }\n if (op.responses.length > 0) {\n lines.push(...printResponseBlock(op.responses));\n }\n\n lines.push(`${I1}}`);\n return lines;\n}\n\n// ─── Security ────────────────────────────────────────────────────────────────\n\n/** Print a signature key: unquoted when it's a plain identifier, quoted otherwise. */\nfunction formatSignatureValue(value: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(value) ? value : `\"${value}\"`;\n}\n\n// indent: indentation for the `security` keyword line\n// innerIndent: indentation for field lines inside the block\nexport function printSecurity(security: SecurityNode, indent = I2, innerIndent = I3): string[] {\n if (security === SECURITY_NONE) return [`${indent}security: none`];\n const fields = security as SecurityFields;\n const hasRoles = fields.roles && fields.roles.length > 0;\n if (!hasRoles) return [];\n const lines = [`${indent}security: {`];\n const comment = fields.rolesDescription ? ` # ${fields.rolesDescription}` : '';\n lines.push(`${innerIndent}roles: ${fields.roles!.join(' ')}${comment}`);\n lines.push(`${indent}}`);\n return lines;\n}\n\n// ─── Query / headers ─────────────────────────────────────────────────────────\n\nfunction printQueryOrHeaders(keyword: 'query' | 'headers', source: ParamSource, mode?: ObjectMode): string[] {\n const prefix = mode ? `mode(${mode}) ` : '';\n if (source.kind === 'ref') {\n return [`${I2}${prefix}${keyword}: ${source.name}`];\n }\n if (source.kind === 'params') {\n if (source.nodes.length === 0) return [];\n const lines: string[] = [`${I2}${prefix}${keyword}: {`];\n for (const p of source.nodes) {\n const opt = p.optional ? '?' : '';\n let t = printType(p.type);\n if (p.nullable) t += ' | null';\n const def = p.default !== undefined ? ` = ${formatDefault(p.default)}` : '';\n const comment = p.description ? ` # ${p.description}` : '';\n lines.push(`${I3}${p.name}${opt}: ${t}${def}${comment}`);\n }\n lines.push(`${I2}}`);\n return lines;\n }\n // ContractTypeNode (e.g. intersection)\n return [`${I2}${prefix}${keyword}: ${printType(source.node)}`];\n}\n\n// ─── Content-type line ───────────────────────────────────────────────────────\n\n/** Print a `contentType: bodyType` line, expanding inline brace objects onto separate lines. */\nfunction printContentTypeLine(contentType: string, bodyType: ContractTypeNode, lineIndent: string): string[] {\n if (bodyType.kind === 'inlineObject') {\n const fieldIndent = lineIndent + INDENT;\n const lines: string[] = [`${lineIndent}${contentType}: {`];\n for (const f of bodyType.fields) {\n const opt = f.optional ? '?' : '';\n let t = printType(f.type);\n if (f.nullable) t += ' | null';\n const def = f.default !== undefined ? ` = ${formatDefault(f.default)}` : '';\n const comment = f.description ? ` # ${f.description}` : '';\n lines.push(`${fieldIndent}${f.name}${opt}: ${t}${def}${comment}`);\n }\n lines.push(`${lineIndent}}`);\n return lines;\n }\n return [`${lineIndent}${contentType}: ${printType(bodyType)}`];\n}\n\n// ─── Response block ──────────────────────────────────────────────────────────\n\nfunction printResponseBlock(responses: OpResponseNode[]): string[] {\n const lines: string[] = [`${I2}response: {`];\n\n for (const resp of responses) {\n const hasBody = resp.contentType && resp.bodyType;\n const hasHeaders = resp.headers && resp.headers.length > 0;\n const optOut = resp.headersOptOut;\n if (hasBody || hasHeaders || optOut) {\n lines.push(`${I3}${resp.statusCode}: {`);\n if (hasBody) {\n lines.push(...printContentTypeLine(resp.contentType!, resp.bodyType!, I4));\n }\n if (optOut) {\n lines.push(`${I4}headers: none`);\n } else if (hasHeaders) {\n lines.push(`${I4}headers: {`);\n for (const h of resp.headers!) {\n const opt = h.optional ? '?' : '';\n const trail = h.description ? ` # ${h.description}` : '';\n lines.push(`${I4}${INDENT}${h.name}${opt}: ${printType(h.type)}${trail}`);\n }\n lines.push(`${I4}}`);\n }\n lines.push(`${I3}}`);\n } else {\n lines.push(`${I3}${resp.statusCode}:`);\n }\n }\n\n lines.push(`${I2}}`);\n return lines;\n}\n","import type { CkRootNode, OpResponseHeaderNode } from '@contractkit/core';\nimport { printModelDecl } from './print-contract.js';\nimport { printRoute, printSecurity, type CommentBlock } from './print-operation.js';\nimport { printType } from './print-type.js';\nimport { INDENT } from './indent.js';\n\nexport const DEFAULT_PRINT_WIDTH = 80;\n\n// ─── Options block ──────────────────────────────────────────────────────────\n\n/**\n * Quote an options-block value if it isn't a plain identifier.\n *\n * Plain identifiers (starts with letter/underscore/dollar, rest are\n * alphanumeric/underscore/dollar/hyphen/dot) are left bare. Everything\n * else — paths with slashes, values starting with `#`, values with spaces,\n * etc. — is double-quoted so the round-trip parse is unambiguous.\n */\nfunction quoteOptionsValue(value: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/.test(value) ? value : `\"${value}\"`;\n}\n\nfunction printOptionsBlock(ast: CkRootNode): string | null {\n const hasMeta = Object.keys(ast.meta).length > 0;\n const hasServices = Object.keys(ast.services).length > 0;\n const hasSecurity = ast.security !== undefined;\n const hasRequestHeaders = (ast.requestHeaders?.length ?? 0) > 0;\n const hasResponseHeaders = (ast.responseHeaders?.length ?? 0) > 0;\n\n if (!hasMeta && !hasServices && !hasSecurity && !hasRequestHeaders && !hasResponseHeaders) return null;\n\n const lines: string[] = ['options {'];\n\n if (hasMeta) {\n lines.push(`${INDENT}keys: {`);\n for (const [key, value] of Object.entries(ast.meta)) {\n lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasServices) {\n lines.push(`${INDENT}services: {`);\n for (const [key, value] of Object.entries(ast.services)) {\n lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasRequestHeaders) {\n lines.push(...printOptionsHeaderScope('request', ast.requestHeaders!));\n }\n\n if (hasResponseHeaders) {\n lines.push(...printOptionsHeaderScope('response', ast.responseHeaders!));\n }\n\n if (hasSecurity) {\n lines.push(...printSecurity(ast.security!, INDENT, INDENT + INDENT));\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\nfunction printOptionsHeaderScope(keyword: 'request' | 'response', headers: OpResponseHeaderNode[]): string[] {\n const I2 = INDENT + INDENT;\n const I3 = INDENT + INDENT + INDENT;\n const lines = [`${INDENT}${keyword}: {`, `${I2}headers: {`];\n for (const h of headers) {\n const opt = h.optional ? '?' : '';\n const trail = h.description ? ` # ${h.description}` : '';\n lines.push(`${I3}${h.name}${opt}: ${printType(h.type)}${trail}`);\n }\n lines.push(`${I2}}`);\n lines.push(`${INDENT}}`);\n return lines;\n}\n\n// ─── CK file printer ───────────────────────────────────────────────────────\n\n/**\n * Render a parsed `.ck` AST back to source. Output is byte-identical on\n * round-trip when the input is already canonically formatted: options block\n * first, then contracts, then operations, separated by blank lines.\n *\n * `printWidth` is forwarded to per-model printing for line wrapping inside\n * inline-object types.\n */\nexport function printCk(ast: CkRootNode, printWidth: number = DEFAULT_PRINT_WIDTH): string {\n const parts: string[] = [];\n\n // Options block\n const options = printOptionsBlock(ast);\n if (options) parts.push(options);\n\n // Contracts (models)\n for (const model of ast.models) {\n if (parts.length > 0) parts.push('');\n parts.push(`contract ${printModelDecl(model, printWidth)}`);\n }\n\n // Operations (routes)\n const emptyBlocks: CommentBlock[] = [];\n const emptyIdx = { value: 0 };\n for (const route of ast.routes) {\n if (parts.length > 0) parts.push('');\n const modPart = route.modifiers?.length ? `(${route.modifiers[0]})` : '';\n parts.push(`operation${modPart} ${printRoute(route, emptyBlocks, emptyIdx, Infinity)}`);\n }\n\n return parts.join('\\n') + '\\n';\n}\n"],"mappings":"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","names":["builders","parseCk","DiagnosticCollector","INDENT","printType","type","kind","constraints","format","undefined","fmt","push","test","min","max","len","regex","length","name","join","args","item","items","map","key","value","values","members","discriminator","printInlineObjectCompact","inner","obj","prefix","mode","fields","parts","f","opt","optional","t","nullable","printEnumExpanded","indent","innerIndent","INDENT","v","printField","field","printWidth","ovr","override","dep","deprecated","vis","visibility","mods","def","default","formatDefault","comment","description","trailing","extractTrailingInlineObject","inlineObj","modePart","header","printInlineObjectExpanded","typeStr","fullLine","enumStr","val","String","last","prefixStr","slice","printModelDecl","model","printWidth","type","undefined","printTypeAlias","commentSuffix","description","modifiers","deprecated","inputCase","outputCase","filter","Boolean","join","mode","modePrefix","baseChain","bases","length","header","name","lines","field","fields","push","printField","INDENT","trailing","extractTrailingInlineObject","prefix","inlineObj","modePart","printInlineObjectExpanded","singleLine","printType","kind","printEnumExpanded","values","SECURITY_NONE","I1","INDENT","I2","repeat","I3","I4","flushBlocks","out","blocks","idx","beforeLine","_indent","value","length","startLine","l","lines","push","printRoute","route","nextRouteStart","commentSuffix","description","path","params","undefined","printParamsBlock","I1","paramsMode","security","printSecurity","I2","op","operations","loc","line","printOperation","join","source","indent","mode","prefix","kind","name","inner","INDENT","p","nodes","opt","optional","t","printType","type","nullable","def","default","formatDefault","comment","node","modPart","modifiers","method","service","sdk","signature","signatureDescription","formatSignatureValue","plugins","Object","keys","key","val","entries","I3","replace","query","printQueryOrHeaders","queryMode","requestHeadersOptOut","headers","headersMode","request","body","bodies","printContentTypeLine","contentType","bodyType","responses","printResponseBlock","test","innerIndent","SECURITY_NONE","fields","hasRoles","roles","rolesDescription","keyword","lineIndent","fieldIndent","f","resp","hasBody","hasHeaders","optOut","headersOptOut","statusCode","I4","h","trail","DEFAULT_PRINT_WIDTH","quoteOptionsValue","value","test","printOptionsBlock","ast","hasMeta","Object","keys","meta","length","hasServices","services","hasSecurity","security","undefined","hasRequestHeaders","requestHeaders","hasResponseHeaders","responseHeaders","lines","push","INDENT","key","entries","printOptionsHeaderScope","printSecurity","join","keyword","headers","I2","I3","h","opt","optional","trail","description","name","printType","type","printCk","printWidth","parts","options","model","models","printModelDecl","emptyBlocks","emptyIdx","route","routes","modPart","modifiers","printRoute","Infinity","hardline","join","builders","toDoc","text","lines","trimEnd","split","plugin","languages","name","parsers","extensions","vscodeLanguageIds","parse","_options","diag","DiagnosticCollector","parseCk","astFormat","locStart","locEnd","_node","printers","print","path","options","node","printCk","printWidth"]}
|
package/dist/print-ck.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { CkRootNode } from '@contractkit/core';
|
|
2
2
|
export declare const DEFAULT_PRINT_WIDTH = 80;
|
|
3
|
+
/**
|
|
4
|
+
* Render a parsed `.ck` AST back to source. Output is byte-identical on
|
|
5
|
+
* round-trip when the input is already canonically formatted: options block
|
|
6
|
+
* first, then contracts, then operations, separated by blank lines.
|
|
7
|
+
*
|
|
8
|
+
* `printWidth` is forwarded to per-model printing for line wrapping inside
|
|
9
|
+
* inline-object types.
|
|
10
|
+
*/
|
|
3
11
|
export declare function printCk(ast: CkRootNode, printWidth?: number): string;
|
|
4
12
|
//# sourceMappingURL=print-ck.d.ts.map
|
package/dist/print-ck.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-ck.d.ts","sourceRoot":"","sources":["../src/print-ck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,mBAAmB,CAAC;AAM1E,eAAO,MAAM,mBAAmB,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"print-ck.d.ts","sourceRoot":"","sources":["../src/print-ck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,mBAAmB,CAAC;AAM1E,eAAO,MAAM,mBAAmB,KAAK,CAAC;AA2EtC;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,GAAE,MAA4B,GAAG,MAAM,CAuBzF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-operation.d.ts","sourceRoot":"","sources":["../src/print-operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,WAAW,EAIX,YAAY,EAIf,MAAM,mBAAmB,CAAC;AAY3B,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AACnD,MAAM,MAAM,YAAY,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAElE,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAarE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,SAAK,QAK1H;AAID,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAwB7H;
|
|
1
|
+
{"version":3,"file":"print-operation.d.ts","sourceRoot":"","sources":["../src/print-operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,WAAW,EAIX,YAAY,EAIf,MAAM,mBAAmB,CAAC;AAY3B,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AACnD,MAAM,MAAM,YAAY,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAElE,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAarE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,SAAK,QAK1H;AAID,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAwB7H;AAgFD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAK,EAAE,WAAW,SAAK,GAAG,MAAM,EAAE,CAU7F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractkit/prettier-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Prettier plugin for ContractKit DSL",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Marooned Software",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"prettier": "^3.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@contractkit/core": "0.
|
|
32
|
+
"@contractkit/core": "0.13.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"prettier": "^3.8.3",
|
package/src/print-ck.ts
CHANGED
|
@@ -8,6 +8,18 @@ export const DEFAULT_PRINT_WIDTH = 80;
|
|
|
8
8
|
|
|
9
9
|
// ─── Options block ──────────────────────────────────────────────────────────
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Quote an options-block value if it isn't a plain identifier.
|
|
13
|
+
*
|
|
14
|
+
* Plain identifiers (starts with letter/underscore/dollar, rest are
|
|
15
|
+
* alphanumeric/underscore/dollar/hyphen/dot) are left bare. Everything
|
|
16
|
+
* else — paths with slashes, values starting with `#`, values with spaces,
|
|
17
|
+
* etc. — is double-quoted so the round-trip parse is unambiguous.
|
|
18
|
+
*/
|
|
19
|
+
function quoteOptionsValue(value: string): string {
|
|
20
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$\-.]*$/.test(value) ? value : `"${value}"`;
|
|
21
|
+
}
|
|
22
|
+
|
|
11
23
|
function printOptionsBlock(ast: CkRootNode): string | null {
|
|
12
24
|
const hasMeta = Object.keys(ast.meta).length > 0;
|
|
13
25
|
const hasServices = Object.keys(ast.services).length > 0;
|
|
@@ -22,8 +34,7 @@ function printOptionsBlock(ast: CkRootNode): string | null {
|
|
|
22
34
|
if (hasMeta) {
|
|
23
35
|
lines.push(`${INDENT}keys: {`);
|
|
24
36
|
for (const [key, value] of Object.entries(ast.meta)) {
|
|
25
|
-
|
|
26
|
-
lines.push(`${INDENT}${INDENT}${key}: ${v}`);
|
|
37
|
+
lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);
|
|
27
38
|
}
|
|
28
39
|
lines.push(`${INDENT}}`);
|
|
29
40
|
}
|
|
@@ -31,8 +42,7 @@ function printOptionsBlock(ast: CkRootNode): string | null {
|
|
|
31
42
|
if (hasServices) {
|
|
32
43
|
lines.push(`${INDENT}services: {`);
|
|
33
44
|
for (const [key, value] of Object.entries(ast.services)) {
|
|
34
|
-
|
|
35
|
-
lines.push(`${INDENT}${INDENT}${key}: ${v}`);
|
|
45
|
+
lines.push(`${INDENT}${INDENT}${key}: ${quoteOptionsValue(value)}`);
|
|
36
46
|
}
|
|
37
47
|
lines.push(`${INDENT}}`);
|
|
38
48
|
}
|
|
@@ -69,6 +79,14 @@ function printOptionsHeaderScope(keyword: 'request' | 'response', headers: OpRes
|
|
|
69
79
|
|
|
70
80
|
// ─── CK file printer ───────────────────────────────────────────────────────
|
|
71
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Render a parsed `.ck` AST back to source. Output is byte-identical on
|
|
84
|
+
* round-trip when the input is already canonically formatted: options block
|
|
85
|
+
* first, then contracts, then operations, separated by blank lines.
|
|
86
|
+
*
|
|
87
|
+
* `printWidth` is forwarded to per-model printing for line wrapping inside
|
|
88
|
+
* inline-object types.
|
|
89
|
+
*/
|
|
72
90
|
export function printCk(ast: CkRootNode, printWidth: number = DEFAULT_PRINT_WIDTH): string {
|
|
73
91
|
const parts: string[] = [];
|
|
74
92
|
|
package/src/print-operation.ts
CHANGED
|
@@ -118,6 +118,13 @@ function printOperation(op: OpOperationNode): string[] {
|
|
|
118
118
|
lines.push(`${I2}signature: ${formatSignatureValue(op.signature)}${comment}`);
|
|
119
119
|
}
|
|
120
120
|
if (op.security !== undefined) lines.push(...printSecurity(op.security));
|
|
121
|
+
if (op.plugins && Object.keys(op.plugins).length > 0) {
|
|
122
|
+
lines.push(`${I2}plugins: {`);
|
|
123
|
+
for (const [key, val] of Object.entries(op.plugins)) {
|
|
124
|
+
lines.push(`${I3}${key}: "${val.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`);
|
|
125
|
+
}
|
|
126
|
+
lines.push(`${I2}}`);
|
|
127
|
+
}
|
|
121
128
|
if (op.query !== undefined) lines.push(...printQueryOrHeaders('query', op.query, op.queryMode));
|
|
122
129
|
if (op.requestHeadersOptOut) {
|
|
123
130
|
lines.push(`${I2}headers: none`);
|
package/tests/print-ck.test.ts
CHANGED
|
@@ -181,6 +181,51 @@ describe('printCk — security', () => {
|
|
|
181
181
|
});
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
+
// ─── plugins block printing ───────────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
describe('printCk — plugins block', () => {
|
|
187
|
+
it('prints plugins block with single entry', () => {
|
|
188
|
+
const ast = makeRoot([makeRoute('/auth/token', [makeOp('post', { plugins: { bruno: 'request-token.yml' } })])]);
|
|
189
|
+
const out = printCk(ast);
|
|
190
|
+
expect(out).toContain(' plugins: {');
|
|
191
|
+
expect(out).toContain(' bruno: "request-token.yml"');
|
|
192
|
+
expect(out).toContain(' }');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('prints plugins block with multiple entries', () => {
|
|
196
|
+
const ast = makeRoot([makeRoute('/users', [makeOp('post', { plugins: { bruno: 'create-user.yml', typescript: 'stub.ts' } })])]);
|
|
197
|
+
const out = printCk(ast);
|
|
198
|
+
expect(out).toContain(' bruno: "create-user.yml"');
|
|
199
|
+
expect(out).toContain(' typescript: "stub.ts"');
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('omits plugins block when plugins is undefined', () => {
|
|
203
|
+
const ast = makeRoot([makeRoute('/users', [makeOp('get')])]);
|
|
204
|
+
expect(printCk(ast)).not.toContain('plugins');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('omits plugins block when plugins is empty object', () => {
|
|
208
|
+
const ast = makeRoot([makeRoute('/users', [makeOp('get', { plugins: {} })])]);
|
|
209
|
+
expect(printCk(ast)).not.toContain('plugins');
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('plugins block round-trips via parse', () => {
|
|
213
|
+
const src = `operation /auth/token: {
|
|
214
|
+
post: {
|
|
215
|
+
plugins: {
|
|
216
|
+
bruno: "request-token.yml"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
`;
|
|
221
|
+
const diag = new DiagnosticCollector();
|
|
222
|
+
const ast = parseCk(src, 'test.ck', diag);
|
|
223
|
+
expect(diag.hasErrors()).toBe(false);
|
|
224
|
+
const out = printCk(ast);
|
|
225
|
+
expect(out).toContain(' bruno: "request-token.yml"');
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
184
229
|
// ─── Query / headers with descriptions ───────────────────────────────────────
|
|
185
230
|
|
|
186
231
|
describe('printCk — query and headers descriptions', () => {
|
|
@@ -604,3 +649,67 @@ operation /users/{slug}: {
|
|
|
604
649
|
expect(roundTrip(source)).toBe(source);
|
|
605
650
|
});
|
|
606
651
|
});
|
|
652
|
+
|
|
653
|
+
describe('printCk — options keys and services quoting', () => {
|
|
654
|
+
function roundTrip(source: string): string {
|
|
655
|
+
const diag = new DiagnosticCollector();
|
|
656
|
+
const ast = parseCk(source, 'test.ck', diag);
|
|
657
|
+
expect(diag.hasErrors()).toBe(false);
|
|
658
|
+
return printCk(ast);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
it('leaves simple identifier keys values unquoted', () => {
|
|
662
|
+
const source = `\
|
|
663
|
+
options {
|
|
664
|
+
keys: {
|
|
665
|
+
area: payments
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
`;
|
|
669
|
+
expect(roundTrip(source)).toBe(source);
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
it('preserves quotes on path-like values containing slashes', () => {
|
|
673
|
+
const source = `\
|
|
674
|
+
options {
|
|
675
|
+
keys: {
|
|
676
|
+
bruno: "../../bruno/"
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
`;
|
|
680
|
+
expect(roundTrip(source)).toBe(source);
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
it('quotes values that start with a dot', () => {
|
|
684
|
+
const source = `\
|
|
685
|
+
options {
|
|
686
|
+
keys: {
|
|
687
|
+
path: "../relative"
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
`;
|
|
691
|
+
expect(roundTrip(source)).toBe(source);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it('preserves quotes on service paths starting with #', () => {
|
|
695
|
+
const source = `\
|
|
696
|
+
options {
|
|
697
|
+
services: {
|
|
698
|
+
AuthService: "#src/modules/auth/auth.service.js"
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
`;
|
|
702
|
+
expect(roundTrip(source)).toBe(source);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
it('leaves plain identifier service names unquoted', () => {
|
|
706
|
+
const source = `\
|
|
707
|
+
options {
|
|
708
|
+
services: {
|
|
709
|
+
AuthService: authService
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
`;
|
|
713
|
+
expect(roundTrip(source)).toBe(source);
|
|
714
|
+
});
|
|
715
|
+
});
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @contractkit/prettier-plugin@0.8.0 build /Users/robert/projects/contractkit/apps/prettier-plugin
|
|
3
|
-
> tsup src/index.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly --declaration
|
|
4
|
-
|
|
5
|
-
CLI Building entry: src/index.ts
|
|
6
|
-
CLI Using tsconfig: tsconfig.json
|
|
7
|
-
CLI tsup v8.5.1
|
|
8
|
-
CLI Target: esnext
|
|
9
|
-
ESM Build start
|
|
10
|
-
ESM dist/index.js 17.83 KB
|
|
11
|
-
ESM dist/index.js.map 42.37 KB
|
|
12
|
-
ESM ⚡️ Build success in 107ms
|
|
13
|
-
DTS Build start
|
|
14
|
-
DTS ⚡️ Build success in 582ms
|
|
15
|
-
DTS dist/index.d.ts 157.00 B
|
package/.turbo/turbo-format.log
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
> prettier-plugin-contractkit@0.1.0 format /Users/robert/projects/contractkit/apps/prettier-plugin
|
|
4
|
-
> prettier --write .
|
|
5
|
-
|
|
6
|
-
.turbo/turbo-build.log[2K[1G.turbo/turbo-format.log[2K[1G.turbo/turbo-test.log[2K[1Gdist/__tests__/print-ck.test.d.ts[2K[1Gdist/__tests__/print-ck.test.d.ts 36ms
|
|
7
|
-
dist/__tests__/print-ck.test.d.ts.map[2K[1Gdist/__tests__/print-op.test.d.ts[2K[1Gdist/__tests__/print-op.test.d.ts 1ms
|
|
8
|
-
dist/__tests__/print-op.test.d.ts.map[2K[1Gdist/__tests__/print-op.test.js[2K[1Gdist/__tests__/print-op.test.js 48ms
|
|
9
|
-
dist/__tests__/print-op.test.js.map[2K[1Gdist/indent.d.ts[2K[1Gdist/indent.d.ts 4ms
|
|
10
|
-
dist/indent.d.ts.map[2K[1Gdist/index.d.ts[2K[1Gdist/index.d.ts 2ms
|
|
11
|
-
dist/index.d.ts.map[2K[1Gdist/index.js[2K[1Gdist/index.js 22ms
|
|
12
|
-
dist/index.js.map[2K[1Gdist/print-ck.d.ts[2K[1Gdist/print-ck.d.ts 5ms
|
|
13
|
-
dist/print-ck.d.ts.map[2K[1Gdist/print-dto.d.ts[2K[1Gdist/print-dto.d.ts 1ms
|
|
14
|
-
dist/print-dto.d.ts.map[2K[1Gdist/print-dto.js[2K[1Gdist/print-dto.js 4ms
|
|
15
|
-
dist/print-dto.js.map[2K[1Gdist/print-op.d.ts[2K[1Gdist/print-op.d.ts 4ms
|
|
16
|
-
dist/print-op.d.ts.map[2K[1Gdist/print-op.js[2K[1Gdist/print-op.js 8ms
|
|
17
|
-
dist/print-op.js.map[2K[1Gdist/print-type.d.ts[2K[1Gdist/print-type.d.ts 2ms
|
|
18
|
-
dist/print-type.d.ts.map[2K[1Gdist/print-type.js[2K[1Gdist/print-type.js 5ms
|
|
19
|
-
dist/print-type.js.map[2K[1Geslint.config.js[2K[1G[90meslint.config.js[39m 1ms (unchanged)
|
|
20
|
-
package.json[2K[1Gpackage.json 1ms
|
|
21
|
-
src/indent.ts[2K[1G[90msrc/indent.ts[39m 1ms (unchanged)
|
|
22
|
-
src/index.ts[2K[1Gsrc/index.ts 5ms
|
|
23
|
-
src/print-ck.ts[2K[1Gsrc/print-ck.ts 5ms
|
|
24
|
-
src/print-dto.ts[2K[1Gsrc/print-dto.ts 5ms
|
|
25
|
-
src/print-op.ts[2K[1Gsrc/print-op.ts 9ms
|
|
26
|
-
src/print-type.ts[2K[1Gsrc/print-type.ts 6ms
|
|
27
|
-
tests/print-ck.test.ts[2K[1Gtests/print-ck.test.ts 14ms
|
|
28
|
-
tsconfig.json[2K[1Gtsconfig.json 1ms
|
|
29
|
-
vitest.config.ts[2K[1Gvitest.config.ts 1ms
|
package/.turbo/turbo-test.log
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @contractkit/prettier-plugin@0.8.0 test /Users/robert/projects/contractkit/apps/prettier-plugin
|
|
3
|
-
> vitest run
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/Users/robert/projects/contractkit/apps/prettier-plugin[39m
|
|
7
|
-
|
|
8
|
-
[32m✓[39m tests/print-ck.test.ts [2m([22m[2m45 tests[22m[2m)[22m[32m 24[2mms[22m[39m
|
|
9
|
-
|
|
10
|
-
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
11
|
-
[2m Tests [22m [1m[32m45 passed[39m[22m[90m (45)[39m
|
|
12
|
-
[2m Start at [22m 08:51:33
|
|
13
|
-
[2m Duration [22m 437ms[2m (transform 138ms, setup 0ms, import 266ms, tests 24ms, environment 0ms)[22m
|
|
14
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"print-ck.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/print-ck.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"print-op.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/print-op.test.ts"],"names":[],"mappings":""}
|