@savvy-web/rslib-builder 0.17.0 → 0.18.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.
Files changed (3) hide show
  1. package/index.d.ts +51 -0
  2. package/index.js +46 -4
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -135,6 +135,32 @@ export declare interface ApiModelOptions {
135
135
  * `"include"` otherwise
136
136
  */
137
137
  forgottenExports?: "include" | "error" | "ignore";
138
+ /**
139
+ * Declarative rules for suppressing specific API Extractor warning messages.
140
+ *
141
+ * @remarks
142
+ * Each rule matches on `messageId` (exact), `pattern` (RegExp with substring fallback),
143
+ * or both (AND logic). Suppression is evaluated before `forgottenExports` and TSDoc
144
+ * warning handling and takes priority over both.
145
+ *
146
+ * After each entry, the number of suppressed messages is logged at info level.
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * import type { ApiModelOptions } from '@savvy-web/rslib-builder';
151
+ *
152
+ * const apiModel: ApiModelOptions = {
153
+ * forgottenExports: 'error',
154
+ * suppressWarnings: [
155
+ * // Suppress forgotten-export for Effect _base symbols
156
+ * { messageId: 'ae-forgotten-export', pattern: '_base' },
157
+ * // Suppress a specific TSDoc warning category
158
+ * { messageId: 'tsdoc-param-tag-missing-hyphen' },
159
+ * ],
160
+ * };
161
+ * ```
162
+ */
163
+ suppressWarnings?: WarningSuppressionRule[];
138
164
  }
139
165
 
140
166
  /**
@@ -3373,4 +3399,29 @@ export declare class TsconfigResolver {
3373
3399
  virtualEntryNames: Set<string>;
3374
3400
  }
3375
3401
 
3402
+ /**
3403
+ * A declarative rule for suppressing a specific API Extractor warning message.
3404
+ *
3405
+ * @remarks
3406
+ * Both `messageId` and `pattern` must match when both are specified (AND logic).
3407
+ * Specify at least one field per rule — a rule with neither field matches all messages.
3408
+ *
3409
+ * `pattern` is first tried as a RegExp. If the string is not a valid regular
3410
+ * expression it falls back to substring matching.
3411
+ *
3412
+ * @public
3413
+ */
3414
+ export declare interface WarningSuppressionRule {
3415
+ /**
3416
+ * Exact match against the message's `messageId` property
3417
+ * (e.g., `"ae-forgotten-export"`, `"tsdoc-param-tag-missing-hyphen"`).
3418
+ */
3419
+ messageId?: string;
3420
+ /**
3421
+ * Pattern matched against the message's `text` property.
3422
+ * Tried as a RegExp first; falls back to case-sensitive substring match.
3423
+ */
3424
+ pattern?: string;
3425
+ }
3426
+
3376
3427
  export { }
package/index.js CHANGED
@@ -597,6 +597,34 @@ const TSConfigs = {
597
597
  }
598
598
  }
599
599
  };
