@contractkit/plugin-bruno 0.9.1 → 0.10.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.
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">68.18% </span>
26
+ <span class="strong">75% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>30/44</span>
28
+ <span class='fraction'>33/44</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">67.74% </span>
33
+ <span class="strong">77.41% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>21/31</span>
35
+ <span class='fraction'>24/31</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">72% </span>
40
+ <span class="strong">76% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>18/25</span>
42
+ <span class='fraction'>19/25</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">71.05% </span>
47
+ <span class="strong">78.94% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>27/38</span>
49
+ <span class='fraction'>30/38</span>
50
50
  </div>
51
51
 
52
52
 
@@ -266,7 +266,7 @@
266
266
  <span class="cline-any cline-neutral">&nbsp;</span>
267
267
  <span class="cline-any cline-neutral">&nbsp;</span>
268
268
  <span class="cline-any cline-neutral">&nbsp;</span>
269
- <span class="cline-any cline-yes">228x</span>
269
+ <span class="cline-any cline-yes">248x</span>
270
270
  <span class="cline-any cline-neutral">&nbsp;</span>
271
271
  <span class="cline-any cline-neutral">&nbsp;</span>
272
272
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -298,7 +298,7 @@
298
298
  <span class="cline-any cline-neutral">&nbsp;</span>
299
299
  <span class="cline-any cline-neutral">&nbsp;</span>
300
300
  <span class="cline-any cline-neutral">&nbsp;</span>
301
- <span class="cline-any cline-yes">10x</span>
301
+ <span class="cline-any cline-yes">11x</span>
302
302
  <span class="cline-any cline-neutral">&nbsp;</span>
303
303
  <span class="cline-any cline-neutral">&nbsp;</span>
304
304
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -361,16 +361,16 @@
361
361
  <span class="cline-any cline-neutral">&nbsp;</span>
362
362
  <span class="cline-any cline-neutral">&nbsp;</span>
363
363
  <span class="cline-any cline-neutral">&nbsp;</span>
364
- <span class="cline-any cline-yes">3x</span>
365
- <span class="cline-any cline-yes">3x</span>
364
+ <span class="cline-any cline-yes">10x</span>
365
+ <span class="cline-any cline-yes">10x</span>
366
366
  <span class="cline-any cline-neutral">&nbsp;</span>
367
367
  <span class="cline-any cline-neutral">&nbsp;</span>
368
368
  <span class="cline-any cline-neutral">&nbsp;</span>
369
- <span class="cline-any cline-no">&nbsp;</span>
370
- <span class="cline-any cline-no">&nbsp;</span>
369
+ <span class="cline-any cline-yes">1x</span>
370
+ <span class="cline-any cline-yes">1x</span>
371
371
  <span class="cline-any cline-no">&nbsp;</span>
372
372
  <span class="cline-any cline-neutral">&nbsp;</span>
373
- <span class="cline-any cline-no">&nbsp;</span>
373
+ <span class="cline-any cline-yes">1x</span>
374
374
  <span class="cline-any cline-neutral">&nbsp;</span>
375
375
  <span class="cline-any cline-neutral">&nbsp;</span>
376
376
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -384,10 +384,10 @@
384
384
  <span class="cline-any cline-neutral">&nbsp;</span>
385
385
  <span class="cline-any cline-neutral">&nbsp;</span>
386
386
  <span class="cline-any cline-neutral">&nbsp;</span>
387
- <span class="cline-any cline-yes">84x</span>
388
- <span class="cline-any cline-yes">84x</span>
389
- <span class="cline-any cline-yes">84x</span>
390
- <span class="cline-any cline-yes">84x</span>
387
+ <span class="cline-any cline-yes">94x</span>
388
+ <span class="cline-any cline-yes">94x</span>
389
+ <span class="cline-any cline-yes">94x</span>
390
+ <span class="cline-any cline-yes">94x</span>
391
391
  <span class="cline-any cline-neutral">&nbsp;</span>
392
392
  <span class="cline-any cline-neutral">&nbsp;</span>
393
393
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -402,12 +402,12 @@
402
402
  <span class="cline-any cline-neutral">&nbsp;</span>
403
403
  <span class="cline-any cline-neutral">&nbsp;</span>
404
404
  <span class="cline-any cline-neutral">&nbsp;</span>
405
- <span class="cline-any cline-yes">80x</span>
406
- <span class="cline-any cline-yes">80x</span>
405
+ <span class="cline-any cline-yes">90x</span>
406
+ <span class="cline-any cline-yes">90x</span>
407
407
  <span class="cline-any cline-neutral">&nbsp;</span>
