@savvy-web/rslib-builder 0.1.2 → 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.
- package/index.d.ts +241 -16
- package/index.js +178 -6
- package/package.json +5 -2
- package/tsdoc-metadata.json +11 -0
package/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
import type { ConfigParams } from '@rslib/core';
|
|
43
43
|
import type { PackageJson } from 'type-fest';
|
|
44
|
+
import type { PathLike } from 'node:fs';
|
|
44
45
|
import type { RawCopyPattern } from '@rspack/binding';
|
|
45
46
|
import type { RsbuildPlugin } from '@rsbuild/core';
|
|
46
47
|
import type { RslibConfig } from '@rslib/core';
|
|
@@ -90,13 +91,38 @@ export declare interface ApiModelOptions {
|
|
|
90
91
|
* ```
|
|
91
92
|
*/
|
|
92
93
|
localPaths?: string[];
|
|
94
|
+
/**
|
|
95
|
+
* TSDoc configuration for custom tag definitions.
|
|
96
|
+
* Passed to API Extractor for documentation processing.
|
|
97
|
+
*
|
|
98
|
+
* @remarks
|
|
99
|
+
* By default, all standard tag groups (core, extended, discretionary) are
|
|
100
|
+
* enabled. Custom tags defined in `tagDefinitions` are automatically
|
|
101
|
+
* supported. Use `supportForTags` only to disable specific tags.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* apiModel: {
|
|
106
|
+
* enabled: true,
|
|
107
|
+
* tsdoc: {
|
|
108
|
+
* tagDefinitions: [{ tagName: "@error", syntaxKind: "inline" }]
|
|
109
|
+
* }
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
tsdoc?: TsDocOptions;
|
|
114
|
+
/**
|
|
115
|
+
* Options for tsdoc-metadata.json generation.
|
|
116
|
+
* @defaultValue true (enabled when apiModel is enabled)
|
|
117
|
+
*/
|
|
118
|
+
tsdocMetadata?: TsDocMetadataOptions | boolean;
|
|
93
119
|
}
|
|
94
120
|
|
|
95
121
|
/**
|
|
96
122
|
* Plugin to read package.json and configure entry points based on exports.
|
|
97
123
|
*
|
|
98
|
-
* @param options - Plugin configuration options
|
|
99
|
-
*
|
|
124
|
+
* @param options - Plugin configuration options with properties:
|
|
125
|
+
* - `exportsAsIndexes`: When true, export paths create index files in nested directories
|
|
100
126
|
* @public
|
|
101
127
|
*/
|
|
102
128
|
export declare const AutoEntryPlugin: (options?: {
|
|
@@ -122,7 +148,7 @@ export declare function collectDtsFiles(dir: string, baseDir?: string): Promise<
|
|
|
122
148
|
* Plugin to generate TypeScript declaration files using tsgo and emit them through Rslib's asset pipeline.
|
|
123
149
|
*
|
|
124
150
|
* @remarks
|
|
125
|
-
* This plugin uses tsgo (
|
|
151
|
+
* This plugin uses tsgo (`\@typescript/native-preview`) for faster declaration file generation
|
|
126
152
|
* and integrates with Rslib's build system by emitting generated files as compilation assets.
|
|
127
153
|
*
|
|
128
154
|
* ## Features
|
|
@@ -205,7 +231,7 @@ export declare interface DtsPluginOptions {
|
|
|
205
231
|
/**
|
|
206
232
|
* Packages whose types should be bundled (inlined) into the output .d.ts files.
|
|
207
233
|
* Only applies when bundle is true.
|
|
208
|
-
* Supports glob patterns (e.g., '
|
|
234
|
+
* Supports glob patterns (e.g., '\@commitlint/*', 'type-fest')
|
|
209
235
|
* @defaultValue []
|
|
210
236
|
*/
|
|
211
237
|
bundledPackages?: string[];
|
|
@@ -250,7 +276,7 @@ export declare function ensureTempDeclarationDir(cwd: string, name: string): Pro
|
|
|
250
276
|
* TypeScript source files.
|
|
251
277
|
*
|
|
252
278
|
* **Export Path Mapping:**
|
|
253
|
-
* - Converts export keys to entry names (e.g., "./utils"
|
|
279
|
+
* - Converts export keys to entry names (e.g., "./utils" becomes "utils")
|
|
254
280
|
* - Maps the root export "." to "index" entry
|
|
255
281
|
* - Replaces path separators with hyphens for nested exports (default)
|
|
256
282
|
* - When `exportsAsIndexes` is true, preserves path structure
|
|
@@ -506,7 +532,7 @@ export declare interface NodeLibraryBuilderOptions {
|
|
|
506
532
|
* specify which packages (including transitive dependencies) should have their types bundled.
|
|
507
533
|
* This is particularly useful for ensuring devDependencies are fully inlined without external imports.
|
|
508
534
|
*
|
|
509
|
-
* Supports minimatch patterns (e.g., '
|
|
535
|
+
* Supports minimatch patterns (e.g., '\@pnpm/**', 'picocolors')
|
|
510
536
|
*
|
|
511
537
|
* @example
|
|
512
538
|
* ```typescript
|
|
@@ -520,10 +546,10 @@ export declare interface NodeLibraryBuilderOptions {
|
|
|
520
546
|
* Optional callback to transform files after they're built but before the files array is finalized.
|
|
521
547
|
* Useful for copying/renaming files or adding additional files to the build output.
|
|
522
548
|
*
|
|
523
|
-
* @param context - Transform context
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
549
|
+
* @param context - Transform context with properties:
|
|
550
|
+
* - `compilation`: Rspack compilation object with assets
|
|
551
|
+
* - `filesArray`: Set of files that will be included in package.json files field
|
|
552
|
+
* - `target`: Current build target (dev/npm/jsr)
|
|
527
553
|
*
|
|
528
554
|
* @example
|
|
529
555
|
* ```typescript
|
|
@@ -603,7 +629,7 @@ export declare interface NodeLibraryBuilderOptions {
|
|
|
603
629
|
*
|
|
604
630
|
* @remarks
|
|
605
631
|
* This class consolidates all package.json transformation logic including:
|
|
606
|
-
* - Path transformations (src/
|
|
632
|
+
* - Path transformations (src/ to dist/, .ts to .js)
|
|
607
633
|
* - Export conditions generation (types, import, require)
|
|
608
634
|
* - Bin field transformations
|
|
609
635
|
* - PNPM catalog and workspace resolution
|
|
@@ -680,9 +706,9 @@ export declare class PackageJsonTransformer {
|
|
|
680
706
|
* Performs the complete package.json transformation.
|
|
681
707
|
*
|
|
682
708
|
* @param packageJson - The source package.json
|
|
683
|
-
* @param context - Transform context
|
|
684
|
-
*
|
|
685
|
-
*
|
|
709
|
+
* @param context - Transform context with properties:
|
|
710
|
+
* - `isProduction`: Whether this is a production build
|
|
711
|
+
* - `customTransform`: Optional custom transform function
|
|
686
712
|
* @returns The transformed package.json
|
|
687
713
|
*/
|
|
688
714
|
transform(packageJson: PackageJson, context?: {
|
|
@@ -723,7 +749,7 @@ export declare interface PackageJsonTransformOptions {
|
|
|
723
749
|
*/
|
|
724
750
|
processTSExports?: boolean;
|
|
725
751
|
/**
|
|
726
|
-
* Whether to collapse index files (./foo/index.ts
|
|
752
|
+
* Whether to collapse index files (./foo/index.ts becomes ./foo.js).
|
|
727
753
|
* This is typically true for bundled builds.
|
|
728
754
|
* @defaultValue false
|
|
729
755
|
*/
|
|
@@ -816,7 +842,7 @@ export declare class PnpmCatalog {
|
|
|
816
842
|
* @param dir - The directory containing the package (defaults to cwd)
|
|
817
843
|
* @returns The resolved package.json
|
|
818
844
|
*
|
|
819
|
-
* @throws
|
|
845
|
+
* @throws When resolution fails for critical dependencies
|
|
820
846
|
*/
|
|
821
847
|
resolvePackageJson(packageJson: PackageJson, dir?: string): Promise<PackageJson>;
|
|
822
848
|
/**
|
|
@@ -859,4 +885,203 @@ export declare type TransformPackageJsonFn = (context: {
|
|
|
859
885
|
pkg: PackageJson;
|
|
860
886
|
}) => PackageJson;
|
|
861
887
|
|
|
888
|
+
/**
|
|
889
|
+
* Builder for TSDoc configuration files.
|
|
890
|
+
* Handles tag group expansion, config generation, and file persistence.
|
|
891
|
+
* @public
|
|
892
|
+
*/
|
|
893
|
+
export declare class TsDocConfigBuilder {
|
|
894
|
+
/** All available TSDoc tag groups. */
|
|
895
|
+
static readonly ALL_GROUPS: TsDocTagGroup[];
|
|
896
|
+
/** Maps group names to TSDoc Standardization enum values. */
|
|
897
|
+
private static readonly GROUP_TO_STANDARDIZATION;
|
|
898
|
+
/**
|
|
899
|
+
* Standard TSDoc tag definitions organized by standardization group.
|
|
900
|
+
* Lazily computed from `\@microsoft/tsdoc` StandardTags.
|
|
901
|
+
*/
|
|
902
|
+
static readonly TAG_GROUPS: Record<TsDocTagGroup, TsDocTagDefinition[]>;
|
|
903
|
+
/**
|
|
904
|
+
* Detects if running in a CI environment.
|
|
905
|
+
* @returns true if CI or GITHUB_ACTIONS environment variable is "true"
|
|
906
|
+
*/
|
|
907
|
+
static isCI(): boolean;
|
|
908
|
+
/**
|
|
909
|
+
* Gets standard TSDoc tag definitions for a specific group.
|
|
910
|
+
* Uses StandardTags from `\@microsoft/tsdoc` package.
|
|
911
|
+
*/
|
|
912
|
+
static getTagsForGroup(group: TsDocTagGroup): TsDocTagDefinition[];
|
|
913
|
+
/**
|
|
914
|
+
* Determines if the TSDoc config should be persisted to disk.
|
|
915
|
+
* @param persistConfig - The persistConfig option value
|
|
916
|
+
* @returns true if the config should be persisted
|
|
917
|
+
*/
|
|
918
|
+
static shouldPersist(persistConfig: boolean | PathLike | undefined): boolean;
|
|
919
|
+
/**
|
|
920
|
+
* Gets the output path for the tsdoc.json file.
|
|
921
|
+
* @param persistConfig - The persistConfig option value
|
|
922
|
+
* @param cwd - The current working directory
|
|
923
|
+
* @returns The absolute path where tsdoc.json should be written
|
|
924
|
+
*/
|
|
925
|
+
static getConfigPath(persistConfig: boolean | PathLike | undefined, cwd: string): string;
|
|
926
|
+
/**
|
|
927
|
+
* Builds the complete TSDoc configuration from options.
|
|
928
|
+
*
|
|
929
|
+
* @remarks
|
|
930
|
+
* When all groups are enabled (default), returns `useStandardTags: true` to signal
|
|
931
|
+
* that the generated config should use `noStandardTags: false` and let TSDoc
|
|
932
|
+
* automatically load all standard tags. However, `supportForTags` is still populated
|
|
933
|
+
* because API Extractor requires explicit support declarations for each tag.
|
|
934
|
+
*
|
|
935
|
+
* When a subset of groups is specified, returns `useStandardTags: false` to signal
|
|
936
|
+
* that we must explicitly define which tags to include via `noStandardTags: true`.
|
|
937
|
+
*/
|
|
938
|
+
static build(options?: TsDocOptions): {
|
|
939
|
+
tagDefinitions: TsDocTagDefinition[];
|
|
940
|
+
supportForTags: Record<string, boolean>;
|
|
941
|
+
useStandardTags: boolean;
|
|
942
|
+
};
|
|
943
|
+
/**
|
|
944
|
+
* Generates a tsdoc.json file from options.
|
|
945
|
+
*
|
|
946
|
+
* @remarks
|
|
947
|
+
* When all groups are enabled (default), generates a minimal config with
|
|
948
|
+
* `noStandardTags: false` so TSDoc automatically loads all standard tags.
|
|
949
|
+
* Only custom tags need to be defined in this case.
|
|
950
|
+
*
|
|
951
|
+
* When a subset of groups is specified, generates a config with
|
|
952
|
+
* `noStandardTags: true` and explicitly defines only the tags from
|
|
953
|
+
* the enabled groups.
|
|
954
|
+
*/
|
|
955
|
+
static writeConfigFile(options: TsDocOptions | undefined, outputDir: string): Promise<string>;
|
|
956
|
+
/** Converts TSDocTagSyntaxKind enum to string format. */
|
|
957
|
+
private static syntaxKindToString;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* Options for tsdoc-metadata.json generation.
|
|
962
|
+
* @public
|
|
963
|
+
*/
|
|
964
|
+
export declare interface TsDocMetadataOptions {
|
|
965
|
+
/**
|
|
966
|
+
* Whether to generate tsdoc-metadata.json.
|
|
967
|
+
* @defaultValue true (when apiModel is enabled)
|
|
968
|
+
*/
|
|
969
|
+
enabled?: boolean;
|
|
970
|
+
/**
|
|
971
|
+
* Custom filename for the TSDoc metadata file.
|
|
972
|
+
* @defaultValue "tsdoc-metadata.json"
|
|
973
|
+
*/
|
|
974
|
+
filename?: string;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* TSDoc configuration options for API Extractor.
|
|
979
|
+
* @remarks
|
|
980
|
+
* Provides ergonomic defaults - standard tags are auto-enabled via `groups`,
|
|
981
|
+
* custom tags are auto-supported, and `supportForTags` is only needed to
|
|
982
|
+
* disable specific tags.
|
|
983
|
+
*
|
|
984
|
+
* **Config optimization:** When all groups are enabled (default), the generated
|
|
985
|
+
* `tsdoc.json` uses `noStandardTags: false` to let TSDoc automatically load
|
|
986
|
+
* all standard tags, producing a minimal config file. When a subset of groups
|
|
987
|
+
* is specified, `noStandardTags: true` is used and only the enabled groups'
|
|
988
|
+
* tags are explicitly defined.
|
|
989
|
+
*
|
|
990
|
+
* @public
|
|
991
|
+
*/
|
|
992
|
+
export declare interface TsDocOptions {
|
|
993
|
+
/**
|
|
994
|
+
* TSDoc tag groups to enable. Each group includes predefined standard tags
|
|
995
|
+
* from the official `\@microsoft/tsdoc` package.
|
|
996
|
+
* - "core": Essential TSDoc tags (\@param, \@returns, \@remarks, \@deprecated, etc.)
|
|
997
|
+
* - "extended": Additional tags (\@example, \@defaultValue, \@see, \@throws, etc.)
|
|
998
|
+
* - "discretionary": Release stage tags (\@alpha, \@beta, \@public, \@internal)
|
|
999
|
+
*
|
|
1000
|
+
* @remarks
|
|
1001
|
+
* When all groups are enabled (the default), the generated config uses
|
|
1002
|
+
* `noStandardTags: false` and TSDoc loads standard tags automatically.
|
|
1003
|
+
* When a subset is specified, `noStandardTags: true` is used and only
|
|
1004
|
+
* the tags from enabled groups are defined.
|
|
1005
|
+
*
|
|
1006
|
+
* @defaultValue ["core", "extended", "discretionary"]
|
|
1007
|
+
*/
|
|
1008
|
+
groups?: TsDocTagGroup[];
|
|
1009
|
+
/**
|
|
1010
|
+
* Custom TSDoc tag definitions beyond the standard groups.
|
|
1011
|
+
* These are automatically added to supportForTags (no need to declare twice).
|
|
1012
|
+
*
|
|
1013
|
+
* @example
|
|
1014
|
+
* ```typescript
|
|
1015
|
+
* tagDefinitions: [
|
|
1016
|
+
* { tagName: "@error", syntaxKind: "inline" },
|
|
1017
|
+
* { tagName: "@category", syntaxKind: "block", allowMultiple: false }
|
|
1018
|
+
* ]
|
|
1019
|
+
* ```
|
|
1020
|
+
*/
|
|
1021
|
+
tagDefinitions?: TsDocTagDefinition[];
|
|
1022
|
+
/**
|
|
1023
|
+
* Override support for specific tags. Only needed to DISABLE tags.
|
|
1024
|
+
* Tags from enabled groups and custom tagDefinitions are auto-supported.
|
|
1025
|
+
*
|
|
1026
|
+
* @example
|
|
1027
|
+
* ```typescript
|
|
1028
|
+
* // Disable @beta even though "extended" group is enabled
|
|
1029
|
+
* supportForTags: { "@beta": false }
|
|
1030
|
+
* ```
|
|
1031
|
+
*/
|
|
1032
|
+
supportForTags?: Record<string, boolean>;
|
|
1033
|
+
/**
|
|
1034
|
+
* Persist tsdoc.json to disk for tool integration (ESLint, IDEs).
|
|
1035
|
+
* - `true`: Write to project root as "tsdoc.json"
|
|
1036
|
+
* - `PathLike`: Write to specified path
|
|
1037
|
+
* - `false`: Clean up after API Extractor
|
|
1038
|
+
*
|
|
1039
|
+
* @defaultValue `true` when `CI` and `GITHUB_ACTIONS` env vars are not "true",
|
|
1040
|
+
* `false` otherwise (CI environments)
|
|
1041
|
+
*/
|
|
1042
|
+
persistConfig?: boolean | PathLike;
|
|
1043
|
+
/**
|
|
1044
|
+
* How to handle TSDoc validation warnings from API Extractor.
|
|
1045
|
+
* - `"log"`: Show warnings in the console but continue the build
|
|
1046
|
+
* - `"fail"`: Show warnings and fail the build if any are found
|
|
1047
|
+
* - `"none"`: Suppress TSDoc warnings entirely
|
|
1048
|
+
*
|
|
1049
|
+
* @remarks
|
|
1050
|
+
* TSDoc warnings include unknown tags, malformed syntax, and other
|
|
1051
|
+
* documentation issues detected by API Extractor during processing.
|
|
1052
|
+
*
|
|
1053
|
+
* @example
|
|
1054
|
+
* ```typescript
|
|
1055
|
+
* // Fail build on any TSDoc issues (CI default)
|
|
1056
|
+
* warnings: "fail"
|
|
1057
|
+
*
|
|
1058
|
+
* // Show warnings but continue build (local default)
|
|
1059
|
+
* warnings: "log"
|
|
1060
|
+
* ```
|
|
1061
|
+
*
|
|
1062
|
+
* @defaultValue `"fail"` in CI environments (`CI` or `GITHUB_ACTIONS` env vars),
|
|
1063
|
+
* `"log"` otherwise
|
|
1064
|
+
*/
|
|
1065
|
+
warnings?: "log" | "fail" | "none";
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
/**
|
|
1069
|
+
* TSDoc tag definition for custom documentation tags.
|
|
1070
|
+
* @public
|
|
1071
|
+
*/
|
|
1072
|
+
export declare interface TsDocTagDefinition {
|
|
1073
|
+
/** The tag name including the at-sign prefix (e.g., `\@error`, `\@category`) */
|
|
1074
|
+
tagName: string;
|
|
1075
|
+
/** How the tag is parsed: "block" | "inline" | "modifier" */
|
|
1076
|
+
syntaxKind: "block" | "inline" | "modifier";
|
|
1077
|
+
/** Whether the tag can appear multiple times on a declaration */
|
|
1078
|
+
allowMultiple?: boolean;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* TSDoc standardization groups for predefined tag sets.
|
|
1083
|
+
* @public
|
|
1084
|
+
*/
|
|
1085
|
+
export declare type TsDocTagGroup = "core" | "extended" | "discretionary";
|
|
1086
|
+
|
|
862
1087
|
export { }
|
package/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { getWorkspaceRoot } from "workspace-tools";
|
|
|
8
8
|
import { logger as core_logger } from "@rsbuild/core";
|
|
9
9
|
import picocolors from "picocolors";
|
|
10
10
|
import { spawn } from "node:child_process";
|
|
11
|
+
import { StandardTags, Standardization, TSDocTagSyntaxKind } from "@microsoft/tsdoc";
|
|
11
12
|
import { createCompilerHost, findConfigFile, formatDiagnostic, parseJsonConfigFileContent, readConfigFile, sys } from "typescript";
|
|
12
13
|
import { createRequire } from "node:module";
|
|
13
14
|
import { inspect } from "node:util";
|
|
@@ -394,6 +395,98 @@ const TSConfigs = {
|
|
|
394
395
|
}
|
|
395
396
|
}
|
|
396
397
|
};
|
|
398
|
+
class TsDocConfigBuilder {
|
|
399
|
+
static ALL_GROUPS = [
|
|
400
|
+
"core",
|
|
401
|
+
"extended",
|
|
402
|
+
"discretionary"
|
|
403
|
+
];
|
|
404
|
+
static GROUP_TO_STANDARDIZATION = {
|
|
405
|
+
core: Standardization.Core,
|
|
406
|
+
extended: Standardization.Extended,
|
|
407
|
+
discretionary: Standardization.Discretionary
|
|
408
|
+
};
|
|
409
|
+
static TAG_GROUPS = {
|
|
410
|
+
get core () {
|
|
411
|
+
return TsDocConfigBuilder.getTagsForGroup("core");
|
|
412
|
+
},
|
|
413
|
+
get extended () {
|
|
414
|
+
return TsDocConfigBuilder.getTagsForGroup("extended");
|
|
415
|
+
},
|
|
416
|
+
get discretionary () {
|
|
417
|
+
return TsDocConfigBuilder.getTagsForGroup("discretionary");
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
static isCI() {
|
|
421
|
+
return "true" === process.env.CI || "true" === process.env.GITHUB_ACTIONS;
|
|
422
|
+
}
|
|
423
|
+
static getTagsForGroup(group) {
|
|
424
|
+
const standardization = TsDocConfigBuilder.GROUP_TO_STANDARDIZATION[group];
|
|
425
|
+
return StandardTags.allDefinitions.filter((tag)=>tag.standardization === standardization).map((tag)=>({
|
|
426
|
+
tagName: tag.tagName,
|
|
427
|
+
syntaxKind: TsDocConfigBuilder.syntaxKindToString(tag.syntaxKind),
|
|
428
|
+
...tag.allowMultiple ? {
|
|
429
|
+
allowMultiple: true
|
|
430
|
+
} : {}
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
static shouldPersist(persistConfig) {
|
|
434
|
+
if (false === persistConfig) return false;
|
|
435
|
+
if (void 0 !== persistConfig) return true;
|
|
436
|
+
return !TsDocConfigBuilder.isCI();
|
|
437
|
+
}
|
|
438
|
+
static getConfigPath(persistConfig, cwd) {
|
|
439
|
+
if ("string" == typeof persistConfig) return (0, external_node_path_.isAbsolute)(persistConfig) ? persistConfig : (0, external_node_path_.join)(cwd, persistConfig);
|
|
440
|
+
if (persistConfig instanceof URL || Buffer.isBuffer(persistConfig)) {
|
|
441
|
+
const pathStr = persistConfig.toString();
|
|
442
|
+
return (0, external_node_path_.isAbsolute)(pathStr) ? pathStr : (0, external_node_path_.join)(cwd, pathStr);
|
|
443
|
+
}
|
|
444
|
+
return (0, external_node_path_.join)(cwd, "tsdoc.json");
|
|
445
|
+
}
|
|
446
|
+
static build(options = {}) {
|
|
447
|
+
const groups = options.groups ?? TsDocConfigBuilder.ALL_GROUPS;
|
|
448
|
+
const allGroupsEnabled = TsDocConfigBuilder.ALL_GROUPS.every((g)=>groups.includes(g));
|
|
449
|
+
const tagDefinitions = [];
|
|
450
|
+
const supportForTags = {};
|
|
451
|
+
for (const group of groups)for (const tag of TsDocConfigBuilder.TAG_GROUPS[group]){
|
|
452
|
+
supportForTags[tag.tagName] = true;
|
|
453
|
+
if (!allGroupsEnabled) tagDefinitions.push(tag);
|
|
454
|
+
}
|
|
455
|
+
if (options.tagDefinitions) for (const tag of options.tagDefinitions){
|
|
456
|
+
tagDefinitions.push(tag);
|
|
457
|
+
supportForTags[tag.tagName] = true;
|
|
458
|
+
}
|
|
459
|
+
if (options.supportForTags) Object.assign(supportForTags, options.supportForTags);
|
|
460
|
+
return {
|
|
461
|
+
tagDefinitions,
|
|
462
|
+
supportForTags,
|
|
463
|
+
useStandardTags: allGroupsEnabled
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
static async writeConfigFile(options = {}, outputDir) {
|
|
467
|
+
const { tagDefinitions, supportForTags, useStandardTags } = TsDocConfigBuilder.build(options);
|
|
468
|
+
const tsdocConfig = {
|
|
469
|
+
$schema: "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
|
|
470
|
+
noStandardTags: !useStandardTags,
|
|
471
|
+
reportUnsupportedHtmlElements: false
|
|
472
|
+
};
|
|
473
|
+
if (tagDefinitions.length > 0) tsdocConfig.tagDefinitions = tagDefinitions;
|
|
474
|
+
if (Object.keys(supportForTags).length > 0) tsdocConfig.supportForTags = supportForTags;
|
|
475
|
+
const configPath = (0, external_node_path_.join)(outputDir, "tsdoc.json");
|
|
476
|
+
await writeFile(configPath, JSON.stringify(tsdocConfig, null, 2));
|
|
477
|
+
return configPath;
|
|
478
|
+
}
|
|
479
|
+
static syntaxKindToString(kind) {
|
|
480
|
+
switch(kind){
|
|
481
|
+
case TSDocTagSyntaxKind.InlineTag:
|
|
482
|
+
return "inline";
|
|
483
|
+
case TSDocTagSyntaxKind.BlockTag:
|
|
484
|
+
return "block";
|
|
485
|
+
case TSDocTagSyntaxKind.ModifierTag:
|
|
486
|
+
return "modifier";
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
397
490
|
function getUnscopedPackageName(name) {
|
|
398
491
|
return name.startsWith("@") ? name.split("/")[1] ?? name : name;
|
|
399
492
|
}
|
|
@@ -448,9 +541,25 @@ async function bundleDtsFiles(options) {
|
|
|
448
541
|
const { cwd, tempDtsDir, tempOutputDir, tsconfigPath, bundledPackages, entryPoints, banner, footer, apiModel } = options;
|
|
449
542
|
const bundledFiles = new Map();
|
|
450
543
|
let apiModelPath;
|
|
544
|
+
let tsdocMetadataPath;
|
|
451
545
|
const apiModelEnabled = true === apiModel || "object" == typeof apiModel && (void 0 === apiModel.enabled || true === apiModel.enabled);
|
|
452
546
|
const apiModelFilename = "object" == typeof apiModel && apiModel.filename ? apiModel.filename : "api.json";
|
|
547
|
+
const tsdocOptions = "object" == typeof apiModel ? apiModel.tsdoc : void 0;
|
|
548
|
+
const tsdocMetadataOption = "object" == typeof apiModel ? apiModel.tsdocMetadata : void 0;
|
|
549
|
+
const tsdocWarnings = tsdocOptions?.warnings ?? (TsDocConfigBuilder.isCI() ? "fail" : "log");
|
|
550
|
+
const tsdocMetadataEnabled = apiModelEnabled && (void 0 === tsdocMetadataOption || true === tsdocMetadataOption || "object" == typeof tsdocMetadataOption && false !== tsdocMetadataOption.enabled);
|
|
551
|
+
const tsdocMetadataFilename = "object" == typeof tsdocMetadataOption && tsdocMetadataOption.filename ? tsdocMetadataOption.filename : "tsdoc-metadata.json";
|
|
453
552
|
getApiExtractorPath();
|
|
553
|
+
const persistConfig = tsdocOptions?.persistConfig;
|
|
554
|
+
const shouldPersist = TsDocConfigBuilder.shouldPersist(persistConfig);
|
|
555
|
+
const tsdocConfigOutputPath = TsDocConfigBuilder.getConfigPath(persistConfig, cwd);
|
|
556
|
+
let tsdocConfigPath;
|
|
557
|
+
let tsdocConfigFile;
|
|
558
|
+
if (apiModelEnabled) {
|
|
559
|
+
tsdocConfigPath = await TsDocConfigBuilder.writeConfigFile(tsdocOptions ?? {}, (0, external_node_path_.dirname)(tsdocConfigOutputPath));
|
|
560
|
+
const { TSDocConfigFile } = await import("@microsoft/tsdoc-config");
|
|
561
|
+
tsdocConfigFile = TSDocConfigFile.loadForFolder((0, external_node_path_.dirname)(tsdocConfigPath));
|
|
562
|
+
}
|
|
454
563
|
const { Extractor, ExtractorConfig } = await import("@microsoft/api-extractor");
|
|
455
564
|
for (const [entryName, sourcePath] of entryPoints){
|
|
456
565
|
const normalizedSourcePath = sourcePath.replace(/^\.\//, "");
|
|
@@ -472,6 +581,8 @@ async function bundleDtsFiles(options) {
|
|
|
472
581
|
const tempBundledPath = (0, external_node_path_.join)(tempOutputDir, outputFileName);
|
|
473
582
|
const generateApiModel = apiModelEnabled && "index" === entryName;
|
|
474
583
|
const tempApiModelPath = generateApiModel ? (0, external_node_path_.join)(tempOutputDir, apiModelFilename) : void 0;
|
|
584
|
+
const generateTsdocMetadata = tsdocMetadataEnabled && "index" === entryName;
|
|
585
|
+
const tempTsdocMetadataPath = generateTsdocMetadata ? (0, external_node_path_.join)(tempOutputDir, tsdocMetadataFilename) : void 0;
|
|
475
586
|
const extractorConfig = ExtractorConfig.prepare({
|
|
476
587
|
configObject: {
|
|
477
588
|
projectFolder: cwd,
|
|
@@ -487,11 +598,17 @@ async function bundleDtsFiles(options) {
|
|
|
487
598
|
enabled: true,
|
|
488
599
|
apiJsonFilePath: tempApiModelPath
|
|
489
600
|
} : void 0,
|
|
601
|
+
tsdocMetadata: generateTsdocMetadata ? {
|
|
602
|
+
enabled: true,
|
|
603
|
+
tsdocMetadataFilePath: tempTsdocMetadataPath
|
|
604
|
+
} : void 0,
|
|
490
605
|
bundledPackages: bundledPackages
|
|
491
606
|
},
|
|
492
607
|
packageJsonFullPath: (0, external_node_path_.join)(cwd, "package.json"),
|
|
493
|
-
configObjectFullPath: void 0
|
|
608
|
+
configObjectFullPath: void 0,
|
|
609
|
+
tsdocConfigFile: tsdocConfigFile
|
|
494
610
|
});
|
|
611
|
+
const collectedTsdocWarnings = [];
|
|
495
612
|
const extractorResult = Extractor.invoke(extractorConfig, {
|
|
496
613
|
localBuild: true,
|
|
497
614
|
showVerboseMessages: false,
|
|
@@ -500,11 +617,35 @@ async function bundleDtsFiles(options) {
|
|
|
500
617
|
message.logLevel = "none";
|
|
501
618
|
return;
|
|
502
619
|
}
|
|
503
|
-
if (message.text?.includes("You have changed the public API signature"))
|
|
620
|
+
if (message.text?.includes("You have changed the public API signature")) {
|
|
621
|
+
message.logLevel = "none";
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
const isTsdocMessage = message.messageId?.startsWith("tsdoc-");
|
|
625
|
+
if (isTsdocMessage && message.text) if ("none" === tsdocWarnings) message.logLevel = "none";
|
|
626
|
+
else {
|
|
627
|
+
collectedTsdocWarnings.push({
|
|
628
|
+
text: message.text,
|
|
629
|
+
sourceFilePath: message.sourceFilePath,
|
|
630
|
+
sourceFileLine: message.sourceFileLine,
|
|
631
|
+
sourceFileColumn: message.sourceFileColumn
|
|
632
|
+
});
|
|
633
|
+
message.logLevel = "none";
|
|
634
|
+
}
|
|
504
635
|
}
|
|
505
636
|
});
|
|
506
637
|
if (!extractorResult.succeeded) throw new Error(`API Extractor failed for entry "${entryName}"`);
|
|
638
|
+
if (collectedTsdocWarnings.length > 0) {
|
|
639
|
+
const formatWarning = (warning)=>{
|
|
640
|
+
const location = warning.sourceFilePath ? `${picocolors.cyan((0, external_node_path_.relative)(cwd, warning.sourceFilePath))}${warning.sourceFileLine ? `:${warning.sourceFileLine}` : ""}${warning.sourceFileColumn ? `:${warning.sourceFileColumn}` : ""}` : null;
|
|
641
|
+
return location ? `${location}: ${picocolors.yellow(warning.text)}` : picocolors.yellow(warning.text);
|
|
642
|
+
};
|
|
643
|
+
const warningMessages = collectedTsdocWarnings.map(formatWarning).join("\n ");
|
|
644
|
+
if ("fail" === tsdocWarnings) throw new Error(`TSDoc validation failed for entry "${entryName}":\n ${warningMessages}`);
|
|
645
|
+
if ("log" === tsdocWarnings) core_logger.warn(`TSDoc warnings for entry "${entryName}":\n ${warningMessages}`);
|
|
646
|
+
}
|
|
507
647
|
if (generateApiModel && tempApiModelPath) apiModelPath = tempApiModelPath;
|
|
648
|
+
if (generateTsdocMetadata && tempTsdocMetadataPath) tsdocMetadataPath = tempTsdocMetadataPath;
|
|
508
649
|
if (banner || footer) {
|
|
509
650
|
let content = await promises_readFile(tempBundledPath, "utf-8");
|
|
510
651
|
if (banner) content = `${banner}\n${content}`;
|
|
@@ -513,9 +654,16 @@ async function bundleDtsFiles(options) {
|
|
|
513
654
|
}
|
|
514
655
|
bundledFiles.set(entryName, tempBundledPath);
|
|
515
656
|
}
|
|
657
|
+
let persistedTsdocConfigPath;
|
|
658
|
+
if (tsdocConfigPath) if (shouldPersist) persistedTsdocConfigPath = tsdocConfigPath;
|
|
659
|
+
else try {
|
|
660
|
+
await unlink(tsdocConfigPath);
|
|
661
|
+
} catch {}
|
|
516
662
|
return {
|
|
517
663
|
bundledFiles,
|
|
518
|
-
apiModelPath
|
|
664
|
+
apiModelPath,
|
|
665
|
+
tsdocMetadataPath,
|
|
666
|
+
tsdocConfigPath: persistedTsdocConfigPath
|
|
519
667
|
};
|
|
520
668
|
}
|
|
521
669
|
function stripSourceMapComment(content) {
|
|
@@ -722,7 +870,7 @@ function runTsgo(options) {
|
|
|
722
870
|
await mkdir(tempBundledDir, {
|
|
723
871
|
recursive: true
|
|
724
872
|
});
|
|
725
|
-
const { bundledFiles, apiModelPath } = await bundleDtsFiles({
|
|
873
|
+
const { bundledFiles, apiModelPath, tsdocMetadataPath, tsdocConfigPath } = await bundleDtsFiles({
|
|
726
874
|
cwd,
|
|
727
875
|
tempDtsDir,
|
|
728
876
|
tempOutputDir: tempBundledDir,
|
|
@@ -766,6 +914,13 @@ function runTsgo(options) {
|
|
|
766
914
|
});
|
|
767
915
|
const apiModelDestPath = (0, external_node_path_.join)(resolvedPath, apiModelFilename);
|
|
768
916
|
await writeFile(apiModelDestPath, apiModelContent, "utf-8");
|
|
917
|
+
if (tsdocMetadataPath) {
|
|
918
|
+
const tsdocMetadataOption = "object" == typeof options.apiModel ? options.apiModel.tsdocMetadata : void 0;
|
|
919
|
+
const localTsdocFilename = "object" == typeof tsdocMetadataOption && tsdocMetadataOption.filename ? tsdocMetadataOption.filename : "tsdoc-metadata.json";
|
|
920
|
+
const tsdocContent = await promises_readFile(tsdocMetadataPath, "utf-8");
|
|
921
|
+
const tsdocDestPath = (0, external_node_path_.join)(resolvedPath, localTsdocFilename);
|
|
922
|
+
await writeFile(tsdocDestPath, tsdocContent, "utf-8");
|
|
923
|
+
}
|
|
769
924
|
const packageJsonAsset = context.compilation.assets["package.json"];
|
|
770
925
|
if (packageJsonAsset) {
|
|
771
926
|
const rawContent = "function" == typeof packageJsonAsset.source ? packageJsonAsset.source() : packageJsonAsset.source;
|
|
@@ -773,9 +928,26 @@ function runTsgo(options) {
|
|
|
773
928
|
const packageJsonDestPath = (0, external_node_path_.join)(resolvedPath, "package.json");
|
|
774
929
|
await writeFile(packageJsonDestPath, packageJsonContent, "utf-8");
|
|
775
930
|
}
|
|
776
|
-
|
|
931
|
+
const copiedFiles = tsdocMetadataPath ? "API model, tsdoc-metadata.json, and package.json" : "API model and package.json";
|
|
932
|
+
core_logger.info(`${picocolors.dim(`[${envId}]`)} Copied ${copiedFiles} to: ${localPath}`);
|
|
777
933
|
}
|
|
778
934
|
}
|
|
935
|
+
if (tsdocMetadataPath) {
|
|
936
|
+
const tsdocMetadataOption = "object" == typeof options.apiModel ? options.apiModel.tsdocMetadata : void 0;
|
|
937
|
+
const tsdocMetadataFilename = "object" == typeof tsdocMetadataOption && tsdocMetadataOption.filename ? tsdocMetadataOption.filename : "tsdoc-metadata.json";
|
|
938
|
+
const tsdocMetadataContent = await promises_readFile(tsdocMetadataPath, "utf-8");
|
|
939
|
+
const tsdocMetadataSource = new context.sources.OriginalSource(tsdocMetadataContent, tsdocMetadataFilename);
|
|
940
|
+
context.compilation.emitAsset(tsdocMetadataFilename, tsdocMetadataSource);
|
|
941
|
+
if (filesArray) filesArray.add(tsdocMetadataFilename);
|
|
942
|
+
core_logger.info(`${picocolors.dim(`[${envId}]`)} Emitted TSDoc metadata: ${tsdocMetadataFilename}`);
|
|
943
|
+
}
|
|
944
|
+
if (tsdocConfigPath) {
|
|
945
|
+
const tsdocConfigContent = await promises_readFile(tsdocConfigPath, "utf-8");
|
|
946
|
+
const tsdocConfigSource = new context.sources.OriginalSource(tsdocConfigContent, "tsdoc.json");
|
|
947
|
+
context.compilation.emitAsset("tsdoc.json", tsdocConfigSource);
|
|
948
|
+
if (filesArray) filesArray.add("!tsdoc.json");
|
|
949
|
+
core_logger.info(`${picocolors.dim(`[${envId}]`)} Emitted TSDoc config: tsdoc.json (excluded from npm publish)`);
|
|
950
|
+
}
|
|
779
951
|
for (const [entryName] of bundledFiles){
|
|
780
952
|
const bundledFileName = `${entryName}.d.ts`;
|
|
781
953
|
const mapFileName = `${bundledFileName}.map`;
|
|
@@ -1514,4 +1686,4 @@ const PackageJsonTransformPlugin = (options = {})=>{
|
|
|
1514
1686
|
});
|
|
1515
1687
|
}
|
|
1516
1688
|
}
|
|
1517
|
-
export { AutoEntryPlugin, DtsPlugin, EntryExtractor, FilesArrayPlugin, NodeLibraryBuilder, PackageJsonTransformPlugin, PackageJsonTransformer, PnpmCatalog, collectDtsFiles, ensureTempDeclarationDir, findTsConfig, generateTsgoArgs, getTsgoBinPath, getUnscopedPackageName, stripSourceMapComment };
|
|
1689
|
+
export { AutoEntryPlugin, DtsPlugin, EntryExtractor, FilesArrayPlugin, NodeLibraryBuilder, PackageJsonTransformPlugin, PackageJsonTransformer, PnpmCatalog, TsDocConfigBuilder, collectDtsFiles, ensureTempDeclarationDir, findTsConfig, generateTsgoArgs, getTsgoBinPath, getUnscopedPackageName, stripSourceMapComment };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/rslib-builder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "RSlib-based build system for Node.js libraries with automatic package.json transformation, TypeScript declaration bundling, and multi-target support",
|
|
6
6
|
"homepage": "https://github.com/savvy-web/rslib-builder",
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
"./tsconfig/node/ecma/bundleless.json": "./public/tsconfig/node/ecma/bundleless.json"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@microsoft/tsdoc": "^0.16.0",
|
|
35
|
+
"@microsoft/tsdoc-config": "^0.18.0",
|
|
34
36
|
"@pnpm/exportable-manifest": "^1000.3.0",
|
|
35
37
|
"glob": "^13.0.0",
|
|
36
38
|
"markdownlint-cli2": "^0.20.0",
|
|
@@ -80,6 +82,7 @@
|
|
|
80
82
|
"package.json",
|
|
81
83
|
"rslib-runtime.js",
|
|
82
84
|
"tsconfig/node/ecma/lib.json",
|
|
83
|
-
"tsconfig/root.json"
|
|
85
|
+
"tsconfig/root.json",
|
|
86
|
+
"tsdoc-metadata.json"
|
|
84
87
|
]
|
|
85
88
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
|
2
|
+
// It should be published with your NPM package. It should not be tracked by Git.
|
|
3
|
+
{
|
|
4
|
+
"tsdocVersion": "0.12",
|
|
5
|
+
"toolPackages": [
|
|
6
|
+
{
|
|
7
|
+
"packageName": "@microsoft/api-extractor",
|
|
8
|
+
"packageVersion": "7.55.2"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|