wormajs 0.4.0 → 1.0.0-beta.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/dist/bin/actions.js +182 -5
- package/dist/bin/cli.js +8 -1
- package/dist/bin/renderer.js +2 -8
- package/dist/checkUpdates.js +98 -0
- package/dist/config.js +7 -0
- package/dist/constant.js +1 -2
- package/dist/core/WorkerPool.js +14 -0
- package/dist/core/loader/callingCodeLoader/helper.js +2 -3
- package/dist/core/loader/callingCodeLoader/index.js +1 -1
- package/dist/core/parser/openApiParser/helper.js +32 -19
- package/dist/core/parser/templateParser/index.js +25 -12
- package/dist/core/workerPool/index.js +2 -1
- package/dist/functions/changeReport.js +265 -0
- package/dist/functions/diffApis.js +82 -0
- package/dist/functions/diffDocument.js +542 -0
- package/dist/functions/sourceSnapshot.js +107 -0
- package/dist/functions/wormaJson.js +306 -66
- package/dist/generate.js +24 -2
- package/dist/helper/config/ConfigHelper.js +1 -2
- package/dist/helper/config/ConfigManager.js +7 -0
- package/dist/helper/config/GeneratorHelper.js +74 -21
- package/dist/helper/config/zType.js +24 -1
- package/dist/helper/template/index.js +113 -5
- package/dist/index.js +18 -1
- package/dist/plugins/index.js +2 -2
- package/dist/plugins/presets/aiDoc.js +27 -2
- package/dist/plugins/presets/payloadModifier/dsl.js +147 -0
- package/dist/plugins/presets/payloadModifier/index.js +122 -135
- package/dist/plugins/presets/payloadModifier/patch.js +171 -0
- package/dist/plugins/presets/payloadModifier/scope.js +109 -0
- package/dist/plugins/presets/platform/index.js +1 -3
- package/dist/plugins/presets/postman.js +105 -0
- package/dist/template/presets/alova/common/services/{tag}.d.cts.handlebars +1 -1
- package/dist/template/presets/alova/module/services/{tag}.d.ts.handlebars +1 -1
- package/dist/template/presets/alova/partials/dts-fn-declare.handlebars +1 -1
- package/dist/template/presets/alova/partials/dts-types.handlebars +12 -0
- package/dist/template/presets/alova/typescript/services/{tag}.ts.handlebars +11 -6
- package/dist/template/presets/axios/partials/dts-types.handlebars +9 -5
- package/dist/template/presets/axios/typescript/services/{tag}.ts.handlebars +9 -5
- package/dist/template/presets/fetch/partials/dts-types.handlebars +8 -5
- package/dist/template/presets/fetch/typescript/services/{tag}.ts.handlebars +9 -5
- package/dist/template/presets/ky/partials/dts-types.handlebars +8 -5
- package/dist/template/presets/ky/typescript/services/{tag}.ts.handlebars +9 -5
- package/dist/utils/format.js +62 -15
- package/dist/utils/template.js +1 -1
- package/package.json +3 -2
- package/typings/index.d.ts +279 -13
- package/typings/plugins.d.ts +166 -81
- package/dist/plugins/presets/payloadModifier/hepler.js +0 -347
- package/dist/plugins/presets/platform/fastapi.js +0 -22
- package/dist/template/presets/alova/partials/dts-extra-config.handlebars +0 -8
package/typings/index.d.ts
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import { MethodType, RequestBody } from 'alova';
|
|
2
2
|
import { OpenAPIV3_1 } from 'openapi-types';
|
|
3
|
+
import { FormatConfig as OxfmtFormatConfig } from 'oxfmt';
|
|
3
4
|
import { z } from 'zod/v3';
|
|
4
5
|
|
|
5
|
-
declare const DEFAULT_CONFIG: {
|
|
6
|
-
cacheDir: string;
|
|
7
|
-
/** Overrides cacheDir's parent directory for monorepo unified cache. */
|
|
8
|
-
cacheRoot: string | undefined;
|
|
9
|
-
Error: ErrorConstructor;
|
|
10
|
-
templateData: Map<string, any>;
|
|
11
|
-
};
|
|
12
|
-
export declare function setGlobalConfig(config: Partial<typeof DEFAULT_CONFIG>): void;
|
|
13
6
|
export type OpenAPIDocument = OpenAPIV3_1.Document;
|
|
14
7
|
export type SchemaObject = OpenAPIV3_1.SchemaObject;
|
|
15
8
|
export type Parameter = OpenAPIV3_1.ParameterObject;
|
|
@@ -203,11 +196,34 @@ export interface PerformanceConfig {
|
|
|
203
196
|
transformConcurrency?: number;
|
|
204
197
|
/** Max parallelism for file writes. Default 32 */
|
|
205
198
|
writeConcurrency?: number;
|
|
206
|
-
/**
|
|
207
|
-
|
|
208
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Sort the collected component types alphabetically so the output order stays
|
|
201
|
+
* stable regardless of worker scheduling. `false` keeps collection order.
|
|
202
|
+
* Default true
|
|
203
|
+
*/
|
|
209
204
|
deterministicSort?: boolean;
|
|
210
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* 生成产物的格式化配置。
|
|
208
|
+
*
|
|
209
|
+
* 除 `enabled` 外的所有字段都是 oxfmt 原生选项,worma 不做校验、原样透传给 oxfmt,
|
|
210
|
+
* 由 oxfmt 自行校验;类型提示直接来自 oxfmt,因此随 oxfmt 版本自动保持同步。
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```js
|
|
214
|
+
* // 关闭格式化
|
|
215
|
+
* format: { enabled: false }
|
|
216
|
+
*
|
|
217
|
+
* // 自定义风格
|
|
218
|
+
* format: { printWidth: 100, trailingComma: 'all', semi: false }
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
export interface FormatOptions extends OxfmtFormatConfig {
|
|
222
|
+
/**
|
|
223
|
+
* 是否格式化生成的代码,默认 true。
|
|
224
|
+
*/
|
|
225
|
+
enabled?: boolean;
|
|
226
|
+
}
|
|
211
227
|
export interface GeneratorConfig {
|
|
212
228
|
/**
|
|
213
229
|
* Openapi file path, it supports json and yaml file, and network url.
|
|
@@ -324,6 +340,17 @@ export interface Config {
|
|
|
324
340
|
* Currently, only OpenAPI specifications are supported, including OpenAPI 2.0 and 3.0 specifications.
|
|
325
341
|
*/
|
|
326
342
|
generator: GeneratorConfig[];
|
|
343
|
+
/**
|
|
344
|
+
* 生成产物的格式化配置(基于 oxfmt),对所有 generator 生效。
|
|
345
|
+
* 除 `enabled` 外的字段原样透传给 oxfmt,worma 不做额外校验。
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```js
|
|
349
|
+
* format: { enabled: false }
|
|
350
|
+
* format: { printWidth: 100, trailingComma: 'all', semi: false }
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
format?: FormatOptions;
|
|
327
354
|
}
|
|
328
355
|
export type UserConfig = Config;
|
|
329
356
|
export type UserConfigFnObject = () => UserConfig;
|
|
@@ -437,12 +464,83 @@ export type GeneratorProgressEvent = {
|
|
|
437
464
|
phase: "failed";
|
|
438
465
|
error: string;
|
|
439
466
|
});
|
|
467
|
+
/** Id and aggregated row counts of a change record persisted by one `generate()` run. */
|
|
468
|
+
export interface RecordedChangeInfo {
|
|
469
|
+
/** Zero-padded record id, e.g. `"0007"` */
|
|
470
|
+
id: string;
|
|
471
|
+
added: number;
|
|
472
|
+
removed: number;
|
|
473
|
+
modified: number;
|
|
474
|
+
}
|
|
440
475
|
export interface GenerateApiOptions {
|
|
441
|
-
force?: boolean;
|
|
442
476
|
projectPath?: string;
|
|
443
477
|
/** Per-generator lifecycle callback. Receives a discriminated union of {@link GeneratorProgressEvent}. */
|
|
444
478
|
onProgress?: (event: GeneratorProgressEvent) => void;
|
|
479
|
+
/**
|
|
480
|
+
* Called once when this run persisted a change record, with its id and
|
|
481
|
+
* aggregated counts. Never called when the source document did not change,
|
|
482
|
+
* so callers can tell "source updated" apart from "nothing to record".
|
|
483
|
+
*/
|
|
484
|
+
onChangeRecorded?: (change: RecordedChangeInfo) => void;
|
|
485
|
+
}
|
|
486
|
+
export type SourceStatus = "unchanged" | "changed" | "new" | "error";
|
|
487
|
+
export interface SourceUpdateInfo {
|
|
488
|
+
/** Index inside `config.generator` */
|
|
489
|
+
index: number;
|
|
490
|
+
output: string;
|
|
491
|
+
serverName?: string;
|
|
492
|
+
status: SourceStatus;
|
|
493
|
+
/** The URL / file that actually served the spec — also the cache key */
|
|
494
|
+
resolvedInput?: string;
|
|
495
|
+
/** Normalized hash of the raw spec text */
|
|
496
|
+
hash?: string;
|
|
497
|
+
error?: string;
|
|
498
|
+
}
|
|
499
|
+
export interface CheckUpdatesResult {
|
|
500
|
+
projectPath: string;
|
|
501
|
+
updates: SourceUpdateInfo[];
|
|
502
|
+
hasChanges: boolean;
|
|
503
|
+
/**
|
|
504
|
+
* Whether the project already carries a generation baseline (any index entry
|
|
505
|
+
* with a non-empty `tags` map). Lets callers decide whether a `new` source is
|
|
506
|
+
* worth surfacing: a brand-new project must stay silent on its first run,
|
|
507
|
+
* while an established project that gained a source should be noticed.
|
|
508
|
+
*/
|
|
509
|
+
hasGenerationBaseline: boolean;
|
|
445
510
|
}
|
|
511
|
+
/**
|
|
512
|
+
* Detect whether the configured OpenAPI sources changed since the last
|
|
513
|
+
* recorded baseline.
|
|
514
|
+
*
|
|
515
|
+
* This is a **source-level, side-effect free** check:
|
|
516
|
+
*
|
|
517
|
+
* - it only hashes the raw spec text — no parsing, no plugin hooks;
|
|
518
|
+
* - it only reads/writes the `source` sub-field of `index.json` entries, never
|
|
519
|
+
* the generation-side `hash` / `tags`;
|
|
520
|
+
* - when no baseline exists yet (`new`) it writes the baseline silently and
|
|
521
|
+
* does *not* report a change (first run must not nag the user).
|
|
522
|
+
*
|
|
523
|
+
* Nothing on the user's disk is rewritten — callers decide what to do with the
|
|
524
|
+
* result (the VS Code extension asks for confirmation before generating).
|
|
525
|
+
*/
|
|
526
|
+
export declare function checkUpdates(config: Config, options?: {
|
|
527
|
+
projectPath?: string;
|
|
528
|
+
}): Promise<CheckUpdatesResult>;
|
|
529
|
+
declare const DEFAULT_CONFIG: {
|
|
530
|
+
cacheDir: string;
|
|
531
|
+
/** Overrides cacheDir's parent directory for monorepo unified cache. */
|
|
532
|
+
cacheRoot: string | undefined;
|
|
533
|
+
/**
|
|
534
|
+
* Maximum number of `changes/<NNNN>.json` records to keep.
|
|
535
|
+
* `0` (or any non-positive value) keeps every record.
|
|
536
|
+
*/
|
|
537
|
+
changeHistoryLimit: number;
|
|
538
|
+
/** 用户自定义的产物格式化配置,未设置时使用内置默认值 */
|
|
539
|
+
format: FormatOptions | undefined;
|
|
540
|
+
Error: ErrorConstructor;
|
|
541
|
+
templateData: Map<string, any>;
|
|
542
|
+
};
|
|
543
|
+
export declare function setGlobalConfig(config: Partial<typeof DEFAULT_CONFIG>): void;
|
|
446
544
|
export type TemplatePreset = "alova" | "alovaGlobals" | "axios" | "fetch" | "ky";
|
|
447
545
|
export interface ConfigCreationOptions {
|
|
448
546
|
projectPath?: string;
|
|
@@ -460,6 +558,174 @@ export declare function defineConfig(config: UserConfigFnObject): UserConfigFnOb
|
|
|
460
558
|
export declare function defineConfig(config: UserConfigFnPromise): UserConfigFnPromise;
|
|
461
559
|
export declare function defineConfig(config: UserConfigFn): UserConfigFn;
|
|
462
560
|
export declare function defineConfig(config: UserConfigExport): UserConfigExport;
|
|
561
|
+
/**
|
|
562
|
+
* Structural diff of the **source** OpenAPI document.
|
|
563
|
+
*
|
|
564
|
+
* The baseline is the document parsed from the `beforeSpecParse` output, i.e.
|
|
565
|
+
* taken *before* the `specParsed` hooks run: it is the source file as authored,
|
|
566
|
+
* not the plugin-normalised document that generation consumes. Every difference
|
|
567
|
+
* is reported as a flat {@link SourceChange} row so a caller (the CLI table, the
|
|
568
|
+
* editor webview, a CI script) can render it without any further shaping.
|
|
569
|
+
*
|
|
570
|
+
* Design notes:
|
|
571
|
+
* - `$ref`s are deliberately **not** inlined: the record is a source view, so a
|
|
572
|
+
* component change is reported once under `#/components/...`, with the
|
|
573
|
+
* affected operations attached as `affects` (resolved through the reverse
|
|
574
|
+
* `$ref` index, including transitive references) so the impact stays visible
|
|
575
|
+
* without duplicating the row.
|
|
576
|
+
* - Description-ish keys are still recorded (they are source changes) but get
|
|
577
|
+
* the `doc` level so callers can de-emphasise them.
|
|
578
|
+
*/
|
|
579
|
+
/** Category of a change row. */
|
|
580
|
+
export type ChangeKind = "api" | "param" | "body" | "resp" | "comp" | "meta";
|
|
581
|
+
/** `+` added, `-` removed, `~` modified. */
|
|
582
|
+
export type ChangeOp = "+" | "-" | "~";
|
|
583
|
+
/** Coarse severity, used for ordering and colour only. */
|
|
584
|
+
export type ChangeLevel = "breaking" | "additive" | "doc";
|
|
585
|
+
/** One flattened source-document change. */
|
|
586
|
+
export interface SourceChange {
|
|
587
|
+
op: ChangeOp;
|
|
588
|
+
kind: ChangeKind;
|
|
589
|
+
/** `GET /pets`, `#/components/schemas/Pet` or `#/info` */
|
|
590
|
+
target: string;
|
|
591
|
+
/** Location inside the target, e.g. `query.status.schema.enum` */
|
|
592
|
+
item?: string;
|
|
593
|
+
/** Short description, e.g. `createPet -> addPet` or `+"sold"` */
|
|
594
|
+
detail?: string;
|
|
595
|
+
level: ChangeLevel;
|
|
596
|
+
/**
|
|
597
|
+
* Operations affected by a `comp` change, rendered as a list next to the
|
|
598
|
+
* change (one per line). Always absent for non-component kinds.
|
|
599
|
+
*/
|
|
600
|
+
affects?: string[];
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Diff two source documents and return the flattened change rows.
|
|
604
|
+
*
|
|
605
|
+
* Returns an empty array when the documents are structurally identical, so the
|
|
606
|
+
* caller can decide not to write a change record at all.
|
|
607
|
+
*/
|
|
608
|
+
export declare function diffSourceDocument(before: unknown, after: unknown): SourceChange[];
|
|
609
|
+
/** Alias accepted by {@link getChange} — resolves to the newest record. */
|
|
610
|
+
export declare const LATEST_CHANGE_ID = "latest";
|
|
611
|
+
/** One generator's (output's) contribution to a change record. */
|
|
612
|
+
export interface ChangeItem {
|
|
613
|
+
output: string;
|
|
614
|
+
serverName?: string;
|
|
615
|
+
/** URL / file that served the spec this record was built from */
|
|
616
|
+
resolvedInput?: string;
|
|
617
|
+
/** Flattened source-document changes (see `diffSourceDocument`) */
|
|
618
|
+
changes: SourceChange[];
|
|
619
|
+
}
|
|
620
|
+
/** Aggregated row counts of a change record. */
|
|
621
|
+
export interface ChangeCounts {
|
|
622
|
+
added: number;
|
|
623
|
+
removed: number;
|
|
624
|
+
modified: number;
|
|
625
|
+
}
|
|
626
|
+
/** Lightweight list entry returned by {@link listChanges}. */
|
|
627
|
+
export interface ChangeSummary {
|
|
628
|
+
id: string;
|
|
629
|
+
createdAt: number;
|
|
630
|
+
summary: {
|
|
631
|
+
generators: number;
|
|
632
|
+
} & ChangeCounts;
|
|
633
|
+
outputs: string[];
|
|
634
|
+
}
|
|
635
|
+
/** A full change record — one `generate()` run aggregated. */
|
|
636
|
+
export interface Change {
|
|
637
|
+
/** Record schema; `1` for the source-document view (absent on legacy records) */
|
|
638
|
+
schemaVersion?: number;
|
|
639
|
+
id: string;
|
|
640
|
+
createdAt: number;
|
|
641
|
+
projectPath: string;
|
|
642
|
+
generators: ChangeItem[];
|
|
643
|
+
}
|
|
644
|
+
/** Aggregate the change rows of every generator into flat counts. */
|
|
645
|
+
export declare function countChanges(generators: ChangeItem[]): ChangeCounts;
|
|
646
|
+
/**
|
|
647
|
+
* List recorded changes, newest first.
|
|
648
|
+
*
|
|
649
|
+
* Sorted by `createdAt` (id as tie-breaker) rather than by file name: an id is
|
|
650
|
+
* only chronological as long as `index.json#changeSeq` never resets, and a
|
|
651
|
+
* reset would otherwise make a brand-new record show up last.
|
|
652
|
+
*/
|
|
653
|
+
export declare function listChanges(projectPath: string): Promise<ChangeSummary[]>;
|
|
654
|
+
/**
|
|
655
|
+
* Read a single change record.
|
|
656
|
+
*
|
|
657
|
+
* @param projectPath absolute path of the project root
|
|
658
|
+
* @param id `"0007"` or the alias `"latest"` (newest record)
|
|
659
|
+
*/
|
|
660
|
+
export declare function getChange(projectPath: string, id: string): Promise<Change | undefined>;
|
|
661
|
+
/**
|
|
662
|
+
* Delete a single recorded change.
|
|
663
|
+
*
|
|
664
|
+
* @param projectPath absolute path of the project root
|
|
665
|
+
* @param id `"0007"` or the alias `"latest"` (newest record)
|
|
666
|
+
*
|
|
667
|
+
* `index.json#changeSeq` is deliberately left untouched: it only ever allocates
|
|
668
|
+
* new* ids, so keeping it monotonic guarantees the deleted id is never handed
|
|
669
|
+
* out again for a different record.
|
|
670
|
+
*
|
|
671
|
+
* @returns the id that was deleted, or `undefined` when nothing matched
|
|
672
|
+
*/
|
|
673
|
+
export declare function removeChange(projectPath: string, id: string): Promise<string | undefined>;
|
|
674
|
+
/** A newly added or removed API (identified by `method` + `path`). */
|
|
675
|
+
export interface ApiChange {
|
|
676
|
+
method: string;
|
|
677
|
+
path: string;
|
|
678
|
+
name?: string;
|
|
679
|
+
tag?: string;
|
|
680
|
+
}
|
|
681
|
+
/** An API that still exists but whose definition changed. */
|
|
682
|
+
export interface ApiFieldChange extends ApiChange {
|
|
683
|
+
/** Names of the fields whose value differs between the two versions */
|
|
684
|
+
changedFields: string[];
|
|
685
|
+
}
|
|
686
|
+
export interface ApiDiffResult {
|
|
687
|
+
added: ApiChange[];
|
|
688
|
+
removed: ApiChange[];
|
|
689
|
+
modified: ApiFieldChange[];
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Stable matching key for an API.
|
|
693
|
+
*
|
|
694
|
+
* `method` + `path` is used instead of `name` because it survives function
|
|
695
|
+
* renames: a renamed API is reported as *modified* rather than
|
|
696
|
+
* removed + added.
|
|
697
|
+
*/
|
|
698
|
+
export declare function apiDiffKey(api: Pick<Api, "method" | "path">): string;
|
|
699
|
+
/**
|
|
700
|
+
* Diff two API lists at API level.
|
|
701
|
+
*
|
|
702
|
+
* @param oldApis API list as of the previous generation (from cache)
|
|
703
|
+
* @param newApis API list parsed from the current spec
|
|
704
|
+
*/
|
|
705
|
+
export declare function diffApis(oldApis?: Api[], newApis?: Api[]): ApiDiffResult;
|
|
706
|
+
/**
|
|
707
|
+
* The source document as of the last successful generation.
|
|
708
|
+
*
|
|
709
|
+
* It is captured **before** the `specParsed` hooks run, so the snapshot is the
|
|
710
|
+
* source file the user authored (after `beforeSpecParse`), not the document the
|
|
711
|
+
* plugin pipeline turns it into.
|
|
712
|
+
*/
|
|
713
|
+
export interface SourceSnapshot {
|
|
714
|
+
version: number;
|
|
715
|
+
/** URL / file that served the spec */
|
|
716
|
+
resolvedInput?: string;
|
|
717
|
+
/** Hash of the stable-stringified document */
|
|
718
|
+
hash: string;
|
|
719
|
+
updatedAt: number;
|
|
720
|
+
/** The stable-stringified document, parsed back into a plain value */
|
|
721
|
+
doc: unknown;
|
|
722
|
+
}
|
|
723
|
+
/** Stable hash of a stable-stringified source document. */
|
|
724
|
+
export declare function sourceDocumentHash(documentText: string): string;
|
|
725
|
+
/** Read one generator's last source snapshot. */
|
|
726
|
+
export declare function readSourceSnapshot(projectRoot: string, outputPath: string): Promise<SourceSnapshot | null>;
|
|
727
|
+
/** Persist one generator's source snapshot. */
|
|
728
|
+
export declare function writeSourceSnapshot(projectRoot: string, outputPath: string, snapshot: SourceSnapshot): Promise<void>;
|
|
463
729
|
/**
|
|
464
730
|
* Generate relevant API information based on the configuration object.
|
|
465
731
|
*
|
|
@@ -467,7 +733,7 @@ export declare function defineConfig(config: UserConfigExport): UserConfigExport
|
|
|
467
733
|
* its lifecycle via {@link GeneratorProgressEvent} discriminated union events.
|
|
468
734
|
*
|
|
469
735
|
* @param config generating config
|
|
470
|
-
* @param options config rules that contains `
|
|
736
|
+
* @param options config rules that contains `projectPath`, `onProgress`
|
|
471
737
|
* @returns An array that contains the result of `generator` items in configuration whether generation is successful.
|
|
472
738
|
*/
|
|
473
739
|
export declare function generate(config: Config, options?: GenerateApiOptions): Promise<boolean[]>;
|
package/typings/plugins.d.ts
CHANGED
|
@@ -231,9 +231,11 @@ export interface PerformanceConfig {
|
|
|
231
231
|
transformConcurrency?: number;
|
|
232
232
|
/** Max parallelism for file writes. Default 32 */
|
|
233
233
|
writeConcurrency?: number;
|
|
234
|
-
/**
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Sort the collected component types alphabetically so the output order stays
|
|
236
|
+
* stable regardless of worker scheduling. `false` keeps collection order.
|
|
237
|
+
* Default true
|
|
238
|
+
*/
|
|
237
239
|
deterministicSort?: boolean;
|
|
238
240
|
}
|
|
239
241
|
export interface GeneratorConfig {
|
|
@@ -580,105 +582,129 @@ export interface ImportTypeOptions {
|
|
|
580
582
|
export declare function importType(imports: Record<string, string[]>, options?: {
|
|
581
583
|
files?: string[];
|
|
582
584
|
}): ApiPlugin;
|
|
583
|
-
export type ModifierScope = "params" | "pathParams" | "data" | "response";
|
|
584
|
-
export type SchemaPrimitive = "number" | "string" | "boolean" | "undefined" | "null" | "unknown" | "any" | "never";
|
|
585
585
|
/**
|
|
586
|
-
*
|
|
587
|
-
*
|
|
586
|
+
* The part of the API the modification applies to.
|
|
587
|
+
* - `params` — query parameters
|
|
588
|
+
* - `pathParams` — path parameters
|
|
589
|
+
* - `data` — request body
|
|
590
|
+
* - `response` — response body
|
|
588
591
|
*/
|
|
589
|
-
export type
|
|
592
|
+
export type ModifierScope = "params" | "pathParams" | "data" | "response";
|
|
590
593
|
/**
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
594
|
+
* A matching rule.
|
|
595
|
+
* - string: the value contains this substring
|
|
596
|
+
* - RegExp: the value matches this pattern
|
|
597
|
+
* - function: a predicate receiving the value
|
|
595
598
|
*/
|
|
596
|
-
export
|
|
597
|
-
[attr: string]: Schema;
|
|
598
|
-
}
|
|
599
|
+
export type Matcher = string | RegExp | ((value: string) => boolean);
|
|
599
600
|
/**
|
|
600
|
-
*
|
|
601
|
+
* Type expressions understood by the plugin. TS-only types (`undefined`, `unknown`,
|
|
602
|
+
* `any`, `never`) are valid and are written through to the schema as-is.
|
|
601
603
|
*/
|
|
602
|
-
export
|
|
604
|
+
export type SchemaPrimitive = "number" | "string" | "boolean" | "undefined" | "null" | "unknown" | "any" | "never";
|
|
605
|
+
/**
|
|
606
|
+
* The spec DSL. It only ever *describes a type*, therefore it always appears in a type
|
|
607
|
+
* value position (`FieldPatchObject.type`, `FieldPatchObject.items`, union members, ...).
|
|
608
|
+
*/
|
|
609
|
+
export type SchemaDSL = SchemaPrimitive
|
|
610
|
+
/** `['string']` = `string[]`, `['string', 'number']` = the tuple `[string, number]` */
|
|
611
|
+
| SchemaDSL[] | {
|
|
612
|
+
oneOf: SchemaDSL[];
|
|
613
|
+
} | {
|
|
614
|
+
anyOf: SchemaDSL[];
|
|
615
|
+
} | {
|
|
616
|
+
allOf: SchemaDSL[];
|
|
617
|
+
} | {
|
|
603
618
|
enum: Array<string | number | boolean | null>;
|
|
604
619
|
type?: SchemaPrimitive;
|
|
605
620
|
}
|
|
621
|
+
/** object shorthand: every listed field is required */
|
|
622
|
+
| {
|
|
623
|
+
[field: string]: SchemaDSL;
|
|
624
|
+
};
|
|
606
625
|
/**
|
|
607
|
-
*
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
626
|
+
* OpenAPI keywords usable inside a patch object. Every other key is documented by the
|
|
627
|
+
* plugin itself, so a patch object holding one of these keys is a partial patch of the
|
|
628
|
+
* target while an object holding none of them is a shorthand for `properties`.
|
|
629
|
+
*/
|
|
630
|
+
export interface FieldPatchObject {
|
|
631
|
+
/** Replaces the type: type-family keys are cleared, documentation keys are kept. */
|
|
632
|
+
type?: SchemaDSL;
|
|
633
|
+
/** Field-level requiredness, translated to the parent `required` array (or to `ParameterObject.required`). */
|
|
634
|
+
required?: boolean;
|
|
635
|
+
description?: string;
|
|
636
|
+
/** Explicit field-table patch, also the escape hatch when a field is named like a reserved key. */
|
|
637
|
+
properties?: Record<string, FieldValue>;
|
|
638
|
+
items?: SchemaDSL;
|
|
639
|
+
enum?: Array<string | number | boolean | null>;
|
|
640
|
+
oneOf?: SchemaDSL[];
|
|
641
|
+
anyOf?: SchemaDSL[];
|
|
642
|
+
allOf?: SchemaDSL[];
|
|
643
|
+
format?: string;
|
|
644
|
+
example?: unknown;
|
|
645
|
+
default?: unknown;
|
|
646
|
+
deprecated?: boolean;
|
|
647
|
+
nullable?: boolean;
|
|
648
|
+
title?: string;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* A field table: an object without reserved keys, read as a patch of the field table of
|
|
652
|
+
* the target. Every value follows the same rules as `FieldValue`, recursively.
|
|
653
|
+
*/
|
|
654
|
+
export interface FieldTable {
|
|
655
|
+
[field: string]: FieldValue;
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* A patch value. The same syntax is used for the top level `patch` and for every value
|
|
659
|
+
* inside a field table, so the rules below apply recursively.
|
|
660
|
+
*
|
|
661
|
+
* | form | meaning |
|
|
662
|
+
* | --- | --- |
|
|
663
|
+
* | `null` | delete the target |
|
|
664
|
+
* | string / array | shorthand for `{ type: value }`, documentation keys are kept |
|
|
665
|
+
* | object without reserved keys | field table, merged into the target field table |
|
|
666
|
+
* | object with reserved keys | partial patch of the target itself |
|
|
667
|
+
*/
|
|
668
|
+
export type FieldValue = null | SchemaDSL | FieldPatchObject | FieldTable;
|
|
634
669
|
export interface ModifierConfig {
|
|
635
|
-
/**
|
|
636
|
-
* The scope the modifier applies to (which parameter location to process).
|
|
637
|
-
*/
|
|
670
|
+
/** The scope the config applies to. */
|
|
638
671
|
scope: ModifierScope;
|
|
639
|
-
/**
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
*
|
|
653
|
-
* @
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
* @param key the matched field key. When `match` is omitted, the whole scope object is passed to the handler
|
|
657
|
-
* once and `key` is `undefined`; when `match` is set, `key` is the matched field name for each call.
|
|
658
|
-
* @returns Schema to change the type; { required: boolean, type: Schema } to change requiredness (driven by `type`);
|
|
659
|
-
* void | null | undefined to remove the field.
|
|
660
|
-
*/
|
|
661
|
-
handler: (schema: Schema, key?: string) => Schema | {
|
|
662
|
-
required: boolean;
|
|
663
|
-
type: Schema;
|
|
664
|
-
} | void | null | undefined;
|
|
672
|
+
/** URL filter. Omitted = every API. Multiple rules are ORed, `path` and `tag` are ANDed. */
|
|
673
|
+
path?: Matcher | Matcher[];
|
|
674
|
+
/** Tag filter: any tag of the API hitting any rule makes the config apply. */
|
|
675
|
+
tag?: Matcher | Matcher[];
|
|
676
|
+
/** Replaces the scope root with a nested node, navigating along `properties` only. */
|
|
677
|
+
unwrap?: string;
|
|
678
|
+
/** Locator. Omitted = the root itself, otherwise every matching top-level field. */
|
|
679
|
+
match?: Matcher;
|
|
680
|
+
/** Declarative patch (add / delete / modify). Runs before `handler`. */
|
|
681
|
+
patch?: FieldValue;
|
|
682
|
+
/**
|
|
683
|
+
* Escape hatch taking and returning raw OpenAPI schema objects.
|
|
684
|
+
* @param schema the located raw schema
|
|
685
|
+
* @param key the located field name, `undefined` when the root itself is located
|
|
686
|
+
* @returns the replacement schema, or `null` / `undefined` to delete the target
|
|
687
|
+
*/
|
|
688
|
+
handler?: (schema: SchemaObject, key?: string) => SchemaObject | null | undefined;
|
|
665
689
|
}
|
|
666
690
|
export type PayloadModifierConfig = ModifierConfig;
|
|
667
|
-
export declare function payloadModifier(configs: PayloadModifierConfig[]): ApiPlugin;
|
|
668
691
|
/**
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
* Pass the base URL of your FastAPI app; the plugin will try `/openapi.json`
|
|
672
|
-
* first, then fall back to the bare base URL.
|
|
692
|
+
* Flexibly adds, deletes and modifies the payload of your APIs.
|
|
673
693
|
*
|
|
674
|
-
*
|
|
694
|
+
* Every config runs the same fixed pipeline: interface filter (`path` / `tag`) → redirect
|
|
695
|
+
* (`unwrap`) → locate (`match`) → patch (`patch`) → custom (`handler`). Configs are applied
|
|
696
|
+
* in array order, so a later config sees the result of the previous ones.
|
|
675
697
|
*
|
|
676
698
|
* @example
|
|
677
699
|
* ```ts
|
|
678
|
-
*
|
|
700
|
+
* payloadModifier([
|
|
701
|
+
* { scope: 'response', unwrap: 'data' },
|
|
702
|
+
* { scope: 'response', match: /[Ii]d$/, patch: 'string' },
|
|
703
|
+
* { scope: 'data', path: '/planPoint', patch: { operatorId: { type: 'string', required: true } } },
|
|
704
|
+
* ])
|
|
679
705
|
* ```
|
|
680
706
|
*/
|
|
681
|
-
export declare
|
|
707
|
+
export declare function payloadModifier(configs: PayloadModifierConfig[]): ApiPlugin;
|
|
682
708
|
/**
|
|
683
709
|
* Knife4j platform plugin.
|
|
684
710
|
*
|
|
@@ -766,6 +792,65 @@ export interface YapiOptions {
|
|
|
766
792
|
* ```
|
|
767
793
|
*/
|
|
768
794
|
export declare function yapi(options: YapiOptions): ApiPlugin;
|
|
795
|
+
export interface PostmanOptions {
|
|
796
|
+
/** Postman API Key, generated from Postman → Settings → API keys */
|
|
797
|
+
apiKey: string;
|
|
798
|
+
/** The uid of the Postman collection */
|
|
799
|
+
collectionId: string;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Unwraps the OpenAPI definition returned by the Postman collection
|
|
803
|
+
* transformation endpoint, which responds with `{ output: "<stringified spec>" }`
|
|
804
|
+
* instead of the specification itself.
|
|
805
|
+
*
|
|
806
|
+
* The response is parsed exactly once. Anything that is not a transformation
|
|
807
|
+
* envelope (an error payload, an HTML page, a malformed body, …) throws instead
|
|
808
|
+
* of being silently passed through, so the real problem surfaces immediately.
|
|
809
|
+
* The unwrapped spec is then validated by the generator's parser, like any other
|
|
810
|
+
* input — this function does not re-parse or validate it.
|
|
811
|
+
*/
|
|
812
|
+
export declare function unwrapTransformationOutput(spec: string): string;
|
|
813
|
+
/**
|
|
814
|
+
* Postman platform plugin.
|
|
815
|
+
*
|
|
816
|
+
* Postman collections are not OpenAPI documents, so the plugin points `input` to
|
|
817
|
+
* the collection transformation endpoint, which converts the collection into an
|
|
818
|
+
* OpenAPI definition:
|
|
819
|
+
*
|
|
820
|
+
* ```
|
|
821
|
+
* https://api.getpostman.com/collections/<collectionId>/transformations
|
|
822
|
+
* ```
|
|
823
|
+
*
|
|
824
|
+
* The `x-api-key` header is injected through `fetchOptions`. The endpoint responds
|
|
825
|
+
* with `{ output: "<spec>" }`, so the plugin unwraps that envelope in its
|
|
826
|
+
* `beforeSpecParse` hook.
|
|
827
|
+
*
|
|
828
|
+
* `apiKey` and `collectionId` are both required — the plugin throws a clear error
|
|
829
|
+
* when either is missing.
|
|
830
|
+
*
|
|
831
|
+
* @param options - `{ apiKey, collectionId }`
|
|
832
|
+
* @param options.apiKey - Postman API key used to read the collection
|
|
833
|
+
* @param options.collectionId - The uid of the Postman collection
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* ```ts
|
|
837
|
+
* import { postman, alovaGlobals } from 'wormajs/plugin';
|
|
838
|
+
*
|
|
839
|
+
* defineConfig({
|
|
840
|
+
* generator: [{
|
|
841
|
+
* plugins: [
|
|
842
|
+
* postman({
|
|
843
|
+
* apiKey: 'PMAK-xxx',
|
|
844
|
+
* collectionId: '12345678-a1b2-c3d4-e5f6-7890abcdef12',
|
|
845
|
+
* }),
|
|
846
|
+
* alovaGlobals(),
|
|
847
|
+
* ],
|
|
848
|
+
* output: './src/api',
|
|
849
|
+
* }]
|
|
850
|
+
* });
|
|
851
|
+
* ```
|
|
852
|
+
*/
|
|
853
|
+
export declare function postman({ apiKey, collectionId }: PostmanOptions): ApiPlugin;
|
|
769
854
|
/**
|
|
770
855
|
* Rename style options
|
|
771
856
|
*/
|