408
408
  <span class="cline-any cline-neutral">&nbsp;</span>
409
409
  <span class="cline-any cline-neutral">&nbsp;</span>
410
- <span class="cline-any cline-yes">79x</span>
410
+ <span class="cline-any cline-yes">89x</span>
411
411
  <span class="cline-any cline-neutral">&nbsp;</span>
412
412
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import type {
413
413
  ContractRootNode,
@@ -534,16 +534,16 @@ export function opRequest(
534
534
  &nbsp;
535
535
  export function opResponse(statusCode: number, bodyType?: string | ContractTypeNode, contentType?: 'application/json'): OpResponseNode {
536
536
  const bt: ContractTypeNode | undefined =
537
- bodyType === undefined ? undefined : <span class="branch-1 cbranch-no" title="branch not covered" >typeof bodyType === 'string' ? parseBodyTypeString(bodyType) : bodyType;</span>
537
+ bodyType === undefined ? undefined : typeof bodyType === 'string' ? parseBodyTypeString(bodyType) : <span class="branch-1 cbranch-no" title="branch not covered" >bodyType;</span>
538
538
  return { statusCode, contentType, bodyType: bt };
539
539
  }
540
540
  &nbsp;
541
- function <span class="fstat-no" title="function not covered" >parseBodyTypeString(s</span>: string): ContractTypeNode {
542
- const arrayMatch = <span class="cstat-no" title="statement not covered" >s.match(/^array\((.+)\)$/);</span>
543
- <span class="cstat-no" title="statement not covered" > if (arrayMatch?.[1]) {</span>
541
+ function parseBodyTypeString(s: string): ContractTypeNode {
542
+ const arrayMatch = s.match(/^array\((.+)\)$/);
543
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (arrayMatch?.[1]) {
544
544
  <span class="cstat-no" title="statement not covered" > return { kind: 'array', item: refType(arrayMatch[1]) };</span>
545
545
  }
546
- <span class="cstat-no" title="statement not covered" > return refType(s);</span>
546
+ return refType(s);
547
547
  }
548
548
  &nbsp;
549
549
  /** Normalize a raw param value (old bare format or new discriminated union) to ParamSource. */
@@ -589,7 +589,7 @@ export function opRoot(routes: OpRouteNode[], file = 'users.op', meta: Record&lt
589
589
  <div class='footer quiet pad2 space-top1 center small'>
590
590
  Code coverage generated by
591
591
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
592
- at 2026-04-29T12:51:10.099Z
592
+ at 2026-05-01T17:30:36.787Z
593
593
  </div>
594
594
  <script src="../prettify.js"></script>
595
595
  <script>
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">68.18% </span>
26
+ <span class="strong">75% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>30/44</span>
28
+ <span class='fraction'>33/44</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">67.74% </span>
33
+ <span class="strong">77.41% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>21/31</span>
35
+ <span class='fraction'>24/31</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">72% </span>
40
+ <span class="strong">76% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>18/25</span>
42
+ <span class='fraction'>19/25</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">71.05% </span>
47
+ <span class="strong">78.94% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>27/38</span>
49
+ <span class='fraction'>30/38</span>
50
50
  </div>
51
51
 
52
52
 
@@ -80,17 +80,17 @@
80
80
  </thead>
81
81
  <tbody><tr>
82
82
  <td class="file medium" data-value="helpers.ts"><a href="helpers.ts.html">helpers.ts</a></td>
83
- <td data-value="68.18" class="pic medium">
84
- <div class="chart"><div class="cover-fill" style="width: 68%"></div><div class="cover-empty" style="width: 32%"></div></div>
83
+ <td data-value="75" class="pic medium">
84
+ <div class="chart"><div class="cover-fill" style="width: 75%"></div><div class="cover-empty" style="width: 25%"></div></div>
85
85
  </td>
86
- <td data-value="68.18" class="pct medium">68.18%</td>
87
- <td data-value="44" class="abs medium">30/44</td>
88
- <td data-value="67.74" class="pct medium">67.74%</td>
89
- <td data-value="31" class="abs medium">21/31</td>
90
- <td data-value="72" class="pct medium">72%</td>
91
- <td data-value="25" class="abs medium">18/25</td>
92
- <td data-value="71.05" class="pct medium">71.05%</td>
93
- <td data-value="38" class="abs medium">27/38</td>
86
+ <td data-value="75" class="pct medium">75%</td>
87
+ <td data-value="44" class="abs medium">33/44</td>
88
+ <td data-value="77.41" class="pct medium">77.41%</td>
89
+ <td data-value="31" class="abs medium">24/31</td>
90
+ <td data-value="76" class="pct medium">76%</td>
91
+ <td data-value="25" class="abs medium">19/25</td>
92
+ <td data-value="78.94" class="pct medium">78.94%</td>
93
+ <td data-value="38" class="abs medium">30/38</td>
94
94
  </tr>
95
95
 
96
96
  </tbody>
@@ -101,7 +101,7 @@
101
101
  <div class='footer quiet pad2 space-top1 center small'>
102
102
  Code coverage generated by
103
103
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2026-04-29T12:51:10.099Z
104
+ at 2026-05-01T17:30:36.787Z
105
105
  </div>
106
106
  <script src="../prettify.js"></script>
107
107
  <script>
@@ -1,4 +1,5 @@
1
1
  import type { OpRootNode, ContractRootNode } from '@contractkit/core';
2
+ /** A single file produced by the Bruno codegen — a relative output path and its YAML content. */
2
3
  export interface OpenCollectionFile {
3
4
  relativePath: string;
4
5
  content: string;
@@ -12,12 +13,14 @@ export interface BrunoSecurityScheme {
12
13
  name?: string;
13
14
  in?: string;
14
15
  }
16
+ /** Auth configuration passed to the Bruno codegen; drives collection-level auth and per-operation auth blocks. */
15
17
  export interface BrunoAuthOptions {
16
18
  /** Name of the default scheme (from config.security.default) */
17
19
  defaultScheme?: string;
18
20
  /** Scheme definitions keyed by name (non-HMAC only) */
19
21
  schemes?: Record<string, BrunoSecurityScheme>;
20
22
  }
23
+ /** Options controlling what {@link generateOpenCollection} emits. */
21
24
  export interface OpenCollectionOptions {
22
25
  collectionName: string;
23
26
  contractRoots?: ContractRootNode[];
@@ -43,6 +46,18 @@ export interface OpenCollectionOptions {
43
46
  export declare function generateOpenCollection(roots: OpRootNode[], options: OpenCollectionOptions): OpenCollectionFile[];
44
47
  /** Parse a previously-written manifest. Returns the list of relative paths to clean up. Returns [] if missing or unreadable so a stale/garbled manifest never blocks regeneration. */
45
48
  export declare function parseManifest(content: string): string[];
49
+ /**
50
+ * Deep-merges a YAML override string into a generated YAML string.
51
+ *
52
+ * Objects are merged recursively; arrays and scalars in the override replace the
53
+ * generated value entirely. If `pluginFileContent` is not a YAML mapping (e.g. it
54
+ * is a scalar or a list), the generated content is returned unchanged.
55
+ *
56
+ * @param generatedYaml - The YAML string produced by the Bruno codegen.
57
+ * @param pluginFileContent - The YAML override string to merge in.
58
+ * @returns The merged YAML string, or `generatedYaml` if the override is not a mapping.
59
+ */
60
+ export declare function mergePluginFile(generatedYaml: string, pluginFileContent: string): string;
46
61
  /** Convert "Create an Offer" → create-an-offer (for .yml file names) */
47
62
  export declare function slugifyName(name: string): string;
48
63
  /** Convert /users/{id}/posts → users-id-posts (for .yml file names) */
@@ -1 +1 @@
1
- {"version":3,"file":"codegen-bruno.d.ts","sourceRoot":"","sources":["../src/codegen-bruno.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,UAAU,EAMV,gBAAgB,EAGnB,MAAM,mBAAmB,CAAC;AAI3B,MAAM,WAAW,kBAAkB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,8JAA8J;AAC9J,eAAO,MAAM,iBAAiB,qCAAqC,CAAC;AAEpE,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC7B,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,qBAAqB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACnC,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,EAAE,CAmDhH;AAED,sLAAsL;AACtL,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAUvD;AAybD,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASjD"}
1
+ {"version":3,"file":"codegen-bruno.d.ts","sourceRoot":"","sources":["../src/codegen-bruno.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,UAAU,EAMV,gBAAgB,EAGnB,MAAM,mBAAmB,CAAC;AAK3B,iGAAiG;AACjG,MAAM,WAAW,kBAAkB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,8JAA8J;AAC9J,eAAO,MAAM,iBAAiB,qCAAqC,CAAC;AAEpE,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED,kHAAkH;AAClH,MAAM,WAAW,gBAAgB;IAC7B,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CACjD;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACnC,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,EAAE,CAqDhH;AAED,sLAAsL;AACtL,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAUvD;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAOxF;AAubD,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASjD"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { BrunoSecurityScheme } from './codegen-bruno.js';
2
2
  import type { ContractKitPlugin } from '@contractkit/core';
3
+ /** Configuration accepted by the Bruno plugin, both via `contractkit.config.json` and `createBrunoPlugin`. */
3
4
  export interface BrunoPluginConfig {
4
5
  baseDir?: string;
5
6
  output?: string;
@@ -16,7 +17,16 @@ export interface BrunoPluginConfig {
16
17
  * benefit from full coverage. Set to `false` to omit internal ops.
17
18
  */
18
19
  includeInternal?: boolean;
20
+ /**
21
+ * Directory containing YAML override files, resolved relative to `rootDir`.
22
+ * The directory mirrors the generated output structure — a file at
23
+ * `<overrideDir>/payments/get-payment.yml` is deep-merged into the generated
24
+ * `payments/get-payment.yml`. Arrays in the override replace the generated
25
+ * array entirely. Files with no matching override are emitted unchanged.
26
+ */
27
+ overrideDir?: string;
19
28
  }
29
+ /** Full plugin options shape read from `ctx.options` — extends {@link BrunoPluginConfig} with the `auth` block. */
20
30
  export interface BrunoPluginOptions extends BrunoPluginConfig {
21
31
  auth?: {
22
32
  defaultScheme: string;
@@ -25,6 +35,16 @@ export interface BrunoPluginOptions extends BrunoPluginConfig {
25
35
  }
26
36
  declare const plugin: ContractKitPlugin;
27
37
  export default plugin;
38
+ /**
39
+ * Creates a Bruno plugin instance with explicit configuration, for programmatic use.
40
+ *
41
+ * Prefer the default export when loading via `contractkit.config.json`. Use this
42
+ * factory when constructing the plugin in code (e.g. in tests or custom build scripts).
43
+ *
44
+ * @param config - Plugin configuration (output paths, feature flags, overrides).
45
+ * @param rootDir - Absolute path used to resolve relative paths in `config`.
46
+ * @param auth - Optional auth scheme configuration mirroring the `auth` key in plugin options.
47
+ */
28
48
  export declare function createBrunoPlugin(config: BrunoPluginConfig, rootDir: string, auth?: {
29
49
  defaultScheme: string;
30
50
  schemes?: Record<string, BrunoSecurityScheme>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IACzD,IAAI,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;KAAE,CAAC;CACnF;AAID,QAAA,MAAM,MAAM,EAAE,iBAsBb,CAAC;AAEF,eAAe,MAAM,CAAC;AAItB,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;CAAE,GAChF,iBAAiB,CAsBnB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,8GAA8G;AAC9G,MAAM,WAAW,iBAAiB;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,mHAAmH;AACnH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IACzD,IAAI,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;KAAE,CAAC;CACnF;AAID,QAAA,MAAM,MAAM,EAAE,iBAuBb,CAAC;AAEF,eAAe,MAAM,CAAC;AAItB;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;CAAE,GAChF,iBAAiB,CAuBnB"}
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import { existsSync, readFileSync, rmSync, readdirSync, rmdirSync } from "fs";
8
8
  // src/codegen-bruno.ts
9
9
  import { resolveSecurity, resolveModifiers, SECURITY_NONE } from "@contractkit/core";
10
10
  import { basename } from "path";
11
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
11
12
  var MANIFEST_FILENAME = ".contractkit-bruno-manifest.json";
12
13
  function generateOpenCollection(roots, options) {
13
14
  const files = [];
@@ -48,9 +49,14 @@ function generateOpenCollection(roots, options) {
48
49
  if (!includeInternal && resolveModifiers(route, op).includes("internal")) continue;
49
50
  const requestName = op.name ?? route.path;
50
51
  const fileName = op.name ? `${slugifyName(op.name)}.yml` : `${op.method}-${sanitizePath(route.path)}.yml`;
52
+ let content = generateRequestFile(route, op, requestName, seq, modelMap, root, defaultScheme, randomExamples);
53
+ const pluginOverride = op.pluginFiles?.["bruno"];
54
+ if (pluginOverride !== void 0) {
55
+ content = mergePluginFile(content, pluginOverride);
56
+ }
51
57
  files.push({
52
58
  relativePath: `${requestDir}/${fileName}`,
53
- content: generateRequestFile(route, op, requestName, seq, modelMap, root, defaultScheme, randomExamples)
59
+ content
54
60
  });
55
61
  seq++;
56
62
  }
@@ -80,6 +86,30 @@ function parseManifest(content) {
80
86
  return [];
81
87
  }
82
88
  __name(parseManifest, "parseManifest");
89
+ function deepMerge(base, override) {
90
+ if (override !== null && typeof override === "object" && !Array.isArray(override) && base !== null && typeof base === "object" && !Array.isArray(base)) {
91
+ const result = {
92
+ ...base
93
+ };
94
+ for (const [key, val] of Object.entries(override)) {
95
+ result[key] = deepMerge(result[key], val);
96
+ }
97
+ return result;
98
+ }
99
+ return override;
100
+ }
101
+ __name(deepMerge, "deepMerge");
102
+ function mergePluginFile(generatedYaml, pluginFileContent) {
103
+ const overrideParsed = parseYaml(pluginFileContent);
104
+ if (overrideParsed === null || typeof overrideParsed !== "object" || Array.isArray(overrideParsed)) {
105
+ return generatedYaml;
106
+ }
107
+ const merged = deepMerge(parseYaml(generatedYaml), overrideParsed);
108
+ return stringifyYaml(merged, {
109
+ lineWidth: 0
110
+ });
111
+ }
112
+ __name(mergePluginFile, "mergePluginFile");
83
113
  function generateCollectionRoot(name, scheme) {
84
114
  const lines = [
85
115
  `opencollection: "1.0.0"`,
@@ -502,9 +532,7 @@ function fieldsToExampleObject(fields, modelMap, randomExamples = false) {
502
532
  if (field.visibility === "readonly") continue;
503
533
  if (field.default !== void 0) {
504
534
  obj[field.name] = field.default;
505
- } else if (field.optional) {
506
- obj[field.name] = null;
507
- } else {
535
+ } else if (!field.optional) {
508
536
  obj[field.name] = typeToExampleValue(field.type, modelMap, randomExamples);
509
537
  }
510
538
  }
@@ -553,6 +581,7 @@ var plugin = {
553
581
  const outDir = resolve(base, config.output ?? "bruno-collection");
554
582
  const collectionName = config.collectionName ?? basename2(ctx.rootDir);
555
583
  cleanupTrackedFiles(outDir);
584
+ const overrideDirAbs = config.overrideDir ? resolve(ctx.rootDir, config.overrideDir) : void 0;
556
585
  const files = generateOpenCollection(opRoots, {
557
586
  collectionName,
558
587
  contractRoots,
@@ -561,7 +590,7 @@ var plugin = {
561
590
  includeInternal: config.includeInternal
562
591
  });
563
592
  for (const { relativePath, content } of files) {
564
- ctx.emitFile(resolve(outDir, relativePath), content);
593
+ ctx.emitFile(resolve(outDir, relativePath), applyDirOverride(relativePath, content, overrideDirAbs));
565
594
  }
566
595
  }
567
596
  };
@@ -575,6 +604,7 @@ function createBrunoPlugin(config, rootDir, auth) {
575
604
  const outDir = resolve(base, config.output ?? "bruno-collection");
576
605
  const collectionName = config.collectionName ?? basename2(rootDir);
577
606
  cleanupTrackedFiles(outDir);
607
+ const overrideDirAbs = config.overrideDir ? resolve(rootDir, config.overrideDir) : void 0;
578
608
  const files = generateOpenCollection(opRoots, {
579
609
  collectionName,
580
610
  contractRoots,
@@ -582,12 +612,19 @@ function createBrunoPlugin(config, rootDir, auth) {
582
612
  randomExamples: config.randomExamples ?? true
583
613
  });
584
614
  for (const { relativePath, content } of files) {
585
- ctx.emitFile(resolve(outDir, relativePath), content);
615
+ ctx.emitFile(resolve(outDir, relativePath), applyDirOverride(relativePath, content, overrideDirAbs));
586
616
  }
587
617
  }
588
618
  };
589
619
  }
590
620
  __name(createBrunoPlugin, "createBrunoPlugin");
621
+ function applyDirOverride(relativePath, content, overrideDirAbs) {
622
+ if (!overrideDirAbs || relativePath === MANIFEST_FILENAME) return content;
623
+ const overrideFile = resolve(overrideDirAbs, relativePath);
624
+ if (!existsSync(overrideFile)) return content;
625
+ return mergePluginFile(content, readFileSync(overrideFile, "utf-8"));
626
+ }
627
+ __name(applyDirOverride, "applyDirOverride");
591
628
  function cleanupTrackedFiles(outDir) {
592
629
  const manifestPath = resolve(outDir, MANIFEST_FILENAME);
593
630
  if (!existsSync(manifestPath)) return;