genoc 0.1.3 → 0.2.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.
@@ -1,10 +1,13 @@
1
1
  import type { AnalyzedOperation } from '../analyzer/path-analyzer.js';
2
+ import type { SchemaObject } from '../types/openapi.js';
2
3
  /**
3
4
  * Reserved type names used by the generated output's built-in classes,
4
5
  * functions, and types. User-defined schema names that collide with these
5
6
  * are automatically renamed with a suffix to prevent duplicate identifiers.
6
7
  */
7
8
  export declare const RESERVED_TYPE_NAMES: ReadonlySet<string>;
9
+ /** Default module specifier generated code imports shared runtime classes from. */
10
+ export declare const DEFAULT_RUNTIME_IMPORT_PATH = "genoc/runtime";
8
11
  /**
9
12
  * Sanitize a schema type name by converting dot-separated segments into
10
13
  * PascalCase. Names without dots pass through unchanged.
@@ -39,3 +42,34 @@ export declare function getErrorType(op: AnalyzedOperation): string;
39
42
  * Generate the auto-generated header comment.
40
43
  */
41
44
  export declare function makeHeader(version: string): string;
45
+ /**
46
+ * Sanitize free-form text for safe inclusion inside a JSDoc comment.
47
+ *
48
+ * Normalizes CRLF to LF, flattens remaining newlines into single spaces,
49
+ * escapes the comment-closing sequence (asterisk + slash) as `*\/`, and
50
+ * trims leading/trailing whitespace. No other transformation is applied —
51
+ * no HTML stripping, no markdown processing, no wrapping.
52
+ */
53
+ export declare function sanitizeJsDocText(text: string): string;
54
+ /**
55
+ * Format an arbitrary metadata value for a JSDoc tag using JSON.stringify
56
+ * (no indent). Returns `null` when stringify yields `undefined` (e.g. for
57
+ * `undefined` or function values) — callers should skip the tag entirely.
58
+ */
59
+ export declare function formatJsDocValue(value: unknown): string | null;
60
+ /**
61
+ * Build the ordered JSDoc content segments for a schema-backed property.
62
+ *
63
+ * Order (frozen): description → `@deprecated` → `@default` → `@example`(s)
64
+ * → `@title`. Segments are skipped when their value is absent, empty, or
65
+ * whitespace-only. Sanitization is applied AFTER stringification for
66
+ * `@default` / `@example` values.
67
+ */
68
+ export declare function buildFieldJsDocLines(schema: SchemaObject): string[];
69
+ /**
70
+ * Render a schema's JSDoc metadata as a complete comment block.
71
+ *
72
+ * 0 segments → `''`; exactly 1 segment → single-line `/** text *\/`;
73
+ * ≥2 segments → multiline block with a blank ` *` line between segments.
74
+ */
75
+ export declare function buildTypeJsDoc(schema: SchemaObject): string;
@@ -11,9 +11,6 @@ export const RESERVED_TYPE_NAMES = new Set([
11
11
  'UnspecifiedApiError',
12
12
  'DefaultApiError',
13
13
  'RequesterFailError',
14
- // Functions in contracts.ts
15
- 'streamResponse',
16
- 'errorResponse',
17
14
  // Types / functions in client.ts
18
15
  'Requester',
19
16
  'isDefinedError',
@@ -22,6 +19,8 @@ export const RESERVED_TYPE_NAMES = new Set([
22
19
  // Interface in contracts.ts (when file uploads present)
23
20
  'FileInput',
24
21
  ]);
22
+ /** Default module specifier generated code imports shared runtime classes from. */
23
+ export const DEFAULT_RUNTIME_IMPORT_PATH = 'genoc/runtime';
25
24
  /**
26
25
  * Sanitize a schema type name by converting dot-separated segments into
27
26
  * PascalCase. Names without dots pass through unchanged.
@@ -116,3 +115,78 @@ export function getErrorType(op) {
116
115
  export function makeHeader(version) {
117
116
  return `// Auto-generated by genoc from OpenAPI ${version} spec. DO NOT EDIT.`;
118
117
  }
118
+ /**
119
+ * Sanitize free-form text for safe inclusion inside a JSDoc comment.
120
+ *
121
+ * Normalizes CRLF to LF, flattens remaining newlines into single spaces,
122
+ * escapes the comment-closing sequence (asterisk + slash) as `*\/`, and
123
+ * trims leading/trailing whitespace. No other transformation is applied —
124
+ * no HTML stripping, no markdown processing, no wrapping.
125
+ */
126
+ export function sanitizeJsDocText(text) {
127
+ return text.replace(/\r\n/g, '\n').replace(/\n/g, ' ').replace(/\*\//g, '*\\/').trim();
128
+ }
129
+ /**
130
+ * Format an arbitrary metadata value for a JSDoc tag using JSON.stringify
131
+ * (no indent). Returns `null` when stringify yields `undefined` (e.g. for
132
+ * `undefined` or function values) — callers should skip the tag entirely.
133
+ */
134
+ export function formatJsDocValue(value) {
135
+ const json = JSON.stringify(value);
136
+ return json === undefined ? null : json;
137
+ }
138
+ /**
139
+ * Build the ordered JSDoc content segments for a schema-backed property.
140
+ *
141
+ * Order (frozen): description → `@deprecated` → `@default` → `@example`(s)
142
+ * → `@title`. Segments are skipped when their value is absent, empty, or
143
+ * whitespace-only. Sanitization is applied AFTER stringification for
144
+ * `@default` / `@example` values.
145
+ */
146
+ export function buildFieldJsDocLines(schema) {
147
+ const lines = [];
148
+ if (schema.description !== undefined && schema.description.trim() !== '') {
149
+ lines.push(sanitizeJsDocText(schema.description));
150
+ }
151
+ if (schema.deprecated === true) {
152
+ lines.push('@deprecated');
153
+ }
154
+ if (schema.default !== undefined) {
155
+ const formatted = formatJsDocValue(schema.default);
156
+ if (formatted !== null) {
157
+ lines.push(`@default ${sanitizeJsDocText(formatted)}`);
158
+ }
159
+ }
160
+ if (schema.example !== undefined) {
161
+ const formatted = formatJsDocValue(schema.example);
162
+ if (formatted !== null) {
163
+ lines.push(`@example ${sanitizeJsDocText(formatted)}`);
164
+ }
165
+ }
166
+ if (schema.examples !== undefined) {
167
+ for (const value of schema.examples) {
168
+ const formatted = formatJsDocValue(value);
169
+ if (formatted !== null) {
170
+ lines.push(`@example ${sanitizeJsDocText(formatted)}`);
171
+ }
172
+ }
173
+ }
174
+ if (schema.title) {
175
+ lines.push(`@title ${sanitizeJsDocText(schema.title)}`);
176
+ }
177
+ return lines;
178
+ }
179
+ /**
180
+ * Render a schema's JSDoc metadata as a complete comment block.
181
+ *
182
+ * 0 segments → `''`; exactly 1 segment → single-line `/** text *\/`;
183
+ * ≥2 segments → multiline block with a blank ` *` line between segments.
184
+ */
185
+ export function buildTypeJsDoc(schema) {
186
+ const lines = buildFieldJsDocLines(schema);
187
+ if (lines.length === 0)
188
+ return '';
189
+ if (lines.length === 1)
190
+ return `/** ${lines[0]} */`;
191
+ return `/**\n${lines.map((line) => ` * ${line}`).join('\n *\n')}\n */`;
192
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genoc",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Generate typed HTTP clients from OpenAPI 3.0 / 3.1 specifications",
5
5
  "keywords": [
6
6
  "client",
@@ -28,6 +28,10 @@
28
28
  ".": {
29
29
  "import": "./dist/index.js",
30
30
  "types": "./dist/index.d.ts"
31
+ },
32
+ "./runtime": {
33
+ "import": "./dist/runtime/index.js",
34
+ "types": "./dist/runtime/index.d.ts"
31
35
  }
32
36
  },
33
37
  "scripts": {
@@ -39,7 +43,7 @@
39
43
  "format": "oxfmt --write",
40
44
  "format:check": "oxfmt --check",
41
45
  "changeset": "changeset",
42
- "version-packages": "changeset version",
46
+ "version-packages": "changeset version && oxfmt --write",
43
47
  "release": "bun run build && changeset publish"
44
48
  },
45
49
  "dependencies": {