600
+ function compileRule(rule) {
601
+ let regex = null;
602
+ let literal;
603
+ if (void 0 !== rule.pattern) try {
604
+ regex = new RegExp(rule.pattern);
605
+ } catch {
606
+ literal = rule.pattern;
607
+ }
608
+ return {
609
+ messageId: rule.messageId,
610
+ regex,
611
+ literal
612
+ };
613
+ }
614
+ function matchesCompiled(rule, messageId, text) {
615
+ if (void 0 !== rule.messageId && messageId !== rule.messageId) return false;
616
+ if (null !== rule.regex) return rule.regex.test(text ?? "");
617
+ if (void 0 !== rule.literal) return (text ?? "").includes(rule.literal);
618
+ return true;
619
+ }
620
+ function createMessageSuppressor(rules) {
621
+ const compiled = rules.map(compileRule);
622
+ return {
623
+ matches (messageId, text) {
624
+ return compiled.some((rule)=>matchesCompiled(rule, messageId, text));
625
+ }
626
+ };
627
+ }
600
628
  class TsconfigResolverError extends Error {
601
629
  option;
602
630
  value;
@@ -1115,11 +1143,13 @@ async function bundleDtsFiles(options) {
1115
1143
  const bundledFiles = new Map();
1116
1144
  const apiModelPaths = new Map();
1117
1145
  let tsdocMetadataPath;
1118
- const apiModelEnabled = true === apiModel || "object" == typeof apiModel;
1146
+ const apiModelEnabled = (true === apiModel || "object" == typeof apiModel) && "dev" !== options.buildMode;
1119
1147
  const tsdocOptions = "object" == typeof apiModel ? apiModel.tsdoc : void 0;
1120
1148
  const tsdocMetadataOption = "object" == typeof apiModel ? apiModel.tsdocMetadata : void 0;
1121
1149
  const tsdocWarnings = tsdocOptions?.warnings ?? (TsDocConfigBuilder.isCI() ? "fail" : "log");
1122
1150
  const forgottenExports = ("object" == typeof apiModel ? apiModel.forgottenExports : void 0) ?? (TsDocConfigBuilder.isCI() ? "error" : "include");
1151
+ const suppressWarnings = "object" == typeof apiModel ? apiModel.suppressWarnings ?? [] : [];
1152
+ const suppressor = createMessageSuppressor(suppressWarnings);
1123
1153
  const tsdocMetadataEnabled = apiModelEnabled && (void 0 === tsdocMetadataOption || true === tsdocMetadataOption || "object" == typeof tsdocMetadataOption && false !== tsdocMetadataOption.enabled);
1124
1154
  const tsdocMetadataFilename = resolveTsdocMetadataFilename(apiModel);
1125
1155
  getApiExtractorPath();
@@ -1196,10 +1226,16 @@ async function bundleDtsFiles(options) {
1196
1226
  const extractorConfig = ExtractorConfig.prepare(prepareOptions);
1197
1227
  const collectedTsdocWarnings = [];
1198
1228
  const collectedForgottenExports = [];
1229
+ const suppressedMessages = [];
1199
1230
  const extractorResult = Extractor.invoke(extractorConfig, {
1200
1231
  localBuild: true,
1201
1232
  showVerboseMessages: false,
1202
1233
  messageCallback: (message)=>{
1234
+ if (suppressor.matches(message.messageId, message.text)) {
1235
+ message.logLevel = ExtractorLogLevel.None;
1236
+ suppressedMessages.push(`[${message.messageId ?? "unknown"}] ${message.text ?? ""}`);
1237
+ return;
1238
+ }
1203
1239
  if (message.text?.includes("Analysis will use the bundled TypeScript version") || message.text?.includes("The target project appears to use TypeScript")) {
1204
1240
  message.logLevel = ExtractorLogLevel.None;
1205
1241
  return;
@@ -1244,6 +1280,10 @@ async function bundleDtsFiles(options) {
1244
1280
  }
1245
1281
  });
1246
1282
  if (!extractorResult.succeeded) throw new Error(`API Extractor failed for entry "${entryName}"`);
1283
+ if (suppressedMessages.length > 0) {
1284
+ const list = suppressedMessages.map((t)=>` ${picocolors.dim(t)}`).join("\n");
1285
+ core_logger.info(`Suppressed ${suppressedMessages.length} API Extractor message${1 === suppressedMessages.length ? "" : "s"} for entry "${entryName}":\n${list}`);
1286
+ }
1247
1287
  const formatWarning = (warning)=>{
1248
1288
  const location = warning.sourceFilePath ? `${picocolors.cyan(relative(cwd, warning.sourceFilePath))}${warning.sourceFileLine ? `:${warning.sourceFileLine}` : ""}${warning.sourceFileColumn ? `:${warning.sourceFileColumn}` : ""}` : null;
1249
1289
  return location ? `${location}: ${picocolors.yellow(warning.text)}` : picocolors.yellow(warning.text);
@@ -1573,6 +1613,9 @@ function runTsgo(options) {
1573
1613
  },
1574
1614
  ...options.format && {
1575
1615
  format: options.format
1616
+ },
1617
+ ...options.buildMode && {
1618
+ buildMode: options.buildMode
1576
1619
  }
1577
1620
  });
1578
1621
  let apiModelPath;
@@ -2887,7 +2930,6 @@ if (module.exports && module.exports.__esModule && 'default' in module.exports)
2887
2930
  target: void 0,
2888
2931
  pkg
2889
2932
  }) : void 0;
2890
- const apiModelForMode = "npm" === mode ? options.apiModel : void 0;
2891
2933
  const sourceMap = "dev" === mode;
2892
2934
  const externalsConfig = options.externals && options.externals.length > 0 ? {
2893
2935
  externals: options.externals
@@ -2949,8 +2991,8 @@ if (module.exports && module.exports.__esModule && 'default' in module.exports)
2949
2991
  },
2950
2992
  buildMode: mode,
2951
2993
  format: primaryFormat,
2952
- ...void 0 !== apiModelForMode && {
2953
- apiModel: apiModelForMode
2994
+ ...void 0 !== options.apiModel && {
2995
+ apiModel: options.apiModel
2954
2996
  },
2955
2997
  ...isDualFormat && {
2956
2998
  dtsPathPrefix: primaryFormat
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/rslib-builder",
3
- "version": "0.17.0",
3
+ "version": "0.18.1",
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
  "keywords": [