# -*- coding: utf-8 -*- """Helpers for opportunity Bruno .bru generation. Import, don't exec.""" import os DOCS = 'D:/code/crm-api-docs' def ensure_dir(p): os.makedirs(p, exist_ok=True) def write_bru(folder_rel, filename, content): d = os.path.join(DOCS, folder_rel) ensure_dir(d) p = os.path.join(d, filename) with open(p, 'w', encoding='utf-8', newline='\n') as f: f.write(content) print(f' wrote {folder_rel}/{filename}') def write_folder_bru(folder_rel, name, seq): d = os.path.join(DOCS, folder_rel) ensure_dir(d) p = os.path.join(d, 'folder.bru') if os.path.exists(p): return with open(p, 'w', encoding='utf-8', newline='\n') as f: f.write(f'meta {{\n name: {name}\n seq: {seq}\n}}\n') print(f' wrote {folder_rel}/folder.bru') def bru_form(seq, name, method, url, params_rows, docs_body): body_kw = 'formUrlEncoded' if method == 'post' else 'none' lines = [] lines.append('meta {') lines.append(f' name: {name}') lines.append(' type: http') lines.append(f' seq: {seq}') lines.append(' tags: [') lines.append(' generated') lines.append(' ]') lines.append('}') lines.append('') lines.append(f'{method} {{') lines.append(f' url: {{{{baseUrl}}}}{url}') lines.append(f' body: {body_kw}') lines.append(' auth: inherit') lines.append('}') lines.append('') if method == 'post' and params_rows: lines.append('body:form-urlencoded {') for k, v in params_rows: lines.append(f' {k}: {v}') lines.append('}') lines.append('') elif method == 'get' and params_rows: lines.append('params:query {') for k, v in params_rows: lines.append(f' {k}: {v}') lines.append('}') lines.append('') lines.append('docs {') for line in docs_body.rstrip().split('\n'): lines.append((' ' + line) if line else '') lines.append('}') return '\n'.join(lines) + '\n' def build_docs(title, method, path, desc, params_table, req_example, resp_data_table, resp_example_json_or_text, resp_is_text=False): lines = [] lines.append(f'# {title}') lines.append(f'`{method} {path}`') lines.append(desc) lines.append('') lines.append('## 请求参数') lines.append('') if params_table: lines.append('| 参数 | 类型 | 必填 | 默认 | 说明 |') lines.append('| --- | --- | --- | --- | --- |') for name, typ, req, dflt, d in params_table: lines.append(f'| {name} | {typ} | {req} | {dflt} | {d} |') else: lines.append('无参数。') lines.append('') lines.append('## 请求示例') lines.append('') for line in req_example.rstrip().split('\n'): lines.append(line) lines.append('') lines.append('## 响应 data 结构') lines.append('') if resp_data_table is None: lines.append('null') elif isinstance(resp_data_table, str): lines.append(resp_data_table) else: lines.append('| 字段 | 类型 | 说明 |') lines.append('| --- | --- | --- |') for f, t, d in resp_data_table: lines.append(f'| {f} | {t} | {d} |') lines.append('') lines.append('## 响应示例') lines.append('') if resp_is_text: lines.append(resp_example_json_or_text) else: lines.append('// 示例数据,字段结构以上表为准,非真实返回') lines.append('```json') for line in resp_example_json_or_text.rstrip().split('\n'): lines.append(line) lines.append('```') return '\n'.join(lines) def env_json(data_literal): return ( '{\n' ' "code": 0,\n' ' "success": true,\n' ' "message": "success",\n' f' "data": {data_literal}\n' '}' ) def page_json(inner_element_literal, indent_inside=' '): """Wrap element literal (indented as body) into PageResult and full envelope. inner_element_literal must already be indented so its opening { aligns naturally after ' '. Simplest: pass a string that begins right after ' ' indent already applied inside.""" return env_json( '{\n' f' "content": [\n{inner_element_literal}\n ],\n' ' "total": 1,\n' ' "size": 10,\n' ' "current": 1,\n' ' "pages": 1,\n' ' "empty": false\n' ' }' ) def req_form_example(method, path, kv_pairs, public=False): header = '请求头:无需鉴权' if public else '请求头:Authorization: Bearer {{token}}' body = '&'.join(f'{k}={v}' for k, v in kv_pairs) return ( f'{header}\n' f'Content-Type: application/x-www-form-urlencoded\n\n' f'{method} {path}\n' f'{body}' ) def req_query_example(method, path, kv_pairs): header = '请求头:Authorization: Bearer {{token}}' if kv_pairs: qs = '&'.join(f'{k}={v}' for k, v in kv_pairs) return f'{header}\n\n{method} {path}?{qs}' return f'{header}\n\n{method} {path}'